Glotus Client fixed

Good Working bots system

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name            Glotus Client fixed
// @author          Murka / Seldoom
// @description     Good Working bots system
// @icon            https://imagizer.imageshack.com/img924/3497/SedB2D.png
// @version         5.3 fixed by seldoom
// @match           *://moomoo.io/
// @match           *://moomoo.io/?server*
// @match           *://*.moomoo.io/
// @match           *://*.moomoo.io/?server*
// @run-at          document-start
// @grant           none
// @license         MIT
// @namespace       https://github.com/Murka007/Glotus-client
// ==/UserScript==
/* jshint esversion:6 */

/*
    Author: Murka
    Github: https://github.com/Murka007/Glotus-client
    Greasyfork: https://greasyfork.org/users/919633
    Discord: https://discord.gg/cPRFdcZkeD

    Version: 5.3
    Build Time: 23/01/2026 | 12:47:35
    Works On: index-eb87bff7.js
*/

(function() {
    function easeOutQuad(x) {
        return 1 - (1 - x) * (1 - x);
    }

    function shortAngle(a, b) {
        let PI22 = 2 * Math.PI;
        a = (a % PI22 + PI22) % PI22, b = (b % PI22 + PI22) % PI22;
        let diff = b - a;
        if (diff > PI22 / 2) {
            diff -= PI22;
        } else if (diff < -PI22 / 2) {
            diff += PI22;
        }
        return diff;
    }

    class Altcha {
        coreCount=Math.min(16, navigator.hardwareConcurrency || 8);
        workers=[];
        blobUrl=null;
        initPool(challenge, salt) {
            if (this.workers.length > 0) {
                return;
            }
            let workerCode = `\n            ${atob("IWZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIHQodCxpKXtpPyhkWzBdPWRbMTZdPWRbMV09ZFsyXT1kWzNdPWRbNF09ZFs1XT1kWzZdPWRbN109ZFs4XT1kWzldPWRbMTBdPWRbMTFdPWRbMTJdPWRbMTNdPWRbMTRdPWRbMTVdPTAsdGhpcy5ibG9ja3M9ZCk6dGhpcy5ibG9ja3M9WzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF0sdD8odGhpcy5oMD0zMjM4MzcxMDMyLHRoaXMuaDE9OTE0MTUwNjYzLHRoaXMuaDI9ODEyNzAyOTk5LHRoaXMuaDM9NDE0NDkxMjY5Nyx0aGlzLmg0PTQyOTA3NzU4NTcsdGhpcy5oNT0xNzUwNjAzMDI1LHRoaXMuaDY9MTY5NDA3NjgzOSx0aGlzLmg3PTMyMDQwNzU0MjgpOih0aGlzLmgwPTE3NzkwMzM3MDMsdGhpcy5oMT0zMTQ0MTM0Mjc3LHRoaXMuaDI9MTAxMzkwNDI0Mix0aGlzLmgzPTI3NzM0ODA3NjIsdGhpcy5oND0xMzU5ODkzMTE5LHRoaXMuaDU9MjYwMDgyMjkyNCx0aGlzLmg2PTUyODczNDYzNSx0aGlzLmg3PTE1NDE0NTkyMjUpLHRoaXMuYmxvY2s9dGhpcy5zdGFydD10aGlzLmJ5dGVzPXRoaXMuaEJ5dGVzPTAsdGhpcy5maW5hbGl6ZWQ9dGhpcy5oYXNoZWQ9ITEsdGhpcy5maXJzdD0hMCx0aGlzLmlzMjI0PXR9ZnVuY3Rpb24gaShpLHIscyl7dmFyIGUsbj10eXBlb2YgaTtpZigic3RyaW5nIj09PW4pe3ZhciBvLGE9W10sdT1pLmxlbmd0aCxjPTA7Zm9yKGU9MDtlPHU7KytlKShvPWkuY2hhckNvZGVBdChlKSk8MTI4P2FbYysrXT1vOm88MjA0OD8oYVtjKytdPTE5MnxvPj42LGFbYysrXT0xMjh8NjMmbyk6bzw1NTI5Nnx8bz49NTczNDQ/KGFbYysrXT0yMjR8bz4+MTIsYVtjKytdPTEyOHxvPj42JjYzLGFbYysrXT0xMjh8NjMmbyk6KG89NjU1MzYrKCgxMDIzJm8pPDwxMHwxMDIzJmkuY2hhckNvZGVBdCgrK2UpKSxhW2MrK109MjQwfG8+PjE4LGFbYysrXT0xMjh8bz4+MTImNjMsYVtjKytdPTEyOHxvPj42JjYzLGFbYysrXT0xMjh8NjMmbyk7aT1hfWVsc2V7aWYoIm9iamVjdCIhPT1uKXRocm93IG5ldyBFcnJvcihoKTtpZihudWxsPT09aSl0aHJvdyBuZXcgRXJyb3IoaCk7aWYoZiYmaS5jb25zdHJ1Y3Rvcj09PUFycmF5QnVmZmVyKWk9bmV3IFVpbnQ4QXJyYXkoaSk7ZWxzZSBpZighKEFycmF5LmlzQXJyYXkoaSl8fGYmJkFycmF5QnVmZmVyLmlzVmlldyhpKSkpdGhyb3cgbmV3IEVycm9yKGgpfWkubGVuZ3RoPjY0JiYoaT1uZXcgdChyLCEwKS51cGRhdGUoaSkuYXJyYXkoKSk7dmFyIHk9W10scD1bXTtmb3IoZT0wO2U8NjQ7KytlKXt2YXIgbD1pW2VdfHwwO3lbZV09OTJebCxwW2VdPTU0Xmx9dC5jYWxsKHRoaXMscixzKSx0aGlzLnVwZGF0ZShwKSx0aGlzLm9LZXlQYWQ9eSx0aGlzLmlubmVyPSEwLHRoaXMuc2hhcmVkTWVtb3J5PXN9dmFyIGg9ImlucHV0IGlzIGludmFsaWQgdHlwZSIscj0ib2JqZWN0Ij09dHlwZW9mIHdpbmRvdyxzPXI/d2luZG93Ont9O3MuSlNfU0hBMjU2X05PX1dJTkRPVyYmKHI9ITEpO3ZhciBlPSFyJiYib2JqZWN0Ij09dHlwZW9mIHNlbGYsbj0hcy5KU19TSEEyNTZfTk9fTk9ERV9KUyYmIm9iamVjdCI9PXR5cGVvZiBwcm9jZXNzJiZwcm9jZXNzLnZlcnNpb25zJiZwcm9jZXNzLnZlcnNpb25zLm5vZGU7bj9zPWdsb2JhbDplJiYocz1zZWxmKTt2YXIgbz0hcy5KU19TSEEyNTZfTk9fQ09NTU9OX0pTJiYib2JqZWN0Ij09dHlwZW9mIG1vZHVsZSYmbW9kdWxlLmV4cG9ydHMsYT0iZnVuY3Rpb24iPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kLGY9IXMuSlNfU0hBMjU2X05PX0FSUkFZX0JVRkZFUiYmInVuZGVmaW5lZCIhPXR5cGVvZiBBcnJheUJ1ZmZlcix1PSIwMTIzNDU2Nzg5YWJjZGVmIi5zcGxpdCgiIiksYz1bLTIxNDc0ODM2NDgsODM4ODYwOCwzMjc2OCwxMjhdLHk9WzI0LDE2LDgsMF0scD1bMTExNjM1MjQwOCwxODk5NDQ3NDQxLDMwNDkzMjM0NzEsMzkyMTAwOTU3Myw5NjE5ODcxNjMsMTUwODk3MDk5MywyNDUzNjM1NzQ4LDI4NzA3NjMyMjEsMzYyNDM4MTA4MCwzMTA1OTg0MDEsNjA3MjI1Mjc4LDE0MjY4ODE5ODcsMTkyNTA3ODM4OCwyMTYyMDc4MjA2LDI2MTQ4ODgxMDMsMzI0ODIyMjU4MCwzODM1MzkwNDAxLDQwMjIyMjQ3NzQsMjY0MzQ3MDc4LDYwNDgwNzYyOCw3NzAyNTU5ODMsMTI0OTE1MDEyMiwxNTU1MDgxNjkyLDE5OTYwNjQ5ODYsMjU1NDIyMDg4MiwyODIxODM0MzQ5LDI5NTI5OTY4MDgsMzIxMDMxMzY3MSwzMzM2NTcxODkxLDM1ODQ1Mjg3MTEsMTEzOTI2OTkzLDMzODI0MTg5NSw2NjYzMDcyMDUsNzczNTI5OTEyLDEyOTQ3NTczNzIsMTM5NjE4MjI5MSwxNjk1MTgzNzAwLDE5ODY2NjEwNTEsMjE3NzAyNjM1MCwyNDU2OTU2MDM3LDI3MzA0ODU5MjEsMjgyMDMwMjQxMSwzMjU5NzMwODAwLDMzNDU3NjQ3NzEsMzUxNjA2NTgxNywzNjAwMzUyODA0LDQwOTQ1NzE5MDksMjc1NDIzMzQ0LDQzMDIyNzczNCw1MDY5NDg2MTYsNjU5MDYwNTU2LDg4Mzk5Nzg3Nyw5NTgxMzk1NzEsMTMyMjgyMjIxOCwxNTM3MDAyMDYzLDE3NDc4NzM3NzksMTk1NTU2MjIyMiwyMDI0MTA0ODE1LDIyMjc3MzA0NTIsMjM2MTg1MjQyNCwyNDI4NDM2NDc0LDI3NTY3MzQxODcsMzIwNDAzMTQ3OSwzMzI5MzI1Mjk4XSxsPVsiaGV4IiwiYXJyYXkiLCJkaWdlc3QiLCJhcnJheUJ1ZmZlciJdLGQ9W107IXMuSlNfU0hBMjU2X05PX05PREVfSlMmJkFycmF5LmlzQXJyYXl8fChBcnJheS5pc0FycmF5PWZ1bmN0aW9uKHQpe3JldHVybiJbb2JqZWN0IEFycmF5XSI9PT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCl9KSwhZnx8IXMuSlNfU0hBMjU2X05PX0FSUkFZX0JVRkZFUl9JU19WSUVXJiZBcnJheUJ1ZmZlci5pc1ZpZXd8fChBcnJheUJ1ZmZlci5pc1ZpZXc9ZnVuY3Rpb24odCl7cmV0dXJuIm9iamVjdCI9PXR5cGVvZiB0JiZ0LmJ1ZmZlciYmdC5idWZmZXIuY29uc3RydWN0b3I9PT1BcnJheUJ1ZmZlcn0pO3ZhciBBPWZ1bmN0aW9uKGksaCl7cmV0dXJuIGZ1bmN0aW9uKHIpe3JldHVybiBuZXcgdChoLCEwKS51cGRhdGUocilbaV0oKX19LHc9ZnVuY3Rpb24oaSl7dmFyIGg9QSgiaGV4IixpKTtuJiYoaD1iKGgsaSkpLGguY3JlYXRlPWZ1bmN0aW9uKCl7cmV0dXJuIG5ldyB0KGkpfSxoLnVwZGF0ZT1mdW5jdGlvbih0KXtyZXR1cm4gaC5jcmVhdGUoKS51cGRhdGUodCl9O2Zvcih2YXIgcj0wO3I8bC5sZW5ndGg7KytyKXt2YXIgcz1sW3JdO2hbc109QShzLGkpfXJldHVybiBofSxiPWZ1bmN0aW9uKHQsaSl7dmFyIHI9ZXZhbCgicmVxdWlyZSgnY3J5cHRvJykiKSxzPWV2YWwoInJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlciIpLGU9aT8ic2hhMjI0Ijoic2hhMjU2IixuPWZ1bmN0aW9uKGkpe2lmKCJzdHJpbmciPT10eXBlb2YgaSlyZXR1cm4gci5jcmVhdGVIYXNoKGUpLnVwZGF0ZShpLCJ1dGY4IikuZGlnZXN0KCJoZXgiKTtpZihudWxsPT09aXx8dm9pZCAwPT09aSl0aHJvdyBuZXcgRXJyb3IoaCk7cmV0dXJuIGkuY29uc3RydWN0b3I9PT1BcnJheUJ1ZmZlciYmKGk9bmV3IFVpbnQ4QXJyYXkoaSkpLEFycmF5LmlzQXJyYXkoaSl8fEFycmF5QnVmZmVyLmlzVmlldyhpKXx8aS5jb25zdHJ1Y3Rvcj09PXM/ci5jcmVhdGVIYXNoKGUpLnVwZGF0ZShuZXcgcyhpKSkuZGlnZXN0KCJoZXgiKTp0KGkpfTtyZXR1cm4gbn0sdj1mdW5jdGlvbih0LGgpe3JldHVybiBmdW5jdGlvbihyLHMpe3JldHVybiBuZXcgaShyLGgsITApLnVwZGF0ZShzKVt0XSgpfX0sXz1mdW5jdGlvbih0KXt2YXIgaD12KCJoZXgiLHQpO2guY3JlYXRlPWZ1bmN0aW9uKGgpe3JldHVybiBuZXcgaShoLHQpfSxoLnVwZGF0ZT1mdW5jdGlvbih0LGkpe3JldHVybiBoLmNyZWF0ZSh0KS51cGRhdGUoaSl9O2Zvcih2YXIgcj0wO3I8bC5sZW5ndGg7KytyKXt2YXIgcz1sW3JdO2hbc109dihzLHQpfXJldHVybiBofTt0LnByb3RvdHlwZS51cGRhdGU9ZnVuY3Rpb24odCl7aWYoIXRoaXMuZmluYWxpemVkKXt2YXIgaSxyPXR5cGVvZiB0O2lmKCJzdHJpbmciIT09cil7aWYoIm9iamVjdCIhPT1yKXRocm93IG5ldyBFcnJvcihoKTtpZihudWxsPT09dCl0aHJvdyBuZXcgRXJyb3IoaCk7aWYoZiYmdC5jb25zdHJ1Y3Rvcj09PUFycmF5QnVmZmVyKXQ9bmV3IFVpbnQ4QXJyYXkodCk7ZWxzZSBpZighKEFycmF5LmlzQXJyYXkodCl8fGYmJkFycmF5QnVmZmVyLmlzVmlldyh0KSkpdGhyb3cgbmV3IEVycm9yKGgpO2k9ITB9Zm9yKHZhciBzLGUsbj0wLG89dC5sZW5ndGgsYT10aGlzLmJsb2NrcztuPG87KXtpZih0aGlzLmhhc2hlZCYmKHRoaXMuaGFzaGVkPSExLGFbMF09dGhpcy5ibG9jayxhWzE2XT1hWzFdPWFbMl09YVszXT1hWzRdPWFbNV09YVs2XT1hWzddPWFbOF09YVs5XT1hWzEwXT1hWzExXT1hWzEyXT1hWzEzXT1hWzE0XT1hWzE1XT0wKSxpKWZvcihlPXRoaXMuc3RhcnQ7bjxvJiZlPDY0OysrbilhW2U+PjJdfD10W25dPDx5WzMmZSsrXTtlbHNlIGZvcihlPXRoaXMuc3RhcnQ7bjxvJiZlPDY0Oysrbikocz10LmNoYXJDb2RlQXQobikpPDEyOD9hW2U+PjJdfD1zPDx5WzMmZSsrXTpzPDIwNDg/KGFbZT4+Ml18PSgxOTJ8cz4+Nik8PHlbMyZlKytdLGFbZT4+Ml18PSgxMjh8NjMmcyk8PHlbMyZlKytdKTpzPDU1Mjk2fHxzPj01NzM0ND8oYVtlPj4yXXw9KDIyNHxzPj4xMik8PHlbMyZlKytdLGFbZT4+Ml18PSgxMjh8cz4+NiY2Myk8PHlbMyZlKytdLGFbZT4+Ml18PSgxMjh8NjMmcyk8PHlbMyZlKytdKToocz02NTUzNisoKDEwMjMmcyk8PDEwfDEwMjMmdC5jaGFyQ29kZUF0KCsrbikpLGFbZT4+Ml18PSgyNDB8cz4+MTgpPDx5WzMmZSsrXSxhW2U+PjJdfD0oMTI4fHM+PjEyJjYzKTw8eVszJmUrK10sYVtlPj4yXXw9KDEyOHxzPj42JjYzKTw8eVszJmUrK10sYVtlPj4yXXw9KDEyOHw2MyZzKTw8eVszJmUrK10pO3RoaXMubGFzdEJ5dGVJbmRleD1lLHRoaXMuYnl0ZXMrPWUtdGhpcy5zdGFydCxlPj02ND8odGhpcy5ibG9jaz1hWzE2XSx0aGlzLnN0YXJ0PWUtNjQsdGhpcy5oYXNoKCksdGhpcy5oYXNoZWQ9ITApOnRoaXMuc3RhcnQ9ZX1yZXR1cm4gdGhpcy5ieXRlcz40Mjk0OTY3Mjk1JiYodGhpcy5oQnl0ZXMrPXRoaXMuYnl0ZXMvNDI5NDk2NzI5Njw8MCx0aGlzLmJ5dGVzPXRoaXMuYnl0ZXMlNDI5NDk2NzI5NiksdGhpc319LHQucHJvdG90eXBlLmZpbmFsaXplPWZ1bmN0aW9uKCl7aWYoIXRoaXMuZmluYWxpemVkKXt0aGlzLmZpbmFsaXplZD0hMDt2YXIgdD10aGlzLmJsb2NrcyxpPXRoaXMubGFzdEJ5dGVJbmRleDt0WzE2XT10aGlzLmJsb2NrLHRbaT4+Ml18PWNbMyZpXSx0aGlzLmJsb2NrPXRbMTZdLGk+PTU2JiYodGhpcy5oYXNoZWR8fHRoaXMuaGFzaCgpLHRbMF09dGhpcy5ibG9jayx0WzE2XT10WzFdPXRbMl09dFszXT10WzRdPXRbNV09dFs2XT10WzddPXRbOF09dFs5XT10WzEwXT10WzExXT10WzEyXT10WzEzXT10WzE0XT10WzE1XT0wKSx0WzE0XT10aGlzLmhCeXRlczw8M3x0aGlzLmJ5dGVzPj4+MjksdFsxNV09dGhpcy5ieXRlczw8Myx0aGlzLmhhc2goKX19LHQucHJvdG90eXBlLmhhc2g9ZnVuY3Rpb24oKXt2YXIgdCxpLGgscixzLGUsbixvLGEsZj10aGlzLmgwLHU9dGhpcy5oMSxjPXRoaXMuaDIseT10aGlzLmgzLGw9dGhpcy5oNCxkPXRoaXMuaDUsQT10aGlzLmg2LHc9dGhpcy5oNyxiPXRoaXMuYmxvY2tzO2Zvcih0PTE2O3Q8NjQ7Kyt0KWk9KChzPWJbdC0xNV0pPj4+N3xzPDwyNSleKHM+Pj4xOHxzPDwxNClecz4+PjMsaD0oKHM9Ylt0LTJdKT4+PjE3fHM8PDE1KV4ocz4+PjE5fHM8PDEzKV5zPj4+MTAsYlt0XT1iW3QtMTZdK2krYlt0LTddK2g8PDA7Zm9yKGE9dSZjLHQ9MDt0PDY0O3QrPTQpdGhpcy5maXJzdD8odGhpcy5pczIyND8oZT0zMDAwMzIsdz0ocz1iWzBdLTE0MTMyNTc4MTkpLTE1MDA1NDU5OTw8MCx5PXMrMjQxNzcwNzc8PDApOihlPTcwNDc1MTEwOSx3PShzPWJbMF0tMjEwMjQ0MjQ4KS0xNTIxNDg2NTM0PDwwLHk9cysxNDM2OTQ1NjU8PDApLHRoaXMuZmlyc3Q9ITEpOihpPShmPj4+MnxmPDwzMCleKGY+Pj4xM3xmPDwxOSleKGY+Pj4yMnxmPDwxMCkscj0oZT1mJnUpXmYmY15hLHc9eSsocz13KyhoPShsPj4+NnxsPDwyNileKGw+Pj4xMXxsPDwyMSleKGw+Pj4yNXxsPDw3KSkrKGwmZF5+bCZBKStwW3RdK2JbdF0pPDwwLHk9cysoaStyKTw8MCksaT0oeT4+PjJ8eTw8MzApXih5Pj4+MTN8eTw8MTkpXih5Pj4+MjJ8eTw8MTApLHI9KG49eSZmKV55JnVeZSxBPWMrKHM9QSsoaD0odz4+PjZ8dzw8MjYpXih3Pj4+MTF8dzw8MjEpXih3Pj4+MjV8dzw8NykpKyh3JmxefncmZCkrcFt0KzFdK2JbdCsxXSk8PDAsaT0oKGM9cysoaStyKTw8MCk+Pj4yfGM8PDMwKV4oYz4+PjEzfGM8PDE5KV4oYz4+PjIyfGM8PDEwKSxyPShvPWMmeSleYyZmXm4sZD11KyhzPWQrKGg9KEE+Pj42fEE8PDI2KV4oQT4+PjExfEE8PDIxKV4oQT4+PjI1fEE8PDcpKSsoQSZ3Xn5BJmwpK3BbdCsyXStiW3QrMl0pPDwwLGk9KCh1PXMrKGkrcik8PDApPj4+Mnx1PDwzMCleKHU+Pj4xM3x1PDwxOSleKHU+Pj4yMnx1PDwxMCkscj0oYT11JmMpXnUmeV5vLGw9Zisocz1sKyhoPShkPj4+NnxkPDwyNileKGQ+Pj4xMXxkPDwyMSleKGQ+Pj4yNXxkPDw3KSkrKGQmQV5+ZCZ3KStwW3QrM10rYlt0KzNdKTw8MCxmPXMrKGkrcik8PDA7dGhpcy5oMD10aGlzLmgwK2Y8PDAsdGhpcy5oMT10aGlzLmgxK3U8PDAsdGhpcy5oMj10aGlzLmgyK2M8PDAsdGhpcy5oMz10aGlzLmgzK3k8PDAsdGhpcy5oND10aGlzLmg0K2w8PDAsdGhpcy5oNT10aGlzLmg1K2Q8PDAsdGhpcy5oNj10aGlzLmg2K0E8PDAsdGhpcy5oNz10aGlzLmg3K3c8PDB9LHQucHJvdG90eXBlLmhleD1mdW5jdGlvbigpe3RoaXMuZmluYWxpemUoKTt2YXIgdD10aGlzLmgwLGk9dGhpcy5oMSxoPXRoaXMuaDIscj10aGlzLmgzLHM9dGhpcy5oNCxlPXRoaXMuaDUsbj10aGlzLmg2LG89dGhpcy5oNyxhPXVbdD4+MjgmMTVdK3VbdD4+MjQmMTVdK3VbdD4+MjAmMTVdK3VbdD4+MTYmMTVdK3VbdD4+MTImMTVdK3VbdD4+OCYxNV0rdVt0Pj40JjE1XSt1WzE1JnRdK3VbaT4+MjgmMTVdK3VbaT4+MjQmMTVdK3VbaT4+MjAmMTVdK3VbaT4+MTYmMTVdK3VbaT4+MTImMTVdK3VbaT4+OCYxNV0rdVtpPj40JjE1XSt1WzE1JmldK3VbaD4+MjgmMTVdK3VbaD4+MjQmMTVdK3VbaD4+MjAmMTVdK3VbaD4+MTYmMTVdK3VbaD4+MTImMTVdK3VbaD4+OCYxNV0rdVtoPj40JjE1XSt1WzE1JmhdK3Vbcj4+MjgmMTVdK3Vbcj4+MjQmMTVdK3Vbcj4+MjAmMTVdK3Vbcj4+MTYmMTVdK3Vbcj4+MTImMTVdK3Vbcj4+OCYxNV0rdVtyPj40JjE1XSt1WzE1JnJdK3Vbcz4+MjgmMTVdK3Vbcz4+MjQmMTVdK3Vbcz4+MjAmMTVdK3Vbcz4+MTYmMTVdK3Vbcz4+MTImMTVdK3Vbcz4+OCYxNV0rdVtzPj40JjE1XSt1WzE1JnNdK3VbZT4+MjgmMTVdK3VbZT4+MjQmMTVdK3VbZT4+MjAmMTVdK3VbZT4+MTYmMTVdK3VbZT4+MTImMTVdK3VbZT4+OCYxNV0rdVtlPj40JjE1XSt1WzE1JmVdK3Vbbj4+MjgmMTVdK3Vbbj4+MjQmMTVdK3Vbbj4+MjAmMTVdK3Vbbj4+MTYmMTVdK3Vbbj4+MTImMTVdK3Vbbj4+OCYxNV0rdVtuPj40JjE1XSt1WzE1Jm5dO3JldHVybiB0aGlzLmlzMjI0fHwoYSs9dVtvPj4yOCYxNV0rdVtvPj4yNCYxNV0rdVtvPj4yMCYxNV0rdVtvPj4xNiYxNV0rdVtvPj4xMiYxNV0rdVtvPj44JjE1XSt1W28+PjQmMTVdK3VbMTUmb10pLGF9LHQucHJvdG90eXBlLnRvU3RyaW5nPXQucHJvdG90eXBlLmhleCx0LnByb3RvdHlwZS5kaWdlc3Q9ZnVuY3Rpb24oKXt0aGlzLmZpbmFsaXplKCk7dmFyIHQ9dGhpcy5oMCxpPXRoaXMuaDEsaD10aGlzLmgyLHI9dGhpcy5oMyxzPXRoaXMuaDQsZT10aGlzLmg1LG49dGhpcy5oNixvPXRoaXMuaDcsYT1bdD4+MjQmMjU1LHQ+PjE2JjI1NSx0Pj44JjI1NSwyNTUmdCxpPj4yNCYyNTUsaT4+MTYmMjU1LGk+PjgmMjU1LDI1NSZpLGg+PjI0JjI1NSxoPj4xNiYyNTUsaD4+OCYyNTUsMjU1Jmgscj4+MjQmMjU1LHI+PjE2JjI1NSxyPj44JjI1NSwyNTUmcixzPj4yNCYyNTUscz4+MTYmMjU1LHM+PjgmMjU1LDI1NSZzLGU+PjI0JjI1NSxlPj4xNiYyNTUsZT4+OCYyNTUsMjU1JmUsbj4+MjQmMjU1LG4+PjE2JjI1NSxuPj44JjI1NSwyNTUmbl07cmV0dXJuIHRoaXMuaXMyMjR8fGEucHVzaChvPj4yNCYyNTUsbz4+MTYmMjU1LG8+PjgmMjU1LDI1NSZvKSxhfSx0LnByb3RvdHlwZS5hcnJheT10LnByb3RvdHlwZS5kaWdlc3QsdC5wcm90b3R5cGUuYXJyYXlCdWZmZXI9ZnVuY3Rpb24oKXt0aGlzLmZpbmFsaXplKCk7dmFyIHQ9bmV3IEFycmF5QnVmZmVyKHRoaXMuaXMyMjQ/Mjg6MzIpLGk9bmV3IERhdGFWaWV3KHQpO3JldHVybiBpLnNldFVpbnQzMigwLHRoaXMuaDApLGkuc2V0VWludDMyKDQsdGhpcy5oMSksaS5zZXRVaW50MzIoOCx0aGlzLmgyKSxpLnNldFVpbnQzMigxMix0aGlzLmgzKSxpLnNldFVpbnQzMigxNix0aGlzLmg0KSxpLnNldFVpbnQzMigyMCx0aGlzLmg1KSxpLnNldFVpbnQzMigyNCx0aGlzLmg2KSx0aGlzLmlzMjI0fHxpLnNldFVpbnQzMigyOCx0aGlzLmg3KSx0fSxpLnByb3RvdHlwZT1uZXcgdCxpLnByb3RvdHlwZS5maW5hbGl6ZT1mdW5jdGlvbigpe2lmKHQucHJvdG90eXBlLmZpbmFsaXplLmNhbGwodGhpcyksdGhpcy5pbm5lcil7dGhpcy5pbm5lcj0hMTt2YXIgaT10aGlzLmFycmF5KCk7dC5jYWxsKHRoaXMsdGhpcy5pczIyNCx0aGlzLnNoYXJlZE1lbW9yeSksdGhpcy51cGRhdGUodGhpcy5vS2V5UGFkKSx0aGlzLnVwZGF0ZShpKSx0LnByb3RvdHlwZS5maW5hbGl6ZS5jYWxsKHRoaXMpfX07dmFyIEI9dygpO0Iuc2hhMjU2PUIsQi5zaGEyMjQ9dyghMCksQi5zaGEyNTYuaG1hYz1fKCksQi5zaGEyMjQuaG1hYz1fKCEwKSxvP21vZHVsZS5leHBvcnRzPUI6KHMuc2hhMjU2PUIuc2hhMjU2LHMuc2hhMjI0PUIuc2hhMjI0LGEmJmRlZmluZShmdW5jdGlvbigpe3JldHVybiBCfSkpfSgpOw==")}\n            // let challenge = null, salt = null;\n            self.onmessage = e => {\n                const d = e.data;\n                if (d.init) { challenge = d.challenge; salt = d.salt; return; }\n                const { start, end } = d;\n                for (let i = start; i <= end; i++) {\n                    if (sha256(salt + i) === challenge) {\n                        postMessage(i);\n                        return;\n                    }\n                }\n                postMessage(null);\n            };\n        `;
            this.blobUrl = URL.createObjectURL(new Blob([ workerCode ], {
                type: "application/javascript"
            }));
            for (let i = 0; i < this.coreCount; i++) {
                this.workers.push(new Worker(this.blobUrl)), this.workers[i].postMessage({
                    init: !0,
                    challenge: challenge,
                    salt: salt
                });
            }
        }
        async getChallenge() {
            return (await fetch("https://api.moomoo.io/verify")).json();
        }
        async solve(chal) {
            let {challenge: challenge, salt: salt, maxnumber: maxnumber} = chal;
            this.initPool(challenge, salt);
            let segSize = Math.ceil(maxnumber / this.coreCount);
            return new Promise((resolve, reject) => {
                let solved = !1, done = 0, startTime = performance.now();
                this.workers.forEach((worker, idx) => {
                    let s = idx * segSize, e = Math.min(maxnumber, (idx + 1) * segSize - 1);
                    worker.onmessage = msg => {
                        if (solved) {
                            return;
                        }
                        let number = msg.data;
                        if (number !== null) {
                            solved = !0;
                            let took = ((performance.now() - startTime) / 1e3).toFixed(2);
                            resolve({
                                number: number,
                                took: took
                            }), this.cleanup();
                        } else if (done++, !solved && done === this.coreCount) {
                            reject(Error("Not solved")), this.cleanup();
                        }
                    }, worker.onerror = err => {
                        if (!solved) {
                            reject(err);
                        }
                        this.cleanup();
                    }, worker.postMessage({
                        start: s,
                        end: e
                    });
                });
            });
        }
        cleanup() {
            if (this.workers.forEach(w => w.terminate()), this.workers.length = 0, this.blobUrl) {
                URL.revokeObjectURL(this.blobUrl);
            }
            this.blobUrl = null;
        }
        static makePayload(chal, result) {
            return btoa(JSON.stringify({
                algorithm: "SHA-256",
                challenge: chal.challenge,
                salt: chal.salt,
                signature: chal.signature || null,
                number: result.number,
                took: result.took
            }));
        }
        async generate() {
            let chal = await this.getChallenge(), sol = await this.solve(chal);
            return "alt:" + Altcha.makePayload(chal, sol);
        }
    }

    // ==================================================================
    //  HLM - ALTCHA REMPLACE PAR CLOUDFLARE TURNSTILE
    //  moomoo.io ne sert plus de defi altcha : api.moomoo.io/verify a
    //  disparu et le prefixe de jeton "alt:" n'est plus reconnu. La
    //  connexion principale est ouverte par le jeu lui-meme, qui gere
    //  Turnstile de son cote - elle n'a besoin de rien ici.
    //  Cette fonction ne sert qu'aux bots : on reutilise donc l'adresse
    //  du socket principal, jeton compris, au lieu d'en fabriquer un.
    // ==================================================================
    // ==================================================================
    //  HLM - UN JETON TURNSTILE FRAIS PAR BOT
    //
    //  Un jeton Cloudflare ne sert qu'une fois : celui du menu a ete
    //  consomme par la connexion principale. On rend donc notre propre
    //  widget, avec la cle publique du jeu, et on le reinitialise pour
    //  obtenir un jeton par bot. C'est la seule facon d'ouvrir une
    //  connexion supplementaire acceptee par le serveur.
    // ==================================================================
    // ==================================================================
    //  HLM - JETON POUR LES BOTS : WIDGET DEDIE ET VISIBLE
    //
    //  Historique des tentatives, pour ne pas y revenir :
    //    1. widget cache      -> Turnstile ne resout pas un widget non rendu
    //    2. reset du widget du jeu -> son iframe reste "about:blank", d'ou
    //       "postMessage ... target origin challenges.cloudflare.com does not
    //       match ... sandbox.moomoo.io" : Turnstile parle a un cadre qui n'a
    //       jamais charge. Un reset ne le ressuscite pas.
    //
    //  On rend donc un widget NEUF, reellement visible, dans un coin, et on
    //  le retire des que le jeton est arrive. Un rendu neuf par bot : pas de
    //  reset, pas d'etat a recycler.
    // ==================================================================
    //  Cles publiques lues dans le bundle du jeu :
    //    La = We ? "1x00000000000000000000AA" : "0x4AAAAAAAMYHI96GFiJzMmp"
    //  We designe le developpement local, donc sandbox utilise la seconde.
    const HLM_SITEKEY = /^(localhost|127\.)/.test(window.location.hostname)
        ? "1x00000000000000000000AA"
        : "0x4AAAAAAAMYHI96GFiJzMmp";

    let hlmTokenWaiter = null, hlmTokenTimer = null, hlmBox = null, hlmWidgetId = null;

    function hlmCleanupWidget() {
        try {
            if (hlmWidgetId !== null && window.turnstile && window.turnstile.remove) {
                window.turnstile.remove(hlmWidgetId);
            }
        } catch (err) { /* rien a faire */ }
        hlmWidgetId = null;
        if (hlmBox !== null) {
            hlmBox.remove(), hlmBox = null;
        }
    }

    function hlmTokenSettle(token) {
        let done = hlmTokenWaiter;
        hlmTokenWaiter = null;
        if (hlmTokenTimer !== null) {
            clearTimeout(hlmTokenTimer), hlmTokenTimer = null;
        }
        hlmCleanupWidget();
        console.log("[HLM] jeton pour le bot :", token ? "obtenu" : "ABSENT");
        if (done !== null) done(token || null);
    }

    window.__hlmTokenDelivery = function() { /* plus utilise : widget dedie */ };

    // Les demandes doivent etre SERIALISEES : il n'y a qu'un widget a la
    // fois. Avant, une demande simultanee etait refusee - "une demande de
    // jeton est deja en cours" - et le bot concerne partait sans jeton,
    // donc se faisait fermer en 4001. On les met desormais en file.
    let hlmTokenQueue = Promise.resolve();

    function hlmRenderOnce() {
        return new Promise(resolve => {
            let ts = window.turnstile;
            if (!ts || typeof ts.render !== "function") {
                console.warn("[HLM] turnstile indisponible : le bot partira sans jeton");
                return resolve(null);
            }
            hlmTokenWaiter = resolve;
            hlmTokenTimer = setTimeout(() => {
                console.warn("[HLM] jeton turnstile non obtenu (delai depasse)");
                hlmTokenSettle(null);
            }, 3e4);

            hlmCleanupWidget();
            hlmBox = document.createElement("div");
            hlmBox.id = "hlmTurnstileBox";
            // Volontairement VISIBLE : c'est la condition pour que Cloudflare
            // accepte de resoudre. Il disparait des que le jeton arrive.
            hlmBox.style.cssText = "position:fixed;right:10px;bottom:10px;width:300px;"
                + "height:65px;z-index:2147483647;background:#fff;border-radius:4px;";
            document.body.appendChild(hlmBox);
            try {
                hlmWidgetId = ts.render(hlmBox, {
                    sitekey: HLM_SITEKEY,
                    theme: "light",
                    callback: t => hlmTokenSettle(t || null),
                    "error-callback": () => {
                        console.warn("[HLM] turnstile a signale une erreur");
                        hlmTokenSettle(null);
                    },
                    "expired-callback": () => hlmTokenSettle(null)
                });
                console.log("[HLM] widget dedie rendu, identifiant :", hlmWidgetId,
                    " | cle :", HLM_SITEKEY);
                if (hlmWidgetId === null || hlmWidgetId === undefined) {
                    hlmTokenSettle(null);
                }
            } catch (err) {
                console.error("[HLM] rendu du widget dedie impossible", err);
                hlmTokenSettle(null);
            }
        });
    }

    function hlmFreshToken() {
        // Un seul rendu a la fois, chacun son tour. Une seconde tentative
        // si la premiere revient a vide : un echec isole ne doit pas
        // condamner le bot.
        let run = async () => {
            let token = await hlmRenderOnce();
            if (token === null) {
                console.warn("[HLM] premiere tentative sans jeton, nouvel essai");
                await new Promise(r => setTimeout(r, 800));
                token = await hlmRenderOnce();
            }
            return token;
        };
        let p = hlmTokenQueue.then(run, run);
        hlmTokenQueue = p.then(() => undefined, () => undefined);
        return p;
    }

    const altcha = new Altcha, createSocket = async href => {
        let url = href;
        try {
            let token = await hlmFreshToken();
            if (token !== null) {
                let u = new URL(href);
                u.search = "";
                url = u.href + "?token=" + encodeURIComponent("cf:" + token);
            } else {
                console.error("[HLM] ce bot part SANS jeton : le serveur le fermera"
                    + " en 4001. Ajoute-le a nouveau dans quelques secondes.");
            }
        } catch (err) {
            console.error("[HLM] jeton du bot indisponible", err);
        }
        let ws = new WebSocket(url);
        return ws.binaryType = "arraybuffer", ws;
    }, createSocket_default = createSocket;

    const Hooker = new class {
        createRecursiveHook(target, prop, callback) {
            let newValue = target[prop];
            (function recursiveHook() {
                Object.defineProperty(target, prop, {
                    set(value) {
                        if (delete target[prop], this[prop] = value, newValue = value, callback(this, value)) {
                            return;
                        }
                        recursiveHook();
                    },
                    get() {
                        return newValue;
                    },
                    configurable: !0
                });
            })();
        }
        createHook(target, prop, callback) {
            let symbol = Symbol(prop);
            Object.defineProperty(target, prop, {
                get() {
                    return this[symbol];
                },
                set(value) {
                    callback(this, value, symbol);
                },
                configurable: !0
            });
        }
        linker(value) {
            let hook = [ value ];
            return hook.valueOf = () => hook[0], hook;
        }
    }, blockProperty = (target, key) => {
        let value = target[key];
        Object.defineProperty(target, key, {
            set() {},
            get() {
                return value;
            },
            configurable: !0
        });
    }, Hooker_default = Hooker;

    const Config = {
        maxScreenWidth: 1920,
        maxScreenHeight: 1080,
        serverUpdateRate: 9,
        collisionDepth: 6,
        minimapRate: 3e3,
        colGrid: 10,
        clientSendRate: 5,
        barWidth: 50,
        barHeight: 17,
        barPad: 4.5,
        iconPadding: 15,
        iconPad: .9,
        deathFadeout: 3e3,
        crownIconScale: 60,
        crownPad: 35,
        chatCountdown: 3e3,
        chatCooldown: 500,
        maxAge: 100,
        gatherAngle: Math.PI / 2.6,
        gatherWiggle: 10,
        hitReturnRatio: .25,
        hitAngle: Math.PI / 2,
        playerScale: 35,
        playerSpeed: .0016,
        playerDecel: .993,
        nameY: 34,
        animalCount: 7,
        aiTurnRandom: .06,
        shieldAngle: Math.PI / 3,
        resourceTypes: [ "wood", "food", "stone", "points" ],
        areaCount: 7,
        treesPerArea: 9,
        bushesPerArea: 3,
        totalRocks: 32,
        goldOres: 7,
        riverWidth: 724,
        riverPadding: 114,
        waterCurrent: .0011,
        waveSpeed: 1e-4,
        waveMax: 1.3,
        treeScales: [ 150, 160, 165, 175 ],
        bushScales: [ 80, 85, 95 ],
        rockScales: [ 80, 85, 90 ],
        snowBiomeTop: 2400,
        desertBiomeTop: 2400,
        snowSpeed: .75,
        maxNameLength: 15,
        mapScale: 14400,
        mapPingScale: 40,
        mapPingTime: 2200,
        skinColors: [ "#bf8f54", "#cbb091", "#896c4b", "#fadadc", "#ececec", "#c37373", "#4c4c4c", "#ecaff7", "#738cc3", "#8bc373", "#91B2DB" ]
    }, Config_default = Config;

    const WeaponTypeString = [ "primary", "secondary" ];

    const Weapons = [ {
        id: 0,
        itemType: 0,
        upgradeType: 0,
        type: 0,
        age: 0,
        name: "tool hammer",
        description: "tool for gathering all resources",
        src: "hammer_1",
        length: 140,
        width: 140,
        xOffset: -3,
        yOffset: 18,
        spdMult: 1,
        damage: 25,
        range: 65,
        gather: 1,
        speed: 300,
        knockback: 60
    }, {
        id: 1,
        itemType: 0,
        upgradeType: 1,
        type: 0,
        age: 2,
        name: "hand axe",
        description: "gathers resources at a higher rate",
        src: "axe_1",
        length: 140,
        width: 140,
        xOffset: 3,
        yOffset: 24,
        damage: 30,
        spdMult: 1,
        range: 70,
        gather: 2,
        speed: 400,
        knockback: 60
    }, {
        id: 2,
        itemType: 0,
        upgradeOf: 1,
        upgradeType: 1,
        type: 0,
        age: 8,
        pre: 1,
        name: "great axe",
        description: "deal more damage and gather more resources",
        src: "great_axe_1",
        length: 140,
        width: 140,
        xOffset: -8,
        yOffset: 25,
        damage: 35,
        spdMult: 1,
        range: 75,
        gather: 4,
        speed: 400,
        knockback: 60
    }, {
        id: 3,
        itemType: 0,
        upgradeType: 2,
        type: 0,
        age: 2,
        name: "short sword",
        description: "increased attack power but slower move speed",
        src: "sword_1",
        iPad: 1.3,
        length: 130,
        width: 210,
        xOffset: -8,
        yOffset: 46,
        damage: 35,
        spdMult: .85,
        range: 110,
        gather: 1,
        speed: 300,
        knockback: 60
    }, {
        id: 4,
        itemType: 0,
        upgradeOf: 3,
        upgradeType: 2,
        type: 0,
        age: 8,
        pre: 3,
        name: "katana",
        description: "greater range and damage",
        src: "samurai_1",
        iPad: 1.3,
        length: 130,
        width: 210,
        xOffset: -8,
        yOffset: 59,
        damage: 40,
        spdMult: .8,
        range: 118,
        gather: 1,
        speed: 300,
        knockback: 60
    }, {
        id: 5,
        itemType: 0,
        upgradeType: 3,
        isUpgrade: !1,
        type: 0,
        age: 2,
        name: "polearm",
        description: "long range melee weapon",
        src: "spear_1",
        iPad: 1.3,
        length: 130,
        width: 210,
        xOffset: -8,
        yOffset: 53,
        damage: 45,
        knock: .2,
        spdMult: .82,
        range: 142,
        gather: 1,
        speed: 700,
        knockback: 100
    }, {
        id: 6,
        itemType: 0,
        upgradeType: 4,
        isUpgrade: !1,
        type: 0,
        age: 2,
        name: "bat",
        description: "fast long range melee weapon",
        src: "bat_1",
        iPad: 1.3,
        length: 110,
        width: 180,
        xOffset: -8,
        yOffset: 53,
        damage: 20,
        knock: .7,
        spdMult: 1,
        range: 110,
        gather: 1,
        speed: 300,
        knockback: 204
    }, {
        id: 7,
        itemType: 0,
        upgradeType: 5,
        isUpgrade: !1,
        type: 0,
        age: 2,
        name: "daggers",
        description: "really fast short range weapon",
        src: "dagger_1",
        iPad: .8,
        length: 110,
        width: 110,
        xOffset: 18,
        yOffset: 0,
        damage: 20,
        knock: .1,
        range: 65,
        gather: 1,
        hitSlow: .1,
        spdMult: 1.13,
        speed: 100,
        knockback: 80
    }, {
        id: 8,
        itemType: 0,
        upgradeType: 6,
        isUpgrade: !1,
        type: 0,
        age: 2,
        name: "stick",
        description: "great for gathering but very weak",
        src: "stick_1",
        length: 140,
        width: 140,
        xOffset: 3,
        yOffset: 24,
        damage: 1,
        spdMult: 1,
        range: 70,
        gather: 7,
        speed: 400,
        knockback: 60
    }, {
        id: 9,
        itemType: 1,
        upgradeType: 7,
        projectile: 0,
        type: 1,
        age: 6,
        name: "hunting bow",
        description: "bow used for ranged combat and hunting",
        src: "bow_1",
        cost: {
            food: 0,
            wood: 4,
            stone: 0,
            gold: 0
        },
        length: 120,
        width: 120,
        xOffset: -6,
        yOffset: 0,
        spdMult: .75,
        speed: 600,
        range: 1e3,
        knockback: 60
    }, {
        id: 10,
        itemType: 1,
        upgradeType: 8,
        isUpgrade: !1,
        type: 1,
        age: 6,
        name: "great hammer",
        description: "hammer used for destroying structures",
        src: "great_hammer_1",
        length: 140,
        width: 140,
        xOffset: -9,
        yOffset: 25,
        damage: 10,
        spdMult: .88,
        range: 75,
        sDmg: 7.5,
        gather: 1,
        speed: 400,
        knockback: 60
    }, {
        id: 11,
        itemType: 1,
        upgradeType: 9,
        isUpgrade: !1,
        type: 1,
        age: 6,
        name: "wooden shield",
        description: "blocks projectiles and reduces melee damage",
        src: "shield_1",
        length: 120,
        width: 120,
        shield: .2,
        xOffset: 6,
        yOffset: 0,
        spdMult: .7,
        speed: 1,
        range: 0,
        knockback: 0
    }, {
        id: 12,
        itemType: 1,
        upgradeType: 7,
        projectile: 2,
        upgradeOf: 9,
        type: 1,
        age: 8,
        pre: 9,
        name: "crossbow",
        description: "deals more damage and has greater range",
        src: "crossbow_1",
        cost: {
            food: 0,
            wood: 5,
            stone: 0,
            gold: 0
        },
        aboveHand: !0,
        armS: .75,
        length: 120,
        width: 120,
        xOffset: -4,
        yOffset: 0,
        spdMult: .7,
        speed: 700,
        range: 1200,
        knockback: 60
    }, {
        id: 13,
        itemType: 1,
        upgradeType: 7,
        projectile: 3,
        upgradeOf: 12,
        type: 1,
        age: 9,
        pre: 12,
        name: "repeater crossbow",
        description: "high firerate crossbow with reduced damage",
        src: "crossbow_2",
        cost: {
            food: 0,
            wood: 10,
            stone: 0,
            gold: 0
        },
        aboveHand: !0,
        armS: .75,
        length: 120,
        width: 120,
        xOffset: -4,
        yOffset: 0,
        spdMult: .7,
        speed: 230,
        range: 1200,
        knockback: 60
    }, {
        id: 14,
        itemType: 1,
        upgradeType: 10,
        isUpgrade: !1,
        type: 1,
        age: 6,
        name: "mc grabby",
        description: "steals resources from enemies",
        src: "grab_1",
        length: 130,
        width: 210,
        xOffset: -8,
        yOffset: 53,
        damage: 0,
        steal: 250,
        knock: .2,
        spdMult: 1.05,
        range: 125,
        gather: 0,
        speed: 700,
        knockback: 100
    }, {
        id: 15,
        itemType: 1,
        upgradeType: 7,
        projectile: 5,
        upgradeOf: 12,
        type: 1,
        age: 9,
        pre: 12,
        name: "musket",
        description: "slow firerate but high damage and range",
        src: "musket_1",
        cost: {
            food: 0,
            wood: 0,
            stone: 10,
            gold: 0
        },
        aboveHand: !0,
        rec: .35,
        armS: .6,
        hndS: .3,
        hndD: 1.6,
        length: 205,
        width: 205,
        xOffset: 25,
        yOffset: 0,
        hideProjectile: !0,
        spdMult: .6,
        speed: 1500,
        range: 1400,
        knockback: 60
    } ], ItemGroups = {
        1: {
            name: "Wall",
            limit: 30,
            layer: 0
        },
        2: {
            name: "Spike",
            limit: 15,
            layer: 0
        },
        3: {
            name: "Windmill",
            limit: 7,
            sandboxLimit: 299,
            layer: 1
        },
        4: {
            name: "Mine",
            limit: 1,
            layer: 0
        },
        5: {
            name: "Trap",
            limit: 6,
            layer: -1
        },
        6: {
            name: "Boost",
            limit: 12,
            sandboxLimit: 299,
            layer: -1
        },
        7: {
            name: "Turret",
            limit: 2,
            layer: 1
        },
        8: {
            name: "Plaftorm",
            limit: 12,
            layer: -1
        },
        9: {
            name: "Healing pad",
            limit: 4,
            layer: -1
        },
        10: {
            name: "Spawn",
            limit: 1,
            layer: -1
        },
        11: {
            name: "Sapling",
            limit: 2,
            layer: 0
        },
        12: {
            name: "Blocker",
            limit: 3,
            layer: -1
        },
        13: {
            name: "Teleporter",
            limit: 2,
            sandboxLimit: 299,
            layer: -1
        }
    }, Items = [ {
        id: 0,
        itemType: 2,
        name: "apple",
        description: "restores 20 health when consumed",
        age: 0,
        cost: {
            food: 10,
            wood: 0,
            stone: 0,
            gold: 0
        },
        restore: 20,
        scale: 22,
        holdOffset: 15
    }, {
        id: 1,
        itemType: 2,
        upgradeOf: 0,
        name: "cookie",
        description: "restores 40 health when consumed",
        age: 3,
        cost: {
            food: 15,
            wood: 0,
            stone: 0,
            gold: 0
        },
        restore: 40,
        scale: 27,
        holdOffset: 15
    }, {
        id: 2,
        itemType: 2,
        upgradeOf: 1,
        name: "cheese",
        description: "restores 30 health and another 50 over 5 seconds",
        age: 7,
        cost: {
            food: 25,
            wood: 0,
            stone: 0,
            gold: 0
        },
        restore: 30,
        scale: 27,
        holdOffset: 15
    }, {
        id: 3,
        itemType: 3,
        itemGroup: 1,
        name: "wood wall",
        description: "provides protection for your village",
        age: 0,
        cost: {
            food: 0,
            wood: 10,
            stone: 0,
            gold: 0
        },
        projDmg: !0,
        health: 380,
        scale: 50,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 4,
        itemType: 3,
        itemGroup: 1,
        upgradeOf: 3,
        name: "stone wall",
        description: "provides improved protection for your village",
        age: 3,
        cost: {
            food: 0,
            wood: 0,
            stone: 25,
            gold: 0
        },
        health: 900,
        scale: 50,
        holdOffset: 20,
        placeOffset: -5
    }, {
        pre: 1,
        id: 5,
        itemType: 3,
        itemGroup: 1,
        upgradeOf: 4,
        name: "castle wall",
        description: "provides powerful protection for your village",
        age: 7,
        cost: {
            food: 0,
            wood: 0,
            stone: 35,
            gold: 0
        },
        health: 1500,
        scale: 52,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 6,
        itemType: 4,
        itemGroup: 2,
        name: "spikes",
        description: "damages enemies when they touch them",
        age: 0,
        cost: {
            food: 0,
            wood: 20,
            stone: 5,
            gold: 0
        },
        health: 400,
        damage: 20,
        scale: 49,
        spritePadding: -23,
        holdOffset: 8,
        placeOffset: -5
    }, {
        id: 7,
        itemType: 4,
        itemGroup: 2,
        upgradeOf: 6,
        name: "greater spikes",
        description: "damages enemies when they touch them",
        age: 5,
        cost: {
            food: 0,
            wood: 30,
            stone: 10,
            gold: 0
        },
        health: 500,
        damage: 35,
        scale: 52,
        spritePadding: -23,
        holdOffset: 8,
        placeOffset: -5
    }, {
        id: 8,
        itemType: 4,
        itemGroup: 2,
        upgradeOf: 7,
        name: "poison spikes",
        description: "poisons enemies when they touch them",
        age: 9,
        pre: 1,
        cost: {
            food: 0,
            wood: 35,
            stone: 15,
            gold: 0
        },
        health: 600,
        damage: 30,
        poisonDamage: 5,
        scale: 52,
        spritePadding: -23,
        holdOffset: 8,
        placeOffset: -5
    }, {
        id: 9,
        itemType: 4,
        itemGroup: 2,
        upgradeOf: 7,
        name: "spinning spikes",
        description: "damages enemies when they touch them",
        age: 9,
        pre: 2,
        cost: {
            food: 0,
            wood: 30,
            stone: 20,
            gold: 0
        },
        health: 500,
        damage: 45,
        turnSpeed: .003,
        scale: 52,
        spritePadding: -23,
        holdOffset: 8,
        placeOffset: -5
    }, {
        id: 10,
        itemType: 5,
        itemGroup: 3,
        name: "windmill",
        description: "generates gold over time",
        age: 0,
        cost: {
            food: 0,
            wood: 50,
            stone: 10,
            gold: 0
        },
        health: 400,
        pps: 1,
        turnSpeed: .0016,
        spritePadding: 25,
        iconLineMult: 12,
        scale: 45,
        holdOffset: 20,
        placeOffset: 5
    }, {
        id: 11,
        itemType: 5,
        itemGroup: 3,
        upgradeOf: 10,
        name: "faster windmill",
        description: "generates more gold over time",
        age: 5,
        pre: 1,
        cost: {
            food: 0,
            wood: 60,
            stone: 20,
            gold: 0
        },
        health: 500,
        pps: 1.5,
        turnSpeed: .0025,
        spritePadding: 25,
        iconLineMult: 12,
        scale: 47,
        holdOffset: 20,
        placeOffset: 5
    }, {
        id: 12,
        itemType: 5,
        itemGroup: 3,
        upgradeOf: 11,
        name: "power mill",
        description: "generates more gold over time",
        age: 8,
        pre: 1,
        cost: {
            food: 0,
            wood: 100,
            stone: 50,
            gold: 0
        },
        health: 800,
        pps: 2,
        turnSpeed: .005,
        spritePadding: 25,
        iconLineMult: 12,
        scale: 47,
        holdOffset: 20,
        placeOffset: 5
    }, {
        id: 13,
        itemType: 6,
        itemGroup: 4,
        name: "mine",
        description: "allows you to mine stone",
        age: 5,
        type: 2,
        cost: {
            food: 0,
            wood: 20,
            stone: 100,
            gold: 0
        },
        iconLineMult: 12,
        scale: 65,
        holdOffset: 20,
        placeOffset: 0
    }, {
        id: 14,
        itemType: 6,
        itemGroup: 11,
        name: "sapling",
        description: "allows you to farm wood",
        age: 5,
        type: 0,
        cost: {
            food: 0,
            wood: 150,
            stone: 0,
            gold: 0
        },
        iconLineMult: 12,
        colDiv: .5,
        scale: 110,
        holdOffset: 50,
        placeOffset: -15
    }, {
        id: 15,
        itemType: 7,
        itemGroup: 5,
        name: "pit trap",
        description: "pit that traps enemies if they walk over it",
        age: 4,
        cost: {
            food: 0,
            wood: 30,
            stone: 30,
            gold: 0
        },
        trap: !0,
        ignoreCollision: !0,
        hideFromEnemy: !0,
        health: 500,
        colDiv: .2,
        scale: 50,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 16,
        itemType: 7,
        itemGroup: 6,
        name: "boost pad",
        description: "provides boost when stepped on",
        age: 4,
        cost: {
            food: 0,
            wood: 5,
            stone: 20,
            gold: 0
        },
        boostSpeed: 1.5,
        health: 150,
        colDiv: .7,
        scale: 45,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 17,
        itemType: 8,
        itemGroup: 7,
        name: "turret",
        description: "defensive structure that shoots at enemies",
        age: 7,
        doUpdate: !0,
        cost: {
            food: 0,
            wood: 200,
            stone: 150,
            gold: 0
        },
        health: 800,
        projectile: 1,
        shootRange: 700,
        shootRate: 2200,
        scale: 43,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 18,
        itemType: 8,
        itemGroup: 8,
        name: "platform",
        description: "platform to shoot over walls and cross over water",
        age: 7,
        cost: {
            food: 0,
            wood: 20,
            stone: 0,
            gold: 0
        },
        ignoreCollision: !0,
        zIndex: 1,
        health: 300,
        scale: 43,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 19,
        itemType: 8,
        itemGroup: 9,
        name: "healing pad",
        description: "standing on it will slowly heal you",
        age: 7,
        cost: {
            food: 10,
            wood: 30,
            stone: 0,
            gold: 0
        },
        ignoreCollision: !0,
        healCol: 15,
        health: 400,
        colDiv: .7,
        scale: 45,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 20,
        itemType: 9,
        itemGroup: 10,
        name: "spawn pad",
        description: "you will spawn here when you die but it will dissapear",
        age: 9,
        cost: {
            food: 0,
            wood: 100,
            stone: 100,
            gold: 0
        },
        health: 400,
        ignoreCollision: !0,
        spawnPoint: !0,
        scale: 45,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 21,
        itemType: 8,
        itemGroup: 12,
        name: "blocker",
        description: "blocks building in radius",
        age: 7,
        cost: {
            food: 0,
            wood: 30,
            stone: 25,
            gold: 0
        },
        ignoreCollision: !0,
        blocker: 300,
        health: 400,
        colDiv: .7,
        scale: 45,
        holdOffset: 20,
        placeOffset: -5
    }, {
        id: 22,
        itemType: 8,
        itemGroup: 13,
        name: "teleporter",
        description: "teleports you to a random point on the map",
        age: 7,
        cost: {
            food: 0,
            wood: 60,
            stone: 60,
            gold: 0
        },
        teleport: !0,
        health: 200,
        colDiv: .7,
        scale: 45,
        holdOffset: 20,
        placeOffset: -5
    } ], WeaponVariants = [ {
        id: 0,
        src: "",
        xp: 1,
        needXP: 0,
        val: 1,
        color: "#7e7e90"
    }, {
        id: 1,
        src: "_g",
        xp: 3e3,
        needXP: 3e3,
        val: 1.1,
        color: "#f7cf45"
    }, {
        id: 2,
        src: "_d",
        xp: 7e3,
        needXP: 4e3,
        val: 1.18,
        color: "#6d91cb"
    }, {
        id: 3,
        src: "_r",
        poison: !0,
        xp: 12e3,
        needXP: 5e3,
        val: 1.18,
        color: "#be5454"
    } ], Projectiles = [ {
        id: 0,
        name: "Hunting bow",
        index: 0,
        layer: 0,
        src: "arrow_1",
        damage: 25,
        scale: 103,
        range: 1e3,
        speed: 1.6
    }, {
        id: 1,
        name: "Turret",
        index: 1,
        layer: 1,
        damage: 25,
        scale: 20,
        speed: 1.5,
        range: 700
    }, {
        id: 2,
        name: "Crossbow",
        index: 0,
        layer: 0,
        src: "arrow_1",
        damage: 35,
        scale: 103,
        range: 1200,
        speed: 2.5
    }, {
        id: 3,
        name: "Repeater crossbow",
        index: 0,
        layer: 0,
        src: "arrow_1",
        damage: 30,
        scale: 103,
        range: 1200,
        speed: 2
    }, {
        id: 4,
        index: 1,
        layer: 1,
        damage: 16,
        scale: 20,
        range: 0,
        speed: 0
    }, {
        id: 5,
        name: "Musket",
        index: 0,
        layer: 0,
        src: "bullet_1",
        damage: 50,
        scale: 160,
        range: 1400,
        speed: 3.6
    } ];

    class Vector {
        x;
        y;
        constructor(x = 0, y = 0) {
            this.x = x, this.y = y;
        }
        static fromAngle(angle, length = 1) {
            return new Vector(Math.cos(angle) * length, Math.sin(angle) * length);
        }
        add(vec) {
            if (vec instanceof Vector) {
                this.x += vec.x, this.y += vec.y;
            } else {
                this.x += vec, this.y += vec;
            }
            return this;
        }
        sub(vec) {
            if (vec instanceof Vector) {
                this.x -= vec.x, this.y -= vec.y;
            } else {
                this.x -= vec, this.y -= vec;
            }
            return this;
        }
        mult(scalar) {
            return this.x *= scalar, this.y *= scalar, this;
        }
        div(scalar) {
            let inv = 1 / scalar;
            return this.x *= inv, this.y *= inv, this;
        }
        get length() {
            return Math.hypot(this.x, this.y);
        }
        normalizeVec() {
            let len = this.length;
            if (len > 0) {
                let inv = 1 / len;
                this.x *= inv, this.y *= inv;
            }
            return this;
        }
        dot(vec) {
            return this.x * vec.x + this.y * vec.y;
        }
        setXY(x, y) {
            return this.x = x, this.y = y, this;
        }
        setVec(vec) {
            return this.setXY(vec.x, vec.y);
        }
        setLength(value) {
            return this.normalizeVec().mult(value);
        }
        copy() {
            return new Vector(this.x, this.y);
        }
        distanceDefault(vec) {
            let dx = this.x - vec.x, dy = this.y - vec.y;
            return dx * dx + dy * dy;
        }
        distance(vec) {
            let dx = this.x - vec.x, dy = this.y - vec.y;
            return Math.hypot(dx, dy);
        }
        angle(vec) {
            return Math.atan2(vec.y - this.y, vec.x - this.x);
        }
        addDirection(angle, length) {
            let x = this.x + Math.cos(angle) * length, y = this.y + Math.sin(angle) * length;
            return new Vector(x, y);
        }
        isEqual(vec) {
            return this.x === vec.x && this.y === vec.y;
        }
        makeString() {
            return this.x + ":" + this.y;
        }
    }

    const Vector_default = Vector;

    const getAngle = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1);

    const clamp = (value, min, max) => Math.min(Math.max(value, min), max), fixTo = (value, fraction) => parseFloat(value.toFixed(fraction)), PI = Math.PI, PI2 = PI * 2, getAngleDist = (a, b) => {
        let p = Math.abs(b - a) % (PI * 2);
        return p > PI ? PI * 2 - p : p;
    }, findMiddleAngle = (a, b) => {
        let x = Math.cos(a) + Math.cos(b), y = Math.sin(a) + Math.sin(b);
        return Math.atan2(y, x);
    }, toRadians = degrees => degrees * (PI / 180), removeFast = (array, index) => {
        if (index < 0 || index >= array.length) {
            throw RangeError("removeFast: Index out of range");
        }
        if (index === array.length - 1) {
            array.pop();
        } else {
            array[index] = array.pop();
        }
    };

    const lerp = (start, end, factor) => (1 - factor) * start + factor * end;

    const reverseAngle = angle => Math.atan2(-Math.sin(angle), -Math.cos(angle)), getTargetValue = (target, prop) => target[prop], setTargetValue = (target, prop, value) => {
        target[prop] = value;
    }, formatDate = date => {
        if (date == null) {
            date = new Date;
        }
        let hours = (date.getHours() + "").padStart(2, "0"), minutes = (date.getMinutes() + "").padStart(2, "0"), seconds = (date.getSeconds() + "").padStart(2, "0");
        return `${hours}:${minutes}:${seconds}`;
    }, incrementor = () => {
        let value = 0;
        return function() {
            return value++;
        };
    }, getUniqueID = incrementor(), pointInsideRect = (point, rectStart, rectEnd) => point.x >= rectStart.x && point.x <= rectEnd.x && point.y >= rectStart.y && point.y <= rectEnd.y;

    const isActiveInput = () => {
        let active = document.activeElement || document.body;
        return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement;
    }, getAngleFromBitmask = (bitmask, rotate) => {
        let vec = {
            x: 0,
            y: 0
        };
        if (bitmask & 1) {
            vec.y--;
        }
        if (bitmask & 2) {
            vec.y++;
        }
        if (bitmask & 4) {
            vec.x--;
        }
        if (bitmask & 8) {
            vec.x++;
        }
        if (rotate) {
            vec.x *= -1, vec.y *= -1;
        }
        return vec.x === 0 && vec.y === 0 ? null : Math.atan2(vec.y, vec.x);
    }, formatCode = code => {
        if (code += "", code === "Backspace") {
            return code;
        }
        if (code === "Escape") {
            return "ESC";
        }
        if (code === "Delete") {
            return "DEL";
        }
        if (code === "Minus") {
            return "-";
        }
        if (code === "Equal") {
            return "=";
        }
        if (code === "BracketLeft") {
            return "[";
        }
        if (code === "BracketRight") {
            return "]";
        }
        if (code === "Slash") {
            return "/";
        }
        if (code === "Backslash") {
            return "\\";
        }
        if (code === "Quote") {
            return "'";
        }
        if (code === "Backquote") {
            return "`";
        }
        if (code === "Semicolon") {
            return ";";
        }
        if (code === "Comma") {
            return ",";
        }
        if (code === "Period") {
            return ".";
        }
        if (code === "CapsLock") {
            return "CAPS";
        }
        if (code === "ContextMenu") {
            return "CTXMENU";
        }
        if (code === "NumLock") {
            return "LOCK";
        }
        return code.replace(/^Page/, "PG").replace(/^Digit/, "").replace(/Button$/, "BTN").replace(/^Key/, "").replace(/^(Shift|Control|Alt)(L|R).*$/, "$2$1").replace(/Control/, "CTRL").replace(/^Arrow/, "").replace(/^Numpad/, "NUM").replace(/Decimal/, "DEC").replace(/Subtract/, "SUB").replace(/Divide/, "DIV").replace(/Multiply/, "MULT").toUpperCase();
    }, formatButton = button => {
        if (button === 0) {
            return "LBTN";
        }
        if (button === 1) {
            return "MBTN";
        }
        if (button === 2) {
            return "RBTN";
        }
        if (button === 3) {
            return "BBTN";
        }
        if (button === 4) {
            return "FBTN";
        }
        throw Error(`formatButton Error: "${button}" is not valid button`);
    }, removeClass = (target, name) => {
        if (target instanceof HTMLElement) {
            target.classList.remove(name);
            return;
        }
        for (let element of target) {
            element.classList.remove(name);
        }
    };

    const pointInRiver = position => {
        let y = position.y, below = y >= Config_default.mapScale / 2 - Config_default.riverWidth / 2, above = y <= Config_default.mapScale / 2 + Config_default.riverWidth / 2;
        return below && above;
    }, pointInDesert = position => position.y >= Config_default.mapScale - Config_default.snowBiomeTop, inRange = (value, min, max) => value >= min && value <= max, targetInsideRect = (target, rectPos, radius) => {
        let screen = new Vector_default(1920, 1080).div(2).add(radius), rectStart = rectPos.copy().sub(screen), rectEnd = rectPos.copy().add(screen);
        return pointInsideRect(target, rectStart, rectEnd);
    }, findPlacementAngles = angles => {
        let output = new Set;
        for (let i = 0; i < angles.length; i++) {
            let [angle, offset] = angles[i], start = angle - offset, end = angle + offset, startIntersects = !1, endIntersects = !1;
            for (let j = 0; j < angles.length; j++) {
                if (startIntersects && endIntersects) {
                    break;
                }
                if (i === j) {
                    continue;
                }
                let [angle2, offset2] = angles[j];
                if (getAngleDist(start, angle2) <= offset2) {
                    startIntersects = !0;
                }
                if (getAngleDist(end, angle2) <= offset2) {
                    endIntersects = !0;
                }
            }
            if (!startIntersects) {
                output.add(start);
            }
            if (!endIntersects) {
                output.add(end);
            }
        }
        return [ ...output ];
    }, createAction = (callback, time = 0) => {
        let state = !1, timeoutID = setTimeout(() => {
            if (state) {
                return;
            }
            state = !0, callback();
        }, time);
        return () => {
            if (state) {
                return;
            }
            state = !0, clearTimeout(timeoutID), callback();
        };
    };

    class CustomStorage {
        static get(key) {
            let value = window.localStorage.getItem(key);
            return value === null ? null : JSON.parse(value);
        }
        static set(key, value, stringify = !0) {
            let data = stringify ? JSON.stringify(value) : value;
            window.localStorage.setItem(key, data);
        }
        static delete(key) {
            let has = window.localStorage.hasOwnProperty(key) && key in window.localStorage;
            return window.localStorage.removeItem(key), has;
        }
    }

    const Header_default = '<header>\n    <div id="credits">\n        <svg version="1.1" id="logo" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">\n        <path transform="translate(868.08 108.59)" d="m0 0c0.70463-0.0067323 1.4093-0.013465 2.1352-0.020401 6.4762 0.12104 11.035 2.1066 15.783 6.4267 6.7355 7.1685 7.4975 15.175 7.2769 24.712-0.32818 6.7315-1.9685 13.117-3.7144 19.6-0.39653 1.5245-0.79241 3.0492-1.1877 4.574-15.141 57.747-33.221 114.75-51.15 171.68-0.77339 2.4566-1.5457 4.9135-2.3178 7.3705-4.8024 15.273-9.6359 30.535-14.809 45.687-0.51513 1.5277-0.51513 1.5277-1.0407 3.0862-5.8617 16.918-5.8617 16.918-12.244 22.918-0.67418 0.65227-1.3484 1.3045-2.043 1.9766-1.7695 1.3984-1.7695 1.3984-3.7695 1.3984v2c-2.0273 1.7234-4.0653 3.3381-6.1875 4.9375-4.8734 3.7442-9.6517 7.5565-14.312 11.562-4.471 3.8341-9.032 7.5173-13.688 11.125-4.9944 3.8756-9.7402 7.9242-14.398 12.203-3.3976 3.0568-6.9447 5.9139-10.496 8.7891-3.7343 3.0494-7.405 6.1702-11.077 9.2942-3.4521 2.9308-6.943 5.8055-10.466 8.6511-4.7271 3.842-9.2068 7.9069-13.688 12.031-3.2993 2.954-6.7453 5.6796-10.227 8.4141-3.423 2.771-6.6461 5.7432-9.8984 8.7109-2.6078 2.3215-5.2829 4.5266-8 6.7188-4.7768 3.8631-9.302 7.9416-13.82 12.102-2.6423 2.3713-5.3491 4.6135-8.1172 6.8359-4.2031 3.3889-8.1871 6.9374-12.125 10.625-4.7712 4.4679-9.6791 8.6676-14.785 12.754-3.9854 3.2972-7.737 6.8279-11.5 10.375-2.2148 1.8711-2.2148 1.8711-4.2148 1.8711v2c-1.2227 1.2695-1.2227 1.2695-3.0625 2.8125-0.72574 0.61746-1.4515 1.2349-2.1992 1.8711-0.90363 0.76441-1.8073 1.5288-2.7383 2.3164-2.4635 2.119-4.9193 4.2469-7.375 6.375-0.6546 0.56598-1.3092 1.132-1.9836 1.7151-3.6698 3.1784-7.3014 6.3911-10.891 9.6599-3.2287 2.9318-6.5326 5.7126-9.9375 8.4375-5.3248 4.3005-10.273 8.933-15.238 13.637-4.625 4.3579-9.3867 8.402-14.403 12.308-2.0969 1.8028-3.6149 3.5924-5.1719 5.8672 5.208 2.3208 10.456 4.2336 15.875 6 4.5547 1.5 4.5547 1.5 6.8157 2.2454 1.6015 0.52332 3.2057 1.0382 4.812 1.5464 0.80478 0.25822 1.6096 0.51643 2.4387 0.78247 0.72905 0.23034 1.4581 0.46068 2.2092 0.698 2.6191 1.0307 3.9951 2.6343 5.8494 4.7278 1.2792 0.95451 2.5725 1.8902 3.875 2.8125 7.5329 5.5831 11.921 11.63 13.938 20.938 1.1447 13.632-5.9612 26.77-14.188 37.188-15.306 17.463-37.523 33.314-58.625 43.062h-2l-1 2c-9.832 3.3392-20.457 3.193-30-1-9.0874-4.8402-17.029-11.545-25-18-1.0018-0.81042-1.0018-0.81042-2.0239-1.6372-3.4276-2.7755-6.85-5.5573-10.269-8.3433-4.5453-3.7035-9.0945-7.3997-13.707-11.02-0.64324-0.51434-1.2865-1.0287-1.9492-1.5586-3.6186-2.7709-6.4181-4.8196-11.051-4.4414-3.0465 1.9411-5.465 4.4432-8 7-0.89461 0.87012-1.7892 1.7402-2.7109 2.6367-4.6551 4.5722-9.1144 9.2354-13.348 14.203-2.5425 2.829-5.236 5.4878-7.9414 8.1602-3.2221 3.1829-6.3905 6.3469-9.3125 9.8125-4.0741 4.7984-8.604 9.1542-13.095 13.558-3.1238 3.0815-6.1309 6.1991-8.991 9.5281-4.0078 4.6483-8.3527 8.9253-12.727 13.227-2.9835 2.9345-5.9455 5.8865-8.875 8.875-0.54793 0.5431-1.0959 1.0862-1.6604 1.6458-2.4213 2.5837-3.3138 4.1479-3.7576 7.6941 0.076055 1.1872 0.15211 2.3745 0.23047 3.5977 0.047874 1.3357 0.088031 2.6717 0.12109 4.0078 0.017886 0.67579 0.035771 1.3516 0.054199 2.0479 0.13648 22.438-9.8287 42.623-25.238 58.386-16.639 15.859-38.194 21.12-60.574 20.77-32.474-0.91475-58.907-15.915-81.383-38.352-17.614-18.76-26.234-43.914-27.043-69.359 0.81801-25.407 10.042-46.905 28.438-64.625 12.128-10.629 27.322-17.522 43.197-20.087 8.9085-1.4767 13.784-3.2843 19.51-10.745 0.6948-0.98355 1.3896-1.9671 2.1055-2.9805 1.4259-1.7595 2.8634-3.5096 4.3125-5.25 0.72832-0.90105 1.4566-1.8021 2.207-2.7305 7.2516-8.8275 14.851-17.375 22.516-25.844 3.9882-4.4163 7.8855-8.9089 11.75-13.434 1.0299-1.2058 2.0599-2.4115 3.0898-3.6172 0.51965-0.60852 1.0393-1.217 1.5747-1.844 3.0292-3.5372 6.1018-7.0249 9.2378-10.469 4.6378-5.11 8.9914-10.434 13.312-15.812 1.0886-1.3052 1.0886-1.3052 2.1992-2.6367 2.6966-3.539 3.2616-6.8067 3.1938-11.236-0.74301-4.0206-3.4519-6.5065-6.2056-9.377-0.58878-0.6455-1.1776-1.291-1.7842-1.9561-1.7834-1.9486-3.5909-3.8723-5.4033-5.7939-1.4678-1.5866-2.93-3.178-4.3914-4.7705-1.3503-1.4704-2.706-2.9359-4.0618-4.4014-3.2209-3.5765-6.2239-7.3042-9.2383-11.055-2.4819-2.9817-5.0951-5.8187-7.7461-8.6484-11.792-12.676-21.99-24.809-21.48-43.066 3.407-27.518 27.039-66.699 47.918-84.559 5.9718-4.5112 12.209-7.1966 19.84-6.8477 17.094 2.7511 34.034 17.486 44.098 30.938 4.2859 6.4381 7.3285 13.191 10.062 20.41 7.824-9.5531 15.526-19.17 23-29 2.0817-2.7304 4.1656-5.4591 6.25-8.1875 0.81356-1.0657 0.81356-1.0657 1.6436-2.1528 4.0884-5.348 8.2159-10.664 12.356-15.972 4.6005-5.8986 9.1409-11.833 13.609-17.832 2.3536-3.1396 4.7426-6.2498 7.1406-9.3555 3.8824-5.0298 7.7073-10.099 11.508-15.191 1.8918-2.5232 3.809-5.0258 5.7344-7.5234 7.5051-9.6188 7.5051-9.6188 14.316-19.73 1.3298-1.8955 2.7369-3.5894 4.2539-5.3359 3.1005-3.572 5.9408-7.2908 8.75-11.094 1.0579-1.4211 2.1165-2.8416 3.1758-4.2617 0.53963-0.72365 1.0793-1.4473 1.6353-2.1929 2.6013-3.4712 5.2376-6.9153 7.8765-10.358 0.52964-0.69182 1.0593-1.3836 1.605-2.0964 2.371-3.0966 4.7431-6.1922 7.1172-9.2864 6.9922-9.117 13.973-18.224 20.592-27.617 3.0266-4.2821 6.1935-8.4387 9.4126-12.577 3.6953-4.7679 7.2699-9.6201 10.836-14.485 5.1531-7.0285 10.394-13.981 15.708-20.889 2.9437-3.8331 5.8403-7.6907 8.6675-11.611 2.947-4.0834 5.9477-8.12 9-12.125 0.79793-1.0493 1.5959-2.0986 2.418-3.1797 7.3745-9.0707 16.159-14.641 27.277-18.121 2.2951-0.62073 2.2951-0.62073 3.1172-2.8242 1.8452-0.2245 3.6914-0.44251 5.5404-0.63281 4.8219-0.71986 9.4052-2.3736 14.034-3.8672 1.11-0.35194 2.2199-0.70389 3.3635-1.0665 3.5853-1.1382 7.1675-2.2859 10.75-3.4335 2.4571-0.78153 4.9145-1.5623 7.3721-2.3423 4.8141-1.5283 9.6274-3.0592 14.44-4.5923 7.9059-2.5156 15.825-4.9889 23.75-7.4404 1.0889-0.33773 2.1777-0.67547 3.2996-1.0234 1.9287-0.59704 3.8581-1.192 5.7883-1.7842 1.8337-0.56302 3.6656-1.1317 5.4961-1.7051 0.89525-0.27683 1.7905-0.55365 2.7129-0.83887 0.78729-0.24573 1.5746-0.49146 2.3857-0.74463 2.0674-0.52881 2.0674-0.52881 5.0674-0.52881l1-2c2.0635-0.65381 2.0635-0.65381 4.8906-1.2734 5.3022-1.2515 10.508-2.6858 15.719-4.2656 0.791-0.2396 1.582-0.4792 2.397-0.72606 1.6915-0.51395 3.3826-1.029 5.0735-1.545 2.7544-0.84057 5.51-1.6773 8.2659-2.5133 8.5257-2.5879 17.048-5.1863 25.57-7.7864 13.103-3.9975 26.21-7.9851 39.326-11.94 6.004-1.8112 12.003-3.6372 17.996-5.485 3.178-0.97486 6.3616-1.9305 9.5474-2.8797 1.3959-0.41997 2.7895-0.84771 4.1802-1.2846 7.4197-2.3263 14.365-3.6465 22.117-3.7067z" fill="#353C35"/>\n        <path transform="translate(843,160)" d="m0 0c0.87909 3.1738 0.98903 4.9646 0.066406 8.1484-0.34938 1.2387-0.34938 1.2387-0.70581 2.5024-0.39506 1.3484-0.39506 1.3484-0.7981 2.7241-0.55849 1.9736-1.1157 3.9476-1.6719 5.9219-0.30357 1.0693-0.60715 2.1386-0.91992 3.2402-1.5967 5.6962-3.1174 11.413-4.6372 17.13-0.50784 1.9089-1.0182 3.8171-1.5285 5.7253-1.4648 5.4908-2.907 10.983-4.262 16.502-1.8468 7.4363-3.9359 14.802-6.043 22.168-0.21587 0.75494-0.43174 1.5099-0.65414 2.2877-8.0126 27.951-17.064 55.512-26.559 82.99-2.8479 8.2577-5.5966 16.548-8.3086 24.851-1.7657 5.3597-3.6081 10.69-5.5405 15.992-0.39316 1.0872-0.78633 2.1745-1.1914 3.2947-0.41121 0.83217-0.82242 1.6643-1.2461 2.5217-3.6956 1.2319-4.5849 0.62215-8.1133-0.83594-1.001-0.40477-2.0019-0.80953-3.0332-1.2266-1.0448-0.43312-2.0896-0.86625-3.166-1.3125-2.0563-0.84665-4.1149-1.688-6.1758-2.5234-0.91306-0.37818-1.8261-0.75636-2.7668-1.146-2.9074-1.0121-5.7004-1.5329-8.7449-1.9556 1.3335 1.3335 2.8308 2.2957 4.3867 3.3633 0.69158 0.47502 1.3832 0.95004 2.0957 1.4395 0.72768 0.49822 1.4554 0.99645 2.2051 1.5098 0.70834 0.48662 1.4167 0.97324 2.1465 1.4746 4.0353 2.7685 8.0873 5.5087 12.166 8.2129-1.5022 3.7389-3.6017 5.5409-6.75 8-4.4989 3.5802-8.9008 7.2395-13.25 11-4.9886 4.3006-10.042 8.5049-15.156 12.656-3.9325 3.2411-7.787 6.5698-11.646 9.8979-3.5828 3.0831-7.2074 6.1011-10.885 9.0708-3.7169 3.0149-7.2893 6.1358-10.812 9.375-4.3903 4.0363-8.9118 7.8403-13.551 11.586-3.3629 2.7527-6.6585 5.5758-9.9492 8.4141-4.1022 3.5362-8.228 7.0286-12.438 10.438-5.0518 4.1023-9.9656 8.3495-14.873 12.623-4.0583 3.5322-8.1393 7.0343-12.252 10.502-12.951 10.904-12.951 10.904-25.625 22.125-3.2492 2.9538-6.5712 5.757-10 8.5-6.0657 4.9025-11.694 10.235-17.367 15.582-3.1257 2.9433-6.314 5.7988-9.5664 8.6016-4.0147 3.4805-7.935 7.0686-11.879 10.629-1.6664 1.5003-3.3331 3.0003-5 4.5-0.82887 0.74637-1.6577 1.4927-2.5117 2.2617-1.626 1.4627-3.2536 2.9237-4.8828 4.3828-8.3305 7.4692-16.56 15.047-24.711 22.711-0.69916 0.65726-1.3983 1.3145-2.1187 1.9917-1.3493 1.2698-2.6973 2.5409-4.0439 3.8135-4.4852 4.2235-9.0804 8.3005-13.732 12.339-1.6688 1.4768-3.3359 2.9554-5 4.4375-0.76312 0.67934-1.5262 1.3587-2.3125 2.0586-0.83531 0.74443-0.83531 0.74443-1.6875 1.5039-3.5083-1.5208-5.9527-3.5996-8.75-6.1875-2.9494-2.7054-5.8997-5.3943-8.9375-8-4.6095-4.0135-9.0492-8.2078-13.509-12.386-5.8936-5.5207-11.839-10.983-17.804-16.427 5.0137-5.9623 10.266-11.693 15.544-17.419 2.3231-2.5226 4.639-5.0519 6.9556-7.5806 0.92056-1.0039 1.8411-2.0078 2.7617-3.0117 1.7961-1.9592 3.59-3.9205 5.3828-5.8828 5.1673-5.6515 10.371-11.266 15.605-16.855 4.0531-4.3292 8.0554-8.6815 11.926-13.176 2.4978-2.8401 5.0669-5.6118 7.6367-8.3867 9.9004-10.674 9.9004-10.674 19.562-21.562 3.6073-4.1544 7.3481-8.1822 11.099-12.207 2.6949-2.8999 5.3367-5.8352 7.9321-8.8247 4.1992-4.8221 8.5917-9.4524 12.988-14.094 3.7604-3.9861 7.4233-8.034 10.996-12.189 1.6392-1.844 3.3487-3.5828 5.1094-5.3105 2.2933-2.258 4.4643-4.56 6.5625-7 5.1684-5.9857 10.626-11.708 16.036-17.474 1.8617-1.9841 3.7216-3.9698 5.5811-5.9561 3.1132-3.3247 6.2293-6.6466 9.3467-9.9673 1.3605-1.4497 2.7205-2.9 4.0801-4.3506 2.1301-2.2727 4.2617-4.5439 6.3936-6.8149 0.6463-0.69013 1.2926-1.3803 1.9585-2.0913 3.0535-3.2496 6.1349-6.4582 9.2993-9.6001 2.3124-2.2965 4.5196-4.6239 6.6172-7.1211 2.5913-3.0097 5.2975-5.8359 8.125-8.625 2.7862-2.7486 5.4531-5.5286 8-8.5 3.18-3.7101 6.5876-7.1298 10.094-10.531 1.9594-2.0103 3.7888-4.0495 5.6172-6.1758 4.0901-4.7132 8.4794-9.0936 12.914-13.48 0.78504-0.78053 1.5701-1.5611 2.3789-2.3652 5.9292-5.8942 5.9292-5.8942 8.1169-8.0286 3.2839-3.2186 5.2875-5.6724 5.4463-10.431-0.0079761-0.71132-0.015952-1.4226-0.02417-2.1555-0.01418-1.2646-0.028359-2.5291-0.042969-3.832-0.8826 0.38333-1.7652 0.76667-2.6746 1.1616-3.2891 1.4283-6.5786 2.8556-9.8682 4.2827-1.421 0.61661-2.8419 1.2335-4.2627 1.8506-2.0476 0.88934-4.0957 1.7778-6.1438 2.666-0.63041 0.27404-1.2608 0.54807-1.9103 0.83041-2.654 1.1501-5.3006 2.2683-8.0116 3.2785-2.707 1.1828-2.9946 2.2719-4.1289 4.9302-1.4805 1.6406-1.4805 1.6406-3.1875 3.25-3.2018 3.0294-6.0544 6.2979-8.9412 9.6226-2.9422 3.3449-5.9993 6.5777-9.0588 9.8149-1.3233 1.4059-2.6462 2.8121-3.9688 4.2188-0.64969 0.69094-1.2994 1.3819-1.9688 2.0938-2.7022 2.8823-5.3852 5.782-8.0625 8.6875-0.4859 0.52715-0.97179 1.0543-1.4724 1.5974-1.922 2.0864-3.8427 4.174-5.7625 6.2625-8.118 8.8299-16.324 17.574-24.552 26.302-5.6877 6.0386-11.357 12.095-17.026 18.151-0.60618 0.64743-1.2124 1.2949-1.8369 1.9619-6.8593 7.3286-13.69 14.682-20.464 22.089-7.7804 8.5011-15.62 16.946-23.49 25.365-3.7309 3.9935-7.4455 8.0013-11.147 12.022-5.716 6.2062-11.487 12.36-17.262 18.512-7.9458 8.4654-15.873 16.948-23.738 25.488-7.6097 8.261-15.309 16.438-22.999 24.624-1.9174 2.0416-3.8344 4.0836-5.751 6.126-0.62117 0.66169-1.2423 1.3234-1.8823 2.0051-3.9812 4.2462-7.9315 8.5194-11.868 12.807-4.4004 4.7913-8.9009 9.4618-13.562 14-5.8423-4.1181-11.1-8.7281-16.355-13.566-4.6205-4.252-9.3708-8.3474-14.145-12.426-0.62673-0.53577-1.2535-1.0715-1.8992-1.6235-1.2542-1.0713-2.5096-2.1413-3.7661-3.21-0.58096-0.49581-1.1619-0.99161-1.7605-1.5024-0.5199-0.44247-1.0398-0.88494-1.5754-1.3408-1.5624-1.3875-3.0357-2.8398-4.4988-4.3311 1.6268-3.6539 3.8669-6.596 6.3125-9.75 0.43441-0.56074 0.86883-1.1215 1.3164-1.6992 4.1028-5.2668 8.3245-10.436 12.55-15.604 3.3615-4.1209 6.6595-8.28 9.8838-12.509 3.5663-4.6743 7.1936-9.2908 10.875-13.875 5.7387-7.148 11.418-14.34 17.062-21.562 0.52288-0.66838 1.0458-1.3368 1.5845-2.0254 8.3281-10.652 16.554-21.378 24.736-32.143 2.9156-3.8344 5.8538-7.6498 8.8047-11.457 4.5205-5.8616 8.8975-11.824 13.273-17.794 4.5458-6.1869 9.1826-12.299 13.852-18.393 4.7428-6.1924 9.4013-12.419 13.884-18.802 3.8186-5.3996 7.843-10.637 11.866-15.885 4.8482-6.3256 9.6231-12.679 14.212-19.195 3.5844-5.0695 7.304-10.033 11.038-14.993 13.008-17.283 25.755-34.749 38.348-52.336 0.59031-0.82234 1.1806-1.6447 1.7888-2.4919 1.1321-1.5772 2.2619-3.1561 3.3892-4.7368 0.50974-0.70955 1.0195-1.4191 1.5447-2.1501 0.44618-0.62383 0.89235-1.2477 1.3521-1.8904 2.4758-3.1838 4.393-4.9888 8.2991-6.1675 0.81133-0.24997 1.6227-0.49994 2.4586-0.75749 0.89321-0.26461 1.7864-0.52921 2.7067-0.80183 0.95336-0.29083 1.9067-0.58166 2.889-0.8813 3.218-0.97942 6.4399-1.9453 9.6618-2.9117 2.2999-0.69745 4.5996-1.3959 6.8989-2.0952 4.3839-1.3323 8.7687-2.6616 13.155-3.9868 9.3777-2.8337 18.747-5.6947 28.114-8.5625 1.5308-0.46858 3.0615-0.93715 4.5923-1.4057 0.76137-0.23306 1.5227-0.46611 2.3072-0.70623 0.76342-0.23368 1.5268-0.46736 2.3134-0.70812 0.76499-0.23418 1.53-0.46836 2.3182-0.70964 8.5298-2.6108 17.062-5.2145 25.594-7.8179 8.9283-2.7244 17.856-5.45 26.781-8.1852 32.342-9.9105 64.783-19.48 97.238-29.01z" fill="#747C77"/>\n        <path transform="translate(843,162)" d="m0 0c-0.87914 0.55043-1.7583 1.1009-2.6641 1.668-3.2988 2.2008-5.9543 4.7869-8.7109 7.6445-3.1416 3.223-6.3009 6.3527-9.75 9.25-2.8194 2.4053-5.2724 4.9422-7.707 7.7344-5.6994 6.3871-11.736 12.422-17.798 18.463-1.9365 1.9311-3.8675 3.8675-5.7981 5.8044-5.5335 5.5362-11.049 11.027-17.017 16.099-2.1348 1.8351-4.0956 3.817-6.0549 5.8367-3.4037 3.4505-6.9244 6.6664-10.602 9.8203-2.455 2.1721-4.7288 4.4971-7.0234 6.8359-1.8109 1.7807-3.6764 3.4458-5.6016 5.1016-4.1474 3.6059-8.1554 7.342-12.148 11.117-1.4111 1.322-2.8226 2.6436-4.2344 3.9648-2.2389 2.0989-4.4567 4.211-6.6562 6.3516-12.756 12.144-30.677 19.789-47.234 25.309-0.69964 1.3163-1.363 2.6522-2 4-1.4805 1.6406-1.4805 1.6406-3.1875 3.25-3.2018 3.0294-6.0544 6.2979-8.9412 9.6226-2.9422 3.3449-5.9993 6.5777-9.0588 9.8149-1.3233 1.4059-2.6462 2.8121-3.9688 4.2188-0.64969 0.69094-1.2994 1.3819-1.9688 2.0938-2.7022 2.8823-5.3852 5.782-8.0625 8.6875-0.4859 0.52715-0.97179 1.0543-1.4724 1.5974-1.922 2.0864-3.8427 4.174-5.7625 6.2625-8.118 8.8299-16.324 17.574-24.552 26.302-5.6877 6.0386-11.357 12.095-17.026 18.151-0.60618 0.64743-1.2124 1.2949-1.8369 1.9619-6.8593 7.3286-13.69 14.682-20.464 22.089-7.7804 8.5011-15.62 16.946-23.49 25.365-3.7309 3.9935-7.4455 8.0013-11.147 12.022-5.716 6.2062-11.487 12.36-17.262 18.512-7.9458 8.4654-15.873 16.948-23.738 25.488-7.6097 8.261-15.309 16.438-22.999 24.624-1.9174 2.0416-3.8344 4.0836-5.751 6.126-0.62117 0.66169-1.2423 1.3234-1.8823 2.0051-3.9812 4.2462-7.9315 8.5194-11.868 12.807-4.4004 4.7913-8.9009 9.4618-13.562 14-5.8423-4.1181-11.1-8.7281-16.355-13.566-4.6205-4.252-9.3708-8.3474-14.145-12.426-0.62673-0.53577-1.2535-1.0715-1.8992-1.6235-1.2542-1.0713-2.5096-2.1413-3.7661-3.21-0.58096-0.49581-1.1619-0.99161-1.7605-1.5024-0.5199-0.44247-1.0398-0.88494-1.5754-1.3408-1.5624-1.3875-3.0357-2.8398-4.4988-4.3311 1.6268-3.6539 3.8669-6.596 6.3125-9.75 0.43441-0.56074 0.86883-1.1215 1.3164-1.6992 4.1028-5.2668 8.3245-10.436 12.55-15.604 3.3615-4.1209 6.6595-8.28 9.8838-12.509 3.5663-4.6743 7.1936-9.2908 10.875-13.875 5.7387-7.148 11.418-14.34 17.062-21.562 0.52288-0.66838 1.0458-1.3368 1.5845-2.0254 8.3281-10.652 16.554-21.378 24.736-32.143 2.9156-3.8344 5.8538-7.6498 8.8047-11.457 4.5205-5.8616 8.8975-11.824 13.273-17.794 4.5458-6.1869 9.1826-12.299 13.852-18.393 4.7428-6.1924 9.4013-12.419 13.884-18.802 3.8186-5.3996 7.843-10.637 11.866-15.885 4.8482-6.3256 9.6231-12.679 14.212-19.195 3.5844-5.0695 7.304-10.033 11.038-14.993 13.008-17.283 25.755-34.749 38.348-52.336 0.59031-0.82234 1.1806-1.6447 1.7888-2.4919 1.1321-1.5772 2.2619-3.1561 3.3892-4.7368 0.50974-0.70955 1.0195-1.4191 1.5447-2.1501 0.44618-0.62383 0.89235-1.2477 1.3521-1.8904 2.4758-3.1838 4.393-4.9888 8.2991-6.1675 0.81133-0.24997 1.6227-0.49994 2.4586-0.75749 0.89321-0.26461 1.7864-0.52921 2.7067-0.80183 0.95336-0.29083 1.9067-0.58166 2.889-0.8813 3.218-0.97942 6.4399-1.9453 9.6618-2.9117 2.2999-0.69745 4.5996-1.3959 6.8989-2.0952 4.3839-1.3323 8.7687-2.6616 13.155-3.9868 9.3777-2.8337 18.747-5.6947 28.114-8.5625 3.0712-0.94012 6.1424-1.8802 9.2136-2.8203 1.1475-0.35129 1.1475-0.35129 2.3183-0.70968 9.2804-2.8405 18.563-5.6724 27.846-8.5048 8.2032-2.5031 16.406-5.0088 24.605-7.5237 21.256-6.5191 42.543-12.934 63.862-19.241 2.6425-0.78197 5.2838-1.5678 7.9242-2.357 3.6676-1.0959 7.3393-2.1775 11.012-3.2577 1.6605-0.49876 1.6605-0.49876 3.3544-1.0076 1.0144-0.29583 2.0289-0.59166 3.074-0.89645 0.88496-0.262 1.7699-0.52399 2.6817-0.79393 2.2531-0.43092 2.2531-0.43092 5.2531 0.56908z" fill="#A8AAA1"/>\n        <path transform="translate(868.08 108.59)" d="m0 0c0.70463-0.0067323 1.4093-0.013465 2.1352-0.020401 6.4762 0.12104 11.035 2.1066 15.783 6.4267 6.7355 7.1685 7.4975 15.175 7.2769 24.712-0.32818 6.7315-1.9685 13.117-3.7144 19.6-0.39653 1.5245-0.79241 3.0492-1.1877 4.574-15.141 57.747-33.221 114.75-51.15 171.68-0.77339 2.4566-1.5457 4.9135-2.3178 7.3705-4.8024 15.273-9.6359 30.535-14.809 45.687-0.51513 1.5277-0.51513 1.5277-1.0407 3.0862-5.8617 16.918-5.8617 16.918-12.244 22.918-0.67418 0.65227-1.3484 1.3045-2.043 1.9766-1.7695 1.3984-1.7695 1.3984-3.7695 1.3984v2c-2.0273 1.7234-4.0653 3.3381-6.1875 4.9375-4.8734 3.7442-9.6517 7.5565-14.312 11.562-4.471 3.8341-9.032 7.5173-13.688 11.125-4.9944 3.8756-9.7402 7.9242-14.398 12.203-3.3976 3.0568-6.9447 5.9139-10.496 8.7891-3.7343 3.0494-7.405 6.1702-11.077 9.2942-3.4521 2.9308-6.943 5.8055-10.466 8.6511-4.7271 3.842-9.2068 7.9069-13.688 12.031-3.2993 2.954-6.7453 5.6796-10.227 8.4141-3.423 2.771-6.6461 5.7432-9.8984 8.7109-2.6078 2.3215-5.2829 4.5266-8 6.7188-4.7768 3.8631-9.302 7.9416-13.82 12.102-2.6423 2.3713-5.3491 4.6135-8.1172 6.8359-4.2031 3.3889-8.1871 6.9374-12.125 10.625-4.7712 4.4679-9.6791 8.6676-14.785 12.754-3.9854 3.2972-7.737 6.8279-11.5 10.375-2.2148 1.8711-2.2148 1.8711-4.2148 1.8711v2c-1.2227 1.2695-1.2227 1.2695-3.0625 2.8125-0.72574 0.61746-1.4515 1.2349-2.1992 1.8711-0.90363 0.76441-1.8073 1.5288-2.7383 2.3164-2.4635 2.119-4.9193 4.2469-7.375 6.375-0.6546 0.56598-1.3092 1.132-1.9836 1.7151-3.6698 3.1784-7.3014 6.3911-10.891 9.6599-3.2287 2.9318-6.5326 5.7126-9.9375 8.4375-5.3248 4.3005-10.273 8.933-15.238 13.637-4.625 4.3579-9.3867 8.402-14.403 12.308-2.0969 1.8028-3.6149 3.5924-5.1719 5.8672 5.208 2.3208 10.456 4.2336 15.875 6 4.5547 1.5 4.5547 1.5 6.8157 2.2454 1.6015 0.52332 3.2057 1.0382 4.812 1.5464 0.80478 0.25822 1.6096 0.51643 2.4387 0.78247 0.72905 0.23034 1.4581 0.46068 2.2092 0.698 2.6191 1.0307 3.9951 2.6343 5.8494 4.7278 1.2792 0.95451 2.5725 1.8902 3.875 2.8125 7.5329 5.5831 11.921 11.63 13.938 20.938 1.1447 13.632-5.9612 26.77-14.188 37.188-15.306 17.463-37.523 33.314-58.625 43.062h-2l-1 2c-9.832 3.3392-20.457 3.193-30-1-9.0874-4.8402-17.029-11.545-25-18-1.0018-0.81042-1.0018-0.81042-2.0239-1.6372-3.4276-2.7755-6.85-5.5573-10.269-8.3433-4.5453-3.7035-9.0945-7.3997-13.707-11.02-0.64324-0.51434-1.2865-1.0287-1.9492-1.5586-3.6186-2.7709-6.4181-4.8196-11.051-4.4414-3.0465 1.9411-5.465 4.4432-8 7-0.89461 0.87012-1.7892 1.7402-2.7109 2.6367-4.6551 4.5722-9.1144 9.2354-13.348 14.203-2.5425 2.829-5.236 5.4878-7.9414 8.1602-3.2221 3.1829-6.3905 6.3469-9.3125 9.8125-4.0741 4.7984-8.604 9.1542-13.095 13.558-3.1238 3.0815-6.1309 6.1991-8.991 9.5281-4.0078 4.6483-8.3527 8.9253-12.727 13.227-2.9835 2.9345-5.9455 5.8865-8.875 8.875-0.54793 0.5431-1.0959 1.0862-1.6604 1.6458-2.4213 2.5837-3.3138 4.1479-3.7576 7.6941 0.076055 1.1872 0.15211 2.3745 0.23047 3.5977 0.047874 1.3357 0.088031 2.6717 0.12109 4.0078 0.017886 0.67579 0.035771 1.3516 0.054199 2.0479 0.13648 22.438-9.8287 42.623-25.238 58.386-16.639 15.859-38.194 21.12-60.574 20.77-32.474-0.91475-58.907-15.915-81.383-38.352-17.614-18.76-26.234-43.914-27.043-69.359 0.81801-25.407 10.042-46.905 28.438-64.625 12.128-10.629 27.322-17.522 43.197-20.087 8.9085-1.4767 13.784-3.2843 19.51-10.745 0.6948-0.98355 1.3896-1.9671 2.1055-2.9805 1.4259-1.7595 2.8634-3.5096 4.3125-5.25 0.72832-0.90105 1.4566-1.8021 2.207-2.7305 7.2516-8.8275 14.851-17.375 22.516-25.844 3.9882-4.4163 7.8855-8.9089 11.75-13.434 1.0299-1.2058 2.0599-2.4115 3.0898-3.6172 0.51965-0.60852 1.0393-1.217 1.5747-1.844 3.0292-3.5372 6.1018-7.0249 9.2378-10.469 4.6378-5.11 8.9914-10.434 13.312-15.812 1.0886-1.3052 1.0886-1.3052 2.1992-2.6367 2.6966-3.539 3.2616-6.8067 3.1938-11.236-0.74301-4.0206-3.4519-6.5065-6.2056-9.377-0.58878-0.6455-1.1776-1.291-1.7842-1.9561-1.7834-1.9486-3.5909-3.8723-5.4033-5.7939-1.4678-1.5866-2.93-3.178-4.3914-4.7705-1.3503-1.4704-2.706-2.9359-4.0618-4.4014-3.2209-3.5765-6.2239-7.3042-9.2383-11.055-2.4819-2.9817-5.0951-5.8187-7.7461-8.6484-11.792-12.676-21.99-24.809-21.48-43.066 3.407-27.518 27.039-66.699 47.918-84.559 5.9718-4.5112 12.209-7.1966 19.84-6.8477 17.094 2.7511 34.034 17.486 44.098 30.938 4.2859 6.4381 7.3285 13.191 10.062 20.41 7.824-9.5531 15.526-19.17 23-29 2.0817-2.7304 4.1656-5.4591 6.25-8.1875 0.81356-1.0657 0.81356-1.0657 1.6436-2.1528 4.0884-5.348 8.2159-10.664 12.356-15.972 4.6005-5.8986 9.1409-11.833 13.609-17.832 2.3536-3.1396 4.7426-6.2498 7.1406-9.3555 3.8824-5.0298 7.7073-10.099 11.508-15.191 1.8918-2.5232 3.809-5.0258 5.7344-7.5234 7.5051-9.6188 7.5051-9.6188 14.316-19.73 1.3298-1.8955 2.7369-3.5894 4.2539-5.3359 3.1005-3.572 5.9408-7.2908 8.75-11.094 1.0579-1.4211 2.1165-2.8416 3.1758-4.2617 0.53963-0.72365 1.0793-1.4473 1.6353-2.1929 2.6013-3.4712 5.2376-6.9153 7.8765-10.358 0.52964-0.69182 1.0593-1.3836 1.605-2.0964 2.371-3.0966 4.7431-6.1922 7.1172-9.2864 6.9922-9.117 13.973-18.224 20.592-27.617 3.0266-4.2821 6.1935-8.4387 9.4126-12.577 3.6953-4.7679 7.2699-9.6201 10.836-14.485 5.1531-7.0285 10.394-13.981 15.708-20.889 2.9437-3.8331 5.8403-7.6907 8.6675-11.611 2.947-4.0834 5.9477-8.12 9-12.125 0.79793-1.0493 1.5959-2.0986 2.418-3.1797 7.3745-9.0707 16.159-14.641 27.277-18.121 2.2951-0.62073 2.2951-0.62073 3.1172-2.8242 1.8452-0.2245 3.6914-0.44251 5.5404-0.63281 4.8219-0.71986 9.4052-2.3736 14.034-3.8672 1.11-0.35194 2.2199-0.70389 3.3635-1.0665 3.5853-1.1382 7.1675-2.2859 10.75-3.4335 2.4571-0.78153 4.9145-1.5623 7.3721-2.3423 4.8141-1.5283 9.6274-3.0592 14.44-4.5923 7.9059-2.5156 15.825-4.9889 23.75-7.4404 1.0889-0.33773 2.1777-0.67547 3.2996-1.0234 1.9287-0.59704 3.8581-1.192 5.7883-1.7842 1.8337-0.56302 3.6656-1.1317 5.4961-1.7051 0.89525-0.27683 1.7905-0.55365 2.7129-0.83887 0.78729-0.24573 1.5746-0.49146 2.3857-0.74463 2.0674-0.52881 2.0674-0.52881 5.0674-0.52881l1-2c2.0635-0.65381 2.0635-0.65381 4.8906-1.2734 5.3022-1.2515 10.508-2.6858 15.719-4.2656 0.791-0.2396 1.582-0.4792 2.397-0.72606 1.6915-0.51395 3.3826-1.029 5.0735-1.545 2.7544-0.84057 5.51-1.6773 8.2659-2.5133 8.5257-2.5879 17.048-5.1863 25.57-7.7864 13.103-3.9975 26.21-7.9851 39.326-11.94 6.004-1.8112 12.003-3.6372 17.996-5.485 3.178-0.97486 6.3616-1.9305 9.5474-2.8797 1.3959-0.41997 2.7895-0.84771 4.1802-1.2846 7.4197-2.3263 14.365-3.6465 22.117-3.7067zm-20.992 17.742c-1.5499 0.45619-3.1001 0.91128-4.6507 1.3653-4.0269 1.1832-8.0487 2.3832-12.069 3.5889-2.2846 0.68421-4.5704 1.3645-6.8568 2.043-9.5576 2.8364-19.105 5.7071-28.647 8.5948-2.3569 0.71299-4.7141 1.425-7.0713 2.1368-28.296 8.5445-56.566 17.173-84.795 25.935-1.0035 0.31135-2.0069 0.6227-3.0408 0.94348-11.996 3.723-23.986 7.464-35.967 11.233-6.2251 1.9577-12.455 3.9007-18.687 5.8356-4.2845 1.3329-8.5657 2.676-12.846 4.0215-2.0207 0.63298-4.0427 1.262-6.066 1.8865-23.47 7.0698-23.47 7.0698-41.393 23.08-0.50999 0.67644-1.02 1.3529-1.5454 2.0498-3.6209 4.8229-7.1758 9.692-10.719 14.572-2.5442 3.4854-5.1374 6.9329-7.7358 10.378-4.2914 5.6993-8.5303 11.435-12.75 17.188-5.8112 7.9174-11.743 15.738-17.71 23.538-3.2287 4.2249-6.4375 8.4557-9.54 12.775-3.7697 5.2477-7.6994 10.369-11.625 15.5-5.1908 6.7865-10.327 13.607-15.375 20.5-6.8698 9.373-13.905 18.615-20.968 27.843-3.3505 4.3809-6.6909 8.7694-10.032 13.157-4.0804 5.3567-8.1618 10.713-12.246 16.066-6.2595 8.207-12.508 16.42-18.688 24.688-3.5663 4.7394-7.1935 9.4319-10.818 14.127-2.004 2.5988-4.0003 5.2034-5.9985 7.8066-4.6667 6.073-9.3716 12.116-14.077 18.159-4.201 5.3973-8.3772 10.813-12.54 16.24-2.0141 2.6188-4.0438 5.225-6.0781 7.8281-6.3274 8.0986-12.608 16.201-18.555 24.586-6.9-5.9417-8.8694-12.752-10.5-21.562-3.1413-16.743-15.725-28.293-28.996-38.324-4.9704-3.3265-9.0877-5.0553-15.129-4.6211-9.0228 1.9292-15.349 9.9374-20.217 17.289-1.8379 3.065-3.6047 6.1599-5.3457 9.281-0.63784 1.1267-1.2757 2.2534-1.9329 3.4143-1.9767 3.4985-3.9284 7.0104-5.8796 10.523-0.62262 1.1121-1.2452 2.2243-1.8867 3.3701-1.7787 3.1828-3.543 6.373-5.3008 9.5674-0.52811 0.95076-1.0562 1.9015-1.6003 2.8811-5.3829 9.9109-10.296 19.829-7.7395 31.302 3.2979 10.131 12.086 18.126 18.922 26.019 1.5739 1.8233 3.1383 3.6543 4.6992 5.4888 4.6212 5.4279 9.2691 10.809 14.094 16.059 4.0031 4.367 7.8029 8.8502 11.488 13.488 1.6811 2.0428 3.3639 3.9542 5.1797 5.8672 6.9058 7.4056 6.9058 7.4056 7.5039 11.293-0.47773 2.4506-1.2972 4.4042-2.3594 6.6641-0.34289 0.95906-0.68578 1.9181-1.0391 2.9062-3.9708 10.697-10.773 17.983-18.41 26.258-2.512 2.7928-4.8847 5.659-7.2383 8.5859-2.4836 3.0794-4.9667 6.0024-7.8125 8.75-2.7851 2.6897-5.205 5.5397-7.625 8.5625-3.6156 4.4979-7.4178 8.7384-11.375 12.938-4.6878 4.9792-9.1123 10.082-13.391 15.422-2.8273 3.4556-5.8354 6.7297-8.8438 10.027-3.1691 3.568-6.1497 7.2777-9.125 11.008-0.70641 0.83918-1.4128 1.6784-2.1406 2.543-1.135 1.3632-1.135 1.3632-2.293 2.7539-3.3422 2.7731-6.0931 3.1088-10.27 3.3711-1.4393 0.14086-2.8781 0.28673-4.3164 0.4375-1.056 0.10635-1.056 0.10635-2.1333 0.21484-16.805 1.8824-30.489 10.283-41.988 22.223-0.67547 0.65613-1.3509 1.3123-2.0469 1.9883-12.766 13.19-16.584 32.001-16.428 49.714 0.79634 25.347 11.757 48.491 30.17 65.836 23.549 19.979 49.936 27.238 80.305 25.461 15.018-1.7793 27.461-8.3189 38-19l2.1875-2.1562c11.759-12.293 16.363-28.618 16.137-45.352-0.30927-3.3312-1.0894-5.9615-2.1367-9.1172-0.57812-2.6211-0.57812-2.6211-0.1875-5.375 3.0217-4.5312 7.3532-8.0332 11.426-11.588 1.8251-1.6371 3.3975-3.3898 4.9487-5.2866 3.4775-4.1066 7.3047-7.8415 11.125-11.625 5.675-5.5854 5.675-5.5854 11-11.5 3.9971-4.7466 8.4812-9.0302 12.908-13.371 3.1365-3.094 6.1552-6.2259 9.0293-9.5664 4.4693-5.1832 9.3664-9.9146 14.246-14.707 4.6633-4.6127 9.0401-9.3842 13.316-14.355 5.8809-6.532 11.024-11.289 19.938-12.562 8.3374 0.47177 15.695 7.3299 21.938 12.312 0.78738 0.62052 1.5748 1.241 2.386 1.8804 5.9714 4.719 11.864 9.5308 17.739 14.37 17.718 15.737 17.718 15.737 40 20 20.093-4.875 39.931-21.506 55-35 0.68578-0.59039 1.3716-1.1808 2.0781-1.7891 7.7419-7.0793 13.824-17.234 15.258-27.652 0.11446-6.2152-1.4044-9.4474-5.7383-14.047-9.3288-8.8271-21.917-12.213-34.098-15.105-7.1522-1.9413-12.027-6.5835-17.5-11.406-1.2255-1.0252-2.4539-2.0471-3.6875-3.0625l-2.3125-1.9375c4.1524-4.3666 8.4172-8.4213 13.125-12.188 4.481-3.5935 8.6987-7.3764 12.875-11.312 4.0586-3.8223 8.143-7.5144 12.5-11 5.6914-4.5564 10.964-9.5079 16.277-14.492 3.044-2.8533 6.1523-5.6197 9.3125-8.3438 2.2722-1.9795 4.4948-4.0099 6.7227-6.0391 3.4413-3.1103 6.9507-6.0898 10.562-9 5.1475-4.1646 10.009-8.5781 14.863-13.074 4.5492-4.2018 9.2254-8.2452 13.941-12.258 5.7571-4.9042 11.467-9.8323 17.008-14.98 4.547-4.2233 9.2639-8.1758 14.098-12.066 2.8216-2.3344 5.5208-4.766 8.2148-7.2461 4.3717-4.0197 8.8779-7.7999 13.496-11.531 5.4653-4.4917 10.768-9.1733 16.103-13.818 12.22-10.613 24.536-21.121 37.088-31.338 3.1305-2.574 6.2242-5.1882 9.3125-7.8125 4.8518-4.1229 9.755-8.1747 14.695-12.191 2.5374-2.0886 5.0421-4.2087 7.5398-6.3442 4.884-4.1751 9.8275-8.2129 14.952-12.089 11.32-8.6011 19.234-15.721 23.746-29.301 0.31375-0.92181 0.6275-1.8436 0.95076-2.7934 1.0272-3.028 2.0408-6.0604 3.0531-9.0934 0.72144-2.1435 1.4431-4.2869 2.165-6.4302 6.7188-20.008 13.145-40.1 19.397-60.257 0.55425-1.7845 0.55425-1.7845 1.1197-3.6051 14.365-46.254 28.643-92.522 40.88-139.39 0.33322-1.27 0.66645-2.5401 1.0098-3.8486 0.88961-3.4212 1.7579-6.8469 2.6152-10.276 0.24798-0.95842 0.49597-1.9168 0.75146-2.9043 1.8143-7.4711 3.4038-15.472-0.18896-22.533-2.1576-2.4042-3.8429-4.1941-7.1086-4.7852-8.4095-0.17858-16.031 2.287-23.989 4.6837z" fill="#E8A371"/>\n        <path transform="translate(317,466)" d="m0 0c8.7462 9.718 10.895 21.708 13.625 34.062 0.57344 2.5517 1.1507 5.1024 1.7325 7.6522 0.35842 1.5749 0.71172 3.151 1.0587 4.7284 4.77 21.192 20.161 34.423 35.271 49.182 1.9066 1.9581 3.6864 3.9452 5.457 6.0234 0.53601 0.62826 1.072 1.2565 1.6243 1.9038 0.4063 0.47776 0.81259 0.95552 1.2312 1.4478-0.25693-0.55873-0.51385-1.1175-0.77856-1.6931-1.1828-2.5793-2.3584-5.1618-3.5339-7.7444-0.40412-0.8785-0.80824-1.757-1.2246-2.6621-5.3301-11.744-5.3301-11.744-6.4629-16.9l1-2c0.48469 0.49629 0.96938 0.99258 1.4688 1.5039 4.0598 4.1145 8.2155 8.0141 12.598 11.781 1.8885 1.6749 3.6652 3.4143 5.4336 5.2148 2.9516 2.998 6.0442 5.7622 9.2266 8.5117 9.9866 8.734 19.585 17.927 29.273 26.988 17.624 16.481 17.624 16.481 35.469 32.723 13.315 11.98 13.315 11.98 19.156 17.965 4.4612 4.5348 9.3307 8.4477 14.375 12.312l-2 1c-2.2492-0.91904-4.346-1.8912-6.5-3-0.62423-0.31598-1.2485-0.63196-1.8916-0.95752-4.8527-2.5159-9.3176-5.4105-13.718-8.6597-1.8423-1.4282-1.8423-1.4282-3.8906-2.3828 5.3218 4.9306 10.647 9.7769 16.312 14.312 4.4112 3.5554 8.5653 7.3072 12.688 11.188 5.7926 5.4464 11.784 10.539 18 15.5 2.067 1.6821 4.1269 3.3725 6.1875 5.0625 0.92168 0.7541 1.8434 1.5082 2.793 2.2852 0.66645 0.54527 1.3329 1.0905 2.0195 1.6523-0.5775-0.825-1.155-1.65-1.75-2.5-2.4488-3.6557-4.3579-7.5347-6.25-11.5 4.4585 1.407 8.6694 3.1163 12.93 5.0391 0.6352 0.28572 1.2704 0.57144 1.9248 0.86581 2.0081 0.90399 4.0143 1.812 6.0205 2.7201 1.3697 0.61745 2.7395 1.2346 4.1094 1.8516 3.3399 1.5048 6.6782 3.0131 10.016 4.5234v2c-1.5906 1.3393-3.2528 2.5936-4.9375 3.8125-1.1049 0.80888-2.209 1.6188-3.3125 2.4297-0.60199 0.44054-1.204 0.88107-1.8242 1.335-3.4874 2.5767-6.9229 5.2214-10.363 7.8604-1.0758 0.82371-1.0758 0.82371-2.1733 1.6641-6.471 4.9559-12.932 9.924-19.389 14.898-3.2446-1.4708-5.8055-3.3142-8.5625-5.5625l-2.6719-2.1719c-1.369-1.1215-1.369-1.1215-2.7656-2.2656l-2.6406-2.1406c-6.637-5.395-13.172-10.905-19.689-16.443-1.6742-1.4192-3.3531-2.8325-5.0337-4.2441-4.989-4.195-9.9398-8.4091-14.762-12.797-3.3337-3.0326-6.7407-5.9225-10.25-8.75-5.5761-4.5188-10.849-9.321-16.097-14.21-1.4808-1.371-2.977-2.7254-4.4736-4.0791-7.8939-7.1496-15.424-14.634-22.9-22.219-4.2506-4.295-8.5627-8.4059-13.147-12.341-3.8497-3.4059-7.446-7.0711-11.07-10.714-0.76377-0.7599-1.5275-1.5198-2.3145-2.3027-3.4802-3.4862-6.8778-6.9949-10.088-10.732-4.0973-4.7586-8.5621-9.1249-13.035-13.527-5.2022-5.12-10.27-10.263-15.025-15.803-1.7357-1.9977-3.5712-3.8595-5.4746-5.6973-3.1479-3.1059-6.0776-6.3219-8.957-9.6758-2.0924-2.3805-4.2414-4.6975-6.405-7.0129-4.8961-5.2406-9.541-10.56-13.954-16.221-2.0675-2.5664-4.3213-4.797-6.6836-7.0898-2-3-2-3-1.7776-5.4028 0.79878-2.6679 1.8073-4.7553 3.219-7.1519 0.49742-0.85473 0.99483-1.7095 1.5073-2.5901 0.53254-0.90097 1.0651-1.8019 1.6138-2.7302 1.0993-1.891 2.1969-3.7829 3.293-5.6758 0.53802-0.92764 1.076-1.8553 1.6304-2.811 5.5524-9.6742 10.594-19.631 15.514-29.638z" fill="#646C65"/>\n        <path transform="translate(843,162)" d="m0 0-7 4-1-1c-2.7155 0.58673-5.3787 1.2293-8.0625 1.9375-0.75861 0.19529-1.5172 0.39059-2.2988 0.5918-1.8809 0.48501-3.76 0.9772-5.6387 1.4707-0.13277 0.73323-0.26555 1.4665-0.40234 2.2219-1.0134 4.7103-2.2424 8.2155-5.5977 11.778-5.1132 2.6545-10.488 4.1934-16 5.8125-1.6126 0.50105-3.2242 1.0055-4.8347 1.5132-3.3608 1.055-6.7263 2.0926-10.096 3.1172-4.8816 1.4902-9.7379 3.0509-14.588 4.6392-0.77013 0.25213-1.5403 0.50426-2.3337 0.76402-1.5468 0.5067-3.0935 1.0136-4.6402 1.5207-3.8779 1.268-7.7605 2.5211-11.643 3.7739-0.75418 0.24344-1.5084 0.48687-2.2854 0.73769-4.7613 1.5365-9.5231 3.0713-14.285 4.6061-1.2268 0.39542-2.4536 0.79084-3.7175 1.1982-2.4766 0.79802-4.9533 1.5955-7.4302 2.3926-7.4276 2.3919-14.848 4.8064-22.262 7.2373-18.255 5.9813-36.529 11.889-54.883 17.562-0.84659 0.26311-1.6932 0.52622-2.5654 0.7973-2.3726 0.73632-4.747 1.4667-7.1221 2.1949-0.70101 0.21801-1.402 0.43603-2.1243 0.66064-2.8482 0.86583-5.1914 1.4722-8.1882 1.4722 0.27264 0.97888 0.27264 0.97888 0.55078 1.9775 3.9917 14.611 6.3633 27.872 5.4492 43.022h-2c-5.0611-9.8452-9.6513-19.822-14-30-4.4853 4.1835-7.9783 8.8493-11.562 13.812-1.2534 1.7178-2.5073 3.4353-3.7617 5.1523-0.62181 0.8532-1.2436 1.7064-1.8843 2.5854-2.5306 3.4604-5.0924 6.8966-7.6665 10.325-0.47784 0.6368-0.95568 1.2736-1.448 1.9297-4.834 6.4273-9.726 12.81-14.61 19.2-4.4604 5.8494-8.8488 11.746-13.192 17.683-5.1353 7.0156-10.405 13.91-15.766 20.755-3.7632 4.8093-7.4615 9.6602-11.109 14.558-4.2179 5.6637-8.5201 11.253-12.875 16.812-4.8811 6.2348-9.638 12.546-14.312 18.938-5.3639 7.3332-10.884 14.513-16.533 21.628-2.1193 2.6872-4.1989 5.4047-6.2793 8.1221-3.4681 4.5256-6.9709 9.0218-10.5 13.5-3.874 4.9169-7.7118 9.8595-11.522 14.826-9.1315 11.896-18.375 23.705-27.652 35.488-2.2775 2.8936-4.5519 5.7897-6.8267 8.6855-2.7961 3.5592-5.5926 7.1181-8.3906 10.676-5.0542 6.4277-10.1 12.862-15.109 19.324 0.99 1.65 1.98 3.3 3 5-4.1242-1.6617-7.0655-4.6234-10.25-7.625-0.5543-0.51562-1.1086-1.0312-1.6797-1.5625-1.3606-1.2668-2.716-2.5391-4.0703-3.8125 1.6268-3.6539 3.8669-6.596 6.3125-9.75 0.43441-0.56074 0.86883-1.1215 1.3164-1.6992 4.1028-5.2668 8.3245-10.436 12.55-15.604 3.3615-4.1209 6.6595-8.28 9.8838-12.509 3.5663-4.6743 7.1936-9.2908 10.875-13.875 5.7387-7.148 11.418-14.34 17.062-21.562 0.52288-0.66838 1.0458-1.3368 1.5845-2.0254 8.3281-10.652 16.554-21.378 24.736-32.143 2.9156-3.8344 5.8538-7.6498 8.8047-11.457 4.5205-5.8616 8.8975-11.824 13.273-17.794 4.5458-6.1869 9.1826-12.299 13.852-18.393 4.7428-6.1924 9.4013-12.419 13.884-18.802 3.8186-5.3996 7.843-10.637 11.866-15.885 4.8482-6.3256 9.6231-12.679 14.212-19.195 3.5844-5.0695 7.304-10.033 11.038-14.993 13.008-17.283 25.755-34.749 38.348-52.336 0.59031-0.82234 1.1806-1.6447 1.7888-2.4919 1.1321-1.5772 2.2619-3.1561 3.3892-4.7368 0.50974-0.70955 1.0195-1.4191 1.5447-2.1501 0.44618-0.62383 0.89235-1.2477 1.3521-1.8904 2.4758-3.1838 4.393-4.9888 8.2991-6.1675 0.81133-0.24997 1.6227-0.49994 2.4586-0.75749 0.89321-0.26461 1.7864-0.52921 2.7067-0.80183 0.95336-0.29083 1.9067-0.58166 2.889-0.8813 3.218-0.97942 6.4399-1.9453 9.6618-2.9117 2.2999-0.69745 4.5996-1.3959 6.8989-2.0952 4.3839-1.3323 8.7687-2.6616 13.155-3.9868 9.3777-2.8337 18.747-5.6947 28.114-8.5625 3.0712-0.94012 6.1424-1.8802 9.2136-2.8203 1.1475-0.35129 1.1475-0.35129 2.3183-0.70968 9.2804-2.8405 18.563-5.6724 27.846-8.5048 8.2032-2.5031 16.406-5.0088 24.605-7.5237 21.256-6.5191 42.543-12.934 63.862-19.241 2.6425-0.78197 5.2838-1.5678 7.9242-2.357 3.6676-1.0959 7.3393-2.1775 11.012-3.2577 1.6605-0.49876 1.6605-0.49876 3.3544-1.0076 1.0144-0.29583 2.0289-0.59166 3.074-0.89645 0.88496-0.262 1.7699-0.52399 2.6817-0.79393 2.2531-0.43092 2.2531-0.43092 5.2531 0.56908z" fill="#DEDBCB"/>\n        <path transform="translate(222,752)" d="m0 0c0.097969 1.2207 0.19594 2.4415 0.29688 3.6992 1.3785 15.768 4.5864 28.154 13.703 41.301 0.4602 0.67805 0.92039 1.3561 1.3945 2.0547 8.4689 11.104 24.144 18.685 37.605 20.945 3.6723 0.22116 7.3228 0.19094 11 0.125 0.96551-0.0090234 1.931-0.018047 2.9258-0.027344 2.3583-0.02335 4.7161-0.056096 7.0742-0.097656 0.17549 4.823-0.23757 8.6279-1.8125 13.188-0.33645 1.0042-0.67289 2.0084-1.0195 3.043-1.1557 2.7403-2.1546 4.5916-4.168 6.7695-2.1538 0.50171-2.1538 0.50171-4.6484 0.49609-1.3744 0.004834-1.3744 0.004834-2.7766 0.0097656-0.97348-0.022559-1.947-0.045117-2.95-0.068359-0.99862-0.016113-1.9972-0.032227-3.0261-0.048828-18.19-0.48409-35.191-6.8886-48.599-19.389-1.1312-0.9958-1.1312-0.9958-2.2852-2.0117-15.52-14.402-24.263-35.347-25.277-56.363-0.066406-2.4609-0.066406-2.4609 0.5625-4.625 3.4222-3.4096 7.078-5.0664 11.562-6.75 1.115-0.42797 2.2301-0.85594 3.3789-1.2969 3.0586-0.95312 3.0586-0.95312 7.0586-0.95312z" fill="#D69E43"/>\n        <path transform="translate(300,679)" d="m0 0c3.0317 3.6421 5.5712 7.4095 8.0625 11.438 11.9 18.702 27.212 35.21 44.938 48.562-2.783 4.6383-6.0497 8.1612-9.9219 11.926-1.9804 1.9767-3.8182 4.0146-5.6406 6.1367-2.3436 2.6967-4.6882 5.3869-7.125 8-0.54012 0.5891-1.0802 1.1782-1.6367 1.7852-1.6758 1.1523-1.6758 1.1523-3.6211 1.0234-18.143-7.692-32.71-31.267-39.876-48.891-5.0057-13.128-5.0057-13.128-4.1787-18.98 1.9414-2.7109 1.9414-2.7109 4.5625-5.375 1.3632-1.4173 1.3632-1.4173 2.7539-2.8633 0.88559-0.91137 1.7712-1.8227 2.6836-2.7617 1.3448-1.5107 2.6798-3.0302 4-4.5625 1.6261-1.8802 3.241-3.6785 5-5.4375z" fill="#597A53"/>\n        <path transform="translate(709,299)" d="m0 0h1c0.2107 4.5403-0.37761 7.9852-1.9375 12.25-0.35965 1.0364-0.7193 2.0728-1.0898 3.1406-5.8514 12.187-19.647 22.363-29.098 31.734-3.2139 3.1871-6.4244 6.3777-9.6328 9.5703-0.72309 0.7148-1.4462 1.4296-2.1912 2.166-4.0306 4.0114-7.8743 8.1207-11.575 12.44-1.8906 2.1757-3.9083 4.1927-5.9765 6.1991-2.6627 2.6271-5.2126 5.2673-7.625 8.125-3.5747 4.1788-7.4706 8.0084-11.375 11.875-4.4304 4.3876-8.7431 8.7779-12.766 13.547-2.7523 3.0994-5.7324 5.9715-8.6819 8.8811-3.2936 3.2663-6.3676 6.6513-9.3767 10.177-2.4423 2.7611-5.0813 5.3092-7.707 7.8945-1.9086 1.9389-3.6959 3.937-5.4688 6-2.3968 2.789-4.8796 5.4199-7.5 8-2.4971 2.4591-4.8606 4.9509-7.125 7.625-3.4278 3.9965-7.1353 7.6743-10.875 11.375-4.2969 4.2521-8.4552 8.5277-12.363 13.145-1.9557 2.2171-4.0323 4.2792-6.1367 6.3555-2.6627 2.6271-5.2126 5.2673-7.625 8.125-4.1496 4.8509-8.727 9.2785-13.282 13.745-3.1547 3.112-6.1806 6.2622-9.062 9.6304-4.1733 4.8399-8.8501 9.0602-13.57 13.355-4.096 3.7718-7.8681 7.6736-11.479 11.914-3.4081 3.9797-7.2579 7.4981-11.107 11.043-1.1331 1.0461-1.1331 1.0461-2.2891 2.1133-2.0859 1.5742-2.0859 1.5742-5.0859 1.5742-2.0948 1.6918-2.0948 1.6918-4.125 3.875-1.0557 1.0789-1.0557 1.0789-2.1328 2.1797-1.7962 1.8336-1.7962 1.8336-2.7422 3.9453l-2-1c5.0659-5.961 10.396-11.664 15.745-17.37 3.2686-3.4905 6.5098-6.9986 9.6926-10.568 4.5965-5.1484 9.3291-10.166 14.072-15.179 3.6989-3.9225 7.2942-7.9151 10.829-11.986 2.4388-2.7858 4.9516-5.4996 7.4736-8.21 1.042-1.1247 2.0836-2.2497 3.125-3.375 0.51305-0.5543 1.0261-1.1086 1.5547-1.6797 5.0266-5.4433 10.031-10.908 14.883-16.508 3.6073-4.1544 7.3481-8.1822 11.099-12.207 2.6949-2.8999 5.3367-5.8352 7.9321-8.8247 4.1992-4.8221 8.5917-9.4524 12.988-14.094 3.7604-3.9861 7.4233-8.034 10.996-12.189 1.6392-1.844 3.3487-3.5828 5.1094-5.3105 2.2933-2.258 4.4643-4.56 6.5625-7 5.1684-5.9857 10.626-11.708 16.036-17.474 1.8617-1.9841 3.7216-3.9698 5.5811-5.9561 3.1132-3.3247 6.2293-6.6466 9.3467-9.9673 1.3605-1.4497 2.7205-2.9 4.0801-4.3506 2.1301-2.2727 4.2617-4.5439 6.3936-6.8149 0.6463-0.69013 1.2926-1.3803 1.9585-2.0913 3.0535-3.2496 6.1349-6.4582 9.2993-9.6001 2.3124-2.2965 4.5196-4.6239 6.6172-7.1211 2.5913-3.0097 5.2975-5.8359 8.125-8.625 2.7862-2.7486 5.4531-5.5286 8-8.5 3.18-3.7101 6.5876-7.1298 10.094-10.531 1.9594-2.0103 3.7888-4.0495 5.6172-6.1758 4.0901-4.7132 8.4794-9.0936 12.914-13.48 1.1776-1.1708 1.1776-1.1708 2.3789-2.3652 1.5045-1.4956 3.01-2.9903 4.5166-4.4839 2.3333-2.3144 4.6578-4.6373 6.9795-6.9634l2-2z" fill="#999E95"/>\n        <path transform="translate(330,646)" d="m0 0c3.0643 2.8786 5.7032 5.8393 8.25 9.1875 13.862 18.047 30.869 32.924 48.75 46.812-3.4059 4.8032-6.9622 9.1072-11.195 13.199-2.5843 2.5788-4.947 5.3327-7.3242 8.1016-1.1122 1.2765-2.2833 2.502-3.4805 3.6992-4.3036-0.136-7.245-3.4296-10.312-6.125-0.60812-0.52989-1.2162-1.0598-1.8428-1.6057-16.559-14.619-35.238-32.125-40.845-54.269 0.56848-0.55688 1.137-1.1138 1.7227-1.6875 4.4723-4.42 8.7818-8.9028 12.867-13.684 1.0864-1.255 2.2364-2.4552 3.4102-3.6289z" fill="#557450"/>\n        <path transform="translate(269,715)" d="m0 0c1.8167 2.7251 2.8339 5.1722 3.9016 8.2412 7.6075 21.783 22.031 41.387 40.098 55.759-1.3319 3.9444-2.9465 6.3059-5.9141 9.207-0.76055 0.75088-1.5211 1.5018-2.3047 2.2754-0.79406 0.76893-1.5881 1.5379-2.4062 2.3301-0.8018 0.78826-1.6036 1.5765-2.4297 2.3887-1.9752 1.9399-3.957 3.8724-5.9453 5.7988-2.6824-1.2558-4.9113-2.5933-7.1719-4.5039-0.5779-0.48823-1.1558-0.97646-1.7512-1.4795-14.855-12.84-27.297-28.164-30.764-48.079-0.12955-0.68127-0.2591-1.3625-0.39258-2.0645-0.35398-1.9497-0.63857-3.9116-0.91992-5.873-0.15727-1.0068-0.31453-2.0135-0.47656-3.0508 0.73735-4.5631 3.5816-6.9043 6.7891-10.074 1.1851-1.2095 2.3687-2.4204 3.5508-3.6328 0.82685-0.83966 0.82685-0.83966 1.6704-1.6963 1.6526-1.7423 3.1039-3.5687 4.4663-5.5459z" fill="#567651"/>\n        <path transform="translate(192,769)" d="m0 0h1c0.14695 1.4715 0.14695 1.4715 0.29688 2.9727 2.6679 24.875 11.39 47.293 30.809 63.898 17.824 13.11 36.184 17.082 57.895 18.129-3.6339 3.1796-6.9801 5.0137-11.5 6.6875-1.1034 0.41637-2.2069 0.83273-3.3438 1.2617-15.543 5.1747-31.668 2.2134-46.242-4.3359-17.807-9.1029-29.218-23.283-36.078-41.746-4.3069-14.772-2.4333-29.741 4.9141-43.18 0.73723-1.2369 1.482-2.4695 2.25-3.6875z" fill="#DBA445"/>\n        <path transform="translate(350,620)" d="m0 0c4.1266 1.5864 6.6322 4.5923 9.5 7.8125 1.0729 1.1824 2.1458 2.3646 3.2188 3.5469 0.54527 0.60521 1.0905 1.2104 1.6523 1.834 10.089 11.19 20.27 22.369 31.754 32.154 3.4577 3.0471 6.6484 6.3647 9.875 9.6523l4 4-11 11c-3.0348-1.5174-5.0628-2.7095-7.6094-4.793-1.0017-0.81573-1.0017-0.81573-2.0237-1.6479-1.0479-0.86456-1.0479-0.86456-2.1169-1.7466-0.72373-0.59442-1.4475-1.1888-2.1931-1.8013-2.0228-1.6658-4.0411-3.3368-6.0569-5.0112-0.71422-0.59087-1.4284-1.1817-2.1643-1.7905-14.287-11.926-27.473-26.068-36.836-42.209 3.2076-3.8064 6.4075-7.5456 10-11z" fill="#536F4F"/>\n        <path transform="translate(541,482)" d="m0 0c0.8125 2.1875 0.8125 2.1875 1 5-2.3125 2.5-2.3125 2.5-5 5-0.29624 0.78206-0.59249 1.5641-0.89771 2.3699-1.3216 3.1535-2.9794 4.8341-5.4265 7.2122-0.86432 0.85014-1.7286 1.7003-2.6191 2.5762-0.90557 0.87592-1.8111 1.7518-2.7441 2.6543-7.198 6.9689-7.198 6.9689-13.957 14.355-4.1005 4.7943-8.7352 8.9477-13.395 13.188-4.096 3.7718-7.8681 7.6736-11.479 11.914-3.4081 3.9797-7.2579 7.4981-11.107 11.043-0.75539 0.69738-1.5108 1.3948-2.2891 2.1133-2.0859 1.5742-2.0859 1.5742-5.0859 1.5742-2.0948 1.6918-2.0948 1.6918-4.125 3.875-1.0557 1.0789-1.0557 1.0789-2.1328 2.1797-1.7962 1.8336-1.7962 1.8336-2.7422 3.9453l-2-1c5.0659-5.961 10.396-11.664 15.745-17.37 3.2686-3.4905 6.5098-6.9986 9.6926-10.568 4.5965-5.1484 9.3291-10.166 14.072-15.179 3.6989-3.9225 7.2942-7.9151 10.829-11.986 2.4388-2.7858 4.9512-5.5 7.4736-8.21 2.9913-3.22 5.9796-6.4401 8.9023-9.7227 13.359-14.965 13.359-14.965 17.285-14.965z" fill="#8F958D"/>\n        <path transform="translate(314,472)" d="m0 0 1 2c-0.70393 1.6517-1.4143 3.301-2.1582 4.9351-1.4948 3.6667-2.2224 7.5243-3.0918 11.377-2.2031 9.317-5.3595 18.002-9.0132 26.835-1.0262 2.5802-1.8744 5.214-2.7368 7.8525l-1 2c-2.6475-2.5778-4.9443-4.9165-7-8 0.34214-3.6963 1.5738-6.3842 3.4414-9.5547 0.49766-0.85521 0.99532-1.7104 1.5081-2.5916 0.79845-1.3507 0.79845-1.3507 1.613-2.7288 1.0954-1.8831 2.1892-3.7673 3.2812-5.6523 0.53754-0.92667 1.0751-1.8533 1.6289-2.8081 4.4393-7.7447 8.5598-15.669 12.527-23.665z" fill="#9EA298"/>\n        <path transform="translate(835,164)" d="m0 0 1 3c-14.214 14.476-14.214 14.476-21 19v-3l-2-1c3.1818-11.319 3.1818-11.319 7.8545-14.106 4.5667-1.8864 9.3062-2.9567 14.146-3.8936z" fill="#BBBCAE"/>\n        <path transform="translate(489,537)" d="m0 0 1 3c-0.99 0.33-1.98 0.66-3 1l0.375 2.1875c-0.375 2.8125-0.375 2.8125-3.0625 5.3125-0.55043 0.4125-1.1009 0.825-1.668 1.25-1.8702 1.3631-1.8702 1.3631-4.1445 3.75-2.7216 2.7216-5.4617 5.1369-8.5 7.5h-2c-1.9982 1.7153-1.9982 1.7153-4.0625 3.875-0.71285 0.7193-1.4257 1.4386-2.1602 2.1797-1.8323 1.8276-1.8323 1.8276-2.7773 3.9453l-2-1c4.5796-5.3888 9.3633-10.581 14.188-15.75 0.60602-0.64977 1.212-1.2995 1.8364-1.969 4.0865-4.3668 8.1549-8.6631 12.726-12.531l1.8594-1.5781 1.3906-1.1719z" fill="#8A9188"/>\n        <path transform="translate(507,525)" d="m0 0c0 3 0 3-1.5605 4.8694-0.71221 0.68377-1.4244 1.3675-2.1582 2.072-1.1505 1.1225-1.1505 1.1225-2.3242 2.2676-1.2162 1.165-1.2162 1.165-2.457 2.3535-1.5981 1.5384-3.1921 3.0812-4.7812 4.6289-0.71221 0.68264-1.4244 1.3653-2.1582 2.0686-1.7831 1.5986-1.7831 1.5986-1.5605 3.74h-3l-0.25 1.875c-0.99452 2.8178-2.1266 2.8352-4.75 4.125-1.7442 1.4565-1.7442 1.4565-3.3828 3.1523-0.60973 0.61166-1.2195 1.2233-1.8477 1.8535-0.6252 0.63744-1.2504 1.2749-1.8945 1.9316-0.63293 0.63357-1.2659 1.2671-1.918 1.9199-2.6158 2.6408-4.8858 5.0357-6.957 8.1426-0.99-0.33-1.98-0.66-3-1 0.4241-0.4125 0.8482-0.825 1.2852-1.25 3.8837-3.824 7.5292-7.7774 11.09-11.902 2.1049-2.3933 4.342-4.6247 6.625-6.8477 2.7908-2.781 5.5691-5.574 8.3398-8.375 1.1992-1.2084 2.3984-2.4167 3.5977-3.625 0.5949-0.60328 1.1898-1.2066 1.8027-1.8281 3.5986-3.6183 7.2862-6.9688 11.26-10.172z" fill="#666E68"/>\n        <path transform="translate(317,466)" d="m0 0c8.7329 9.7032 10.899 21.728 13.625 34.062 0.57344 2.5517 1.1507 5.1024 1.7325 7.6522 0.35842 1.5749 0.71172 3.151 1.0587 4.7284 2.1677 10.528 2.1677 10.528 7.5838 19.557l-1 2c-8.3233-7.6297-9.3156-21.34-11-32h-2l-0.25-3.5625c-1.0117-9.1056-3.4093-18.364-7.75-26.438h-4l2-6z" fill="#889088"/>\n        <path transform="translate(222,752)" d="m0 0v15c-2.2091-3.3137-2.2248-4.3446-2.125-8.1875 0.018047-0.90105 0.036094-1.8021 0.054688-2.7305 0.023203-0.68707 0.046406-1.3741 0.070312-2.082-1.8983 0.59643-3.7935 1.2025-5.6875 1.8125-1.0557 0.33645-2.1115 0.67289-3.1992 1.0195-4.3488 1.5799-4.3488 1.5799-8.1133 4.168-0.54462 2.7532-0.78934 4.9314-0.8125 7.6875-0.025137 0.70189-0.050273 1.4038-0.076172 2.127-0.058773 1.7279-0.087938 3.4568-0.11133 5.1855h2l1 12c-5.4892-5.4892-5.3219-17.243-5.5938-24.695 0.88616-3.4397 2.6573-4.4001 5.5938-6.3047 3.1914-1.4844 3.1914-1.4844 6.5625-2.75 1.115-0.42797 2.2301-0.85594 3.3789-1.2969 3.0586-0.95312 3.0586-0.95312 7.0586-0.95312z" fill="#F2CF53"/>\n        <path transform="translate(630,268)" d="m0 0v20h-2c-1.2284-2.241-2.4323-4.4901-3.625-6.75-0.35062-0.63422-0.70125-1.2684-1.0625-1.9219-0.97656-1.875-0.97656-1.875-2.3125-5.3281 0.78906-2.4531 0.78906-2.4531 2-4 0.99 0.33 1.98 0.66 3 1 0.47438-0.495 0.94875-0.99 1.4375-1.5 1.5625-1.5 1.5625-1.5 2.5625-1.5z" fill="#D4D2C0"/>\n        <path transform="translate(221,899)" d="m0 0c6.329 0.82552 6.329 0.82552 8.9004 1.4941 9.0828 2.2894 18.432 1.7221 27.725 1.6309 1.7852-0.010049 3.5703-0.019171 5.3555-0.027344 4.34-0.021864 8.6797-0.056288 13.02-0.097656-14.144 7.6979-38.701 2.826-53.121-1.4141-0.62004-0.19336-1.2401-0.38672-1.8789-0.58594v-1z" fill="#A6724F"/>\n        <path transform="translate(463,641)" d="m0 0c3.0879 1.4354 5.6993 3.1697 8.4375 5.1875 5.8984 4.1968 12.138 7.4995 18.562 10.812-3.0103 0.93424-3.8665 1.0445-7 0 0.99 1.32 1.98 2.64 3 4-3.9512-1.622-6.7581-4.3566-9.8125-7.25-1.0629-0.99313-2.1267-1.9853-3.1914-2.9766-0.51192-0.47728-1.0238-0.95455-1.5513-1.4463-1.8547-1.7037-3.7651-3.3342-5.6948-4.9521l-2.75-2.375v-1z" fill="#262B26"/>\n        <path transform="translate(232,859)" d="m0 0c0.92941 0.1534 1.8588 0.3068 2.8164 0.46484 5.0197 0.71709 10.059 0.88661 15.121 1.0977 0.97002 0.043184 1.94 0.086367 2.9395 0.13086 2.3742 0.10526 4.7486 0.2074 7.123 0.30664l-1 3c-3.0833 0.058225-6.1664 0.093671-9.25 0.125-1.309 0.025137-1.309 0.025137-2.6445 0.050781-0.84434 0.0064453-1.6887 0.012891-2.5586 0.019531-0.77505 0.010474-1.5501 0.020947-2.3486 0.031738-4.1383-0.42744-6.9982-2.7127-10.198-5.2271z" fill="#D69E3F"/>\n        <path transform="translate(594,390)" d="m0 0c0 3 0 3-1.8984 5.0859-1.6456 1.521-3.2915 3.0419-4.9375 4.5625-2.2384 2.4324-3.0164 4.2993-4.1641 7.3516-3.2847 4.1286-6.8038 7.5828-12 9 1.4841-3.4865 3.4621-5.6419 6.1875-8.25 3.6022-3.5155 6.9624-7.1351 10.238-10.953 2.0876-2.3829 4.3006-4.5921 6.5742-6.7969z" fill="#1C211D"/>\n        <path transform="translate(500,523)" d="m0 0c0 3 0 3-2 6v3c-1.4258 1.8242-1.4258 1.8242-3.3125 3.6875-0.92232 0.93393-0.92232 0.93393-1.8633 1.8867-1.8242 1.4258-1.8242 1.4258-4.8242 1.4258-1.655 1.0773-1.655 1.0773-3.1875 2.5l-2.8125 2.5c1.4841-3.4865 3.4621-5.6419 6.1875-8.25 4.1709-4.0697 8.0464-8.3058 11.812-12.75z" fill="#989F95"/>\n        <path transform="translate(314,472)" d="m0 0 1 2c-0.70673 1.6582-1.4197 3.314-2.1675 4.9541-1.7251 4.2393-2.4514 8.79-3.3813 13.257-0.42594 1.9433-0.93217 3.8686-1.4512 5.7891l-2 1v-7l-3 3c1.5565-5.3537 3.9818-10.002 6.625-14.875 0.42023-0.78375 0.84047-1.5675 1.2734-2.375 1.0297-1.9189 2.065-3.8348 3.1016-5.75z" fill="#AFB2A7"/>\n        <path transform="translate(321,656)" d="m0 0c0 3 0 3-1.418 4.5078-0.87592 0.80051-0.87592 0.80051-1.7695 1.6172-2.3576 2.6146-2.3576 2.6146-2.7539 5.9805 2.2333 7.129 6.4275 14.807 11.941 19.895l-1 3c-5.7437-7.2744-11.359-15.002-14-24 0.97563-3.3476 3.1483-5.365 5.625-7.75 0.63164-0.61359 1.2633-1.2272 1.9141-1.8594 0.72316-0.68836 0.72316-0.68836 1.4609-1.3906z" fill="#659060"/>\n        <path transform="translate(843,162)" d="m0 0-7 4-1-1c-1.1954 0.37137-1.1954 0.37137-2.415 0.75024-2.9645 0.91567-5.9317 1.8222-8.9009 2.7227-1.9138 0.58341-3.8243 1.1773-5.7349 1.7712-1.8079 0.54624-1.8079 0.54624-3.6523 1.1035-1.6653 0.51059-1.6653 0.51059-3.3643 1.0315-2.8388 0.60099-4.2578 0.62531-6.9326-0.37915 8.6851-3.0151 17.427-5.7923 26.25-8.375 1.3751-0.4121 1.3751-0.4121 2.7781-0.83252 0.86214-0.24863 1.7243-0.49726 2.6125-0.75342 0.7686-0.22478 1.5372-0.44956 2.3291-0.68115 2.0303-0.35791 2.0303-0.35791 5.0303 0.64209z" fill="#EEEEE7"/>\n        <path transform="translate(363,539)" d="m0 0c2.4928 2.1978 3.4918 3.8839 4.3906 7.0664 1.9026 6.1312 4.7821 11.714 7.6445 17.443 0.39574 0.81018 0.79148 1.6204 1.1992 2.4551 0.36319 0.72824 0.72639 1.4565 1.1006 2.2068 0.21946 0.60336 0.43893 1.2067 0.66504 1.8284l-1 2c-2.31-2.64-4.62-5.28-7-8l2-1c-0.72316-1.4676-0.72316-1.4676-1.4609-2.9648-3.3664-6.9464-6.3244-13.343-7.5391-21.035z" fill="#202520"/>\n        <path transform="translate(434,704)" d="m0 0 2 2-2.125-0.14062-2.875-0.10938c-1.3922-0.069609-1.3922-0.069609-2.8125-0.14062-8.3614 1.0247-13.593 6.2565-19.188 12.141-0.67934 0.69738-1.3587 1.3948-2.0586 2.1133-1.6567 1.7034-3.3033 3.4154-4.9414 5.1367l-2-3c0.71543-0.38285 1.4309-0.7657 2.168-1.1602 3.2202-2.092 5.5201-4.4782 8.1445-7.2773 7.0863-7.2645 13.197-11.239 23.688-9.5625z" fill="#0C0B12"/>\n        <path transform="translate(529,502)" d="m0 0c0 3 0 3-1.4961 4.7188-0.961 0.88172-0.961 0.88172-1.9414 1.7812-2.4839 2.2882-3.4713 3.2264-4.5625 6.5-3.3945 3.6854-7.1233 6.8445-11 10l-2-1c2.3733-2.5433 4.7489-5.0843 7.125-7.625 0.66516-0.71285 1.3303-1.4257 2.0156-2.1602 3.882-4.1484 7.8168-8.2227 11.859-12.215z" fill="#5F6662"/>\n        <path transform="translate(636,389)" d="m0 0 1 2c-2.7844 3.6093-5.7605 6.7977-9 10-0.9655 0.96419-1.9303 1.929-2.8945 2.8945l-8.1055 8.1055-2-1c2.3733-2.5433 4.7489-5.0843 7.125-7.625 0.66516-0.71285 1.3303-1.4257 2.0156-2.1602 3.882-4.1484 7.8168-8.2227 11.859-12.215z" fill="#69706C"/>\n        <path transform="translate(746,366)" d="m0 0c4.8363 0.99044 9.4762 1.957 14 4-3 1-3 1-5 1 0.99902 0.69867 1.998 1.3973 3.0273 2.1172 1.3035 0.91905 2.6069 1.8383 3.9102 2.7578 0.65936 0.4602 1.3187 0.92039 1.998 1.3945 4.9512 3.5039 4.9512 3.5039 6.0645 5.7305-3.9726-1.3958-6.962-3.2766-10.312-5.8125-3.382-2.5251-6.7496-4.9015-10.375-7.0625l-3.3125-2.125v-2z" fill="#1E231E"/>\n        <path transform="translate(287,640)" d="m0 0c0 3.3118-0.54378 4.313-2.25 7.0625-0.62648 1.0383-0.62648 1.0383-1.2656 2.0977-1.6814 2.084-3.1057 2.6754-5.4844 3.8398-1.8591 1.8681-1.8591 1.8681-3.5625 4-2.1111 2.5577-3.6372 4.1331-6.4375 6 1.6832-4.2338 4.7224-7.1317 7.8125-10.375 3.8774-4.1027 7.6144-8.2528 11.188-12.625z" fill="#B17C56"/>\n        <path transform="translate(269,715)" d="m0 0c1.7369 2.6054 2.691 4.5834 3.6875 7.5 0.27199 0.77344 0.54398 1.5469 0.82422 2.3438 0.48828 2.1562 0.48828 2.1562-0.51172 5.1562l-4-9-3.8125 2.875c-2.3634 1.7822-4.7226 3.4818-7.1875 5.125 1.5778-3.7105 3.907-6.2991 6.625-9.25 0.81727-0.89203 1.6345-1.7841 2.4766-2.7031 0.62648-0.67547 1.253-1.3509 1.8984-2.0469z" fill="#659360"/>\n        <path transform="translate(539,583)" d="m0 0 2 1c-2.7654 2.8396-5.5406 5.6692-8.3252 8.49-1.4099 1.4324-2.8119 2.8725-4.2139 4.3127-0.88945 0.89912-1.7789 1.7982-2.6953 2.7246-0.81694 0.83265-1.6339 1.6653-2.4756 2.5232-2.2207 1.8905-3.4429 2.5807-6.29 2.9495 4.1488-5.1314 8.6395-9.4801 13.586-13.844 2.9258-2.6133 5.6771-5.3473 8.4141-8.1562z" fill="#252A24"/>\n        <path transform="translate(624,272)" d="m0 0c1.9375 0.5625 1.9375 0.5625 4 2 0.6875 3.1875 0.6875 3.1875 1 7l1 7h-2c-2.6939-4.7755-4.3135-9.5655-5-15l1-1z" fill="#CAC8B8"/>\n        <path transform="translate(365,599)" d="m0 0h2c1.4102 1.4688 1.4102 1.4688 3.0625 3.5 2.6813 3.175 5.4664 5.9251 8.625 8.625 3.5174 3.0372 6.0011 5.8552 8.3125 9.875-3.4361-1.4823-5.687-3.4295-8.3281-6.0625-0.79922-0.79664-1.5984-1.5933-2.4219-2.4141-0.825-0.83273-1.65-1.6655-2.5-2.5234-0.84047-0.83273-1.6809-1.6655-2.5469-2.5234-0.79406-0.79664-1.5881-1.5933-2.4062-2.4141-1.093-1.0963-1.093-1.0963-2.208-2.2148-1.5889-1.8477-1.5889-1.8477-1.5889-3.8477z" fill="#6A736B"/>\n        <path transform="translate(809,287)" d="m0 0c1.9919 6.925-1.0559 14.487-4.1875 20.75l-1.8125 3.25c-1.1931-3.4444-0.80482-5.3763 0.43359-8.7656 0.31904-0.88945 0.63809-1.7789 0.9668-2.6953 0.34225-0.92039 0.68449-1.8408 1.0371-2.7891 0.33838-0.93586 0.67676-1.8717 1.0254-2.8359 0.83619-2.3083 1.6821-4.6126 2.5371-6.9141z" fill="#272D28"/>\n        <path transform="translate(264,854)" d="m0 0h18c-4.4605 3.5684-6.8589 5.1911-12 7-0.99-0.33-1.98-0.66-3-1 2.31-0.99 4.62-1.98 7-3l-10-2v-1z" fill="#EEBC46"/>\n        <path transform="translate(782,362)" d="m0 0c1.2403 3.7209 0.5719 4.9946-0.75 8.625-0.5182 1.4734-0.5182 1.4734-1.0469 2.9766-1.2031 2.3984-1.2031 2.3984-4.2031 3.3984-2.6992-0.99609-2.6992-0.99609-5.6875-2.4375-0.99387-0.47309-1.9877-0.94617-3.0117-1.4336-0.75926-0.37254-1.5185-0.74508-2.3008-1.1289 3.4787-1.1596 4.3422-0.77457 7.6875 0.4375 0.80824 0.28746 1.6165 0.57492 2.4492 0.87109 0.61488 0.22816 1.2298 0.45633 1.8633 0.69141v-2h2c0.99-3.3 1.98-6.6 3-10z" fill="#868E89"/>\n        <path transform="translate(734,320)" d="m0 0 3 2c0.1875 2.625 0.1875 2.625 0 5h2l-1 3h-4v-3c-0.99-0.33-1.98-0.66-3-1v-5c0.99 0.33 1.98 0.66 3 1v-2z" fill="#7B827E"/>\n        <path transform="translate(350,620)" d="m0 0c2.8606 1.3594 4.8593 2.6452 7 5l-1 2-5-4c-0.48211 0.50531-0.96422 1.0106-1.4609 1.5312-0.63164 0.64969-1.2633 1.2994-1.9141 1.9688-0.62648 0.64969-1.253 1.2994-1.8984 1.9688-1.7266 1.5312-1.7266 1.5312-3.7266 1.5312l-1 2c0-3 0-3 1.9688-5.2617 1.253-1.2008 1.253-1.2008 2.5312-2.4258 0.83531-0.80824 1.6706-1.6165 2.5312-2.4492 0.64969-0.61488 1.2994-1.2298 1.9688-1.8633z" fill="#5F845A"/>\n        <path transform="translate(193,766)" d="m0 0c2 2 2 2 2.25 5.5-0.25 3.5-0.25 3.5-2.25 5.5l-1-7c-1.98 3.63-3.96 7.26-6 11l-1-2c0.89062-2.2773 0.89062-2.2773 2.25-4.9375 0.43828-0.87527 0.87656-1.7505 1.3281-2.6523 1.2949-2.1948 2.5315-3.7255 4.4219-5.4102z" fill="#1D202B"/>\n        <path transform="translate(732,266)" d="m0 0 2 1c-1.9681 1.9681-3.9364 3.936-5.9062 5.9023-1.6034 1.6064-3.1949 3.2245-4.7812 4.8477-2.3234 2.2606-4.7471 4.271-7.3125 6.25l-2-1c0.43868-0.40839 0.87737-0.81678 1.3293-1.2375 1.9949-1.8578 3.989-3.7163 5.9832-5.575 1.0354-0.9639 1.0354-0.9639 2.0918-1.9473 0.66709-0.62197 1.3342-1.2439 2.0215-1.8848 0.91906-0.85622 0.91906-0.85622 1.8567-1.7297 1.6011-1.5155 3.1671-3.0587 4.7175-4.6257z" fill="#69706D"/>\n        <path transform="translate(568,461)" d="m0 0v5c-1.4609 1.1836-1.4609 1.1836-3.375 2.4375-2.7109 1.7794-3.753 2.7544-5.625 5.5625-1.7266 1.3867-1.7266 1.3867-3.625 2.6875-0.94746 0.65549-0.94746 0.65549-1.9141 1.3242-0.72316 0.4892-0.72316 0.4892-1.4609 0.98828 1.3584-3.0433 2.8846-5.1231 5.2578-7.4531 0.6252-0.61875 1.2504-1.2375 1.8945-1.875 0.65098-0.63422 1.302-1.2684 1.9727-1.9219 0.65871-0.64969 1.3174-1.2994 1.9961-1.9688 1.6219-1.5984 3.2482-3.1919 4.8789-4.7812z" fill="#686F6B"/>\n        <path transform="translate(242,692)" d="m0 0 1 3-1.9375 1.25c-2.2156 1.5244-2.2156 1.5244-2.5 3.6875-0.86056 3.1554-2.9377 4.27-5.5625 6.0625h-2c1.5778-3.7105 3.907-6.2991 6.625-9.25 0.81727-0.89203 1.6345-1.7841 2.4766-2.7031 0.62648-0.67547 1.253-1.3509 1.8984-2.0469z" fill="#D69566"/>\n        <path transform="translate(309,616)" d="m0 0c0 3.5166-0.67787 4.3185-2.75 7.0625-0.51047 0.69223-1.0209 1.3845-1.5469 2.0977-1.7987 1.9431-3.3542 2.6892-5.7031 3.8398l-2 3-2-1c1.3891-1.7553 2.7866-3.504 4.1875-5.25 0.7773-0.97453 1.5546-1.9491 2.3555-2.9531 2.3127-2.6326 4.6551-4.7066 7.457-6.7969z" fill="#C58B5F"/>\n        <path transform="translate(296,820)" d="m0 0c0.125 3.375 0.125 3.375 0 7l-2 2v-7h-20v-1c2.9166-0.16803 5.8333-0.33448 8.75-0.5 1.2375-0.071543 1.2375-0.071543 2.5-0.14453 1.1988-0.067676 1.1988-0.067676 2.4219-0.13672 0.73315-0.041895 1.4663-0.083789 2.2217-0.12695 2.0338-0.08863 4.0707-0.091797 6.1064-0.091797z" fill="#EDBA44"/>\n        <path transform="translate(365,540)" d="m0 0c1.1289 0.93274 2.253 1.8714 3.375 2.8125 0.62648 0.52207 1.253 1.0441 1.8984 1.582 1.7266 1.6055 1.7266 1.6055 3.7266 4.6055h-4l-2 2c-0.50368-1.4571-1.0028-2.9157-1.5-4.375-0.27844-0.81211-0.55688-1.6242-0.84375-2.4609-0.65625-2.1641-0.65625-2.1641-0.65625-4.1641z" fill="#7D867F"/>\n        <path transform="translate(710,299)" d="m0 0c0.26925 4.8028-0.56762 8.2823-2.3125 12.75-0.64389 1.6938-0.64389 1.6938-1.3008 3.4219-1.3867 2.8281-1.3867 2.8281-4.3867 4.8281 1.8676-5.7221 3.8529-11.377 6-17l-2-1c2.875-3 2.875-3 4-3z" fill="#A3A89F"/>\n        <path transform="translate(805,242)" d="m0 0h4c-1.4526 3.8295-3.429 5.1205-7 7l-2-2c-0.99-0.33-1.98-0.66-3-1l1-2c1.9929-0.37366 3.9936-0.70741 6-1l1-1z" fill="#7B827F"/>\n        <path transform="translate(544,647)" d="m0 0c5.6683 0.59468 10.603 2.0924 15.938 4.0625 0.77924 0.28166 1.5585 0.56332 2.3613 0.85352 1.9026 0.68866 3.8022 1.3855 5.7012 2.084-3.4782 1.1594-5.459 0.70821-9 0v-2c-0.91523-0.19336-1.8305-0.38672-2.7734-0.58594-1.1885-0.26039-2.377-0.52078-3.6016-0.78906-1.1834-0.25523-2.3667-0.51047-3.5859-0.77344-3.0391-0.85156-3.0391-0.85156-5.0391-2.8516z" fill="#A47250"/>\n        <path transform="translate(477,554)" d="m0 0 2 1c-0.77086 0.83145-1.5417 1.6629-2.3359 2.5195-1.0131 1.0976-2.0261 2.1952-3.0391 3.293-0.50789 0.54721-1.0158 1.0944-1.5391 1.6582-2.2381 2.4295-4.2497 4.775-6.0859 7.5293-0.99-0.33-1.98-0.66-3-1 0.63615-0.61875 0.63615-0.61875 1.2852-1.25 4.4672-4.3985 8.6427-8.9847 12.715-13.75z" fill="#606762"/>\n        <path transform="translate(538,756)" d="m0 0c-2.2887 1.3386-4.5807 2.671-6.875 4-0.65098 0.38156-1.302 0.76312-1.9727 1.1562-4.9258 2.8438-4.9258 2.8438-7.1523 2.8438l-1 2-2-2c1.2891-0.67155 2.5814-1.3371 3.875-2 0.7193-0.37125 1.4386-0.7425 2.1797-1.125 1.9453-0.875 1.9453-0.875 3.9453-0.875l1-3c5.4023-2.2989 5.4023-2.2989 8-1z" fill="#A97551"/>\n        <path transform="translate(311,481)" d="m0 0h3c-0.56821 5.4548-1.9464 9.9106-4 15l-2-2c0.46094-3.0391 0.46094-3.0391 1.375-6.625 0.29648-1.1885 0.59297-2.377 0.89844-3.6016 0.23977-0.91523 0.47953-1.8305 0.72656-2.7734z" fill="#707770"/>\n        <path transform="translate(697,160)" d="m0 0c-2.2881 2.2881-3.8075 2.7545-6.875 3.6875-0.86367 0.27199-1.7273 0.54398-2.6172 0.82422-2.5948 0.50521-4.0386 0.34389-6.5078-0.51172h2v-2c4.9274-1.9709 8.7802-2.18 14-2z" fill="#D39968"/>\n        <path transform="translate(275,656)" d="m0 0 2 1c-0.48211 0.47051-0.96422 0.94102-1.4609 1.4258-0.63164 0.62262-1.2633 1.2452-1.9141 1.8867-0.62648 0.61488-1.253 1.2298-1.8984 1.8633-1.9074 1.9123-1.9074 1.9123-3.7266 4.8242-1.9675 1.0625-3.9659 2.0714-6 3 1.5658-4.0372 4.4417-6.4707 7.625-9.25l1.5625-1.3906c1.266-1.1253 2.5386-2.2431 3.8125-3.3594z" fill="#D29566"/>\n        <path transform="translate(489,537)" d="m0 0 1 3c-0.99 0.33-1.98 0.66-3 1 0.061875 0.78375 0.12375 1.5675 0.1875 2.375l-0.1875 2.625-3 2-2-4 7-7zm-8 8 1 3-2-1 1-2z" fill="#7E847C"/>\n        <path transform="translate(395,449)" d="m0 0 1 3-10 9c0-3.524 0.55115-4.015 2.8125-6.5625 0.78311-0.89912 0.78311-0.89912 1.582-1.8164 1.6055-1.6211 1.6055-1.6211 4.6055-3.6211z" fill="#CA8F63"/>\n        <path transform="translate(659,351)" d="m0 0 1 4-2.5625 1.5625c-3.9798 2.631-7.166 5.9918-10.438 9.4375 0-3 0-3 2.625-5.918 1.1175-1.0975 2.2429-2.1871 3.375-3.2695 0.57234-0.55881 1.1447-1.1176 1.7344-1.6934 1.4153-1.3799 2.8396-2.7504 4.2656-4.1191z" fill="#B3B8AE"/>\n        <path transform="translate(295,434)" d="m0 0 2 1c-2.8252 4.6725-5.6776 7.66-10 11 0-3.9613 1.3488-4.8291 4-7.6875 0.7425-0.80824 1.485-1.6165 2.25-2.4492 0.5775-0.61488 1.155-1.2298 1.75-1.8633z" fill="#AE7B56"/>\n        <path transform="translate(752,369)" d="m0 0c8.282 0.34725 8.282 0.34725 11.062 2.875 0.9375 2.125 0.9375 2.125 0.9375 5.125-4.5567-1.5189-8.3172-3.954-12-7v-1z" fill="#3D443E"/>\n        <path transform="translate(197,888)" d="m0 0c3.7189 0.50712 6.7345 1.1161 10 3v2c1.98 0.66 3.96 1.32 6 2-3 1-3 1-6.1367-0.43359-1.1893-0.65777-2.3727-1.3262-3.5508-2.0039-0.6065-0.33838-1.213-0.67676-1.8379-1.0254-1.4966-0.83669-2.9863-1.6857-4.4746-2.5371v-1z" fill="#B9825A"/>\n        <path transform="translate(551,613)" d="m0 0 2 1-12 11-2-1c1.3021-1.4974 2.6042-2.9948 3.9062-4.4922 1.2895-1.4672 1.2895-1.4672 1.0938-3.5078 0.78375-0.12375 1.5675-0.2475 2.375-0.375 2.7656-0.41618 2.7656-0.41618 4.625-2.625z" fill="#1E1C1E"/>\n        <path transform="translate(456,571)" d="m0 0 2 3-6 4 5 7c-3.7952-1.491-5.6104-3.757-8-7l7-7z" fill="#858E85"/>\n        <path transform="translate(282,551)" d="m0 0c1.98 0.66 3.96 1.32 6 2l0.25 2.25c0.88969 3.2622 2.235 4.5595 4.75 6.75l-1 2c-1.6728-1.7863-3.3382-3.5785-5-5.375-0.71543-0.76184-0.71543-0.76184-1.4453-1.5391-3.5547-3.8594-3.5547-3.8594-3.5547-6.0859z" fill="#191B1D"/>\n        <path transform="translate(317,466)" d="m0 0c3.3865 3.8702 6.3295 8.1013 8 13l-1 3-5-10h-4l2-6z" fill="#929B92"/>\n        <path transform="translate(818,176)" d="m0 0c2 3 2 3 1.875 5-1.114 2.5463-2.5705 3.5132-4.875 5v-3l-2-1 2-4 1 2-1 2h2l1-6z" fill="#B8B9AD"/>\n        <path transform="translate(322,838)" d="m0 0h1c-0.0603 1.9175-0.14917 3.8342-0.25 5.75l-0.14062 3.2344c-0.71527 3.5397-1.8652 4.7544-4.6094 7.0156 1.1506-5.398 2.4242-10.71 4-16z" fill="#F4C182"/>\n        <path transform="translate(843,162)" d="m0 0-7 4-1-1c-1.9214 0.32744-1.9214 0.32744-4.0625 0.9375-0.73348 0.19465-1.467 0.3893-2.2227 0.58984-0.5659 0.15598-1.1318 0.31195-1.7148 0.47266l-1-2c2.2681-0.69809 4.5387-1.3837 6.8125-2.0625 0.6426-0.19916 1.2852-0.39832 1.9473-0.60352 4.9004-1.4473 4.9004-1.4473 8.2402-0.33398z" fill="#DBDDD0"/>\n        <path transform="translate(545,475)" d="m0 0h1l-0.0625 2.8125c-0.095196 3.2104-0.095196 3.2104 1.0625 6.1875l-4 3c0-10 0-10 2-12z" fill="#8E948B"/>\n        <path transform="translate(191,773)" d="m0 0h1l1 8h1v6l-1-3h-2l-0.375-1.9375-0.625-2.0625-2-1 3-6z" fill="#E4B44E"/>\n        <path transform="translate(380,468)" d="m0 0c0 3.5891-0.66437 4.1086-3 6.6875-0.55688 0.62262-1.1138 1.2452-1.6875 1.8867-0.43312 0.47051-0.86625 0.94102-1.3125 1.4258l-1-4 7-6z" fill="#D89A6A"/>\n        <path transform="translate(746,366)" d="m0 0c4.8363 0.99044 9.4762 1.957 14 4-3.1335 1.0445-3.9897 0.93424-7 0l-1 2c-2.0383-1.274-4.0385-2.6106-6-4v-2z" fill="#2A2F2B"/>\n        <path transform="translate(610,261)" d="m0 0 1 2c-0.92735 1.4856-1.8672 2.9633-2.8125 4.4375-0.78311 1.2356-0.78311 1.2356-1.582 2.4961-1.6055 2.0664-1.6055 2.0664-4.6055 3.0664 1.4098-3.0385 3.0887-5.594 5.125-8.25 0.80824-1.0596 0.80824-1.0596 1.6328-2.1406 0.40992-0.53109 0.81984-1.0622 1.2422-1.6094z" fill="#9E9F96"/>\n        <path transform="translate(822,238)" d="m0 0c1.5639 3.9738 0.36145 6.8138-0.9375 10.75-0.38027 1.1705-0.76055 2.3409-1.1523 3.5469-0.30035 0.89203-0.6007 1.7841-0.91016 2.7031h-1c-0.46904-6.0975 1.2914-11.583 4-17z" fill="#909892"/>\n        <path transform="translate(708,200)" d="m0 0c-1 2-1 2-4.3125 3.1875-3.2631 0.71899-4.6803 1.0154-7.6875-0.1875h2v-2c6.2857-2.4286 6.2857-2.4286 10-1z" fill="#272B26"/>\n        <path transform="translate(279,856)" d="m0 0 2 1c-4.75 3-4.75 3-7 3v2c-3.287 0.79953-4.7102 1.0966-8 0 2.1204-1.0303 4.2465-2.049 6.375-3.0625 1.1834-0.56848 2.3667-1.137 3.5859-1.7227 1.0029-0.4009 2.0058-0.8018 3.0391-1.2148z" fill="#161929"/>\n        <path transform="translate(198,719)" d="m0 0-4 1v3l-5 2-2-3c1.2642-0.69965 2.5367-1.3843 3.8125-2.0625 0.7077-0.38285 1.4154-0.7657 2.1445-1.1602 2.043-0.77734 2.043-0.77734 5.043 0.22266z" fill="#BF885E"/>\n        <path transform="translate(477,341)" d="m0 0 1 2c-2.6496 3.6309-5.0182 5.8985-9 8l-1-2c2.8528-2.932 5.6508-5.6432 9-8z" fill="#C48B60"/>\n        <path transform="translate(810,225)" d="m0 0 5 2-3 2h2v2h-2v2h-2c-0.79953-3.287-1.0966-4.7102 0-8z" fill="#7B827F"/>\n        <path transform="translate(469,559)" d="m0 0 2 3-5 5c-0.99-0.33-1.98-0.66-3-1 1.98-2.31 3.96-4.62 6-7z" fill="#777E76"/>\n        <path transform="translate(536,546)" d="m0 0c4.6769 1.4769 4.6769 1.4769 6.3125 4.125 0.22688 0.61875 0.45375 1.2375 0.6875 1.875h-4c-3-4.1786-3-4.1786-3-6z" fill="#6D7570"/>\n        <path transform="translate(707,312)" d="m0 0c1 2 1 2 0.375 4.8125-1.5563 3.6078-3.4684 5.5868-6.375 8.1875l-2-1c0.76312-0.86625 1.5262-1.7325 2.3125-2.625 2.4397-2.911 4.1175-5.9044 5.6875-9.375z" fill="#6B726E"/>\n        <path transform="translate(355,453)" d="m0 0c6.7046 3.9562 6.7046 3.9562 7.9375 8.3125l0.0625 2.6875c-5.8021-5.6452-5.8021-5.6452-8-9v-2z" fill="#DCA06D"/>\n        <path transform="translate(625,277)" d="m0 0c2.7296 2.3574 3.8889 4.5813 5 8v3h-2c-2.1531-3.8576-3.3925-6.5513-3-11z" fill="#C1C0B1"/>\n        <path transform="translate(798,225)" d="m0 0 3 2v2l-4 2-2-5c0.99-0.33 1.98-0.66 3-1zm-5 3 3 2h-3v-2z" fill="#7C8480"/>\n        <path transform="translate(151,760)" d="m0 0h1c0.125 5.75 0.125 5.75-1 8h-2l-1 6c-1.371-3.6904-0.60011-5.7088 0.9375-9.25 0.38027-0.89203 0.76055-1.7841 1.1523-2.7031 0.30035-0.67547 0.6007-1.3509 0.91016-2.0469z" fill="#AD7B56"/>\n        <path transform="translate(520,513)" d="m0 0 1 2-2-1 1-1zm-5 5v3c-2.5 2.1875-2.5 2.1875-5 4l-2-1 7-6z" fill="#676E6A"/>\n        <path transform="translate(544,486)" d="m0 0c0 3.7791-0.99704 4.4611-3.5 7.1875-0.64969 0.71543-1.2994 1.4309-1.9688 2.168-0.50531 0.5427-1.0106 1.0854-1.5312 1.6445l-2-1c1.1241-1.2924 2.2493-2.5839 3.375-3.875 0.62648-0.7193 1.253-1.4386 1.8984-2.1797 1.2008-1.353 2.4474-2.6661 3.7266-3.9453z" fill="#646B67"/>\n        <path transform="translate(773,326)" d="m0 0c2.9719 1.1245 5.3344 2.2229 8 4l-1 3-1.75-1.4375c-2.1758-1.511-3.676-2.1029-6.25-2.5625l1-3z" fill="#7B827E"/>\n        <path transform="translate(511,296)" d="m0 0 1 2c-2.3896 3.243-4.2048 5.509-8 7 1.555-3.8168 4.036-6.192 7-9z" fill="#C68D61"/>\n        <path transform="translate(582,222)" d="m0 0c0 3.0522-0.32293 4.0453-1.75 6.625-0.32484 0.61102-0.64969 1.222-0.98438 1.8516-1.6012 1.9273-2.8354 2.1456-5.2656 2.5234 0.95545-1.4602 1.9145-2.9181 2.875-4.375 0.53367-0.81211 1.0673-1.6242 1.6172-2.4609 1.5078-2.1641 1.5078-2.1641 3.5078-4.1641z" fill="#1B1C1F"/>\n        <path transform="translate(325,864)" d="m0 0 1 2-6 9-1-2 1-3h2l0.375-2.4375 0.625-2.5625 2-1z" fill="#B67E57"/>\n        <path transform="translate(168,863)" d="m0 0 1.8125 1.5c2.1578 1.7828 2.1578 1.7828 5.1875 1.5l1 3-2 2c-1.006-0.95207-2.0046-1.9119-3-2.875-0.55688-0.53367-1.1138-1.0673-1.6875-1.6172-1.3125-1.5078-1.3125-1.5078-1.3125-3.5078z" fill="#BD8259"/>\n        <path transform="translate(328,855)" d="m0 0h1c0.25 2.75 0.25 2.75 0 6-2 2.375-2 2.375-4 4l-1-2c0.77734-1.9453 0.77734-1.9453 1.9375-4.125 0.57041-1.0867 0.57041-1.0867 1.1523-2.1953 0.30035-0.5543 0.6007-1.1086 0.91016-1.6797z" fill="#D79969"/>\n        <path transform="translate(415,421)" d="m0 0 1 4-6 5c0-4.3897 2.1281-5.7691 5-9z" fill="#B5815A"/>\n        <path transform="translate(633,390)" d="m0 0c0 3 0 3-1.5312 4.8242-0.64969 0.61488-1.2994 1.2298-1.9688 1.8633-0.64969 0.62262-1.2994 1.2452-1.9688 1.8867-0.50531 0.47051-1.0106 0.94102-1.5312 1.4258 0-3 0-3 2-6v-2l1.9375-0.4375c2.038-0.37257 2.038-0.37257 3.0625-1.5625z" fill="#9FA49B"/>\n        <path transform="translate(500,309)" d="m0 0 1 4-6 5c0-4.3897 2.1281-5.7691 5-9z" fill="#B9835B"/>\n        <path transform="translate(808,211)" d="m0 0 1 2h2l1-2c0.99 1.65 1.98 3.3 3 5-1.3333 0.66667-2.6667 1.3333-4 2l-4-6 1-1z" fill="#7D8480"/>\n        <path transform="translate(518,686)" d="m0 0c2.5 2.3125 2.5 2.3125 5 5v3l-7-6 2-2z" fill="#252A23"/>\n        <path transform="translate(488,567)" d="m0 0c2.125 0.375 2.125 0.375 4 1v3h-2l-2 2-2-4 2-2z" fill="#6A716C"/>\n        <path transform="translate(507,550)" d="m0 0h2v3h3l1 3-4 1c-2-5.875-2-5.875-2-7z" fill="#6A726C"/>\n        <path transform="translate(453,371)" d="m0 0 1 4-7 5c1.5271-3.436 3.5993-6.1191 6-9z" fill="#B38058"/>\n        <path transform="translate(466,354)" d="m0 0 1 4-5 4c0-3.9084 1.5057-5.1159 4-8z" fill="#B8835B"/>\n        <path transform="translate(696,312)" d="m0 0 2 4-6 4c1.75-5.75 1.75-5.75 4-8z" fill="#A3A79E"/>\n        <path transform="translate(811,219)" d="m0 0 2.875 1.0625c2.9956 1.2878 2.9956 1.2878 5.125-0.0625l-2 4-2-1-1 2-1-4h-2v-2z" fill="#7C8480"/>\n        <path transform="translate(220,854)" d="M0 0 C1.46067199 0.45082469 2.91848032 0.91093537 4.375 1.375 C5.18710938 1.63023437 5.99921875 1.88546875 6.8359375 2.1484375 C9 3 9 3 11 5 C4.61764706 5.49095023 4.61764706 5.49095023 1.5625 3.0625 C0 1 0 1 0 0 Z " fill="#CF9940"/>\n        <path transform="translate(515,679)" d="m0 0 5 1 1 4-3 2c-0.99-2.31-1.98-4.62-3-7z" fill="#5B645B"/>\n        <path transform="translate(463,430)" d="m0 0c0 3.2818-0.47836 5.1089-2 8-2.125 0.8125-2.125 0.8125-4 1 1.5271-3.436 3.5993-6.1191 6-9z" fill="#EFEFE7"/>\n        <path transform="translate(506,303)" d="m0 0c0 3 0 3-2.5 5.6875l-2.5 2.3125c0.3505-3.2421 0.56221-4.6153 3.0625-6.8125 0.63938-0.39188 1.2788-0.78375 1.9375-1.1875z" fill="#D89B69"/>\n        <path transform="translate(475,753)" d="m0 0c2.3125 0.1875 2.3125 0.1875 5 1 1.8125 2.5625 1.8125 2.5625 3 5-3.3659-1.4425-5.5105-3.3326-8-6z" fill="#B9835A"/>\n        <path transform="translate(162,743)" d="m0 0 1 2c-1.25 2.5625-1.25 2.5625-3 5-0.99 0.33-1.98 0.66-3 1 1.1858-3.375 2.2757-5.6472 5-8z" fill="#B47F58"/>\n        <path transform="translate(181,727)" d="m0 0 1 2c-1.75 1.5625-1.75 1.5625-4 3-2.25-0.3125-2.25-0.3125-4-1 2.1742-2.5004 3.7305-3.4363 7-4z" fill="#C99064"/>\n        <path transform="translate(242,692)" d="m0 0 1 3c-2.3125 2.5-2.3125 2.5-5 5h-3c2.31-2.64 4.62-5.28 7-8z" fill="#AE7B55"/>\n        <path transform="translate(370,499)" d="m0 0c0 3 0 3-1.5 4.6875l-1.5 1.3125c-1.5-1.375-1.5-1.375-3-3v-2l1.875 0.625 2.125 0.375 2-2z" fill="#E6BE85"/>\n        <path transform="translate(272,467)" d="m0 0 1 2c-0.93579 2.3598-1.9335 4.6963-3 7h-2c1.0588-3.4031 2.009-6.0135 4-9z" fill="#B5805A"/>\n        <path transform="translate(277,458)" d="m0 0c1 2 1 2 0.25 5.0625l-1.25 2.9375c-0.99 0.33-1.98 0.66-3 1 1.0588-3.4031 2.009-6.0135 4-9z" fill="#AF7C57"/>\n        <path transform="translate(437,392)" d="m0 0 1 4-6 4c1.3715-2.9541 2.9886-5.4401 5-8z" fill="#B18159"/>\n        <path transform="translate(553,310)" d="m0 0 1 4-4 3-2-1 5-6z" fill="#E8E7DD"/>\n        <path transform="translate(526,274)" d="m0 0 1 4-6 4c1.3715-2.9541 2.9886-5.4401 5-8z" fill="#B37F57"/>\n        <path transform="translate(565,222)" d="m0 0c1.125 3.75 1.125 3.75 0 6-1.6436 0.72159-3.3105 1.3935-5 2 1.3715-2.9541 2.9886-5.4401 5-8z" fill="#B98158"/>\n        <path transform="translate(407,717)" d="m0 0c0 3 0 3-1.3125 4.3867-1.5625 1.2044-3.125 2.4089-4.6875 3.6133l-1-3 2.375-1.375c2.662-1.5093 2.662-1.5093 4.625-3.625z" fill="#11161B"/>\n        <path transform="translate(477,362)" d="m0 0 1 2c-0.93306 2.7144-1.6267 3.7804-4.125 5.25l-1.875 0.75c1.1858-3.375 2.2757-5.6472 5-8z" fill="#191C1F"/>\n        <path transform="translate(462,361)" d="m0 0 1 2-5 5c0.3125-2.375 0.3125-2.375 1-5l3-2z" fill="#D59868"/>\n        <path transform="translate(531,290)" d="m0 0 2 1c-1.0487 2.6219-1.6493 3.7937-4.125 5.25l-1.875 0.75c1.074-2.9152 1.7781-4.7781 4-7z" fill="#202223"/>\n        <path transform="translate(793,209)" d="m0 0c0.99 0.33 1.98 0.66 3 1l-6 5-2-1 5-5z" fill="#6A706E"/>\n        <path transform="translate(465,748)" d="m0 0c0.99 0.33 1.98 0.66 3 1v2c-0.99-0.33-1.98-0.66-3-1v-2z" fill="#C78A5F"/>\n        <path transform="translate(249,531)" d="m0 0 2 4-2-1v-3z" fill="#B8835C"/>\n        <path transform="translate(370,472)" d="m0 0 3 2h-3v-2z" fill="#D7956A"/>\n        <path transform="translate(162,859)" d="m0 0 2 1-1 2-1-3z" fill="#BC835A"/>\n        <path transform="translate(146,829)" d="m0 0h2l-1 3-1-3z" fill="#BA815A"/>\n        <path transform="translate(836,340)" d="m0 0 1 4z" fill="#C98C62"/>\n        <path transform="translate(472,341)" d="m0 0 2 1-2 2v-3z" fill="#C2895F"/>\n        <path transform="translate(277,903)" d="m0 0c3 1 3 1 3 1z" fill="#BF845A"/>\n        <path transform="translate(228,903)" d="m0 0c3 1 3 1 3 1z" fill="#BE855B"/>\n        <path transform="translate(555,648)" d="m0 0c3 1 3 1 3 1z" fill="#D29063"/>\n        <path transform="translate(306,602)" d="m0 0 2 2h-2v-2z" fill="#CE8F63"/>\n        <path transform="translate(884,182)" d="m0 0 2 2h-2v-2z" fill="#C48961"/>\n        <path transform="translate(632,176)" d="m0 0c3 1 3 1 3 1z" fill="#CF8F62"/>\n        <path transform="translate(672,163)" d="m0 0c3 1 3 1 3 1z" fill="#C78B60"/>\n        <path transform="translate(834,114)" d="m0 0c3 1 3 1 3 1z" fill="#CA8B5F"/>\n        <path transform="translate(224,902)" d="m0 0 2 1z" fill="#BC835B"/>\n        <path transform="translate(491,766)" d="m0 0 2 1z" fill="#C2855B"/>\n        <path transform="translate(432,725)" d="m0 0 2 1z" fill="#D09164"/>\n        <path transform="translate(193,717)" d="m0 0 2 1z" fill="#C68B60"/>\n        <path transform="translate(595,700)" d="m0 0 2 1z" fill="#BA805A"/>\n        <path transform="translate(268,658)" d="m0 0 2 1z" fill="#C88B60"/>\n        <path transform="translate(564,651)" d="m0 0 2 1z" fill="#D49266"/>\n        <path transform="translate(304,601)" d="m0 0 2 1z" fill="#CC8D62"/>\n        <path transform="translate(600,591)" d="m0 0 2 1z" fill="#CE8E61"/>\n        <path transform="translate(604,588)" d="m0 0 2 1z" fill="#CD8D61"/>\n        <path transform="translate(273,565)" d="m0 0 2 1z" fill="#CA8C63"/>\n        <path transform="translate(779,438)" d="m0 0 2 1z" fill="#C58A60"/>\n        <path transform="translate(496,304)" d="m0 0 2 1z" fill="#BE875E"/>\n        <path transform="translate(867,239)" d="m0 0 2 1z" fill="#C88C64"/>\n        <path transform="translate(626,178)" d="m0 0 2 1z" fill="#C88A5E"/>\n        <path transform="translate(657,168)" d="m0 0 2 1z" fill="#CD8F65"/>\n        <path transform="translate(709,152)" d="m0 0 2 1z" fill="#CB8A5E"/>\n        <path transform="translate(776,131)" d="m0 0 2 1z" fill="#C7895F"/>\n        </svg>\n\n        <h1 class="page-title">Glotus Client</h1>\n        <p id="script-description" class="page-description"></p>\n    </div>\n\n    <svg\n        id="close-button"\n        class="icon"\n        xmlns="http://www.w3.org/2000/svg"\n        viewBox="0 0 30 30"\n    >\n        <path d="M 7 4 C 6.744125 4 6.4879687 4.0974687 6.2929688 4.2929688 L 4.2929688 6.2929688 C 3.9019687 6.6839688 3.9019687 7.3170313 4.2929688 7.7070312 L 11.585938 15 L 4.2929688 22.292969 C 3.9019687 22.683969 3.9019687 23.317031 4.2929688 23.707031 L 6.2929688 25.707031 C 6.6839688 26.098031 7.3170313 26.098031 7.7070312 25.707031 L 15 18.414062 L 22.292969 25.707031 C 22.682969 26.098031 23.317031 26.098031 23.707031 25.707031 L 25.707031 23.707031 C 26.098031 23.316031 26.098031 22.682969 25.707031 22.292969 L 18.414062 15 L 25.707031 7.7070312 C 26.098031 7.3170312 26.098031 6.6829688 25.707031 6.2929688 L 23.707031 4.2929688 C 23.316031 3.9019687 22.682969 3.9019687 22.292969 4.2929688 L 15 11.585938 L 7.7070312 4.2929688 C 7.5115312 4.0974687 7.255875 4 7 4 z"/>\n    </svg>\n</header>';

    const Navbar_default = '<div id="navbar-container">\n    <button data-id="0" class="open-menu active">\n        <span>\n            <svg class="small-icon" xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">\n                <path fill="currentColor"\n                    d="M240 6.1c9.1-8.2 22.9-8.2 32 0l232 208c9.9 8.8 10.7 24 1.8 33.9s-24 10.7-33.9 1.8l-8-7.2v205.3c0 35.3-28.7 64-64 64h-288c-35.3 0-64-28.7-64-64V242.6l-8 7.2c-9.9 8.8-25 8-33.9-1.8s-8-25 1.8-33.9zm16 50.1L96 199.7V448c0 8.8 7.2 16 16 16h48V360c0-39.8 32.2-72 72-72h48c39.8 0 72 32.2 72 72v104h48c8.8 0 16-7.2 16-16V199.7L256 56.3zM208 464h96V360c0-13.3-10.7-24-24-24h-48c-13.3 0-24 10.7-24 24z" />\n            </svg>\n            Home\n        </span>\n    </button>\n    <button data-id="1" class="open-menu">\n        <span>\n            <svg class="small-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n                <path fill="currentColor"\n                    d="M6.21 13.29a.9.9 0 0 0-.33-.21a1 1 0 0 0-.76 0a.9.9 0 0 0-.54.54a1 1 0 1 0 1.84 0a1 1 0 0 0-.21-.33M13.5 11h1a1 1 0 0 0 0-2h-1a1 1 0 0 0 0 2m-4 0h1a1 1 0 0 0 0-2h-1a1 1 0 0 0 0 2m-3-2h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2M20 5H4a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h16a3 3 0 0 0 3-3V8a3 3 0 0 0-3-3m1 11a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1Zm-6-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2m3.5-4h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2m.71 4.29a1 1 0 0 0-.33-.21a1 1 0 0 0-.76 0a.9.9 0 0 0-.33.21a1 1 0 0 0-.21.33a1 1 0 1 0 1.92.38a.84.84 0 0 0-.08-.38a1 1 0 0 0-.21-.33" />\n            </svg>\n            Keybinds\n        </span>\n    </button>\n    <button data-id="2" class="open-menu">\n        <span>\n            <svg class="small-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n                <path fill="currentColor"\n                    d="m19.05 21.6l-2.925-2.9l-2.2 2.2l-.7-.7q-.575-.575-.575-1.425t.575-1.425l4.225-4.225q.575-.575 1.425-.575t1.425.575l.7.7l-2.2 2.2l2.9 2.925q.3.3.3.7t-.3.7l-1.25 1.25q-.3.3-.7.3t-.7-.3M22 5.9L10.65 17.25l.125.1q.575.575.575 1.425t-.575 1.425l-.7.7l-2.2-2.2l-2.925 2.9q-.3.3-.7.3t-.7-.3L2.3 20.35q-.3-.3-.3-.7t.3-.7l2.9-2.925l-2.2-2.2l.7-.7q.575-.575 1.425-.575t1.425.575l.1.125L18 1.9h4zM6.95 10.85L2 5.9v-4h4l4.95 4.95z" />\n            </svg>\n            Combat\n        </span>\n    </button>\n    <button data-id="3" class="open-menu">\n        <span>\n            <svg class="small-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n                <g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">\n                    <path\n                        d="M12 5c-6.307 0-9.367 5.683-9.91 6.808a.44.44 0 0 0 0 .384C2.632 13.317 5.692 19 12 19s9.367-5.683 9.91-6.808a.44.44 0 0 0 0-.384C21.368 10.683 18.308 5 12 5" />\n                    <circle cx="12" cy="12" r="3" />\n                </g>\n            </svg>\n            Visuals\n        </span>\n    </button>\n    <button data-id="4" class="open-menu">\n        <span>\n            <svg class="small-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n                <path fill="currentColor"\n                    d="M2 18h7v2H2zm0-7h9v2H2zm0-7h20v2H2zm18.674 9.025l1.156-.391l1 1.732l-.916.805a4 4 0 0 1 0 1.658l.916.805l-1 1.732l-1.156-.391a4 4 0 0 1-1.435.83L19 21h-2l-.24-1.196a4 4 0 0 1-1.434-.83l-1.156.392l-1-1.732l.916-.805a4 4 0 0 1 0-1.658l-.916-.805l1-1.732l1.156.391c.41-.37.898-.655 1.435-.83L17 11h2l.24 1.196a4 4 0 0 1 1.434.83M18 17a1 1 0 1 0 0-2a1 1 0 0 0 0 2" />\n            </svg>\n            Misc\n        </span>\n    </button>\n    <button data-id="5" class="open-menu">\n        <span>\n            <svg class="small-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n                <path fill="currentColor"\n                    d="M22 14h-1c0-3.87-3.13-7-7-7h-1V5.73A2 2 0 1 0 10 4c0 .74.4 1.39 1 1.73V7h-1c-3.87 0-7 3.13-7 7H2c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1h1v1a2 2 0 0 0 2 2h14c1.11 0 2-.89 2-2v-1h1c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1m-1 3h-2v3H5v-3H3v-1h2v-2c0-2.76 2.24-5 5-5h4c2.76 0 5 2.24 5 5v2h2zm-3.5-1.5c0 1.11-.89 2-2 2c-.97 0-1.77-.69-1.96-1.6l2.96-2.12c.6.35 1 .98 1 1.72m-10-1.72l2.96 2.12c-.18.91-.99 1.6-1.96 1.6a2 2 0 0 1-2-2c0-.74.4-1.37 1-1.72" />\n            </svg>\n            Bots\n        </span>\n    </button>\n    <button data-id="6" class="open-menu bottom-align">\n        <span>\n            <svg class="small-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n                <path fill="currentColor"\n                    d="m19.546 7.573l-1.531-1.57l-1.442 1.291l-.959.86l3.876 3.987l-2.426 2.496l-1.451 1.492c.55.499 1.091.99 1.64 1.486l.764.694l2.21-2.277L24 12.14v-.001zM2.992 9.072L0 12.14c2.01 2.073 3.993 4.115 5.984 6.167l.51-.464l1.893-1.715L6.94 14.64l-2.43-2.5l3.109-3.196l.767-.789c-.434-.39-.86-.772-1.288-1.154L5.984 6v.001zm12.585-6.038L11.632 21.6l-.196-.039l-3.029-.595l2.555-12.02L12.353 2.4z" />\n            </svg>\n            Devtool\n        </span>\n    </button>\n    <div\n        style="margin-top: auto; padding: 15px 10px; text-align: center; border-top: 1px solid rgba(255,255,255,0.05); background: rgba(0,0,0,0.1);">\n        <span\n            style="color: #f5d951; font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; display: block; opacity: 0.6; margin-bottom: 2px;">Glotus\n            Client!</span>\n        <span\n            style="color: #fff; font-size: 15px; font-weight: 900; display: block; text-shadow: 0 0 8px rgba(245, 217, 81, 0.6);"></span>\n    </div>\n</div>';

    const Home_default = '<div class="menu-page opened" data-id="0">\n    <div class="page-title">Home</div>\n\n    <div class="section">\n        <div class="section-title">Welcome to the Glotus Client! <span class="highlight"\n                style="font-size: 14px;">[Glotus Client!]</span></div>\n        <div class="section-content">\n\n            <div class="content-option text">\n                <span class="text-value simplified">My main goal in creating this hack was to automate absolutely\n                    everything. So don\'t be surprised by the lack of numerous hotkeys - not even for switching weapons.\n                    This client is designed for simple <span class="highlight">WASD</span> movement and primarly <span\n                        class="highlight">polearm + hammer</span>, which is what makes it great. There\'s no need to\n                    remember dozens of hotkeys, chat commands, or anything else.</span>\n            </div>\n\n            <div class="content-option text">\n                <span class="text-value simplified">It is still in development, so please, report about all issues. Let\n                    the client keep growing!</span>\n            </div>\n        </div>\n    </div>\n\n    <div class="section">\n\n        <div class="section-content">\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Author: </span>\n                <span id="author" class="text-value">Murka (<span class="highlight">Glotus Client!</span>)</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <a href="https://discord.gg/cPRFdcZkeD" class="text-value" target="_blank">\n                    <svg class="icon link" xmlns="http://www.w3.org/2000/svg" width="24" height="24"\n                        viewBox="0 0 24 24">\n                        <path fill="currentColor"\n                            d="M19.303 5.337A17.3 17.3 0 0 0 14.963 4c-.191.329-.403.775-.552 1.125a16.6 16.6 0 0 0-4.808 0C9.454 4.775 9.23 4.329 9.05 4a17 17 0 0 0-4.342 1.337C1.961 9.391 1.218 13.35 1.59 17.255a17.7 17.7 0 0 0 5.318 2.664a13 13 0 0 0 1.136-1.836c-.627-.234-1.22-.52-1.794-.86c.149-.106.297-.223.435-.34c3.46 1.582 7.207 1.582 10.624 0c.149.117.287.234.435.34c-.573.34-1.167.626-1.793.86a13 13 0 0 0 1.135 1.836a17.6 17.6 0 0 0 5.318-2.664c.457-4.52-.722-8.448-3.1-11.918M8.52 14.846c-1.04 0-1.889-.945-1.889-2.101s.828-2.102 1.89-2.102c1.05 0 1.91.945 1.888 2.102c0 1.156-.838 2.1-1.889 2.1m6.974 0c-1.04 0-1.89-.945-1.89-2.101s.828-2.102 1.89-2.102c1.05 0 1.91.945 1.889 2.102c0 1.156-.828 2.1-1.89 2.1" />\n                    </svg>\n                </a>\n\n                <a href="https://github.com/Murka007/Glotus-Client" class="text-value" target="_blank">\n                    <svg class="icon link" xmlns="http://www.w3.org/2000/svg" width="24" height="24"\n                        viewBox="0 0 24 24">\n                        <path fill="currentColor"\n                            d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2" />\n                    </svg>\n                </a>\n\n                <a href="https://greasyfork.org/en/users/919633-murka007" class="text-value" target="_blank">\n                    <svg class="icon link" version="1.1" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg">\n                        <circle cx="48" cy="48" r="48" />\n                        <clipPath id="a">\n                            <circle cx="48" cy="48" r="47" />\n                        </clipPath>\n                        <text clip-path="url(#a)" fill="#fff"\n                            font-family="\'DejaVu Sans\', Verdana, Arial, \'Liberation Sans\', sans-serif" font-size="18"\n                            letter-spacing="-.75" pointer-events="none" text-anchor="middle"\n                            style="-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none">\n                            <tspan x="51" y="13" textLength="57">= null;</tspan>\n                            <tspan x="56" y="35" textLength="98">function init</tspan>\n                            <tspan x="49" y="57" textLength="113">for (const i = 0;</tspan>\n                            <tspan x="50" y="79" textLength="105">XmlHttpReq</tspan>\n                            <tspan x="48" y="101" textLength="80">appendCh</tspan>\n                        </text>\n                        <path\n                            d="m44 29a6.364 6.364 0 0 1 0 9l36 36a3.25 3.25 0 0 1-6.5 6.5l-36-36a6.364 6.364 0 0 1-9 0l-19-19a1.7678 1.7678 0 0 1 0-2.5l13-13a1.7678 1.7678 0 0 1 2.5 0z"\n                            stroke="#000" stroke-width="4" />\n                        <path\n                            d="m44 29a6.364 6.364 0 0 1 0 9l36 36a3.25 3.25 0 0 1-6.5 6.5l-36-36a6.364 6.364 0 0 1-9 0l-19-19a1.7678 1.7678 0 0 1 2.5-2.5l14 14 4-4-14-14a1.7678 1.7678 0 0 1 2.5-2.5l14 14 4-4-14-14a1.7678 1.7678 0 0 1 2.5-2.5z"\n                            fill="#fff" />\n                    </svg>\n                </a>\n\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Building hash: </span>\n                <span id="author" class="text-value">{HASH}</span>\n            </div>\n\n        </div>\n    </div>\n\n</div>';

    const Keybinds_default = '<div class="menu-page" data-id="1">\n    <div class="page-title">Keybinds</div>\n    <p class="page-description">Setup keybinds for items, weapons and hats</p>\n\n    \x3c!-- Items & Weapons --\x3e\n    <div class="section">\n        <div class="section-title">Items & Weapons</div>\n        <div class="section-content split">\n\n            <div class="content-split">\n                <div class="content-option">\n                    <span class="option-title">Food</span>\n                    <button id="_food" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Wall</span>\n                    <button id="_wall" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Spike</span>\n                    <button id="_spike" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Windmill</span>\n                    <button id="_windmill" class="hotkeyInput"></button>\n                </div>\n            </div>\n\n            <div class="content-split">\n                <div class="content-option">\n                    <span class="option-title">Farm</span>\n                    <button id="_farm" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Trap</span>\n                    <button id="_trap" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Turret</span>\n                    <button id="_turret" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Spawn</span>\n                    <button id="_spawn" class="hotkeyInput"></button>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    \x3c!-- Controls & Movement --\x3e\n    <div class="section">\n        <div class="section-title">Controls & Movement</div>\n        <div class="section-content">\n\n            <div class="content-split">\n\n                <div class="content-option">\n                    <span class="option-title">Lock bot position</span>\n                    <button id="_lockBotPosition" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Toggle Shop</span>\n                    <button id="_toggleShop" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Toggle Clan</span>\n                    <button id="_toggleClan" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Toggle Menu</span>\n                    <button id="_toggleMenu" class="hotkeyInput"></button>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Instakill</span>\n                    <button id="_instakill" class="hotkeyInput"></button>\n                </div>\n\n            </div>\n        </div>\n    </div>\n</div>';

    const Combat_default = '<div class="menu-page" data-id="2">\n    <div class="page-title">Combat</div>\n    <p class="page-description">Modify combat settings, change pvp behavior</p>\n\n    \x3c!-- Defense --\x3e\n    <div class="section">\n        <div class="section-title">Defense</div>\n        <div class="section-content">\n\n            \x3c!-- <div class="content-option">\n                <span class="option-title">Biome hats</span>\n                <label class="switch-checkbox">\n                    <input id="_biomehats" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div> --\x3e\n\n            \x3c!-- <div class="content-option">\n                <span class="option-title">Auto emp</span>\n                <label class="switch-checkbox">\n                    <input id="_autoemp" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div> --\x3e\n\n            <div class="content-option">\n                <span class="option-title">Anti enemy</span>\n                <label class="switch-checkbox">\n                    <input id="_antienemy" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Basic soldier equipment for all types of antis</span>\n            </div>\n\n            \x3c!-- <div class="content-option">\n                <span class="option-title">Soldier default</span>\n                <label class="switch-checkbox">\n                    <input id="_soldierDefault" type="checkbox"></input>\n                    <span></span>\n                </label>\n\n                <span class="option-description">Equips soldier by default, when antis fail to do its work</span>\n            </div> --\x3e\n\n            \x3c!-- <div class="content-option">\n                <span class="option-title">Anti animal</span>\n                <label class="switch-checkbox">\n                    <input id="_antianimal" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Equips a soldier when danger animal is nearby</span>\n            </div> --\x3e\n\n            <div class="content-option">\n                <span class="option-title">Anti spike</span>\n                <label class="switch-checkbox">\n                    <input id="_antispike" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Adds additional layer of protection against spikes</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Emp Defense</span>\n                <label class="switch-checkbox">\n                    <input id="_empDefense" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Equips emp by default when you are not moving</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Autoheal</span>\n                <label class="switch-checkbox">\n                    <input id="_autoheal" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n            \n            <div class="content-option">\n                <span class="option-title">Autobreak</span>\n                <label class="switch-checkbox">\n                    <input id="_autobreak" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Destroys nearby enemy traps and spikes</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Safe walk</span>\n                <label class="switch-checkbox">\n                    <input id="_safeWalk" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Prevents from colliding enemy spikes, cactuses, boostpads</span>\n            </div>\n        </div>\n    </div>\n\n    \x3c!-- Placement --\x3e\n     <div class="section">\n        <div class="section-title">Placement</div>\n\n        <div class="section-content">\n            <div class="content-option">\n                <span class="option-title">Autoplacer</span>\n                <label class="switch-checkbox">\n                    <input id="_autoplacer" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Automatically places traps and spikes when enemy is nearby</span>\n            </div>\n\n            \x3c!-- <div class="content-option">\n                <span class="option-title">Preplacer</span>\n                <label class="switch-checkbox">\n                    <input id="_preplacer" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div> --\x3e\n\n            <div class="content-option">\n                <span class="option-title">Autoplacer radius</span>\n                <label class="slider">\n                    <span class="slider-value"></span>\n                    <input id="_autoplacerRadius" type="range" step="25" min="100" max="450">\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Placement accuracy</span>\n                <label class="slider">\n                    <span class="slider-value"></span>\n                    <input id="_placeAttempts" type="range" min="1" max="10">\n                </label>\n                <span class="option-description">Algorithm calculates all the possible attempts. But later this value decreases in order to avoid lags.</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Automill</span>\n                <label class="switch-checkbox">\n                    <input id="_automill" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Automatically places 3x windmills behind your back</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Auto grind</span>\n                <label class="switch-checkbox">\n                    <input id="_autoGrind" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Stay still to get autogrind working</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Placement Defense</span>\n                <label class="switch-checkbox">\n                    <input id="_placementDefense" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Places a wall/windmill on projectile threats</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Dash Movement</span>\n                <label class="switch-checkbox">\n                    <input id="_dashMovement" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">When holding a boostpad hotkey, it is gonna place boost pad once and immediately destroy it, giving you additional speed.</span>\n            </div>\n        </div>\n    </div>\n    \n    \x3c!-- Instakills --\x3e\n    <div class="section">\n        <div class="section-title">Instakills</div>\n\n        <div class="section-content">\n            <div class="content-option">\n                <span class="option-title">Auto sync</span>\n                <label class="switch-checkbox">\n                    <input id="_autoSync" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Attacks when it is possible to sync enemy with 2 primary weapons</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Velocity tick</span>\n                <label class="switch-checkbox">\n                    <input id="_velocityTick" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Attacks using turret + diamond polearm in one tick</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Spike tick</span>\n                <label class="switch-checkbox">\n                    <input id="_spikeTick" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">When enemy is about to collide a spike, attacks with primary weapon</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Spike sync</span>\n                <label class="switch-checkbox">\n                    <input id="_spikeSync" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Spike sync hammer</span>\n                <label class="switch-checkbox">\n                    <input id="_spikeSyncHammer" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Knockback tick</span>\n                <label class="switch-checkbox">\n                    <input id="_knockbackTick" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Attacks enemy when its possible to knockback on spike</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Knockback tick hammer</span>\n                <label class="switch-checkbox">\n                    <input id="_knockbackTickHammer" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Knockbacks enemy using hammer + turret + primary weapon on spike</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Knockback tick trap</span>\n                <label class="switch-checkbox">\n                    <input id="_knockbackTickTrap" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Destroys a trap and knockbacks enemy on spike</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Anti Retrap</span>\n                <label class="switch-checkbox">\n                    <input id="_antiRetrap" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">When you are trapped, attacks enemy with primary weapon to push it away</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Tool Spear Insta</span>\n                <label class="switch-checkbox">\n                    <input id="_toolSpearInsta" type="checkbox"></input>\n                    <span></span>\n                </label>\n\n                <span class="option-description">When you have Tool Hammer and also Polearm could be upgraded, then it is going to perform instakill on nearest enemy.</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Autosteal</span>\n                <label class="switch-checkbox">\n                    <input id="_autoSteal" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Steals kills/animals from other players</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Autopush</span>\n                <label class="switch-checkbox">\n                    <input id="_autoPush" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Turret steal</span>\n                <label class="switch-checkbox">\n                    <input id="_turretSteal" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Equips a turret hat if possible to kill with it</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Spike Gear Insta</span>\n                <label class="switch-checkbox">\n                    <input id="_spikeGearInsta" type="checkbox"></input>\n                    <span></span>\n                </label>\n\n                <span class="option-description">Equips Spike Gear when it is possible to deal potential damage with it to the enemy. Instakill may happen.</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Turret Sync</span>\n                <label class="switch-checkbox">\n                    <input id="_turretSync" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Attacks using primary in sync with other turret objects</span>\n            </div>\n        </div>\n    </div>\n\n</div>';

    const Visuals_default = '<div class="menu-page" data-id="3">\n    <div class="page-title">Visuals</div>\n    <p class="page-description">Customize your visuals, or you can disable it for performance</p>\n\n    \x3c!-- Tracers --\x3e\n    <div class="section">\n        <div class="section-title">Tracers</div>\n        <div class="section-content">\n\n            <div class="content-option">\n                <span class="option-title">Enemies</span>\n                <div class="option-content">\n                    <button class="reset-color" title="Reset Color"></button>\n                    <input id="_enemyTracersColor" type="color" title="Select Color">\n                    <label class="switch-checkbox">\n                        <input id="_enemyTracers" type="checkbox"></input>\n                        <span></span>\n                    </label>\n                </div>\n            </div>\n\n            <div class="content-option">\n                    <span class="option-title">Teammates</span>\n                    <div class="option-content">\n                        <button class="reset-color" title="Reset Color"></button>\n                        <input id="_teammateTracersColor" type="color" title="Select Color">\n                        <label class="switch-checkbox">\n                            <input id="_teammateTracers" type="checkbox"></input>\n                            <span></span>\n                        </label>\n                    </div>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Animal</span>\n                    <div class="option-content">\n                        <button class="reset-color" title="Reset Color"></button>\n                        <input id="_animalTracersColor" type="color" title="Select Color">\n                        <label class="switch-checkbox">\n                            <input id="_animalTracers" type="checkbox"></input>\n                            <span></span>\n                        </label>\n                    </div>\n                </div>\n\n                <div class="content-option">\n                    <span class="option-title">Notification</span>\n                    <div class="option-content">\n                        <button class="reset-color" title="Reset Color"></button>\n                        <input id="_notificationTracersColor" type="color" title="Select Color">\n                        <label class="switch-checkbox">\n                            <input id="_notificationTracers" type="checkbox"></input>\n                            <span></span>\n                        </label>\n                    </div>\n                </div>\n\n        </div>\n    </div>\n\n    \x3c!-- Markers --\x3e\n    <div class="section">\n        <div class="section-title">Markers</div>\n\n        <div class="section-content">\n\n            <div class="content-option">\n                <span class="option-title">Item Markers</span>\n                <div class="option-content">\n                    <button class="reset-color" title="Reset Color"></button>\n                    <input id="_itemMarkersColor" type="color" title="Select Color">\n                    <label class="switch-checkbox">\n                        <input id="_itemMarkers" type="checkbox"></input>\n                        <span></span>\n                    </label>\n                </div>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Teammates</span>\n                <div class="option-content">\n                    <button class="reset-color" title="Reset Color"></button>\n                    <input id="_teammateMarkersColor" type="color" title="Select Color">\n                    <label class="switch-checkbox">\n                        <input id="_teammateMarkers" type="checkbox"></input>\n                        <span></span>\n                    </label>\n                </div>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Enemies</span>\n                <div class="option-content">\n                    <button class="reset-color" title="Reset Color"></button>\n                    <input id="_enemyMarkersColor" type="color" title="Select Color">\n                    <label class="switch-checkbox">\n                        <input id="_enemyMarkers" type="checkbox"></input>\n                        <span></span>\n                    </label>\n                </div>\n            </div>\n                \n        </div>\n    </div>\n\n    \x3c!-- Player --\x3e\n    <div class="section">\n        <div class="section-title">Player</div>\n\n        <div class="section-content">\n\n            <div class="content-option">\n                <span class="option-title">Weapon XP Bar</span>\n                <label class="switch-checkbox">\n                    <input id="_weaponXPBar" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Turret Reload Bar</span>\n                <div class="option-content">\n                    <button class="reset-color" title="Reset Color"></button>\n                    <input id="_playerTurretReloadBarColor" type="color" title="Select Color">\n                    <label class="switch-checkbox">\n                        <input id="_playerTurretReloadBar" type="checkbox"></input>\n                        <span></span>\n                    </label>\n                </div>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Weapon Reload Bar</span>\n                <div class="option-content">\n                    <button class="reset-color" title="Reset Color"></button>\n                    <input id="_weaponReloadBarColor" type="color" title="Select Color">\n                    <label class="switch-checkbox">\n                        <input id="_weaponReloadBar" type="checkbox"></input>\n                        <span></span>\n                    </label>\n                </div>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Render HP</span>\n                <label class="switch-checkbox">\n                    <input id="_renderHP" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            \x3c!-- <div class="content-option">\n                <span class="option-title">Stacked Damage</span>\n                <label class="switch-checkbox">\n                    <input id="_stackedDamage" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div> --\x3e\n        </div>\n    </div>\n\n    \x3c!-- Object --\x3e\n    <div class="section">\n        <div class="section-title">Object</div>\n\n        <div class="section-content">\n\n            <div class="content-option">\n                <span class="option-title">Turret Reload Bar</span>\n                <div class="option-content">\n                    <button class="reset-color" title="Reset Color"></button>\n                    <input id="_objectTurretReloadBarColor" type="color" title="Select Color">\n                    <label class="switch-checkbox">\n                        <input id="_objectTurretReloadBar" type="checkbox"></input>\n                        <span></span>\n                    </label>\n                </div>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Item Health Bar</span>\n                <div class="option-content">\n                    <button class="reset-color" title="Reset Color"></button>\n                    <input id="_itemHealthBarColor" type="color" title="Select Color">\n                    <label class="switch-checkbox">\n                        <input id="_itemHealthBar" type="checkbox"></input>\n                        <span></span>\n                    </label>\n                </div>\n            </div>\n\n        </div>\n    </div>\n\n</div>';

    const Misc_default = '<div class="menu-page" data-id="4">\n    <div class="page-title">Misc</div>\n    <p class="page-description">Customize misc settings, add autochat messages, reset settings</p>\n\n    \x3c!-- Other --\x3e\n    <div class="section">\n        <h2 class="section-title">Other</h2>\n\n        <div class="section-content">\n\n            <div class="content-option">\n                <span class="option-title">Kill Message</span>\n                <div class="option-content">\n                    <span class="seldoom-locked">seldoom is goated</span>\n                </div>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Autospawn</span>\n                <label class="switch-checkbox">\n                    <input id="_autospawn" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Autoaccept</span>\n                <label class="switch-checkbox">\n                    <input id="_autoaccept" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Texture pack</span>\n                <label class="switch-checkbox">\n                    <input id="_texturepack" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Some old looking texture pack. Reload the page to make it work! :)</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Hide game HUD</span>\n                <label class="switch-checkbox">\n                    <input id="_hideHUD" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Smooth rendering</span>\n                <label class="slider">\n                    <span class="slider-value"></span>\n                    <input id="_smoothRendering" type="range" step="10" min="100" max="200">\n                </label>\n                <span class="option-description">Control how smoothly your game is being rendering. Higher speeds give you more accurate position of entities, making you analyze situation better.</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Chat Log</span>\n                <label class="switch-checkbox">\n                    <input id="_chatLog" type="checkbox"></input>\n                    <span></span>\n                </label>\n\n                <span class="option-description">Use this only for debugging purposes. Report about any known problems</span>\n            </div>\n\n            <div class="content-option">\n                <button id="resetSettings" class="option-button red">RESET SETTINGS</button>\n            </div>\n\n        </div>\n    </div>\n\n\n    \x3c!-- Menu --\x3e\n    \x3c!-- <div class="section">\n        <h2 class="section-title">Menu</h2>\n\n        <div class="section-content">\n\n            <div class="content-option">\n                <span class="option-title">Transparency</span>\n                <label class="switch-checkbox">\n                    <input id="_menuTransparency" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n        </div>\n    </div> --\x3e\n\n</div>';

    const Devtool_default = '<div class="menu-page" data-id="6">\n    <div class="page-title">Devtool</div>\n    <p class="page-description">Test Glotus Client and report about bugs!</p>\n\n\n    \x3c!-- myPlayer --\x3e\n    <div class="section">\n        <h2 class="section-title">myPlayer</h2>\n\n        <div class="section-content">\n\n            <div class="content-option">\n                <span class="option-title">Display player angle</span>\n                <label class="switch-checkbox">\n                    <input id="_displayPlayerAngle" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n        </div>\n    </div>\n\n\n    \x3c!-- Hitboxes --\x3e\n    <div class="section">\n        <h2 class="section-title">Hitboxes</h2>\n\n        <div class="section-content">\n\n            <div class="content-option">\n                <span class="option-title">Weapon hitbox</span>\n                <label class="switch-checkbox">\n                    <input id="_weaponHitbox" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Collision hitbox</span>\n                <label class="switch-checkbox">\n                    <input id="_collisionHitbox" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Placement hitbox</span>\n                <label class="switch-checkbox">\n                    <input id="_placementHitbox" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Possible placement</span>\n                <label class="switch-checkbox">\n                    <input id="_possiblePlacement" type="checkbox"></input>\n                    <span></span>\n                </label>\n            </div>\n        \n        </div>\n    </div>\n\n    \x3c!-- Statistics --\x3e\n    <div class="section">\n        <h2 class="section-title">Statistics</h2>\n\n        <div class="section-content small-section">\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Total kills: </span>\n                <span id="_totalKills" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Global kills with bots: </span>\n                <span id="_globalKills" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Deaths: </span>\n                <span id="_deaths" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Autosync: </span>\n                <span id="_autoSyncTimes" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Velocity tick: </span>\n                <span id="_velocityTickTimes" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">SSHammer: </span>\n                <span id="_spikeSyncHammerTimes" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Spike sync: </span>\n                <span id="_spikeSyncTimes" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">Spike tick: </span>\n                <span id="_spikeTickTimes" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">KBTrap: </span>\n                <span id="_knockbackTickTrapTimes" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">KBHammer: </span>\n                <span id="_knockbackTickHammerTimes" class="text-value">0</span>\n            </div>\n\n            <div class="content-option left-flex text">\n                <span class="option-title">KB Reg: </span>\n                <span id="_knockbackTickTimes" class="text-value">0</span>\n            </div>\n\n        </div>\n    </div>\n\n</div>';

    const Bots_default = '<div class="menu-page" data-id="5">\n    <div class="page-title">Bots</div>\n    <p class="page-description">Create bots, control them and dominate the entire server</p>\n\n    \x3c!-- Controller --\x3e\n    <div class="section">\n        <div class="section-title">Controller</div>\n\n        <div class="section-content">\n            <div class="content-option">\n                <span class="option-title">Follow cursor</span>\n                <label class="switch-checkbox">\n                    <input id="_followCursor" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Bots are going to follow your cursor instead of character</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Stop movement radius</span>\n                <label class="slider">\n                    <span class="slider-value"></span>\n                    <input id="_movementRadius" type="range" step="25" min="25" max="250">\n                </label>\n                <span class="option-description">Bots will stop movement at this radius</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Circle formation</span>\n                <label class="switch-checkbox">\n                    <input id="_circleFormation" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Bots will form a circle around you</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Circle rotation</span>\n                <label class="switch-checkbox">\n                    <input id="_circleRotation" type="checkbox"></input>\n                    <span></span>\n                </label>\n                <span class="option-description">Bots will move in a circular way around you</span>\n            </div>\n\n            <div class="content-option">\n                <span class="option-title">Circle radius</span>\n                <label class="slider">\n                    <span class="slider-value"></span>\n                    <input id="_circleRadius" type="range" step="25" min="50" max="600">\n                </label>\n            </div>\n        </div>\n\n        <div id="bot-container" class="section-content"></div>\n\n        <div class="content-option centered">\n            <button id="add-bot" class="option-button">Add Bot</button>\n        </div>\n    </div>\n\n</div>';

    const styles_default = '@import "https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;600;800&display=swap";\n\n* {\n    user-select: none;\n}\n\n/* Slightly lighter + bluish dark backgrounds */\nheader {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    height: 45px;\n    background: #16181c; /* was #121212 → lighter + hint of blue */\n    padding: 10px;\n    border-radius: 6px;\n}\n\nheader .page-title {\n    font-size: 2.3em;\n}\n\nheader #credits {\n    display: flex;\n    justify-content: space-between;\n    gap: 10px;\n    height: 45px;\n}\n\nheader #credits p {\n    margin-top: auto;\n}\n\nheader #logo {\n    display: block;\n    width: auto;\n    height: 100%;\n    scale: 1.2;\n}\n\nheader #close-button {\n    display: block;\n    fill: #b5b5b5; /* slightly lighter */\n    cursor: pointer;\n    width: auto;\n    height: 100%;\n    transition: fill 200ms;\n}\n\nheader #close-button:hover {\n    fill: #f0f0f0;\n}\n\n@keyframes ripple {\n    from {\n        opacity: 1;\n        transform: scale(0);\n    }\n    to {\n        opacity: 0;\n        transform: scale(0.7);\n    }\n}\n\n#navbar-container {\n    display: flex;\n    flex-direction: column;\n    background: #16181c; /* was #121212 */\n    padding: 10px;\n    border-radius: 6px;\n    row-gap: 3px;\n}\n\n#navbar-container .open-menu {\n    position: relative;\n    width: 8.5em;\n    height: 3.2em;\n    background: #101215; /* was #0d0d0d → slightly lighter + blue */\n    font-weight: 800;\n    font-size: 1.3em;\n    overflow: hidden;\n    transition: all 400ms;\n    display: flex;\n    justify-content: left;\n    align-items: center;\n    padding: 0px 25px;\n    border-radius: 3px;\n    border: 1px solid rgba(200, 210, 220, 0.08); /* cooler gray border */\n}\n\n.open-menu > span {\n    display: flex;\n    justify-content: left;\n    align-items: center;\n    gap: 10px;\n    transition: all 300ms;\n    pointer-events: none;\n}\n\n.open-menu:hover {\n    background: #3a3d42; /* was #3d3d3d → cooler tone */\n}\n\n.open-menu:hover span {\n    transform: translateY(-2px);\n}\n\n.open-menu.active {\n    background: #3a3d42;\n    pointer-events: none;\n}\n\n#navbar-container .open-menu.bottom-align {\n    margin-top: auto;\n}\n\n#navbar-container .open-menu .ripple {\n    position: absolute;\n    z-index: 5;\n    background: rgba(200, 215, 230, 0.4); /* slightly bluish white ripple */\n    top: 0;\n    left: 0;\n    border-radius: 50%;\n    opacity: 0;\n    animation: ripple 800ms;\n    pointer-events: none;\n}\n\n/* Animations unchanged */\n@keyframes toclose {\n    from {\n        opacity: 1;\n        transform: scale(1);\n    }\n    to {\n        opacity: 0;\n        transform: scale(0);\n    }\n}\n\n@keyframes toopen {\n    from {\n        opacity: 0;\n        transform: scale(0);\n    }\n    to {\n        opacity: 1;\n        transform: scale(1);\n    }\n}\n\n@keyframes appear {\n    from {\n        opacity: 0;\n    }\n    to {\n        opacity: 1;\n    }\n}\n\n#page-container {\n    width: 100%;\n    height: 100%;\n    overflow-y: scroll;\n}\n\n.menu-page {\n    background: #16181c; /* consistent background */\n    padding: 10px;\n    border-radius: 6px;\n    display: none;\n}\n\n.menu-page.opened {\n    display: block;\n}\n\n.menu-page .page-title {\n    font-size: 2.8em;\n}\n\n.menu-page > .section {\n    margin-top: 20px;\n    background: #101215; /* was #0d0d0d */\n    padding: 15px;\n    border-radius: 6px;\n}\n\n.menu-page > .section .section-title {\n    font-weight: 800;\n    font-size: 1.8em;\n    color: #a0a5aa; /* slightly lighter + bluish gray */\n    margin-bottom: 10px;\n}\n\n.section-content {\n    display: flex;\n    flex-direction: column;\n    gap: 5px;\n}\n\n.small-section {\n    gap: 0px;\n    font-size: 0.85rem;\n}\n\n.menu-page > .section .section-content.split {\n    display: flex;\n    justify-content: space-between;\n    flex-direction: row;\n    column-gap: 30px;\n}\n\n.menu-page > .section .section-content .content-split {\n    width: 50%;\n    display: flex;\n    flex-direction: column;\n    row-gap: 10px;\n}\n\n.menu-page > .section .section-content .content-option {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    min-height: 40px;\n    padding: 3px 10px;\n    transition: background 300ms;\n    border-radius: 8px;\n}\n\n.content-option:hover {\n    background: rgba(60, 65, 75, 0.25); /* cooler hover bg */\n}\n\n.option-description {\n    position: absolute;\n    z-index: 99;\n    visibility: hidden;\n    background: #282b30; /* was #2a2a2a → bluish dark */\n    padding: 8px;\n    border-radius: 6px;\n    font-weight: 600;\n    pointer-events: none;\n    max-width: 300px;\n}\n\n.description-show {\n    visibility: visible;\n}\n\n.menu-page > .section .content-option.centered {\n    display: flex;\n    justify-content: center;\n}\n\n.menu-page > .section .section-content .content-option .option-title {\n    font-weight: 800;\n    font-size: 1.4em;\n    color: #60656b; /* was #585858 → lighter + cooler */\n    transition: color 300ms;\n}\n\n.menu-page > .section .section-content .content-option .option-content {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    column-gap: 10px;\n}\n\n.menu-page > .section .section-content .content-option .disconnect-button {\n    width: 30px;\n    height: 30px;\n    cursor: pointer;\n    fill: rgba(130, 55, 60, 0.5); /* slightly softened */\n    transition: fill 300ms;\n}\n\n.menu-page > .section .section-content .content-option:hover .option-title {\n    color: #888c92; /* was #7e7d7d */\n}\n\n.menu-page > .section .section-content .content-option:hover .disconnect-button {\n    fill: #8a3636;\n}\n\n.menu-page > .section .section-content .content-option:hover .disconnect-button:hover {\n    fill: #983a3a;\n}\n\n.menu-page > .section .section-content .text {\n    display: flex;\n    justify-content: left;\n    gap: 10px;\n}\n\n.menu-page > .section .section-content .text .text-value {\n    color: #8e8888; /* slightly lighter */\n    font-weight: 800;\n    font-size: 1.5em;\n}\n\n.simplified {\n    font-weight: 600 !important;\n    font-size: 1.2em !important;\n    word-spacing: 2px;\n}\n\n.highlight {\n    color: #c0c5ca; /* cooler highlight */\n}\n\n.menu-page > .section .option-button {\n    /* width: 117px;\n    height: 45px; */\n    background: #2e3136; /* was #303030 → bluish dark */\n    border: 5px solid #24272b; /* was #262626 */\n    padding: 10px 30px;\n    border-radius: 6px;\n    font-weight: 800;\n    font-size: 1.1em;\n    color: #888c92;\n    transition: background 300ms, border-color 300ms;\n}\n\n\n#bot-container {\n    margin: 10px 0;\n}\n\n.menu-page > .section .option-button:hover {\n    background: #34383d;\n    border-color: #282b30;\n}\n\n.menu-page > .section .section-content .hotkeyInput {\n    width: 90px;\n    height: 40px;\n    background: #2e3136;\n    border: 5px solid #24272b;\n    border-radius: 6px;\n    font-weight: 800;\n    font-size: 1.1em;\n    color: #888c92;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    transition: background 300ms, border-color 300ms, color 300ms;\n}\n\n.menu-page > .section .section-content .hotkeyInput:hover {\n    background: #34383d;\n    border-color: #282b30;\n}\n\n.menu-page > .section .section-content .hotkeyInput.active {\n    background: #3a3e44;\n    border-color: #2c3035;\n}\n\n.red {\n    background: #853838!important;\n    border-color: #6f2f2f!important;\n    color: #c07878!important;\n}\n\n.red:hover {\n    background: #b24848!important;\n    border-color: #753131!important;\n}\n\n.red.active {\n    background: #9c4040!important;\n    border-color: #753131!important;\n}\n\n.menu-page > .section .section-content .switch-checkbox {\n    position: relative;\n    width: 90px;\n    height: 34px;\n}\n\n.menu-page > .section .section-content .switch-checkbox input {\n    width: 0;\n    height: 0;\n    opacity: 0;\n}\n\n.input {\n    outline: 3px solid transparent;\n    border: none;\n    text-align: center;\n    padding: 0;\n    margin: 0;\n    width: 225px;\n    height: 30px;\n    background: #2e3136;\n    box-shadow: 0px -6px 0px 0px #24272b inset;\n    border-radius: 6px;\n    font-weight: 800;\n    font-size: 1.1em;\n    color: #888c92;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    transition: background 300ms, border-color 300ms, color 300ms, outline 300ms;\n}\n\n.input:focus {\n    outline: 3px solid #757a80; /* cooler focus ring */\n}\n\n.menu-page > .section .section-content .switch-checkbox input:checked + span {\n    background: #3a3e44;\n    box-shadow: 0px -17px 0px 0px #2f3338 inset;\n}\n\n.menu-page > .section .section-content .switch-checkbox input:checked + span:before {\n    transform: translateX(50px) scale(0.6);\n    background: #888c92;\n}\n\n.menu-page > .section .section-content .switch-checkbox span {\n    position: absolute;\n    cursor: pointer;\n    top: 0;\n    left: 0;\n    bottom: 0;\n    right: 0;\n    width: 100%;\n    height: 100%;\n    display: flex;\n    align-items: center;\n    background: #2e3136;\n    border-radius: 6px;\n    box-shadow: 0px -17px 0px 0px #282b30 inset;\n}\n\n.menu-page > .section .section-content .switch-checkbox span:before {\n    position: absolute;\n    content: "";\n    transform: scale(0.6);\n    transition: transform 300ms;\n    width: 40px;\n    height: 40px;\n    border-radius: 6px;\n    background: #60656b;\n}\n\n.menu-page > .section .section-content input[id][type="color"] {\n    width: 60px;\n    height: 33.3333333333px;\n    outline: none;\n    border: none;\n    padding: 3px;\n    margin: 0;\n    background: #2e3136;\n    border-radius: 6px;\n    cursor: pointer;\n}\n\n.menu-page > .section .section-content .reset-color {\n    background: var(--data-color);\n    width: 10px;\n    height: 10px;\n    border-radius: 50%;\n}\n\n.menu-page > .section .section-content .slider {\n    position: relative;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 10px;\n}\n\n.menu-page > .section .section-content .slider input {\n    appearance: none;\n    outline: none;\n    cursor: pointer;\n    padding: 0;\n    margin: 0;\n    border: none;\n    width: 144px;\n    height: 30px;\n    background: #3a3e44;\n    box-shadow: 0px -15px 0px 0px #2f3338 inset;\n    border-radius: 6px;\n}\n\n.menu-page > .section .section-content .slider input::-webkit-slider-thumb {\n    -webkit-appearance: none;\n    transform: scale(0.7);\n    width: 30px;\n    height: 30px;\n    background: #888c92;\n    border-radius: 6px;\n}\n\n.menu-page > .section .section-content .slider .slider-value {\n    color: #60656b;\n    font-weight: 800;\n    font-size: 1.4em;\n    opacity: 0.4;\n}\n\n.left-flex {\n    display: flex;\n    justify-content: left !important;\n    gap: 10px;\n}\n\nhtml,\nbody {\n    margin: 0;\n    padding: 0;\n    scrollbar-width: thin;\n    scrollbar-track-color: #2e3136;\n    scrollbar-face-color: #24272b;\n    overflow: hidden;\n}\n\n* {\n    font-family: "Noto Sans", sans-serif;\n    color: #f2f4f6; /* slightly softer white */\n}\n\nh1, .page-title {\n    font-weight: 800;\n    margin: 0;\n}\n\nh2 {\n    margin: 0;\n}\n\np {\n    font-weight: 800;\n    font-size: 1.1rem;\n    margin: 0;\n    color: #c0c5ca; /* cooler light gray */\n}\n\nbutton {\n    border: none;\n    outline: none;\n    cursor: pointer;\n}\n\n#menu-container {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    width: 1280px;\n    height: 720px;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n}\n\n#menu-container.transparent #menu-wrapper {\n    background: rgba(10, 12, 16, 0.6); /* bluish transparent */\n    backdrop-filter: blur(3px);\n    box-shadow: 0 0 15px rgba(0, 10, 20, 0.4); /* subtle blue shadow */\n}\n\n#menu-container.transparent header,\n#menu-container.transparent .menu-page,\n#menu-container.transparent #navbar-container {\n    background: rgba(22, 24, 28, 0.59); /* matching transparent bg */\n}\n\n#menu-container.transparent .section {\n    background: rgba(16, 18, 21, 0.46);\n}\n\n#menu-container.transparent .open-menu {\n    background: rgba(16, 18, 21, 0.46);\n}\n\n#menu-container.transparent .open-menu:hover,\n#menu-container.transparent .open-menu.active {\n    background: rgba(58, 61, 66, 0.60);\n}\n\n#menu-wrapper {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n    row-gap: 5px;\n    width: 85%;\n    height: 85%;\n    padding: 10px;\n    border-radius: 6px;\n    background: #0a0c10; /* bluish black */\n}\n\n#menu-wrapper.toclose {\n    animation: 150ms ease-in toclose forwards;\n}\n\n#menu-wrapper.toopen {\n    animation: 150ms ease-in toopen forwards;\n}\n\nmain {\n    display: flex;\n    column-gap: 10px;\n    width: 100%;\n    height: calc(100% - 75px);\n}\n\n::-webkit-scrollbar {\n    width: 12px;\n}\n\n::-webkit-scrollbar-track {\n    background: #2e3136;\n    border-radius: 6px;\n}\n\n::-webkit-scrollbar-thumb {\n    background: #24272b;\n    border-radius: 6px;\n}\n\n.icon {\n    width: 50px;\n    height: 50px;\n}\n\n.small-icon {\n    width: 22px;\n    height: 22px;\n}';

    // Style de la ligne verrouillee du message de kill.
    const Seldoom_style = ".seldoom-locked{display:inline-block;padding:4px 10px;border-radius:6px;"
        + "background:rgba(245,217,81,.12);border:1px solid rgba(245,217,81,.45);"
        + "color:#f5d951;font-weight:700;letter-spacing:.4px;white-space:nowrap}";

    const Game_default = '#iframe-container {\n    position: absolute;\n    top: 0;\n    left: 0;\n    bottom: 0;\n    right: 0;\n    width: 100%;\n    height: 100%;\n    border: none;\n    outline: none;\n    z-index: 10;\n}\n\n#promoImgHolder,\n.menuHeader,\n.menuText,\n#guideCard,\n#altServer,\n#gameName,\n#pingDisplay,\n#partyButton,\n#onetrust-consent-sdk,\n.adMenuCard,\n#topInfoHolder > div:not([id]):not([class]),\n#touch-controls-fullscreen,\n#altcha,\n#joinPartyButton {\n    display: none!important;\n}\n\n.menuCard {\n    box-shadow: none;\n}\n\n#setupCard {\n    display: flex;\n    flex-direction: column;\n    gap: 12px;\n    background: #6d6d6d77;\n    max-height: auto;\n    width: 280px;\n}\n\n#setupCard > * {\n    margin: 0!important;\n}\n\n#linksContainer2 {\n    background: #6d6d6d77;\n}\n\n#bottomContainer {\n    bottom: 20px;\n}\n\n#topInfoHolder {\n    display: flex;\n    flex-direction: column;\n    justify-content: right;\n    align-items: flex-end;\n    gap: 10px;\n}\n\n#killCounter, #totalKillCounter {\n    position: static;\n    margin: 0;\n    background-image: url(../img/icons/skull.png);\n}\n\n.actionBarItem {\n    position: relative;\n}\n\n.itemCounter {\n    position: absolute;\n    top: 3px;\n    right: 3px;\n    font-size: 0.95em;\n    color: white;\n    text-shadow: #3d3f42 2px 0px 0px, #3d3f42 1.75517px 0.958851px 0px, #3d3f42 1.0806px 1.68294px 0px, #3d3f42 0.141474px 1.99499px 0px, #3d3f42 -0.832294px 1.81859px 0px, #3d3f42 -1.60229px 1.19694px 0px, #3d3f42 -1.97998px 0.28224px 0px, #3d3f42 -1.87291px -0.701566px 0px, #3d3f42 -1.30729px -1.5136px 0px, #3d3f42 -0.421592px -1.95506px 0px, #3d3f42 0.567324px -1.91785px 0px, #3d3f42 1.41734px -1.41108px 0px, #3d3f42 1.92034px -0.558831px 0px;\n}\n\n.itemCounter.hidden {\n    display: none;\n}\n\n#glotusStats {\n    position: absolute;\n    color: rgb(221, 221, 221);\n    font: 13px "Hammersmith One";\n    bottom: 210px;\n    left: 20px;\n\n    display: flex;\n    flex-direction: column;\n    gap: 5px;\n}\n\n.hidden {\n    display: none!important;\n}\n\n#chatLog {\n    position: absolute;\n    top: 65px;\n    left: 10px;\n\n    width: 380px;\n    height: 180px;\n\n    background: rgba(10, 12, 16, 0.6);\n    padding: 10px;\n    color: #f2f4f6;\n    border-radius: 6px;\n\n    display: flex;\n    flex-direction: column;\n}\n\n#chatLogHeader {\n    font-size: 1.8rem;\n    margin: 0 0 5px 0;\n    flex-shrink: 0;\n}\n\n#messageContainer {\n    flex: 1;\n    overflow-y: auto;\n    overflow-x: hidden;\n}\n\n#messageContainer::-webkit-scrollbar {\n    width: 6px;\n}\n\n#messageContainer::-webkit-scrollbar-track {\n    background: #4c4f55;\n    border-radius: 6px;\n}\n\n#messageContainer::-webkit-scrollbar-thumb {\n    background: #303338;\n    border-radius: 6px;\n}\n\n.logMessage {\n    display: flex;\n    gap: 8px;\n    align-items: flex-start;\n}\n\n.logMessage span {\n    word-break: break-word;\n    overflow-wrap: anywhere;\n}\n\n.logMessage .darken {\n    white-space: nowrap;\n    flex-shrink: 0;\n}\n\n.logMessage .log,\n.logMessage .warn,\n.logMessage .error {\n    flex: 1;\n    min-width: 0;\n}';

    const Store_default = "#storeContainer {\n    display: flex;\n    flex-direction: column;\n    gap: 10px;\n    max-width: 400px;\n    width: 100%;\n\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%) scale(0.9);\n}\n\n#toggleStoreType {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    padding: 10px;\n    background-color: rgba(0, 0, 0, 0.15);\n    color: #fff;\n    border-radius: 4px;\n    cursor: pointer;\n    font-size: 20px;\n    pointer-events: all;\n}\n\n#itemHolder {\n    background-color: rgba(0, 0, 0, 0.15);\n    max-height: 200px;\n    height: 100%;\n    padding: 10px;\n    overflow-y: scroll;\n    border-radius: 4px;\n    pointer-events: all;\n    scrollbar-width: none;\n}\n\n#itemHolder::-webkit-scrollbar {\n    display: none;\n    width: 0;\n    height: 0;\n    background: transparent;\n}\n\n.storeItemContainer {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    padding: 5px;\n    height: 50px;\n    box-sizing: border-box;\n    overflow: hidden;\n}\n\n.storeHat {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    width: 45px;\n    height: 45px;\n    margin-top: -5px;\n    pointer-events: none;\n}\n\n.storeItemName {\n    color: #fff;\n    font-size: 20px;\n}\n\n.equipButton {\n    margin-left: auto;\n    color: #80eefc;\n    cursor: pointer;\n    font-size: 35px;\n}";

    const Hats = {
        0: {
            index: 0,
            id: 0,
            name: "Unequip",
            dontSell: !0,
            price: 0,
            scale: 0,
            description: "None"
        },
        45: {
            index: 1,
            id: 45,
            name: "Shame!",
            dontSell: !0,
            price: 0,
            scale: 120,
            description: "hacks are for losers"
        },
        51: {
            index: 2,
            id: 51,
            name: "Moo Cap",
            price: 0,
            scale: 120,
            description: "coolest mooer around"
        },
        50: {
            index: 3,
            id: 50,
            name: "Apple Cap",
            price: 0,
            scale: 120,
            description: "apple farms remembers"
        },
        28: {
            index: 4,
            id: 28,
            name: "Moo Head",
            price: 0,
            scale: 120,
            description: "no effect"
        },
        29: {
            index: 5,
            id: 29,
            name: "Pig Head",
            price: 0,
            scale: 120,
            description: "no effect"
        },
        30: {
            index: 6,
            id: 30,
            name: "Fluff Head",
            price: 0,
            scale: 120,
            description: "no effect"
        },
        36: {
            index: 7,
            id: 36,
            name: "Pandou Head",
            price: 0,
            scale: 120,
            description: "no effect"
        },
        37: {
            index: 8,
            id: 37,
            name: "Bear Head",
            price: 0,
            scale: 120,
            description: "no effect"
        },
        38: {
            index: 9,
            id: 38,
            name: "Monkey Head",
            price: 0,
            scale: 120,
            description: "no effect"
        },
        44: {
            index: 10,
            id: 44,
            name: "Polar Head",
            price: 0,
            scale: 120,
            description: "no effect"
        },
        35: {
            index: 11,
            id: 35,
            name: "Fez Hat",
            price: 0,
            scale: 120,
            description: "no effect"
        },
        42: {
            index: 12,
            id: 42,
            name: "Enigma Hat",
            price: 0,
            scale: 120,
            description: "join the enigma army"
        },
        43: {
            index: 13,
            id: 43,
            name: "Blitz Hat",
            price: 0,
            scale: 120,
            description: "hey everybody i'm blitz"
        },
        49: {
            index: 14,
            id: 49,
            name: "Bob XIII Hat",
            price: 0,
            scale: 120,
            description: "like and subscribe"
        },
        57: {
            index: 15,
            id: 57,
            name: "Pumpkin",
            price: 50,
            scale: 120,
            description: "Spooooky"
        },
        8: {
            index: 16,
            id: 8,
            name: "Bummle Hat",
            price: 100,
            scale: 120,
            description: "no effect"
        },
        2: {
            index: 17,
            id: 2,
            name: "Straw Hat",
            price: 500,
            scale: 120,
            description: "no effect"
        },
        15: {
            index: 18,
            id: 15,
            name: "Winter Cap",
            price: 600,
            scale: 120,
            description: "allows you to move at normal speed in snow",
            coldM: 1
        },
        5: {
            index: 19,
            id: 5,
            name: "Cowboy Hat",
            price: 1e3,
            scale: 120,
            description: "no effect"
        },
        4: {
            index: 20,
            id: 4,
            name: "Ranger Hat",
            price: 2e3,
            scale: 120,
            description: "no effect"
        },
        18: {
            index: 21,
            id: 18,
            name: "Explorer Hat",
            price: 2e3,
            scale: 120,
            description: "no effect"
        },
        31: {
            index: 22,
            id: 31,
            name: "Flipper Hat",
            price: 2500,
            scale: 120,
            description: "have more control while in water",
            watrImm: !0
        },
        1: {
            index: 23,
            id: 1,
            name: "Marksman Cap",
            price: 3e3,
            scale: 120,
            description: "increases arrow speed and range",
            aMlt: 1.3
        },
        10: {
            index: 24,
            id: 10,
            name: "Bush Gear",
            price: 3e3,
            scale: 160,
            description: "allows you to disguise yourself as a bush"
        },
        48: {
            index: 25,
            id: 48,
            name: "Halo",
            price: 3e3,
            scale: 120,
            description: "no effect"
        },
        6: {
            index: 26,
            id: 6,
            name: "Soldier Helmet",
            price: 4e3,
            scale: 120,
            description: "reduces damage taken but slows movement",
            spdMult: .94,
            dmgMult: .75
        },
        23: {
            index: 27,
            id: 23,
            name: "Anti Venom Gear",
            price: 4e3,
            scale: 120,
            description: "makes you immune to poison",
            poisonRes: 1
        },
        13: {
            index: 28,
            id: 13,
            name: "Medic Gear",
            price: 5e3,
            scale: 110,
            description: "slowly regenerates health over time",
            healthRegen: 3
        },
        9: {
            index: 29,
            id: 9,
            name: "Miners Helmet",
            price: 5e3,
            scale: 120,
            description: "earn 1 extra gold per resource",
            extraGold: 1
        },
        32: {
            index: 30,
            id: 32,
            name: "Musketeer Hat",
            price: 5e3,
            scale: 120,
            description: "reduces cost of projectiles",
            projCost: .5
        },
        7: {
            index: 31,
            id: 7,
            name: "Bull Helmet",
            price: 6e3,
            scale: 120,
            description: "increases damage done but drains health",
            healthRegen: -5,
            dmgMultO: 1.5,
            spdMult: .96
        },
        22: {
            index: 32,
            id: 22,
            name: "Emp Helmet",
            price: 6e3,
            scale: 120,
            description: "turrets won't attack but you move slower",
            antiTurret: 1,
            spdMult: .7
        },
        12: {
            index: 33,
            id: 12,
            name: "Booster Hat",
            price: 6e3,
            scale: 120,
            description: "increases your movement speed",
            spdMult: 1.16
        },
        26: {
            index: 34,
            id: 26,
            name: "Barbarian Armor",
            price: 8e3,
            scale: 120,
            description: "knocks back enemies that attack you",
            dmgK: .6
        },
        21: {
            index: 35,
            id: 21,
            name: "Plague Mask",
            price: 1e4,
            scale: 120,
            description: "melee attacks deal poison damage",
            poisonDmg: 5,
            poisonTime: 6
        },
        46: {
            index: 36,
            id: 46,
            name: "Bull Mask",
            price: 1e4,
            scale: 120,
            description: "bulls won't target you unless you attack them",
            bullRepel: 1
        },
        14: {
            index: 37,
            id: 14,
            name: "Windmill Hat",
            topSprite: !0,
            price: 1e4,
            scale: 120,
            description: "generates points while worn",
            pps: 1.5
        },
        11: {
            index: 38,
            id: 11,
            name: "Spike Gear",
            topSprite: !0,
            price: 1e4,
            scale: 120,
            description: "deal damage to players that damage you",
            dmg: .45
        },
        53: {
            index: 39,
            id: 53,
            name: "Turret Gear",
            topSprite: !0,
            price: 1e4,
            scale: 120,
            description: "you become a walking turret",
            turret: {
                projectile: 1,
                range: 700,
                rate: 2500
            },
            spdMult: .7,
            knockback: 60
        },
        20: {
            index: 40,
            id: 20,
            name: "Samurai Armor",
            price: 12e3,
            scale: 120,
            description: "increased attack speed and fire rate",
            atkSpd: .78
        },
        58: {
            index: 41,
            id: 58,
            name: "Dark Knight",
            price: 12e3,
            scale: 120,
            description: "restores health when you deal damage",
            healD: .4
        },
        27: {
            index: 42,
            id: 27,
            name: "Scavenger Gear",
            price: 15e3,
            scale: 120,
            description: "earn double points for each kill",
            kScrM: 2
        },
        40: {
            index: 43,
            id: 40,
            name: "Tank Gear",
            price: 15e3,
            scale: 120,
            description: "increased damage to buildings but slower movement",
            spdMult: .3,
            bDmg: 3.3
        },
        52: {
            index: 44,
            id: 52,
            name: "Thief Gear",
            price: 15e3,
            scale: 120,
            description: "steal half of a players gold when you kill them",
            goldSteal: .5
        },
        55: {
            index: 45,
            id: 55,
            name: "Bloodthirster",
            price: 2e4,
            scale: 120,
            description: "Restore Health when dealing damage. And increased damage",
            healD: .25,
            dmgMultO: 1.2
        },
        56: {
            index: 46,
            id: 56,
            name: "Assassin Gear",
            price: 2e4,
            scale: 120,
            description: "Go invisible when not moving. Can't eat. Increased speed",
            noEat: !0,
            spdMult: 1.1,
            invisTimer: 1e3
        }
    }, Accessories = {
        0: {
            index: 0,
            id: 0,
            name: "Unequip",
            dontSell: !0,
            price: 0,
            scale: 0,
            xOffset: 0,
            description: "None"
        },
        12: {
            index: 1,
            id: 12,
            name: "Snowball",
            price: 1e3,
            scale: 105,
            xOffset: 18,
            description: "no effect"
        },
        9: {
            index: 2,
            id: 9,
            name: "Tree Cape",
            price: 1e3,
            scale: 90,
            description: "no effect"
        },
        10: {
            index: 3,
            id: 10,
            name: "Stone Cape",
            price: 1e3,
            scale: 90,
            description: "no effect"
        },
        3: {
            index: 4,
            id: 3,
            name: "Cookie Cape",
            price: 1500,
            scale: 90,
            description: "no effect"
        },
        8: {
            index: 5,
            id: 8,
            name: "Cow Cape",
            price: 2e3,
            scale: 90,
            description: "no effect"
        },
        11: {
            index: 6,
            id: 11,
            name: "Monkey Tail",
            price: 2e3,
            scale: 97,
            xOffset: 25,
            description: "Super speed but reduced damage",
            spdMult: 1.35,
            dmgMultO: .2
        },
        17: {
            index: 7,
            id: 17,
            name: "Apple Basket",
            price: 3e3,
            scale: 80,
            xOffset: 12,
            description: "slowly regenerates health over time",
            healthRegen: 1
        },
        6: {
            index: 8,
            id: 6,
            name: "Winter Cape",
            price: 3e3,
            scale: 90,
            description: "no effect"
        },
        4: {
            index: 9,
            id: 4,
            name: "Skull Cape",
            price: 4e3,
            scale: 90,
            description: "no effect"
        },
        5: {
            index: 10,
            id: 5,
            name: "Dash Cape",
            price: 5e3,
            scale: 90,
            description: "no effect"
        },
        2: {
            index: 11,
            id: 2,
            name: "Dragon Cape",
            price: 6e3,
            scale: 90,
            description: "no effect"
        },
        1: {
            index: 12,
            id: 1,
            name: "Super Cape",
            price: 8e3,
            scale: 90,
            description: "no effect"
        },
        7: {
            index: 13,
            id: 7,
            name: "Troll Cape",
            price: 8e3,
            scale: 90,
            description: "no effect"
        },
        14: {
            index: 14,
            id: 14,
            name: "Thorns",
            price: 1e4,
            scale: 115,
            xOffset: 20,
            description: "no effect"
        },
        15: {
            index: 15,
            id: 15,
            name: "Blockades",
            price: 1e4,
            scale: 95,
            xOffset: 15,
            description: "no effect"
        },
        20: {
            index: 16,
            id: 20,
            name: "Devils Tail",
            price: 1e4,
            scale: 95,
            xOffset: 20,
            description: "no effect"
        },
        16: {
            index: 17,
            id: 16,
            name: "Sawblade",
            price: 12e3,
            scale: 90,
            spin: !0,
            xOffset: 0,
            description: "deal damage to players that damage you",
            dmg: .15
        },
        13: {
            index: 18,
            id: 13,
            name: "Angel Wings",
            price: 15e3,
            scale: 138,
            xOffset: 22,
            description: "slowly regenerates health over time",
            healthRegen: 3
        },
        19: {
            index: 19,
            id: 19,
            name: "Shadow Wings",
            price: 15e3,
            scale: 138,
            xOffset: 22,
            description: "increased movement speed",
            spdMult: 1.1
        },
        18: {
            index: 20,
            id: 18,
            name: "Blood Wings",
            price: 2e4,
            scale: 178,
            xOffset: 26,
            description: "restores health when you deal damage",
            healD: .2
        },
        21: {
            index: 21,
            id: 21,
            name: "Corrupt X Wings",
            price: 2e4,
            scale: 178,
            xOffset: 26,
            description: "deal damage to players that damage you",
            dmg: .25
        }
    }, store = [ Hats, Accessories ];

    const DataHandler = new class {
        isWeaponType(type) {
            return type <= 1;
        }
        isItemType(type) {
            return type >= 2;
        }
        getStore(type) {
            return store[type];
        }
        getStoreItem(type, id) {
            switch (type) {
              case 0:
                return Hats[id];

              case 1:
                return Accessories[id];

              default:
                throw Error(`getStoreItem Error: type "${type}" is not defined`);
            }
        }
        getProjectile(id) {
            return Projectiles[this.getWeapon(id).projectile];
        }
        getWeapon(id) {
            return Weapons[id];
        }
        getItem(id) {
            return Items[id];
        }
        isWeapon(id) {
            return this.getWeapon(id) !== void 0;
        }
        isItem(id) {
            return Items[id] !== void 0;
        }
        isPrimary(id) {
            return id != null && this.getWeapon(id).itemType === 0;
        }
        isSecondary(id) {
            return id != null && this.getWeapon(id).itemType === 1;
        }
        isMelee(id) {
            return id != null && "damage" in this.getWeapon(id);
        }
        isAttackable(id) {
            return id != null && "range" in this.getWeapon(id);
        }
        isShootable(id) {
            return id != null && "projectile" in this.getWeapon(id);
        }
        isPlaceable(id) {
            return id !== -1 && "itemGroup" in Items[id];
        }
        isHealable(id) {
            return "restore" in Items[id];
        }
        isDestroyable(id) {
            return "health" in Items[id];
        }
        canMoveOnTop(id) {
            return "ignoreCollision" in Items[id];
        }
    }, DataHandler_default = DataHandler;

    class ObjectItem {
        id;
        pos;
        angle;
        scale=0;
        constructor(id, x, y, angle, scale) {
            this.id = id, this.pos = {
                current: new Vector_default(x, y)
            }, this.angle = angle, this.scale = scale;
        }
        get hitScale() {
            return this.scale;
        }
    }

    class Resource extends ObjectItem {
        type;
        layer;
        constructor(id, x, y, angle, scale, type) {
            super(id, x, y, angle, scale);
            this.type = type, this.layer = type === 0 ? 3 : type === 2 ? 0 : 2;
        }
        formatScale(scaleMult = 1) {
            let reduceScale = this.type === 0 || this.type === 1 ? .6 * scaleMult : 1;
            return this.scale * reduceScale;
        }
        get collisionScale() {
            return this.formatScale();
        }
        get placementScale() {
            return this.formatScale(.6);
        }
        get isCactus() {
            return this.type === 1 && pointInDesert(this.pos.current);
        }
        getDamage() {
            if (this.isCactus) {
                return 35;
            }
            return 0;
        }
    }

    class PlayerObject extends ObjectItem {
        type;
        ownerID;
        collisionDivider;
        health;
        tempHealth;
        maxHealth;
        reload=-1;
        maxReload=-1;
        isDestroyable;
        destroyingTick=0;
        canBeDestroyed=!1;
        trapActivated=!1;
        wasTeammate=!1;
        seenPlacement=!1;
        layer;
        itemGroup;
        projectile=null;
        constructor(id, x, y, angle, scale, type, ownerID) {
            super(id, x, y, angle, scale);
            this.type = type, this.ownerID = ownerID;
            let item = Items[type];
            if (this.collisionDivider = "colDiv" in item ? item.colDiv : 1, this.health = "health" in item ? item.health : 1 / 0,
            this.tempHealth = this.health, this.maxHealth = this.health, this.isDestroyable = this.maxHealth !== 1 / 0,
            item.id === 17) {
                this.reload = Math.ceil(item.shootRate / 111), this.maxReload = this.reload;
            }
            this.layer = ItemGroups[item.itemGroup].layer, this.itemGroup = item.itemGroup;
        }
        formatScale(placeCollision = !1) {
            return this.scale * (placeCollision ? 1 : this.collisionDivider);
        }
        get collisionScale() {
            return this.formatScale();
        }
        get placementScale() {
            let item = Items[this.type];
            if (item.id === 21) {
                return item.blocker;
            }
            return this.scale;
        }
        get isSpike() {
            return this.itemGroup === 2;
        }
        getDamage() {
            if (this.isSpike) {
                let type = this.type;
                return DataHandler_default.getItem(type).damage;
            }
            return 0;
        }
    }

    class Entity {
        id=-1;
        pos={
            previous: new Vector_default,
            current: new Vector_default,
            future: new Vector_default
        };
        angle=0;
        scale=0;
        speed=0;
        move_dir=0;
        setFuturePosition() {
            let {previous: previous, current: current, future: future} = this.pos, distance = previous.distance(current);
            this.speed = distance;
            let angle = previous.angle(current);
            this.move_dir = angle, future.setVec(current.addDirection(angle, distance));
        }
        get collisionScale() {
            return this.scale;
        }
        get hitScale() {
            return this.scale * 1.8;
        }
        client;
        constructor(client) {
            this.client = client;
        }
        getFuturePosition(speed) {
            return this.pos.current.copy().add(Vector_default.fromAngle(this.move_dir, speed));
        }
        colliding(object, radius) {
            let {previous: a0, current: a1, future: a2} = this.pos, b0 = object.pos.current;
            return a0.distance(b0) <= radius || a1.distance(b0) <= radius || a2.distance(b0) <= radius;
        }
        collidingObject(object, addRadius = 0, checkType = 3) {
            let {previous: a0, current: a1, future: a2} = this.pos, b0 = object.pos.current, radius = this.collisionScale + object.collisionScale + addRadius;
            return !!(checkType & 4) && a0.distance(b0) <= radius || !!(checkType & 2) && a1.distance(b0) <= radius || !!(checkType & 1) && a2.distance(b0) <= radius;
        }
        collidingSimple(entity, range, tempPos = this.pos.current) {
            let pos1 = tempPos, pos2 = entity.pos.current;
            return pos1.distance(pos2) <= range;
        }
        collidingEntity(entity, range, checkBased = !1, prev = !0) {
            let {previous: a0, current: a1, future: a2} = this.pos, {previous: b0, current: b1, future: b2} = entity.pos;
            if (checkBased) {
                return prev && a0.distance(b0) <= range || a1.distance(b1) <= range || a2.distance(b2) <= range;
            }
            return a0.distance(b0) <= range || a0.distance(b1) <= range || a0.distance(b2) <= range || a1.distance(b0) <= range || a1.distance(b1) <= range || a1.distance(b2) <= range || a2.distance(b0) <= range || a2.distance(b1) <= range || a2.distance(b2) <= range;
        }
        runningAwayFrom(entity, angle) {
            if (angle === null) {
                return !1;
            }
            let pos1 = this.pos.current, pos2 = entity.pos.current, angleTo = pos1.angle(pos2);
            if (getAngleDist(angle, angleTo) <= Math.PI / 2) {
                return !1;
            }
            return !0;
        }
    }

    const Entity_default = Entity;

    class EnemyManager {
        client;
        dangerousEnemies=[];
        _nearestEnemy=[ null, null ];
        nearestDangerAnimal=null;
        nearestTrap=null;
        nearestCollider=null;
        secondNearestCollider=null;
        nearestEnemySpikeCollider=null;
        spikeCollider=null;
        enemySpikeCollider=null;
        nearestTurretEntity=null;
        detectedEnemy=!1;
        dangerWithoutSoldier=!1;
        detectedDangerEnemy=!1;
        nearestTrappedEnemy=null;
        previousTrappedEnemy=null;
        nearestPlayerObject=null;
        secondNearestPlayerObject=null;
        nearestObject=null;
        nearestEnemyObject=null;
        secondNearestEnemyObject=null;
        nearestSpike=null;
        willCollideSpike=!1;
        collidingSpike=!1;
        nearestSpikePlacerAngle=null;
        prevNearestSpikePlacerAngle=null;
        nearestEnemyToNearestEnemy=null;
        enemyCanPlaceSpike=!1;
        possibleToKnockback=!1;
        potentialSpikeKnockbackDamage=0;
        potentialSpikeDamage=0;
        potentialDamage=0;
        primaryDamage=0;
        detectedDanger=!1;
        reverseInsta=!1;
        rangedBowInsta=!1;
        spikeSyncThreat=!1;
        velocityTickThreat=!1;
        nearestLowEntity=null;
        nearestEnemyPush=null;
        nearestPushSpike=null;
        nearestLowHPObjectPrev=null;
        nearestLowHPObject=null;
        nearestSyncEnemy=null;
        constructor(client) {
            this.client = client;
        }
        preReset() {
            this._nearestEnemy[0] = null, this._nearestEnemy[1] = null, this.nearestDangerAnimal = null,
            this.nearestLowEntity = null;
        }
        reset() {
            this.nearestEnemyToNearestEnemy = null, this.willCollideSpike = !1, this.collidingSpike = !1,
            this.prevNearestSpikePlacerAngle = this.nearestSpikePlacerAngle, this.nearestSpikePlacerAngle = null,
            this.dangerousEnemies.length = 0, this.nearestTrap = null, this.nearestCollider = null,
            this.nearestEnemySpikeCollider = null, this.spikeCollider = null, this.enemySpikeCollider = null,
            this.nearestTurretEntity = null, this.detectedEnemy = !1, this.dangerWithoutSoldier = !1,
            this.detectedDangerEnemy = !1, this.previousTrappedEnemy = this.nearestTrappedEnemy,
            this.nearestTrappedEnemy = null, this.nearestPlayerObject = null, this.nearestObject = null,
            this.secondNearestPlayerObject = null, this.nearestEnemyObject = null, this.secondNearestEnemyObject = null,
            this.nearestSpike = null, this.enemyCanPlaceSpike = !1, this.possibleToKnockback = !1,
            this.velocityTickThreat = !1, this.potentialSpikeKnockbackDamage = 0, this.potentialSpikeDamage = 0,
            this.potentialDamage = 0, this.detectedDanger = !1, this.reverseInsta = !1,
            this.rangedBowInsta = !1, this.spikeSyncThreat = !1, this.nearestEnemyPush = null,
            this.nearestPushSpike = null, this.nearestLowHPObjectPrev = this.nearestLowHPObject,
            this.nearestLowHPObject = null, this.nearestSyncEnemy = null, this.primaryDamage = 0;
        }
        get wasTrappedEnemy() {
            let enemy = this.previousTrappedEnemy;
            if (enemy !== null && this.nearestTrappedEnemy === null) {
                return enemy;
            }
            return null;
        }
        get nearestPlaceSpikeAngle() {
            let prevAngle = this.prevNearestSpikePlacerAngle, currAngle = this.nearestSpikePlacerAngle;
            if (prevAngle === null && currAngle !== null) {
                return currAngle;
            }
            return null;
        }
        get nearestEnemy() {
            return this._nearestEnemy[0];
        }
        get nearestAnimal() {
            return this._nearestEnemy[1];
        }
        get canSpikeSync() {
            return this.nearestPlaceSpikeAngle !== null && this.client.ObjectManager.isDestroyedObject();
        }
        isNear(enemy, nearest, owner = this.client.myPlayer) {
            if (nearest === null || enemy === nearest) {
                return !0;
            }
            let a0 = owner.pos.current, distance1 = a0.distanceDefault(enemy.pos.current), distance2 = a0.distanceDefault(nearest.pos.current);
            return distance1 < distance2;
        }
        get nearestEntity() {
            let target1 = this.nearestEnemy, target2 = this.nearestAnimal;
            if (target1 === null) {
                return target2;
            }
            return this.isNear(target1, target2) ? target1 : target2;
        }
        instaThreat() {
            return this.velocityTickThreat || this.reverseInsta || this.rangedBowInsta || this.primaryDamage + this.potentialSpikeKnockbackDamage >= 100;
        }
        shouldIgnoreModule() {
            return this.instaThreat() || this.detectedDangerEnemy || this.spikeSyncThreat;
        }
        nearestEnemyInRangeOf(range, target) {
            let enemy = target || this.nearestEnemy;
            return enemy !== null && this.client.myPlayer.collidingEntity(enemy, range);
        }
        handleDanger(enemy) {
            let danger = enemy.canPossiblyInstakill();
            if (enemy.prevDanger = enemy.danger, enemy.danger = danger, enemy.canPlaceSpikeObject) {
                this.potentialSpikeDamage = Math.max(this.potentialSpikeDamage, enemy.spikeDamage);
            }
            if (this.potentialDamage += enemy.potentialDamage, this.primaryDamage = Math.max(enemy.primaryDamage, this.primaryDamage),
            enemy.prevDanger !== enemy.danger && enemy.danger >= 2) {
                this.detectedDanger = !0;
            }
            if (enemy.velocityTicking) {
                this.velocityTickThreat = !0;
            }
            if (enemy.reverseInsta) {
                this.reverseInsta = !0;
            }
            if (enemy.rangedBowInsta) {
                this.rangedBowInsta = !0;
            }
            if (enemy.spikeSyncThreat) {
                this.spikeSyncThreat = !0;
            }
        }
        checkCollision(target, isOwner = !1) {
            target.isTrapped = !1, target.trappedInPrev = target.trappedIn, target.trappedIn = null;
            let {ObjectManager: ObjectManager, PlayerManager: PlayerManager, myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client, pos1 = myPlayer.pos.current, pos2 = target.pos.current, distanceToTarget = pos1.distance(pos2), angleToTarget = pos1.angle(pos2);
            ObjectManager.grid2D.query(target.pos.current.x, target.pos.current.y, 3, id => {
                let object = ObjectManager.objects.get(id), pos3 = object.pos.current, isPlayerObject = object instanceof PlayerObject, isCactus = !isPlayerObject && object.isCactus, isSpike = isPlayerObject && object.itemGroup === 2, isEnemyObject = !isPlayerObject || PlayerManager.isEnemyByID(object.ownerID, target), isEnemyObjectToMyPlayer = !isPlayerObject || PlayerManager.isEnemyByID(object.ownerID, myPlayer), collidingObject = target.collidingObject(object, 1), collidingCurrent = target.collidingObject(object, 1, 1);
                if (isPlayerObject && !isEnemyObject) {
                    object.wasTeammate = !0;
                }
                if (isPlayerObject && isEnemyObject && object.type === 15) {
                    if (collidingObject) {
                        if (!isOwner) {
                            if (this.isNear(target, this.nearestTrappedEnemy)) {
                                this.nearestTrappedEnemy = target;
                            }
                            if (!isEnemyObjectToMyPlayer && this.isNear(target, this.nearestEnemyPush)) {
                                this.nearestEnemyPush = target;
                            }
                        }
                        if (target.isTrapped = !0, target.hatID === 40) {
                            target.usesTank = !0;
                        }
                        if (this.isNear(object, target.trappedIn)) {
                            target.trappedIn = object;
                        }
                        if (isOwner && this.isNear(object, this.nearestTrap)) {
                            this.nearestTrap = object;
                        }
                    }
                    if (collidingCurrent || !object.seenPlacement && !object.wasTeammate) {
                        object.trapActivated = !0;
                    }
                }
                if (isOwner && isPlayerObject && object.type === 22 && collidingCurrent) {
                    myPlayer.teleportPos.setVec(pos1), myPlayer.teleported = !0;
                }
                if (isPlayerObject && object.isDestroyable) {
                    if (object.destroyingTick !== ModuleHandler.tickCount) {
                        object.canBeDestroyed = !1, object.tempHealth = object.health;
                    }
                    let damage = target.getMaxBuildingDamage(object, !0), canSee = !isEnemyObject || object.type !== 15 || isEnemyObject && object.type === 15 && object.trapActivated;
                    if (damage !== null && canSee) {
                        if (object.destroyingTick = ModuleHandler.tickCount, object.tempHealth -= damage,
                        object.tempHealth <= 0) {
                            object.canBeDestroyed = !0;
                        }
                    }
                }
                if (isOwner) {
                    if (isEnemyObject && isPlayerObject && object.isDestroyable) {
                        if (object.type === 15 || object.type === 16 || object.itemGroup === 2) {
                            if (this.isNear(object, this.nearestEnemyObject)) {
                                this.secondNearestEnemyObject = this.nearestEnemyObject, this.nearestEnemyObject = object;
                            }
                            if (object !== this.nearestEnemyObject && this.isNear(object, this.secondNearestEnemyObject)) {
                                this.secondNearestEnemyObject = object;
                            }
                        }
                        if (object.itemGroup === 2 && this.isNear(object, this.nearestSpike)) {
                            this.nearestSpike = object;
                        }
                    }
                    if (this.isNear(object, this.nearestObject)) {
                        this.nearestObject = object;
                    }
                    if (isPlayerObject && object.isDestroyable) {
                        if (this.isNear(object, this.nearestPlayerObject)) {
                            this.secondNearestPlayerObject = this.nearestPlayerObject, this.nearestPlayerObject = object;
                        }
                        if (object !== this.nearestPlayerObject && this.isNear(object, this.secondNearestPlayerObject)) {
                            this.secondNearestPlayerObject = object;
                        }
                    }
                    if (!this.willCollideSpike && isEnemyObject && (isSpike || isCactus) && target.collidingObject(object, 70)) {
                        this.willCollideSpike = !0;
                    }
                    if (isEnemyObject && (isSpike || isCactus) && target.colliding(object, target.collisionScale + object.collisionScale + 1)) {
                        this.collidingSpike = !0, this.potentialSpikeDamage = Math.max(this.potentialSpikeDamage, object.getDamage());
                    }
                    let isAdditional = isPlayerObject && object.type === 16;
                    if (isEnemyObject && (isSpike || isCactus || isAdditional) && target.collidingObject(object, 150)) {
                        if (this.isNear(object, this.nearestCollider)) {
                            this.secondNearestCollider = this.nearestCollider, this.nearestCollider = object;
                        }
                        if (object !== this.nearestCollider && this.isNear(object, this.secondNearestCollider)) {
                            this.secondNearestCollider = object;
                        }
                    }
                } else {
                    let {primary: primary, secondary: secondary} = myPlayer.weapon;
                    if (isPlayerObject && object.isDestroyable && secondary === 10 && primary !== null && primary !== 8) {
                        let damage = myPlayer.getBuildingDamage(secondary, !0), primaryRange = DataHandler_default.getWeapon(primary).range + target.hitScale, secondaryRange = DataHandler_default.getWeapon(secondary).range + object.hitScale;
                        if (myPlayer.collidingSimple(target, primaryRange) && myPlayer.collidingSimple(object, secondaryRange) && object.health <= damage) {
                            let itemType = 4, spikeID = myPlayer.getItemByType(itemType), placeLength = myPlayer.getItemPlaceScale(spikeID), spikeScale = Items[spikeID].scale, spikePos = pos1.addDirection(angleToTarget, placeLength), distance = pos2.distance(spikePos), range = target.collisionScale + spikeScale;
                            if (distance <= range && this.isNear(object, this.nearestLowHPObject)) {
                                this.nearestLowHPObject = object, this.nearestSyncEnemy = target;
                            }
                        }
                    }
                    if (isEnemyObjectToMyPlayer && (isSpike || isCactus) && !myPlayer.isTrapped) {
                        let KBDistance = target.getActualMaxKnockback(myPlayer), spikeScale = object.collisionScale + myPlayer.collisionScale, angleToEnemy = pos2.angle(pos1), angleToSpike = pos2.angle(pos3), distanceToSpike1 = pos2.distance(pos3), offset = Math.asin(2 * spikeScale / (2 * distanceToSpike1)), intersecting = getAngleDist(angleToEnemy, angleToSpike) <= offset, overlapping = distanceToTarget <= distanceToSpike1, inRange2 = KBDistance !== 0 && myPlayer.collidingObject(object, KBDistance);
                        if (intersecting && overlapping && inRange2) {
                            this.possibleToKnockback = !0, this.potentialSpikeKnockbackDamage = Math.max(this.potentialSpikeKnockbackDamage, object.getDamage());
                        }
                    }
                    if (isEnemyObject && (isSpike || isCactus) && target.collidingObject(object) && this.isNear(target, this.enemySpikeCollider)) {
                        this.enemySpikeCollider = target;
                    }
                    if (isEnemyObject && (isSpike || isCactus) && this.isNear(target, this.nearestEnemySpikeCollider)) {
                        let KBDistance = myPlayer.getActualMaxKnockback(target), spikeScale = object.collisionScale + target.collisionScale * 1.5, angleToEnemy = pos1.angle(pos2), angleToSpike = pos1.angle(pos3), distanceToSpike1 = pos1.distance(pos3), offset = Math.asin(2 * spikeScale / (2 * distanceToSpike1)), intersecting = getAngleDist(angleToEnemy, angleToSpike) <= offset, overlapping = distanceToTarget <= distanceToSpike1, inRange2 = KBDistance !== 0 && target.collidingObject(object, KBDistance);
                        if (intersecting && overlapping && inRange2) {
                            if (this.spikeCollider === null) {
                                this.nearestEnemySpikeCollider = target, this.spikeCollider = object;
                            } else {
                                let pos4 = this.spikeCollider.pos.current, angle1 = pos2.angle(pos3), angle2 = pos1.angle(pos3), angle3 = pos2.angle(pos4), angle4 = pos1.angle(pos4), angleDist1 = getAngleDist(angle1, angle2), angleDist2 = getAngleDist(angle3, angle4);
                                if (angleDist1 < angleDist2) {
                                    this.nearestEnemySpikeCollider = target, this.spikeCollider = object;
                                }
                            }
                        }
                    }
                }
            });
        }
        handleNearest(type, enemy) {
            let {myPlayer: myPlayer} = this.client;
            if (myPlayer.getMaxWeaponDamage(myPlayer.weapon.primary, !1) >= enemy.currentHealth && this.isNear(enemy, this.nearestLowEntity)) {
                this.nearestLowEntity = enemy;
            }
            if (this.isNear(enemy, this._nearestEnemy[type])) {
                if (this._nearestEnemy[type] = enemy, enemy.canUseTurret && this.client.myPlayer.collidingSimple(enemy, 700)) {
                    this.nearestTurretEntity = enemy;
                }
            }
        }
        handleNearestDangerAnimal(animal) {
            let {myPlayer: myPlayer} = this.client;
            if (!animal.isDanger) {
                return;
            }
            if (!myPlayer.collidingEntity(animal, animal.collisionRange)) {
                return;
            }
            if (!this.isNear(animal, this.nearestDangerAnimal)) {
                return;
            }
            this.nearestDangerAnimal = animal;
        }
        handleAnimal(animal) {
            this.handleNearest(1, animal), this.handleNearestDangerAnimal(animal);
        }
        attemptSpikePlacement() {
            let {ModuleHandler: ModuleHandler} = this.client, placementAngles = this.nearestSpikePlacerAngle;
            if (placementAngles === null) {
                return;
            }
            let itemType = 4;
            for (let angle of placementAngles) {
                ModuleHandler.place(itemType, angle);
            }
            ModuleHandler.placedOnce = !0, ModuleHandler.placeAngles[0] = itemType, ModuleHandler.placeAngles[1] = placementAngles;
        }
        handleEnemies(enemies) {
            this.reset();
            let {myPlayer: myPlayer, ObjectManager: ObjectManager, PlayerManager: PlayerManager} = this.client;
            this.checkCollision(myPlayer, !0);
            for (let i = 0, len = enemies.length; i < len; i++) {
                let enemy = enemies[i];
                this.checkCollision(enemy), this.handleDanger(enemy), this.handleNearest(0, enemy);
            }
            if (myPlayer.isBullTickTime()) {
                this.potentialDamage += 5;
            }
            this.potentialDamage += this.client.ProjectileManager.totalDamage;
            let actualSpikeDamage = Math.max(this.potentialSpikeDamage, this.potentialSpikeKnockbackDamage);
            this.potentialSpikeDamage = actualSpikeDamage;
            let potentialDamage = this.potentialDamage + actualSpikeDamage, soldierDefense = Hats[6].dmgMult, soldierMult = myPlayer.hatID === 6 ? soldierDefense : 1;
            if (potentialDamage * soldierDefense >= myPlayer.currentHealth) {
                this.detectedDangerEnemy = !0;
            } else if (potentialDamage * soldierMult >= myPlayer.currentHealth) {
                this.detectedEnemy = !0;
            }
            if (potentialDamage >= myPlayer.currentHealth) {
                this.dangerWithoutSoldier = !0;
            }
            let nearest = this.nearestEnemy;
            if (nearest !== null) {
                let pos1 = myPlayer.pos.current, pos2 = nearest.pos.current, angleToEnemy = pos1.angle(pos2), itemType = 4, spikeID = myPlayer.getItemByType(itemType), placeLength = myPlayer.getItemPlaceScale(spikeID), angles = ObjectManager.getBestPlacementAngles({
                    position: pos1,
                    id: spikeID,
                    targetAngle: angleToEnemy,
                    ignoreID: null,
                    preplace: !1,
                    reduce: !1,
                    fill: !1
                }), spikeScale = Items[spikeID].scale, possibleAngles = angles.filter(angle => {
                    let spikePos = pos1.addDirection(angle, placeLength), distance = pos2.distance(spikePos), range = nearest.collisionScale + spikeScale;
                    return distance <= range;
                });
                if (possibleAngles.length !== 0) {
                    this.nearestSpikePlacerAngle = possibleAngles;
                }
                if (Settings_default._autoSync) {
                    for (let i = 0; i < PlayerManager.players.length; i++) {
                        let player = PlayerManager.players[i];
                        if (myPlayer.isMyPlayerByID(player.id)) {
                            continue;
                        }
                        if (PlayerManager.isEnemyByID(nearest.id, player) && this.isNear(player, this.nearestEnemyToNearestEnemy, nearest)) {
                            this.nearestEnemyToNearestEnemy = player;
                        }
                    }
                }
            }
            let nearestEnemyPush = this.nearestEnemyPush;
            if (nearestEnemyPush !== null && myPlayer.trappedIn === null) {
                let trappedIn = nearestEnemyPush.trappedIn, pos0 = trappedIn.pos.current;
                ObjectManager.grid2D.query(pos0.x, pos0.y, 2, id => {
                    let object = ObjectManager.objects.get(id);
                    if (object === trappedIn) {
                        return;
                    }
                    let isPlayerObject = object instanceof PlayerObject, isCactus = !isPlayerObject && object.isCactus, isSpike = isPlayerObject && object.itemGroup === 2;
                    isPlayerObject && object.type;
                    if ((!isPlayerObject || PlayerManager.isEnemyByID(object.ownerID, nearestEnemyPush)) && (isCactus || isSpike) && this.isNear(object, this.nearestPushSpike, nearestEnemyPush)) {
                        let pos1 = object.pos.current, distance = pos0.distance(pos1), range = object.collisionScale + trappedIn.collisionScale + nearestEnemyPush.collisionScale * 2;
                        if (distance <= range) {
                            this.nearestPushSpike = object;
                        }
                    }
                });
            }
            if (this.client.isOwner) {
                GameUI_default.updateSpikeDamage(actualSpikeDamage), GameUI_default.updatePotentialDamage(`${this.potentialDamage}, ${this.primaryDamage}`),
                GameUI_default.updateDangerState(`${this.detectedDangerEnemy}, ${this.detectedEnemy}, ${this.dangerWithoutSoldier}, ${this.rangedBowInsta}`),
                GameUI_default.updateCollideSpike(this.collidingSpike);
            }
        }
    }

    const EnemyManager_default = EnemyManager;

    class LeaderboardManager {
        client;
        list=new Set;
        constructor(client) {
            this.client = client;
        }
        updatePlayer(id, nickname, gold) {
            let owner = this.client.PlayerManager.playerData.get(id) || this.client.PlayerManager.createPlayer({
                id: id,
                nickname: nickname
            });
            this.list.add(owner);
        }
        update(data) {
            this.list.clear();
            for (let i = 0; i < data.length; i += 3) {
                let id = data[i + 0], nickname = data[i + 1], gold = data[i + 2];
                this.updatePlayer(id, nickname, gold);
            }
        }
    }

    const LeaderboardManager_default = LeaderboardManager;

    const HatPredictor = new class {
        transitions=new Map;
        train(history) {
            this.transitions.clear();
            for (let i = 0; i < history.length - 1; i++) {
                let currentHat = history[i], nextHat = history[i + 1];
                if (!this.transitions.has(currentHat)) {
                    this.transitions.set(currentHat, new Map);
                }
                let nextMap = this.transitions.get(currentHat);
                nextMap.set(nextHat, (nextMap.get(nextHat) || 0) + 1);
            }
        }
        predict(currentHat) {
            if (!this.transitions.has(currentHat)) {
                return null;
            }
            let nextMap = this.transitions.get(currentHat), maxCount = 0, predictedHat = null;
            for (let [hat, count] of nextMap) {
                if (count > maxCount) {
                    maxCount = count, predictedHat = hat;
                }
            }
            return predictedHat;
        }
    }, HatPredictor_default = HatPredictor;

    class Player extends Entity_default {
        currentItem=-1;
        clanName=null;
        isLeader=!1;
        prevNickname="";
        nickname="unknown";
        skinID=0;
        scale=35;
        storeData=[ 0, 0 ];
        hatID=0;
        prevHat=0;
        accessoryID=0;
        usesTurret=!1;
        previousHealth=100;
        currentHealth=100;
        tempHealth=100;
        maxHealth=100;
        primaryReloadTickCount=0;
        nextDamageTick=0;
        globalInventory={};
        weapon={};
        oldWeapon=[ 0, null ];
        variant={};
        reload=[ {}, {}, {} ];
        objects=new Set;
        newlyCreated=!0;
        usingBoost=!1;
        isTrapped=!1;
        usesTank=!1;
        trappedIn=null;
        trappedInPrev=null;
        isFullyUpgraded=!1;
        potentialDamage=0;
        primaryDamage=0;
        spikeDamage=0;
        dangerList=[];
        danger=0;
        prevDanger=0;
        hatHistory=[];
        futureHat=0;
        shameActive=!1;
        shameTimer=0;
        shameCount=0;
        receivedDamage=null;
        bullTick=0;
        poisonCount=0;
        isDmgOverTime=!1;
        tickCount=0;
        damageTick=0;
        canPlaceSpikePrev=!1;
        canPlaceSpike=!1;
        velocityTicking=!1;
        reverseInsta=!1;
        rangedBowInsta=!1;
        spikeSyncThreat=!1;
        tickDamage=100;
        stackedDamage=0;
        damages=[];
        prevSeenBefore=!1;
        seenBefore=!1;
        isPlayer=!0;
        lastAttacked=0;
        constructor(client) {
            super(client);
        }
        justAppeared() {
            return !this.prevSeenBefore && this.seenBefore;
        }
        wasTrapped() {
            return this.trappedIn === null && this.trappedInPrev !== null;
        }
        addFound(projectile) {
            projectile.owner = this, this.client.ProjectileManager.foundProjectile(projectile);
        }
        resetReload() {
            let {primary: primary, secondary: secondary} = this.weapon, primarySpeed = this.getWeaponSpeed(primary), secondarySpeed = this.getWeaponSpeed(secondary), reload = this.reload;
            reload[0].previous = primarySpeed, reload[0].current = primarySpeed, reload[0].max = primarySpeed,
            reload[1].previous = secondarySpeed, reload[1].current = secondarySpeed, reload[1].max = secondarySpeed,
            reload[2].previous = 23, reload[2].current = 23, reload[2].max = 23;
        }
        resetGlobalInventory() {
            this.globalInventory[0] = null, this.globalInventory[1] = null, this.globalInventory[2] = null,
            this.globalInventory[3] = null, this.globalInventory[4] = null, this.globalInventory[5] = null,
            this.globalInventory[6] = null, this.globalInventory[7] = null, this.globalInventory[8] = null,
            this.globalInventory[9] = null;
        }
        init() {
            this.weapon.current = 0, this.weapon.oldCurrent = 0, this.weapon.primary = null,
            this.weapon.secondary = null, this.oldWeapon[0] = null, this.oldWeapon[1] = null,
            this.variant.current = 0, this.variant.primary = 0, this.variant.secondary = 0,
            this.resetReload(), this.resetGlobalInventory(), this.newlyCreated = !0, this.usingBoost = !1,
            this.isFullyUpgraded = !1;
        }
        get canUseTurret() {
            return this.hatID !== 22;
        }
        get canPlaceSpikeObject() {
            return !this.canPlaceSpikePrev && this.canPlaceSpike || this.speed >= 10 && this.canPlaceSpike;
        }
        isBullTickTime(adjust = 0) {
            return (this.tickCount - this.bullTick - adjust) % 9 === 0;
        }
        update(id, x, y, angle, currentItem, currentWeapon, weaponVariant, clanName, isLeader, hatID, accessoryID) {
            if (this.prevSeenBefore = this.seenBefore, this.seenBefore = !0, this.justAppeared()) {
                this.resetReload();
            }
            this.tickCount += 1, this.id = id, this.pos.previous.setVec(this.pos.current),
            this.pos.current.setXY(x, y), this.setFuturePosition(), this.angle = angle,
            this.currentItem = currentItem, this.weapon.oldCurrent = this.weapon.current;
            let weaponType = DataHandler_default.getWeapon(this.weapon.current).itemType;
            if (this.oldWeapon[weaponType] = this.weapon.current, this.weapon.current = currentWeapon,
            this.variant.current = weaponVariant, this.clanName = clanName, this.isLeader = !!isLeader,
            this.prevHat = this.hatID, this.hatID = hatID, this.prevHat === 7 && hatID === 53) {
                this.usesTurret = !0;
            }
            if (this.hatHistory.push(hatID), this.hatHistory.length > 4) {
                this.hatHistory.shift();
            }
            if (HatPredictor_default.train(this.hatHistory), this.futureHat = HatPredictor_default.predict(hatID),
            this.usesTurret && hatID === 7) {
                this.futureHat = 53;
            }
            if (this.accessoryID = accessoryID, this.storeData[0] = hatID, this.storeData[1] = accessoryID,
            this.newlyCreated = !1, this.potentialDamage = 0, this.primaryDamage = 0, this.spikeDamage = 0,
            this.canPlaceSpikePrev = this.canPlaceSpike, this.canPlaceSpike = !1, this.velocityTicking = !1,
            this.reverseInsta = !1, this.rangedBowInsta = !1, this.spikeSyncThreat = !1,
            this.predictItems(), this.predictWeapons(), this.updateReloads(), this.isDmgOverTime = !1,
            this.hatID === 45 && !this.shameActive) {
                this.shameActive = !0, this.shameTimer = 0, this.shameCount = 8;
            }
            let {PlayerManager: PlayerManager, myPlayer: myPlayer} = this.client;
            if (this.shameTimer += PlayerManager.step, this.shameTimer >= 3e4 && this.shameActive) {
                this.shameActive = !1, this.shameTimer = 0, this.shameCount = 0;
            }
            if (this.isBullTickTime()) {
                if (this.shameCount > 0) {
                    this.futureHat = 7;
                }
                this.poisonCount = Math.max(this.poisonCount - 1, 0);
            }
            let reload = this.reload;
            reload[0].previous = reload[0].current, reload[1].previous = reload[1].current,
            reload[2].previous = reload[2].current;
        }
        updateHealth(health) {
            if (this.previousHealth = this.currentHealth, this.currentHealth = health, this.tempHealth = health,
            this.shameActive) {
                return;
            }
            let {myPlayer: myPlayer, PlayerManager: PlayerManager} = this.client, isEnemy = myPlayer.isEnemyByID(this.id), {currentHealth: currentHealth, previousHealth: previousHealth} = this, difference = Math.abs(currentHealth - previousHealth);
            if (this.currentHealth < this.previousHealth) {
                if (this.receivedDamage = Date.now(), this.damageTick !== this.tickCount + 1) {
                    this.tickDamage = 0, this.stackedDamage = 0, this.damages.length = 0;
                }
                if (this.tickDamage += difference, this.damageTick = this.tickCount + 1, isEnemy) {
                    PlayerManager.lastEnemyReceivedDamage[0] = this.id, PlayerManager.lastEnemyReceivedDamage[1] = Math.round(difference);
                }
            } else if (this.receivedDamage !== null) {
                let step = Date.now() - this.receivedDamage;
                if (this.receivedDamage = null, step <= 120) {
                    this.shameCount += 1;
                } else {
                    this.shameCount -= 2;
                }
                this.shameCount = clamp(this.shameCount, 0, 7);
            }
            let isDmgOverTime = (difference === 5 || difference === 2 || difference === 4) && currentHealth < previousHealth;
            if (this.isDmgOverTime = isDmgOverTime, isDmgOverTime) {
                this.bullTick = this.tickCount;
            }
        }
        predictItems() {
            if (this.currentItem === -1) {
                return;
            }
            let item = Items[this.currentItem];
            this.globalInventory[item.itemType] = this.currentItem;
        }
        increaseReload(reload) {
            if (reload.previous = reload.current, reload.current += 1, reload.current > reload.max) {
                reload.current = reload.max;
            }
        }
        updateMaxReload(reload, weaponID) {
            let speed = this.getWeaponSpeed(weaponID);
            reload.current = speed, reload.max = speed;
        }
        resetCurrentReload(reload) {
            reload.current = 0;
        }
        updateTurretReload() {
            let reload = this.reload[2];
            if (this.increaseReload(reload), this.hatID !== 53) {
                return;
            }
            let {ProjectileManager: ProjectileManager} = this.client, speed = Projectiles[1].speed, list = ProjectileManager.projectiles.get(speed);
            if (list === void 0) {
                return;
            }
            let current = this.pos.current;
            for (let i = 0; i < list.length; i++) {
                let projectile = list[i];
                if (current.distance(projectile.pos.current) < 5) {
                    this.addFound(projectile), this.resetCurrentReload(reload), removeFast(list, i);
                    break;
                }
            }
        }
        updateReloads() {
            if (this.updateTurretReload(), this.currentItem !== -1) {
                return;
            }
            let weapon = DataHandler_default.getWeapon(this.weapon.current), reload = this.reload[weapon.itemType];
            if (this.increaseReload(reload), "projectile" in weapon) {
                let {ProjectileManager: ProjectileManager} = this.client, speedMult = this.getWeaponSpeedMult(), type = weapon.projectile, speed = Projectiles[type].speed * speedMult, list = ProjectileManager.projectiles.get(speed);
                if (list === void 0) {
                    return;
                }
                let current = this.pos.current;
                for (let i = 0; i < list.length; i++) {
                    let projectile = list[i];
                    if (current.distance(projectile.pos.current) < 5 && this.angle === projectile.angle) {
                        this.addFound(projectile), this.updateMaxReload(reload, weapon.id), this.resetCurrentReload(reload),
                        removeFast(list, i);
                        break;
                    }
                }
            }
        }
        handleObjectPlacement(object) {
            this.objects.add(object);
            let {myPlayer: myPlayer, ObjectManager: ObjectManager} = this.client, item = Items[object.type];
            if (object.seenPlacement) {
                if (object.type === 17) {
                    ObjectManager.resetTurret(object.id);
                } else if (object.type === 16 && !this.newlyCreated) {
                    this.usingBoost = !0;
                }
                this.updateInventory(object.type);
            }
            if (myPlayer.isMyPlayerByID(this.id) && item.itemType === 5) {
                myPlayer.totalGoldAmount += item.pps;
            }
        }
        handleObjectDeletion(object) {
            this.objects.delete(object);
            let {myPlayer: myPlayer} = this.client, item = Items[object.type];
            if (myPlayer.isMyPlayerByID(this.id) && item.itemType === 5) {
                myPlayer.totalGoldAmount -= item.pps;
            }
        }
        updateInventory(type) {
            let item = Items[type], inventoryID = this.globalInventory[item.itemType];
            if (inventoryID === null || item.age > Items[inventoryID].age) {
                this.globalInventory[item.itemType] = item.id;
            }
        }
        detectFullUpgrade() {
            let inventory = this.globalInventory, primary = inventory[0], secondary = inventory[1], spike = inventory[4];
            if (primary && secondary) {
                if ("isUpgrade" in DataHandler_default.getWeapon(primary) && "isUpgrade" in DataHandler_default.getWeapon(secondary)) {
                    return !0;
                }
            }
            return primary && DataHandler_default.getWeapon(primary).age === 8 || secondary && DataHandler_default.getWeapon(secondary).age === 9 || spike && Items[spike].age === 9 || inventory[5] === 12 || inventory[9] === 20;
        }
        predictPrimary(id) {
            if (id === 11) {
                return 4;
            }
            return 5;
        }
        predictSecondary(id) {
            if (id === 0) {
                return null;
            }
            if (id === 2 || id === 4) {
                return 10;
            }
            return 15;
        }
        predictWeapons() {
            let {current: current, oldCurrent: oldCurrent} = this.weapon, weapon = DataHandler_default.getWeapon(current), type = WeaponTypeString[weapon.itemType], reload = this.reload[weapon.itemType], oldWeapon = this.oldWeapon[weapon.itemType], upgradedWeapon = oldWeapon === null || current !== oldWeapon && weapon.itemType === DataHandler_default.getWeapon(oldWeapon).itemType;
            if (reload.max === -1 || upgradedWeapon) {
                this.updateMaxReload(reload, weapon.id);
            }
            this.globalInventory[weapon.itemType] = current, this.variant[type] = this.variant.current;
            let currentType = this.weapon[type];
            if (currentType === null || weapon.age > DataHandler_default.getWeapon(currentType).age) {
                this.weapon[type] = current;
            }
            let primary = this.globalInventory[0], secondary = this.globalInventory[1], notPrimaryUpgrade = primary === null || !("isUpgrade" in DataHandler_default.getWeapon(primary)), notSecondaryUpgrade = secondary === null || !("isUpgrade" in DataHandler_default.getWeapon(secondary));
            if (DataHandler_default.isSecondary(current) && notPrimaryUpgrade) {
                let predicted = this.predictPrimary(current);
                if (primary === null || DataHandler_default.getWeapon(predicted).upgradeType === DataHandler_default.getWeapon(primary).upgradeType) {
                    this.weapon.primary = predicted;
                }
            } else if (DataHandler_default.isPrimary(current) && notSecondaryUpgrade) {
                let predicted = this.predictSecondary(current);
                if (predicted === null || secondary === null || DataHandler_default.getWeapon(predicted).upgradeType === DataHandler_default.getWeapon(secondary).upgradeType) {
                    this.weapon.secondary = predicted;
                }
            }
            if (this.isFullyUpgraded = this.detectFullUpgrade(), this.isFullyUpgraded) {
                if (primary !== null) {
                    this.weapon.primary = primary;
                }
                if (secondary !== null) {
                    this.weapon.secondary = secondary;
                }
            }
            if (this.weapon.primary === void 0) {
                throw Error("Primary is 'undefined', value must be at least 'null' or 'number'");
            }
            if (this.weapon.secondary === void 0) {
                throw Error("Secondary is 'undefined', value must be at least 'null' or 'number'");
            }
        }
        getWeaponVariant(id) {
            let type = DataHandler_default.getWeapon(id || 0).itemType, variant = this.variant[WeaponTypeString[type]];
            return {
                current: variant,
                next: Math.min(variant + 1, 3)
            };
        }
        getBuildingDamage(id, isTank = !1) {
            let weapon = DataHandler_default.getWeapon(id), variant = WeaponVariants[this.getWeaponVariant(id).current], damage = weapon.damage * variant.val;
            if ("sDmg" in weapon) {
                damage *= weapon.sDmg;
            }
            let hat = Hats[isTank ? 40 : this.hatID];
            if ("bDmg" in hat) {
                damage *= hat.bDmg;
            }
            return damage;
        }
        getMaxBuildingDamage(object, isTank = !0) {
            let {primary: primary, secondary: secondary} = this.weapon;
            if (DataHandler_default.isMelee(secondary) && secondary === 10 && this.isReloaded(1, 1)) {
                if (this.collidingSimple(object, DataHandler_default.getWeapon(secondary).range + object.hitScale)) {
                    return this.getBuildingDamage(secondary, isTank);
                }
            }
            if (DataHandler_default.isMelee(primary) && this.isReloaded(0, 1)) {
                if (this.collidingSimple(object, DataHandler_default.getWeapon(primary).range + object.hitScale)) {
                    return this.getBuildingDamage(primary, isTank);
                }
            }
            return null;
        }
        canDealPoison(weaponID) {
            let isRuby = this.getWeaponVariant(weaponID).current === 3, hasPlague = this.hatID === 21;
            return {
                isAble: isRuby || hasPlague,
                count: isRuby ? 5 : hasPlague ? 6 : 0
            };
        }
        getWeaponSpeed(id, hat = this.hatID) {
            if (id === null) {
                return -1;
            }
            let reloadSpeed = hat === 20 ? Hats[hat].atkSpd : 1, speed = DataHandler_default.getWeapon(id).speed * reloadSpeed;
            return Math.ceil(speed / this.client.SocketManager.TICK);
        }
        getWeaponSpeedMult() {
            if (this.hatID === 1) {
                return Hats[this.hatID].aMlt;
            }
            return 1;
        }
        getMaxWeaponRange() {
            let {primary: primary, secondary: secondary} = this.weapon, primaryRange = DataHandler_default.getWeapon(primary).range;
            if (DataHandler_default.isMelee(secondary)) {
                let range = DataHandler_default.getWeapon(secondary).range;
                if (range > primaryRange) {
                    return range;
                }
            }
            return primaryRange;
        }
        getWeaponRange(weaponID) {
            if (weaponID === null) {
                return 0;
            }
            let range = DataHandler_default.getWeapon(weaponID).range;
            if (DataHandler_default.isMelee(weaponID)) {
                return range + this.hitScale;
            }
            return range + this.collisionScale;
        }
        getMaxWeaponDamage(id, lookingShield, addBull = !0) {
            if (DataHandler_default.isMelee(id)) {
                let bull = Hats[7], variant = this.getWeaponVariant(id).current, damage = DataHandler_default.getWeapon(id).damage;
                if (addBull) {
                    damage *= bull.dmgMultO;
                }
                if (damage *= WeaponVariants[variant].val, lookingShield) {
                    damage *= DataHandler_default.getWeapon(11).shield;
                }
                return damage;
            } else if (DataHandler_default.isShootable(id) && !lookingShield) {
                return DataHandler_default.getProjectile(id).damage;
            }
            return 0;
        }
        getMaxKnockback() {
            let knockback = 60, {primary: primary, secondary: secondary} = this.weapon;
            if (primary != null) {
                knockback += DataHandler_default.getWeapon(primary).knockback;
            }
            if (secondary != null) {
                knockback += DataHandler_default.getWeapon(secondary).knockback;
            }
            return knockback;
        }
        getPrimaryKnockback(target) {
            let {primary: primary} = this.weapon;
            if (primary !== null && this.isReloaded(0, 1)) {
                let {range: range, knockback: knockback} = DataHandler_default.getWeapon(primary);
                if (this.collidingEntity(target, range)) {
                    return knockback;
                }
            }
            return 0;
        }
        getActualMaxKnockback(target) {
            let output = 0, {primary: primary, secondary: secondary} = this.weapon, hitScale = target.hitScale;
            if (primary !== null && this.isReloaded(0, 1)) {
                let {range: range, knockback: knockback} = DataHandler_default.getWeapon(primary);
                if (this.collidingEntity(target, range + hitScale)) {
                    output += knockback;
                }
            }
            if (secondary !== null && this.isReloaded(1, 1)) {
                let {range: range, knockback: knockback} = DataHandler_default.getWeapon(secondary);
                if (this.collidingEntity(target, range + hitScale)) {
                    output += knockback;
                }
            }
            if (this.isReloaded(2, 1)) {
                if (this.collidingEntity(target, 700 + hitScale)) {
                    output += 60;
                }
            }
            return output;
        }
        getItemPlaceScale(itemID) {
            let item = Items[itemID];
            return this.scale + item.scale + item.placeOffset;
        }
        isReloaded(type, tick) {
            let reload = this.reload[type].current, max = this.reload[type].max - tick;
            return reload >= max;
        }
        atExact(type, tick) {
            let {current: current, max: max} = this.reload[type];
            return current === max - tick;
        }
        isEmptyReload(type) {
            return this.reload[type].current === 0;
        }
        detectSpikeInsta() {
            let {myPlayer: myPlayer, ObjectManager: ObjectManager} = this.client, spikeID = this.globalInventory[4] || 9, placeLength = this.getItemPlaceScale(spikeID), pos1 = this.pos.current, pos2 = myPlayer.pos.current, angleToMyPlayer = pos1.angle(pos2), spike = Items[spikeID], range = this.collisionScale + spike.scale, straightSpikePos = pos1.addDirection(angleToMyPlayer, placeLength);
            if (pos2.distance(straightSpikePos) > range) {
                return 0;
            }
            myPlayer.trappedIn !== null && myPlayer.trappedIn.canBeDestroyed && myPlayer.trappedIn.id;
            let angles = ObjectManager.getBestPlacementAngles({
                position: pos1,
                id: spikeID,
                targetAngle: angleToMyPlayer,
                ignoreID: null,
                preplace: !1,
                reduce: !1,
                fill: !1
            });
            for (let angle of angles) {
                let spikePos = pos1.addDirection(angle, placeLength);
                if (pos2.distance(spikePos) <= range) {
                    return spike.damage;
                }
            }
            return 0;
        }
        canPossiblyInstakill() {
            let {PlayerManager: PlayerManager, myPlayer: myPlayer} = this.client, lookingShield = PlayerManager.lookingShield(myPlayer, this), {primary: primary, secondary: secondary} = this.weapon, primaryDamage = this.getMaxWeaponDamage(primary, lookingShield), secondaryDamage = this.getMaxWeaponDamage(secondary, lookingShield), addRange = this.isTrapped ? 20 : 115, boostRange = this.usingBoost && !this.isTrapped ? 430 : addRange, primaryRange = this.getWeaponRange(primary) + boostRange, secondaryRange = this.getWeaponRange(secondary) + addRange, turretRange = 700 + addRange, primaryReloaded = this.isReloaded(0, 1), primaryVariant = this.getWeaponVariant(primary).current, isDiamondPolearm = primary === 5 && primaryVariant >= 2, collidingPrimary = myPlayer.collidingEntity(this, primaryRange), collidingSecondary = myPlayer.collidingEntity(this, DataHandler_default.isShootable(secondary) ? primaryRange : secondaryRange), collidingTurret = myPlayer.collidingEntity(this, turretRange), spikeSyncDamage = 0, includeTurret = !1;
            if (collidingPrimary) {
                if (primaryReloaded) {
                    this.potentialDamage += primaryDamage, this.primaryDamage = primaryDamage, spikeSyncDamage += primaryDamage;
                }
                includeTurret = !0;
            }
            if (collidingSecondary) {
                if (this.isReloaded(1, 1)) {
                    this.potentialDamage += secondaryDamage;
                }
                if (DataHandler_default.isMelee(secondary)) {
                    includeTurret = !0;
                }
            }
            if (this.isReloaded(2, 1) && includeTurret && !lookingShield) {
                this.potentialDamage += 25;
            }
            if (collidingPrimary && collidingTurret && this.isEmptyReload(2) && primaryReloaded && isDiamondPolearm) {
                this.velocityTicking = !0;
            }
            if (collidingPrimary && collidingSecondary && collidingTurret && this.isEmptyReload(1) && this.isEmptyReload(2) && primaryReloaded) {
                this.reverseInsta = !0;
            }
            let pos1 = this.pos.current, pos2 = myPlayer.pos.current, distance = pos1.distance(pos2), angle = pos1.angle(pos2), offset = Math.asin(2 * myPlayer.scale / (2 * distance)), lookingAt = getAngleDist(angle, this.angle) <= offset, {current: current, oldCurrent: oldCurrent} = this.weapon, bowDetect = current === 9 && oldCurrent !== 9 || current === 12 && oldCurrent === 9 || current === 15 && oldCurrent === 12;
            if (distance > 300 && lookingAt && bowDetect) {
                this.rangedBowInsta = !0;
            }
            let spikeDamage = this.detectSpikeInsta();
            if (spikeDamage !== 0) {
                if (this.canPlaceSpike = !0, this.spikeDamage = spikeDamage, spikeSyncDamage += spikeDamage,
                spikeSyncDamage >= 100) {
                    this.spikeSyncThreat = !0;
                }
            }
            let soldierDefense = Hats[6].dmgMult;
            if (this.potentialDamage * soldierDefense >= myPlayer.currentHealth) {
                return 3;
            }
            let soldierMult = myPlayer.hatID === 6 ? soldierDefense : 1;
            if (this.potentialDamage * soldierMult >= myPlayer.currentHealth) {
                return 2;
            }
            return 0;
        }
    }

    const Player_default = Player;

    const resizeEvent = new Event("resize"), ZoomHandler = new class {
        scale={
            Default: {
                w: 1920,
                h: 1080
            },
            current: {
                w: 1920,
                h: 1080
            },
            smooth: {
                w: Hooker_default.linker(1920),
                h: Hooker_default.linker(1080)
            }
        };
        getScale() {
            return Math.max(window.innerWidth / this.scale.Default.w, window.innerHeight / this.scale.Default.h) * 1;
        }
        tempScale=1;
        handler(event) {
            if (!(event.target instanceof HTMLCanvasElement) || event.ctrlKey || event.shiftKey || event.altKey || isActiveInput()) {
                return;
            }
            let {Default: Default, current: current} = this.scale;
            if (event.deltaY < 0) {
                this.tempScale *= 1.1;
            } else {
                this.tempScale /= 1.1;
            }
            this.tempScale = clamp(this.tempScale, .1, 22);
            let zoom = this.tempScale;
            current.w = Default.w * zoom, current.h = Default.h * zoom;
        }
        renderStart=Date.now();
        smoothUpdate() {
            let {current: current, smooth: smooth} = this.scale, now = Date.now(), delta = now - this.renderStart;
            this.renderStart = now;
            let dt = delta / 1e3, blend = .4 * (1 - Math.exp(-10 * dt));
            smooth.w[0] = lerp(smooth.w[0], current.w, blend), smooth.h[0] = lerp(smooth.h[0], current.h, blend),
            window.dispatchEvent(resizeEvent);
        }
    }, ZoomHandler_default = ZoomHandler;

    const renderText = (ctx, text, size = 25, posx = 10, posy = 9, fill = "#eaeaea", alpha = .6) => {
        ctx.save(), ctx.font = `700 ${size}px sans-serif`, ctx.textAlign = "left", ctx.textBaseline = "top",
        ctx.setTransform(1, 0, 0, 1, 0, 0);
        let scale = ZoomHandler_default.getScale();
        ctx.scale(scale, scale), ctx.fillStyle = fill, ctx.strokeStyle = "#1f2029",
        ctx.lineWidth = 8, ctx.globalAlpha = alpha, ctx.letterSpacing = "6px", ctx.lineJoin = "round",
        ctx.strokeText(text, posx, posy), ctx.fillText(text, posx, posy), ctx.restore();
    }, Renderer = new class {
        renderObjects=[];
        totalTimes=[];
        lastLogTime=performance.now();
        preRender() {
            ZoomHandler_default.smoothUpdate();
        }
        postRender() {
            let now = performance.now();
            while (this.totalTimes.length > 0 && this.totalTimes[0] <= now - 1e3) {
                this.totalTimes.shift();
            }
            this.totalTimes.push(now);
            let fps = this.totalTimes.length;
            if (now - this.lastLogTime >= 1e3) {
                GameUI_default.updateFPS(fps), this.lastLogTime = now;
            }
            let ctx = document.querySelector("#gameCanvas").getContext("2d");
            // Titre, credit d origine (impose par la licence MIT de Glotus),
            // puis la signature de cette version.
            renderText(ctx, atob("R2xvdHVz") + " v" + Glotus.version);
            renderText(ctx, "by Murka", 15, 15, 36);
            renderText(ctx, "fixed by seldoom", 15, 15, 57, "#f5d951", .85);
        }
        mapPreRender(ctx) {
            ctx.save(), ctx.globalAlpha = .6;
            let width = ctx.canvas.width, height = ctx.canvas.height;
            ctx.fillStyle = "#fff", ctx.fillRect(0, 0, width, Config_default.snowBiomeTop / Config_default.mapScale * height),
            ctx.fillStyle = "#dbc666", ctx.fillRect(0, 12e3 / Config_default.mapScale * height, width, height),
            ctx.fillStyle = "#91b2db";
            let startY = (Config_default.mapScale / 2 - Config_default.riverWidth / 2) / Config_default.mapScale * height;
            ctx.fillRect(0, startY, width, Config_default.riverWidth / Config_default.mapScale * height);
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer} = client;
            ctx.globalAlpha = 1;
            let markSize = 8;
            if (ModuleHandler.followPath) {
                let pos = ModuleHandler.endTarget.copy().div(Config_default.mapScale).mult(width);
                ctx.fillStyle = "#c2383d", ctx.beginPath(), ctx.arc(pos.x, pos.y, markSize, 0, 2 * Math.PI),
                ctx.fill();
            }
            if (myPlayer.teleported) {
                let pos = myPlayer.teleportPos.copy().div(Config_default.mapScale).mult(width);
                ctx.fillStyle = "#d76edb", ctx.beginPath(), ctx.arc(pos.x, pos.y, markSize, 0, 2 * Math.PI),
                ctx.fill();
            }
            ctx.fillStyle = Settings_default._notificationTracersColor;
            let notifications = NotificationRenderer_default.notifications;
            for (let notify of notifications) {
                let x = notify.x / Config_default.mapScale * width, y = notify.y / Config_default.mapScale * width;
                ctx.beginPath(), ctx.arc(x, y, markSize * 1.5, 0, 2 * Math.PI), ctx.fill();
            }
            ctx.restore();
        }
        drawNorthArrow(ctx, x, y, angle) {
            ctx.save(), ctx.globalAlpha = .7, ctx.fillStyle = "#883131", ctx.translate(x, y),
            ctx.rotate(angle + Math.PI / 2), ctx.beginPath(), ctx.moveTo(0, -17.5), ctx.lineTo(11.666666666666666, 17.5),
            ctx.lineTo(0, 11.666666666666666), ctx.lineTo(-11.666666666666666, 17.5), ctx.closePath(),
            ctx.fill(), ctx.restore();
        }
        rotation=0;
        arrowPart=2 * Math.PI / 3;
        drawTarget(ctx, entity) {
            let len = entity.scale + 30;
            this.rotation = (this.rotation + .01) % 6.28, ctx.save(), ctx.translate(-client.myPlayer.offset.x, -client.myPlayer.offset.y),
            ctx.translate(entity.x, entity.y), ctx.rotate(this.rotation), this.drawNorthArrow(ctx, len * Math.cos(this.arrowPart * 1), len * Math.sin(this.arrowPart * 1), -1.04),
            this.drawNorthArrow(ctx, len * Math.cos(this.arrowPart * 2), len * Math.sin(this.arrowPart * 2), 1.04),
            this.drawNorthArrow(ctx, len * Math.cos(this.arrowPart * 3), len * Math.sin(this.arrowPart * 3), 3.14),
            ctx.restore();
        }
        rect(ctx, pos, scale, color, lineWidth = 4, alpha = 1) {
            ctx.save(), ctx.globalAlpha = alpha, ctx.strokeStyle = color, ctx.lineWidth = lineWidth,
            ctx.beginPath(), ctx.translate(-client.myPlayer.offset.x, -client.myPlayer.offset.y),
            ctx.translate(pos.x, pos.y), ctx.rect(-scale, -scale, scale * 2, scale * 2),
            ctx.stroke(), ctx.closePath(), ctx.restore();
        }
        roundRect(ctx, x, y, w, h, r) {
            if (w < 2 * r) {
                r = w / 2;
            }
            if (h < 2 * r) {
                r = h / 2;
            }
            if (r < 0) {
                r = 0;
            }
            ctx.beginPath(), ctx.moveTo(x + r, y), ctx.arcTo(x + w, y, x + w, y + h, r),
            ctx.arcTo(x + w, y + h, x, y + h, r), ctx.arcTo(x, y + h, x, y, r), ctx.arcTo(x, y, x + w, y, r),
            ctx.closePath();
        }
        circle(ctx, x, y, radius, color, opacity = 1, lineWidth = 4) {
            ctx.save(), ctx.globalAlpha = opacity, ctx.strokeStyle = color, ctx.lineWidth = lineWidth,
            ctx.beginPath(), ctx.translate(-client.myPlayer.offset.x, -client.myPlayer.offset.y),
            ctx.arc(x, y, radius, 0, 2 * Math.PI), ctx.stroke(), ctx.closePath(), ctx.restore();
        }
        fillCircle(ctx, x, y, radius, color, opacity = 1) {
            ctx.save(), ctx.globalAlpha = opacity, ctx.fillStyle = color, ctx.beginPath(),
            ctx.translate(-client.myPlayer.offset.x, -client.myPlayer.offset.y), ctx.arc(x, y, radius, 0, 2 * Math.PI),
            ctx.fill(), ctx.closePath(), ctx.restore();
        }
        renderText(ctx, text, x, y, fontSize = 14, opacity = .5) {
            ctx.save(), ctx.fillStyle = "#fff", ctx.strokeStyle = "#3d3f42", ctx.lineWidth = 8,
            ctx.lineJoin = "round", ctx.textBaseline = "top", ctx.globalAlpha = opacity,
            ctx.font = fontSize + "px Hammersmith One", ctx.translate(-client.myPlayer.offset.x, -client.myPlayer.offset.y),
            ctx.strokeText(text, x, y), ctx.fillText(text, x, y), ctx.restore();
        }
        line(ctx, start, end, color, opacity = 1, lineWidth = 4) {
            ctx.save(), ctx.translate(-client.myPlayer.offset.x, -client.myPlayer.offset.y),
            ctx.globalAlpha = opacity, ctx.strokeStyle = color, ctx.lineCap = "round", ctx.lineWidth = lineWidth,
            ctx.beginPath(), ctx.moveTo(start.x, start.y), ctx.lineTo(end.x, end.y), ctx.stroke(),
            ctx.restore();
        }
        arrow(ctx, length, x, y, angle, color) {
            ctx.save(), ctx.translate(-client.myPlayer.offset.x, -client.myPlayer.offset.y),
            ctx.translate(x, y), ctx.rotate(Math.PI / 4), ctx.rotate(angle), ctx.globalAlpha = .75,
            ctx.strokeStyle = color, ctx.lineCap = "round", ctx.lineWidth = 8, ctx.beginPath(),
            ctx.moveTo(-length, -length), ctx.lineTo(length, -length), ctx.lineTo(length, length),
            ctx.stroke(), ctx.restore();
        }
        cross(ctx, x, y, size, lineWidth, color) {
            ctx.save(), ctx.globalAlpha = 1, ctx.lineWidth = lineWidth, ctx.strokeStyle = color,
            ctx.translate(x - client.myPlayer.offset.x, y - client.myPlayer.offset.y);
            let halfSize = size / 2;
            ctx.beginPath(), ctx.moveTo(-halfSize, -halfSize), ctx.lineTo(halfSize, halfSize),
            ctx.stroke(), ctx.beginPath(), ctx.moveTo(halfSize, -halfSize), ctx.lineTo(-halfSize, halfSize),
            ctx.stroke(), ctx.restore();
        }
        getTracerColor(entity) {
            if (entity instanceof Notify) {
                return Settings_default._notificationTracersColor;
            }
            if (Settings_default._animalTracers && entity.isAI) {
                return Settings_default._animalTracersColor;
            }
            if (Settings_default._teammateTracers && entity.isPlayer && client.myPlayer.isTeammateByID(entity.sid)) {
                return Settings_default._teammateTracersColor;
            }
            if (Settings_default._enemyTracers && entity.isPlayer && client.myPlayer.isEnemyByID(entity.sid)) {
                return Settings_default._enemyTracersColor;
            }
            return null;
        }
        renderTracer(ctx, entity, player) {
            let color = this.getTracerColor(entity);
            if (color === null) {
                return;
            }
            let pos1 = new Vector_default(player.x, player.y), pos2 = new Vector_default(entity.x, entity.y), w = 8, distance = Math.min(125 + w * 2, pos1.distance(pos2) - w * 2), angle = pos1.angle(pos2), pos = pos1.addDirection(angle, distance);
            this.arrow(ctx, w, pos.x, pos.y, angle, color);
        }
        renderDistance(ctx, entity, player) {
            let pos1 = new Vector_default(player.x, player.y), pos2 = new Vector_default(entity.x, entity.y), entityTarget = client.PlayerManager.getEntity(entity.sid, !!entity.isPlayer);
            if (entityTarget === null) {
                return;
            }
            let pos3 = client.myPlayer.pos.current, pos4 = entityTarget.pos.current, distance = fixTo(pos3.distance(pos4), 2), center = pos1.addDirection(pos1.angle(pos2), pos1.distance(pos2) / 2);
            this.renderText(ctx, `[${entity.sid}]: ${distance}`, center.x, center.y);
        }
        getMarkerColor(object) {
            let id = object.owner?.sid;
            if (typeof id !== "number") {
                return null;
            }
            if (Settings_default._itemMarkers && client.myPlayer.isMyPlayerByID(id)) {
                return Settings_default._itemMarkersColor;
            }
            if (Settings_default._teammateMarkers && client.myPlayer.isTeammateByID(id)) {
                return Settings_default._teammateMarkersColor;
            }
            if (Settings_default._enemyMarkers && client.myPlayer.isEnemyByID(id)) {
                return Settings_default._enemyMarkersColor;
            }
            return null;
        }
        renderMarker(ctx, object) {
            let color = this.getMarkerColor(object);
            if (color === null) {
                return;
            }
            let x = object.x + object.xWiggle - client.myPlayer.offset.x, y = object.y + object.yWiggle - client.myPlayer.offset.y;
            ctx.save(), ctx.strokeStyle = "#3b3b3b", ctx.lineWidth = 3, ctx.fillStyle = color,
            ctx.beginPath(), ctx.arc(x, y, 9, 0, 2 * Math.PI), ctx.fill(), ctx.stroke(),
            ctx.closePath(), ctx.restore();
        }
        barContainer(ctx, x, y, w, h, r = 8) {
            ctx.fillStyle = "#3d3f42", this.roundRect(ctx, x, y, w, h, r), ctx.fill();
        }
        barContent(ctx, x, y, w, h, fill, color) {
            let barPad = Config_default.barPad;
            ctx.fillStyle = color, this.roundRect(ctx, x + barPad, y + barPad, (w - barPad * 2) * fill, h - barPad * 2, 7),
            ctx.fill();
        }
        getNameY(target) {
            let nameY = 34, height = 5;
            if (target === client.myPlayer && Settings_default._weaponXPBar) {
                nameY += height;
            }
            if (Settings_default._playerTurretReloadBar) {
                nameY += height;
            }
            if (Settings_default._weaponReloadBar) {
                nameY += height;
            }
            return nameY;
        }
        getContainerHeight(entity) {
            let {barHeight: barHeight, barPad: barPad} = Config_default, height = barHeight;
            if (entity.isPlayer) {
                let smallBarHeight = barHeight - 4, player = client.PlayerManager.playerData.get(entity.sid);
                if (player === void 0) {
                    return height;
                }
                if (player === client.myPlayer && Settings_default._weaponXPBar) {
                    height += smallBarHeight - barPad;
                }
                if (Settings_default._playerTurretReloadBar) {
                    height += smallBarHeight - barPad;
                }
                if (Settings_default._weaponReloadBar) {
                    height += barHeight - barPad;
                }
            }
            return height;
        }
        renderBar(ctx, entity) {
            let {barWidth: barWidth, barHeight: barHeight, barPad: barPad} = Config_default, smallBarHeight = barHeight - 4, totalWidth = barWidth + barPad, scale = entity.scale + 34, {myPlayer: myPlayer, PlayerManager: PlayerManager} = client, x = entity.x - myPlayer.offset.x - totalWidth, y = entity.y - myPlayer.offset.y + scale;
            ctx.save();
            let player = entity.isPlayer && PlayerManager.playerData.get(entity.sid), animal = entity.isAI && PlayerManager.animalData.get(entity.sid), height = 0;
            if (player instanceof Player_default) {
                let [primary, secondary, turret] = player.reload;
                if (player === myPlayer && Settings_default._weaponXPBar) {
                    let weapon = DataHandler_default.getWeapon(myPlayer.weapon.current), current = WeaponVariants[myPlayer.getWeaponVariant(weapon.id).current].color, next = WeaponVariants[myPlayer.getWeaponVariant(weapon.id).next].color, XP = myPlayer.weaponXP[weapon.itemType];
                    this.barContainer(ctx, x, y, totalWidth * 2, smallBarHeight), this.barContent(ctx, x, y, totalWidth * 2, smallBarHeight, 1, current),
                    this.barContent(ctx, x, y, totalWidth * 2, smallBarHeight, clamp(XP.current / XP.max, 0, 1), next),
                    height += smallBarHeight - barPad;
                }
                if (Settings_default._playerTurretReloadBar) {
                    this.barContainer(ctx, x, y + height, totalWidth * 2, smallBarHeight), this.barContent(ctx, x, y + height, totalWidth * 2, smallBarHeight, turret.current / turret.max, Settings_default._playerTurretReloadBarColor),
                    height += smallBarHeight - barPad;
                }
                if (Settings_default._weaponReloadBar) {
                    this.barContainer(ctx, x, y + height, totalWidth * 2, barHeight), this.barContent(ctx, x, y + height, totalWidth + 2.25, barHeight, primary.current / primary.max, Settings_default._weaponReloadBarColor),
                    this.barContent(ctx, x + totalWidth - 2.25, y + height, totalWidth + 2.25, barHeight, secondary.current / secondary.max, Settings_default._weaponReloadBarColor),
                    height += barHeight - barPad;
                }
            }
            let target = player || animal;
            if (target) {
                let container = getTargetValue(Glotus, "config");
                setTargetValue(container, "nameY", this.getNameY(target));
                let {currentHealth: currentHealth, maxHealth: maxHealth} = target, health = animal ? maxHealth : 100, color = PlayerManager.isEnemyTarget(myPlayer, target) ? "#cc5151" : "#8ecc51";
                this.barContainer(ctx, x, y + height, totalWidth * 2, barHeight), this.barContent(ctx, x, y + height, totalWidth * 2, barHeight, currentHealth / health, color),
                height += barHeight;
            }
            ctx.restore();
        }
        renderHP(ctx, entity) {
            if (!Settings_default._renderHP) {
                return;
            }
            let {barPad: barPad, nameY: nameY} = Config_default, containerHeight = this.getContainerHeight(entity), text = `HP ${Math.floor(entity.health)}/${entity.maxHealth}`, offset = entity.scale + nameY + barPad + containerHeight, {myPlayer: myPlayer} = client, x = entity.x - myPlayer.offset.x, y = entity.y - myPlayer.offset.y + offset;
            if (entity.isPlayer && myPlayer.isMyPlayerByID(entity.sid)) {
                text += ` ${myPlayer.shameCount}/8`;
            }
            ctx.save(), ctx.fillStyle = "#fff", ctx.strokeStyle = "#3d3f42", ctx.lineWidth = 8,
            ctx.lineJoin = "round", ctx.textBaseline = "top", ctx.font = "19px Hammersmith One",
            ctx.strokeText(text, x, y), ctx.fillText(text, x, y), ctx.restore();
        }
        circularBar(ctx, object, perc, angle, color, offset = 0) {
            let x = object.x + object.xWiggle - client.myPlayer.offset.x, y = object.y + object.yWiggle - client.myPlayer.offset.y, height = Config_default.barHeight * .5, defaultScale = 10 + height / 2, scale = defaultScale + 1 + offset;
            return ctx.save(), ctx.translate(x, y), ctx.rotate(angle), ctx.lineCap = "round",
            ctx.strokeStyle = "#3b3b3b", ctx.lineWidth = height, ctx.beginPath(), ctx.arc(0, 0, scale, 0, perc * 2 * Math.PI),
            ctx.stroke(), ctx.closePath(), ctx.strokeStyle = color, ctx.lineWidth = height / 3,
            ctx.beginPath(), ctx.arc(0, 0, scale, 0, perc * 2 * Math.PI), ctx.stroke(),
            ctx.closePath(), ctx.restore(), defaultScale - 3;
        }
    }, Renderer_default = Renderer;

    const Animals = [ {
        id: 0,
        src: "cow_1",
        hostile: !1,
        killScore: 150,
        health: 500,
        weightM: .8,
        speed: 95e-5,
        turnSpeed: .001,
        scale: 72,
        drop: [ "food", 50 ]
    }, {
        id: 1,
        src: "pig_1",
        hostile: !1,
        killScore: 200,
        health: 800,
        weightM: .6,
        speed: 85e-5,
        turnSpeed: .001,
        scale: 72,
        drop: [ "food", 80 ]
    }, {
        id: 2,
        name: "Bull",
        src: "bull_2",
        hostile: !0,
        dmg: 20,
        killScore: 1e3,
        health: 1800,
        weightM: .5,
        speed: 94e-5,
        turnSpeed: 74e-5,
        scale: 78,
        viewRange: 800,
        chargePlayer: !0,
        drop: [ "food", 100 ]
    }, {
        id: 3,
        name: "Bully",
        src: "bull_1",
        hostile: !0,
        dmg: 20,
        killScore: 2e3,
        health: 2800,
        weightM: .45,
        speed: .001,
        turnSpeed: 8e-4,
        scale: 90,
        viewRange: 900,
        chargePlayer: !0,
        drop: [ "food", 400 ]
    }, {
        id: 4,
        name: "Wolf",
        src: "wolf_1",
        hostile: !0,
        dmg: 8,
        killScore: 500,
        health: 300,
        weightM: .45,
        speed: .001,
        turnSpeed: .002,
        scale: 84,
        viewRange: 800,
        chargePlayer: !0,
        drop: [ "food", 200 ]
    }, {
        id: 5,
        name: "Quack",
        src: "chicken_1",
        hostile: !1,
        dmg: 8,
        killScore: 2e3,
        noTrap: !0,
        health: 300,
        weightM: .2,
        speed: .0018,
        turnSpeed: .006,
        scale: 70,
        drop: [ "food", 100 ]
    }, {
        id: 6,
        name: "MOOSTAFA",
        nameScale: 50,
        src: "enemy",
        hostile: !0,
        dontRun: !0,
        fixedSpawn: !0,
        spawnDelay: 6e4,
        noTrap: !0,
        colDmg: 100,
        dmg: 40,
        killScore: 8e3,
        health: 18e3,
        weightM: .4,
        speed: 7e-4,
        turnSpeed: .01,
        scale: 80,
        spriteMlt: 1.8,
        leapForce: .9,
        viewRange: 1e3,
        hitRange: 210,
        hitDelay: 1e3,
        chargePlayer: !0,
        drop: [ "food", 100 ]
    }, {
        id: 7,
        name: "Treasure",
        hostile: !0,
        nameScale: 35,
        src: "crate_1",
        fixedSpawn: !0,
        spawnDelay: 12e4,
        colDmg: 200,
        killScore: 5e3,
        health: 2e4,
        weightM: .1,
        speed: 0,
        turnSpeed: 0,
        scale: 70,
        spriteMlt: 1
    }, {
        id: 8,
        name: "MOOFIE",
        src: "wolf_2",
        hostile: !0,
        fixedSpawn: !0,
        dontRun: !0,
        hitScare: 4,
        spawnDelay: 3e4,
        noTrap: !0,
        nameScale: 35,
        dmg: 10,
        colDmg: 100,
        killScore: 3e3,
        health: 7e3,
        weightM: .45,
        speed: .0015,
        turnSpeed: .002,
        scale: 90,
        viewRange: 800,
        chargePlayer: !0,
        drop: [ "food", 1e3 ]
    }, {
        id: 9,
        name: "💀MOOFIE",
        src: "wolf_2",
        hostile: !0,
        fixedSpawn: !0,
        dontRun: !0,
        hitScare: 50,
        spawnDelay: 6e4,
        noTrap: !0,
        nameScale: 35,
        dmg: 12,
        colDmg: 100,
        killScore: 3e3,
        health: 9e3,
        weightM: .45,
        speed: .0015,
        turnSpeed: .0025,
        scale: 94,
        viewRange: 1440,
        chargePlayer: !0,
        drop: [ "food", 3e3 ],
        minSpawnRange: .85,
        maxSpawnRange: .9
    }, {
        id: 10,
        name: "💀Wolf",
        src: "wolf_1",
        hostile: !0,
        fixedSpawn: !0,
        dontRun: !0,
        hitScare: 50,
        spawnDelay: 3e4,
        dmg: 10,
        killScore: 700,
        health: 500,
        weightM: .45,
        speed: .00115,
        turnSpeed: .0025,
        scale: 88,
        viewRange: 1440,
        chargePlayer: !0,
        drop: [ "food", 400 ],
        minSpawnRange: .85,
        maxSpawnRange: .9
    }, {
        id: 11,
        name: "💀Bully",
        src: "bull_1",
        hostile: !0,
        fixedSpawn: !0,
        dontRun: !0,
        hitScare: 50,
        dmg: 20,
        killScore: 5e3,
        health: 5e3,
        spawnDelay: 1e5,
        weightM: .45,
        speed: .00115,
        turnSpeed: .0025,
        scale: 94,
        viewRange: 1440,
        chargePlayer: !0,
        drop: [ "food", 800 ],
        minSpawnRange: .85,
        maxSpawnRange: .9
    } ], Animals_default = Animals;

    const colors = [ [ "orange", "red" ], [ "aqua", "blue" ] ], EntityRenderer = new class {
        start=Date.now();
        step=0;
        drawWeaponHitbox(ctx, player) {
            if (!Settings_default._weaponHitbox) {
                return;
            }
            let {myPlayer: myPlayer} = client, current = myPlayer.weapon.current;
            if (DataHandler_default.isMelee(current)) {
                let weapon = DataHandler_default.getWeapon(current);
                Renderer_default.circle(ctx, player.x, player.y, weapon.range, "#f5cb42", .5, 1);
            }
        }
        drawPlacement(ctx) {
            if (!Settings_default._possiblePlacement) {
                return;
            }
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler} = client, [type, angles] = ModuleHandler.placeAngles;
            if (type === null || angles === null) {
                return;
            }
            let id = myPlayer.getItemByType(type);
            if (id === null) {
                return;
            }
            let dist = myPlayer.getItemPlaceScale(id), item = Items[id];
            for (let i = 0; i < angles.length; i++) {
                let angle = angles[i], pos = myPlayer.pos.current.addDirection(angle, dist);
                Renderer_default.circle(ctx, pos.x, pos.y, item.scale, "#80edf2", .4, 1);
            }
        }
        drawEntityHP(ctx, entity) {
            Renderer_default.renderBar(ctx, entity), Renderer_default.renderHP(ctx, entity);
        }
        drawHitScale(ctx, entity) {
            if (!Settings_default._weaponHitbox) {
                return;
            }
            let {PlayerManager: PlayerManager} = client, target = (entity.isPlayer ? PlayerManager.playerData : PlayerManager.animalData).get(entity.sid);
            if (target !== void 0) {
                Renderer_default.circle(ctx, entity.x, entity.y, target.hitScale, "#3f4ec4", .5, 1);
            }
            if (entity.isAI && entity.index === 6) {
                let moostafa = Animals_default[6];
                Renderer_default.circle(ctx, entity.x, entity.y, moostafa.hitRange, "#f5cb42", .5, 1);
            }
        }
        drawDanger(ctx, entity) {
            let {PlayerManager: PlayerManager} = client;
            if (entity.isPlayer) {
                let player = PlayerManager.playerData.get(entity.sid);
                if (player !== void 0 && player.danger !== 0) {
                    let isBoost = Number(player.usingBoost), isDanger = Number(player.danger >= 3);
                    Renderer_default.fillCircle(ctx, entity.x, entity.y, player.scale, colors[isBoost][isDanger], .3);
                }
            }
            if (entity.isAI) {
                let animal = PlayerManager.animalData.get(entity.sid);
                if (animal) {
                    let color = animal.isDanger ? "red" : "green";
                    Renderer_default.fillCircle(ctx, entity.x, entity.y, animal.attackRange, color, .3);
                }
            }
        }
        render(ctx, entity, player) {
            let now = Date.now();
            this.step = now - this.start, this.start = now;
            let {myPlayer: myPlayer, EnemyManager: EnemyManager2, ModuleHandler: ModuleHandler, ObjectManager: ObjectManager, InputHandler: InputHandler} = client, isMyPlayer = entity === player;
            if (isMyPlayer) {
                let pos = new Vector_default(player.x, player.y);
                if (Settings_default._displayPlayerAngle) {
                    Renderer_default.line(ctx, pos, pos.addDirection(client.myPlayer.angle, 70), "#e9adf0");
                }
                if (this.drawWeaponHitbox(ctx, player), this.drawPlacement(ctx), myPlayer.isTrapped) {
                    Renderer_default.fillCircle(ctx, pos.x, pos.y, 35, "yellow", .5);
                }
                let {pushPos: pushPos} = ModuleHandler.staticModules.autoPush, nearestPushSpike = client.EnemyManager.nearestPushSpike;
                if (pushPos !== null && nearestPushSpike !== null) {
                    Renderer_default.line(ctx, pos, pushPos, "white", .6, 1), Renderer_default.line(ctx, pushPos, nearestPushSpike.pos.current, "white", .6, 1);
                }
            }
            if (this.drawEntityHP(ctx, entity), Settings_default._collisionHitbox) {
                Renderer_default.circle(ctx, entity.x, entity.y, entity.scale, "#c7fff2", .5, 1);
            }
            if (!isMyPlayer) {
                this.drawHitScale(ctx, entity), Renderer_default.renderTracer(ctx, entity, player),
                Renderer_default.renderDistance(ctx, entity, player);
                let nearestEnemyToNearestEnemy = EnemyManager2.nearestEnemyToNearestEnemy;
                if (nearestEnemyToNearestEnemy !== null && !entity.isAI && entity.sid === nearestEnemyToNearestEnemy.id) {
                    Renderer_default.fillCircle(ctx, entity.x, entity.y, 35, "#48f072", .5);
                } else {
                    this.drawDanger(ctx, entity);
                }
                let spikeCollider = EnemyManager2.enemySpikeCollider;
                if (spikeCollider && !entity.isAI && entity.sid === spikeCollider.id) {
                    Renderer_default.fillCircle(ctx, entity.x, entity.y, 10, "#691313");
                }
            }
            if (isMyPlayer) {
                NotificationRenderer_default.render(ctx, player);
            }
            let instakillTarget = InputHandler.instakillTarget;
            if (entity.isPlayer && instakillTarget !== null && entity.sid === instakillTarget.id) {
                Renderer_default.drawTarget(ctx, entity);
                let {bowInsta: bowInsta} = ModuleHandler.staticModules;
                if (bowInsta.active) {
                    Renderer_default.circle(ctx, entity.x, entity.y, bowInsta.distMin, "#eda0ee", .4, 1),
                    Renderer_default.circle(ctx, entity.x, entity.y, bowInsta.distMax, "#eda0ee", .4, 1);
                }
            }
            let {target: velTickTarget, minKB: minKB, maxKB: maxKB} = ModuleHandler.staticModules.velocityTick;
            if (entity.isPlayer && velTickTarget !== null && entity.sid === velTickTarget.id) {
                let diff = Math.abs(maxKB - minKB), length = minKB + (maxKB - minKB) / 2, angle = getAngle(entity.x, entity.y, player.x, player.y), posX = entity.x + Math.cos(angle) * length, posY = entity.y + Math.sin(angle) * length;
                Renderer_default.circle(ctx, posX, posY, diff, "#e25176", .5, 1);
            }
        }
    }, EntityRenderer_default = EntityRenderer;

    class Notify {
        x;
        y;
        timeout={
            value: 0,
            max: 2e3
        };
        constructor(x, y) {
            this.x = x, this.y = y;
        }
        animate() {
            let {value: value, max: max} = this.timeout;
            if (value >= max) {
                NotificationRenderer.remove(this);
                return;
            }
            this.timeout.value += EntityRenderer_default.step;
        }
        render(ctx, player) {
            this.animate(), Renderer_default.renderTracer(ctx, this, player);
        }
    }

    const NotificationRenderer = new class {
        notifications=new Set;
        remove(notify) {
            this.notifications.delete(notify);
        }
        add(object) {
            let {x: x, y: y} = object.pos.current, notify = new Notify(x, y);
            this.notifications.add(notify);
        }
        render(ctx, player) {
            for (let notification of this.notifications) {
                notification.render(ctx, player);
            }
        }
    }, NotificationRenderer_default = NotificationRenderer;

    class SpatialHashGrid2D {
        cellSize=0;
        grid=new Map;
        constructor(cellSize) {
            this.cellSize = cellSize;
        }
        _getKey(x, y) {
            return x << 16 | y;
        }
        clear() {
            this.grid.clear();
        }
        insert(x, y, radius, objectId) {
            let startX = (x - radius) / this.cellSize | 0, startY = (y - radius) / this.cellSize | 0, endX = (x + radius) / this.cellSize | 0, endY = (y + radius) / this.cellSize | 0;
            for (let i = startX; i <= endX; i++) {
                for (let j = startY; j <= endY; j++) {
                    let key = this._getKey(i, j);
                    if (!this.grid.has(key)) {
                        this.grid.set(key, new Set);
                    }
                    this.grid.get(key).add(objectId);
                }
            }
        }
        query(x, y, search = 1, callback) {
            let cellX = x / this.cellSize | 0, cellY = y / this.cellSize | 0, candidates = new Set, callbackSuccess = !1;
            outerLoop: for (let i = -search; i <= search; i++) {
                for (let j = -search; j <= search; j++) {
                    let key = this._getKey(cellX + i, cellY + j);
                    if (this.grid.has(key)) {
                        for (let objectId of this.grid.get(key)) {
                            if (!candidates.has(objectId)) {
                                if (candidates.add(objectId), callback(objectId)) {
                                    callbackSuccess = !0;
                                    break outerLoop;
                                }
                            }
                        }
                    }
                }
            }
            return callbackSuccess;
        }
        queryFull(x, y, search = 1) {
            let cellX = x / this.cellSize | 0, cellY = y / this.cellSize | 0, candidates = new Set;
            for (let i = -search; i <= search; i++) {
                for (let j = -search; j <= search; j++) {
                    let key = this._getKey(cellX + i, cellY + j);
                    if (this.grid.has(key)) {
                        for (let objectId of this.grid.get(key)) {
                            candidates.add(objectId);
                        }
                    }
                }
            }
            return Array.from(candidates);
        }
        remove(x, y, radius, objectId) {
            let startX = (x - radius) / this.cellSize | 0, startY = (y - radius) / this.cellSize | 0, endX = (x + radius) / this.cellSize | 0, endY = (y + radius) / this.cellSize | 0;
            for (let i = startX; i <= endX; i++) {
                for (let j = startY; j <= endY; j++) {
                    let key = this._getKey(i, j);
                    if (this.grid.has(key)) {
                        let cell = this.grid.get(key);
                        if (cell.delete(objectId), cell.size === 0) {
                            this.grid.delete(key);
                        }
                    }
                }
            }
        }
    }

    class Sorting {
        static byDistance(target, typeA, typeB) {
            return (a, b) => {
                let dist1 = target.position[typeA].distanceDefault(a.position[typeB]), dist2 = target.position[typeA].distanceDefault(b.position[typeB]);
                return dist1 - dist2;
            };
        }
        static byAngleDistance(angle) {
            return (a, b) => getAngleDist(a, angle) - getAngleDist(b, angle);
        }
        static byDanger(a, b) {
            return b.danger - a.danger;
        }
    }

    const Sorting_default = Sorting;

    class ObjectManager {
        objects=new Map;
        grid2D=new SpatialHashGrid2D(100);
        reloadingTurrets=new Map;
        attackedObjects=new Map;
        client;
        constructor(client2) {
            this.client = client2;
        }
        insertObject(object) {
            if (this.grid2D.insert(object.pos.current.x, object.pos.current.y, object.collisionScale, object.id),
            this.objects.set(object.id, object), object instanceof PlayerObject) {
                let {PlayerManager: PlayerManager, myPlayer: myPlayer} = this.client, owner = PlayerManager.playerData.get(object.ownerID) || PlayerManager.createPlayer({
                    id: object.ownerID
                });
                if (object.seenPlacement = this.inPlacementRange(object), owner.handleObjectPlacement(object),
                object.type === 22) {
                    if (myPlayer.collidingObject(object, 1) || myPlayer.collidingObject(object, 4)) {
                        myPlayer.teleportPos.setVec(object.pos.current), myPlayer.teleported = !0;
                    }
                }
            }
        }
        createObjects(buffer) {
            for (let i = 0; i < buffer.length; i += 8) {
                let isResource = buffer[i + 6] === null, data = [ buffer[i + 0], buffer[i + 1], buffer[i + 2], buffer[i + 3], buffer[i + 4] ];
                this.insertObject(isResource ? new Resource(...data, buffer[i + 5]) : new PlayerObject(...data, buffer[i + 6], buffer[i + 7]));
            }
        }
        deletedObjects=new Set;
        isDestroyedObject() {
            return this.deletedObjects.size !== 0;
        }
        removeObject(object) {
            if (this.grid2D.remove(object.pos.current.x, object.pos.current.y, object.collisionScale, object.id),
            this.objects.delete(object.id), object instanceof PlayerObject) {
                let player = this.client.PlayerManager.playerData.get(object.ownerID);
                if (player !== void 0) {
                    player.handleObjectDeletion(object);
                    let {myPlayer: myPlayer} = this.client, pos1 = object.pos.current.copy(), pos2 = this.client.myPlayer.pos.current.copy(), distance = pos1.distance(pos2), spikeID = myPlayer.getItemByType(4), range = myPlayer.getItemPlaceScale(spikeID) + object.placementScale + myPlayer.speed + 25;
                    if (distance <= range) {
                        this.deletedObjects.add(object);
                    }
                }
            }
        }
        removeObjectByID(id) {
            let object = this.objects.get(id);
            if (object !== void 0) {
                if (this.removeObject(object), this.client.isOwner) {
                    let pos1 = object.pos.current.copy(), pos2 = this.client.myPlayer.pos.current.copy();
                    if (Settings_default._notificationTracers && !targetInsideRect(pos1, pos2, object.scale)) {
                        NotificationRenderer_default.add(object);
                    }
                }
            }
        }
        removePlayerObjects(player) {
            for (let object of player.objects) {
                this.removeObject(object);
            }
        }
        resetTurret(id) {
            let object = this.objects.get(id);
            if (object instanceof PlayerObject) {
                object.reload = 0, this.reloadingTurrets.set(id, object);
            }
        }
        isEnemyObject(object) {
            if (object instanceof PlayerObject && !this.client.myPlayer.isEnemyByID(object.ownerID)) {
                return !1;
            }
            return !0;
        }
        isTurretReloaded(object, tick = 1) {
            let turret = this.reloadingTurrets.get(object.id);
            if (turret === void 0) {
                return !0;
            }
            return turret.reload > turret.maxReload - tick;
        }
        postTick() {
            for (let [id, turret] of this.reloadingTurrets) {
                if (turret.reload += 1, turret.reload >= turret.maxReload) {
                    turret.reload = turret.maxReload, this.reloadingTurrets.delete(id);
                }
            }
        }
        canPlaceItem(id, position, addRadius = 0) {
            if (id !== 18 && pointInRiver(position)) {
                return !1;
            }
            let item = Items[id];
            return !this.grid2D.query(position.x, position.y, 1, id2 => {
                let object = this.objects.get(id2), scale = item.scale + object.placementScale + addRadius;
                if (position.distance(object.pos.current) < scale) {
                    return !0;
                }
            });
        }
        inPlacementRange(object) {
            let owner = this.client.PlayerManager.playerData.get(object.ownerID);
            if (owner === void 0 || !this.client.PlayerManager.players.includes(owner)) {
                return !1;
            }
            let {previous: a0, current: a1, future: a2} = owner.pos, b0 = object.pos.current, item = Items[object.type], range = owner.scale * 2 + item.scale + item.placeOffset;
            return a0.distance(b0) <= range || a1.distance(b0) <= range || a2.distance(b0) <= range;
        }
        getBestPlacementAngles(options) {
            let {position: position, id: id, targetAngle: targetAngle, ignoreID: ignoreID, reduce: reduce, preplace: preplace, fill: fill} = options, item = DataHandler_default.getItem(id), {myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client, length = myPlayer.getItemPlaceScale(id), angles = [];
            this.grid2D.query(position.x, position.y, 1, id2 => {
                let object = this.objects.get(id2);
                if (ignoreID !== null && ignoreID === object.id) {
                    return;
                }
                let pos1 = object.pos.current, angle = position.angle(pos1), a = object.placementScale + item.scale + 1, b = position.distance(pos1), c = length, cosArg = (b * b + c * c - a * a) / (2 * b * c);
                if (cosArg < -1) {
                    angles.push([ angle, Math.PI ]);
                } else if (cosArg <= 1) {
                    let offset = Math.acos(cosArg);
                    angles.push([ angle, offset ]);
                }
            });
            let finalAngles = findPlacementAngles(angles);
            if (!angles.some(([angle, offset]) => getAngleDist(targetAngle, angle) <= offset)) {
                if (finalAngles.push(targetAngle), finalAngles.length === 1 && fill) {
                    if (item.itemType === 4) {
                        return [];
                    }
                    let offset = Math.asin((2 * item.scale + 1) / (2 * length)) * 2;
                    return finalAngles.push(targetAngle - offset), finalAngles.push(targetAngle + offset),
                    finalAngles.push(reverseAngle(targetAngle)), finalAngles.slice(0, Settings_default._placeAttempts);
                }
            }
            let anglesSorted = finalAngles.sort(Sorting_default.byAngleDistance(targetAngle));
            if (reduce) {
                if (!DataHandler_default.canMoveOnTop(id) && ModuleHandler.move_dir !== null && myPlayer.speed !== 0) {
                    let scale = item.scale, offset = Math.asin(2 * scale / (2 * length));
                    anglesSorted = anglesSorted.filter(angle => getAngleDist(angle, ModuleHandler.move_dir) > offset);
                }
                return anglesSorted.slice(0, Settings_default._placeAttempts);
            }
            return anglesSorted;
        }
    }

    const ObjectManager_default = ObjectManager;

    class PacketManager {
        client;
        Encoder=null;
        Decoder=null;
        packetCount=0;
        constructor(client2) {
            if (this.client = client2, this.client.isOwner) {
                setInterval(() => {
                    GameUI_default.updatePackets(this.packetCount), this.packetCount = 0;
                }, 1e3);
            }
        }
        send(data) {
            let {socket: socket, socketSend: socketSend} = this.client.SocketManager;
            if (socket === null || socket.readyState !== socket.OPEN || this.Encoder === null || socketSend === null) {
                return;
            }
            let [type, ...args] = data;
            // HLM : passer par le canal du jeu quand il existe. Il signe le
            // paquet et lui donne le bon numero de sequence. Deux compteurs
            // concurrents sur une meme connexion font fermer le serveur.
            let SM = this.client.SocketManager;
            // Rien avant le spawn : sur une connexion neuve le serveur
            // n'accepte que "M" en premier paquet.
            if (!SM.hlmSpawned && type !== "M") {
                if (!SM.hlmDropped) {
                    SM.hlmDropped = 0;
                }
                SM.hlmDropped += 1;
                return;
            }
            SM.hlmSent = (SM.hlmSent || 0) + 1;
            if (!SM.hlmLog) SM.hlmLog = [];
            if (SM.hlmLog.length < 40) SM.hlmLog.push(String(type));
            if (type === "M") {
                SM.hlmSpawned = !0;
            }
            let gameSend = SM.gameSend;
            if (gameSend !== null) {
                gameSend.apply(null, [ type ].concat(args));
            } else if (SM.hlmState !== null) {
                // Bot : on signe avec SA cle et SON compteur.
                let binary = HLM.encode(SM.hlmState, this.Encoder, type, args);
                if (binary !== null) socketSend(binary);
            } else {
                socketSend(this.Encoder.encode([ type, args ]));
            }
            if (this.client.isOwner) {
                this.packetCount += 1;
            }
        }
        clanRequest(id, accept) {
            this.send([ "P", id, Number(accept) ]);
        }
        kick(id) {
            this.send([ "Q", id ]);
        }
        joinClan(name) {
            this.send([ "b", name ]);
        }
        createClan(name) {
            if (!/Glotus Client!/i.test(name)) {
                name += " | Glotus Client!";
            }
            this.send([ "L", name ]);
        }
        leaveClan() {
            this.client.myPlayer.joinRequests.length = 0, this.send([ "N" ]);
        }
        equip(type, id) {
            this.send([ "c", 0, id, type ]);
        }
        buy(type, id) {
            this.send([ "c", 1, id, type ]);
        }
        chat(message) {
            this.send([ "6", message ]);
        }
        attack(angle) {
            this.send([ "F", 1, angle ]);
        }
        stopAttack() {
            this.send([ "F", 0, null ]);
        }
        resetMoveDir() {
            this.send([ "e" ]);
        }
        move(angle) {
            this.send([ "9", angle ]);
        }
        autoAttack() {
            this.send([ "K", 1 ]);
        }
        lockRotation() {
            this.send([ "K", 0 ]);
        }
        pingMap() {
            this.send([ "S" ]);
        }
        selectItemByID(id, type) {
            this.send([ "z", id, type ]);
        }
        spawn(name, moofoll, skin) {
            this.send([ "M", {
                name: name,
                moofoll: moofoll,
                skin: skin
            } ]);
        }
        upgradeItem(id) {
            this.send([ "H", id ]);
        }
        updateAngle(radians) {
            this.send([ "D", radians ]);
        }
        pingRequest() {
            this.client.SocketManager.startPing = performance.now(), this.send([ "0" ]);
        }
    }

    class Animal extends Entity_default {
        type;
        prevHealth=0;
        currentHealth=0;
        receivedDamage=0;
        maxHealth=0;
        isDanger=!1;
        isHostile=!1;
        isPlayer=!1;
        constructor(client2) {
            super(client2);
        }
        canBeTrapped() {
            return !("noTrap" in Animals_default[this.type]);
        }
        update(id, type, x, y, angle, health, nameIndex) {
            this.id = id, this.type = type, this.pos.previous.setVec(this.pos.current),
            this.pos.current.setXY(x, y), this.setFuturePosition();
            let animal = Animals_default[type];
            this.angle = angle, this.prevHealth = this.currentHealth, this.currentHealth = health,
            this.maxHealth = animal.health, this.scale = animal.scale;
            let isHostile = animal.hostile && type !== 7;
            this.isHostile = animal.hostile, this.isDanger = isHostile, this.receivedDamage = 0;
            let difference = Math.abs(this.currentHealth - this.prevHealth);
            if (this.currentHealth < this.prevHealth) {
                this.receivedDamage = difference;
            }
        }
        get attackRange() {
            if (this.type === 6) {
                return Animals_default[this.type].hitRange + Config_default.playerScale;
            }
            return this.scale;
        }
        get collisionRange() {
            if (this.type === 6) {
                return Animals_default[this.type].hitRange + Config_default.playerScale;
            }
            return this.scale + 60;
        }
        get canUseTurret() {
            return this.isHostile;
        }
    }

    const Animal_default = Animal;

    class ClientPlayer extends Player_default {
        inventory={};
        weaponXP=[ {}, {} ];
        itemCount=new Map;
        resources={};
        tempGold=0;
        deathPosition=new Vector_default;
        offset=new Vector_default;
        teleportPos=new Vector_default;
        teleported=!1;
        inGame=!1;
        wasDead=!0;
        diedOnce=!1;
        teammates=new Set;
        totalGoldAmount=0;
        age=1;
        upgradeAge=1;
        prevKills=0;
        underTurretAttack=!1;
        upgradeOrder=[];
        upgradeIndex=0;
        joinRequests=[];
        killedSomeone=!1;
        actuallyKilledSomeone=!1;
        totalKills=0;
        deaths=0;
        constructor(client2) {
            super(client2);
            this.reset(!0);
        }
        isMyPlayerByID(id) {
            return id === this.id;
        }
        isTeammateByID(id) {
            return this.teammates.has(id);
        }
        isEnemyByID(id) {
            return !this.isMyPlayerByID(id) && !this.isTeammateByID(id);
        }
        get isSandbox() {
            return /sandbox/.test(location.hostname) || this.client.SocketManager.isSandbox;
        }
        getItemByType(type) {
            return this.inventory[type];
        }
        hasResourcesForType(type) {
            if (this.isSandbox) {
                return !0;
            }
            let res = this.resources, {food: food, wood: wood, stone: stone, gold: gold} = Items[this.getItemByType(type)].cost;
            return res.food >= food && res.wood >= wood && res.stone >= stone && res.gold >= gold;
        }
        getItemCount(group) {
            let item = ItemGroups[group];
            return {
                count: this.itemCount.get(group) || 0,
                limit: this.isSandbox ? "sandboxLimit" in item ? item.sandboxLimit : 99 : item.limit
            };
        }
        hasItemCountForType(type) {
            if (type === 2) {
                return !0;
            }
            let item = Items[this.getItemByType(type)], {count: count, limit: limit} = this.getItemCount(item.itemGroup);
            return count < limit;
        }
        canPlace(type) {
            return type !== null && this.getItemByType(type) !== null && this.hasResourcesForType(type) && this.hasItemCountForType(type);
        }
        canPlaceObject(type, angle) {
            let {myPlayer: myPlayer, ObjectManager: ObjectManager2} = this.client, id = myPlayer.getItemByType(type), current = myPlayer.getPlacePosition(myPlayer.pos.current, id, angle);
            return ObjectManager2.canPlaceItem(id, current);
        }
        getBestDestroyingWeapon(target = null) {
            let primaryID = this.getItemByType(0), primary = DataHandler_default.getWeapon(primaryID), secondaryID = this.getItemByType(1), isHammer = secondaryID === 10, notStick = primary.damage !== 1, notPolearm = primaryID !== 5, {reloading: reloading} = this.client.ModuleHandler.staticModules, primaryDamage = this.getBuildingDamage(primaryID, !1);
            if (isHammer && notStick && notPolearm && (!reloading.isReloaded(1) || reloading.isFasterThan(0, 1)) && reloading.isReloaded(0) && target != null && primaryDamage >= target.health) {
                return 0;
            }
            if (target != null && isHammer && notStick && notPolearm && this.isTrapped) {
                let hammerRange = DataHandler_default.getWeapon(secondaryID).range + target.hitScale + 1, primaryRange = primary.range + target.hitScale, pos1 = this.pos.current, pos2 = target.pos.current, distance = pos1.distance(pos2);
                if (inRange(distance, hammerRange, primaryRange)) {
                    return 0;
                }
            }
            if (isHammer) {
                return 1;
            }
            if (notStick) {
                return 0;
            }
            return null;
        }
        getWeaponRangeByType(type) {
            let item = this.getItemByType(type);
            if (DataHandler_default.isMelee(item)) {
                return DataHandler_default.getWeapon(item).range;
            }
            return 0;
        }
        getFastestWeapon() {
            let primary = DataHandler_default.getWeapon(this.getItemByType(0)), secondaryID = this.getItemByType(1);
            if (secondaryID === null) {
                return 0;
            }
            let secondary = DataHandler_default.getWeapon(secondaryID);
            if (primary.spdMult > secondary.spdMult) {
                return 0;
            }
            return 1;
        }
        getDmgOverTime() {
            let hat = Hats[this.hatID], accessory = Accessories[this.accessoryID], damage = 0;
            if ("healthRegen" in hat) {
                damage += hat.healthRegen;
            }
            if ("healthRegen" in accessory) {
                damage += accessory.healthRegen;
            }
            if (this.poisonCount !== 0) {
                damage += -5;
            }
            return Math.abs(damage);
        }
        getMaxWeaponRangeClient() {
            let primary = this.inventory[0], secondary = this.inventory[1], primaryRange = DataHandler_default.getWeapon(primary).range;
            if (DataHandler_default.isMelee(secondary)) {
                let range = DataHandler_default.getWeapon(secondary).range;
                if (range > primaryRange) {
                    return range;
                }
            }
            return primaryRange;
        }
        getMaxRangeTypeDestroy() {
            let primaryID = this.inventory[0], secondaryID = this.inventory[1], primary = DataHandler_default.getWeapon(primaryID);
            if (DataHandler_default.isMelee(secondaryID)) {
                let secondary = DataHandler_default.getWeapon(secondaryID);
                if (secondaryID === 10 && secondary.range > primary.range) {
                    return {
                        type: 1,
                        range: secondary.range
                    };
                }
            }
            if (primaryID !== 8) {
                return {
                    type: 0,
                    range: primary.range
                };
            }
            return null;
        }
        getPlacePosition(start, itemID, angle) {
            return start.addDirection(angle, this.getItemPlaceScale(itemID));
        }
        tickUpdate() {
            if (this.inGame && this.wasDead) {
                this.wasDead = !1, this.prevKills = 0, this.onFirstTickAfterSpawn();
            }
            let {ModuleHandler: ModuleHandler, PlayerManager: PlayerManager} = this.client;
            if (this.killedSomeone = !1, this.actuallyKilledSomeone = !1, this.totalKills > this.prevKills) {
                if (this.prevKills = this.totalKills, this.killedSomeone = !0, PlayerManager.prevPlayers.size !== 0) {
                    this.actuallyKilledSomeone = !0;
                }
            }
            ModuleHandler.postTick();
        }
        updateHealth(health) {
            if (!this.inGame) {
                return;
            }
            if (super.updateHealth(health), this.shameActive) {
                return;
            }
            if (health < 100) {
                let {ModuleHandler: ModuleHandler} = this.client;
                ModuleHandler.staticModules.shameReset.healthUpdate();
            }
        }
        playerInit(id) {
            this.id = id;
            let {PlayerManager: PlayerManager} = this.client;
            if (!PlayerManager.playerData.has(id)) {
                PlayerManager.playerData.set(id, this);
            }
        }
        onFirstTickAfterSpawn() {
            let {ModuleHandler: ModuleHandler, isOwner: isOwner} = this.client, {mouse: mouse, staticModules: staticModules} = ModuleHandler;
            if (ModuleHandler.equip(0, 0), ModuleHandler.updateAngle(mouse.sentAngle, !0),
            !isOwner) {
                let owner = this.client.owner;
                UI_default.updateBotOption(this.client, "title"), owner.clientIDList.add(this.id),
                staticModules.tempData.setAttacking(owner.ModuleHandler.attacking), staticModules.tempData.setStore(0, owner.ModuleHandler.store[0].actual),
                staticModules.tempData.setStore(1, owner.ModuleHandler.store[1].actual);
            }
        }
        playerSpawn() {
            this.inGame = !0;
        }
        isUpgradeWeapon(id) {
            let weapon = DataHandler_default.getWeapon(id);
            if ("upgradeOf" in weapon) {
                return this.inventory[weapon.itemType] === weapon.upgradeOf;
            }
            return !0;
        }
        newUpgrade(points, age) {
            if (this.upgradeAge = age, points === 0 || age === 10) {
                return;
            }
            let ids = [];
            for (let weapon of Weapons) {
                if (weapon.age === age && this.isUpgradeWeapon(weapon.id)) {
                    ids.push(weapon.id);
                }
            }
            for (let item of Items) {
                if (item.age === age) {
                    ids.push(item.id + 16);
                }
            }
            if (!this.client.isOwner) {
                let id = this.client.owner.myPlayer.upgradeOrder[this.upgradeIndex];
                if (id !== void 0 && ids.includes(id)) {
                    this.upgradeIndex += 1, this.client.ModuleHandler.upgradeItem(id);
                }
            }
        }
        updateAge(age) {
            this.age = age;
        }
        upgradeItem(id) {
            this.upgradeOrder.push(id);
            let {isOwner: isOwner, clients: clients} = this.client;
            if (isOwner) {
                for (let client2 of clients) {
                    let {age: age, upgradeAge: upgradeAge} = client2.myPlayer;
                    if (age > this.upgradeAge) {
                        client2.myPlayer.newUpgrade(1, upgradeAge);
                    }
                }
            }
            if (id < 16) {
                let weapon = DataHandler_default.getWeapon(id);
                this.inventory[weapon.itemType] = id;
                let XP = this.weaponXP[weapon.itemType];
                XP.current = 0, XP.max = -1;
            } else {
                id -= 16;
                let item = Items[id];
                this.inventory[item.itemType] = id;
            }
            this.upgradeAge += 1;
        }
        updateClanMembers(teammates) {
            this.teammates.clear();
            for (let i = 0; i < teammates.length; i += 2) {
                let id = teammates[i + 0];
                if (!this.isMyPlayerByID(id)) {
                    this.teammates.add(id);
                }
            }
        }
        updateItemCount(group, count) {
            if (this.itemCount.set(group, count), this.client.isOwner) {
                GameUI_default.updateItemCount(group);
            }
        }
        updateResources(type, amount) {
            let previousAmount = this.resources[type];
            if (this.resources[type] = amount, type === "gold") {
                this.tempGold = amount;
                return;
            }
            if (amount < previousAmount) {
                return;
            }
            let difference = amount - previousAmount;
            if (type === "kills") {
                if (this.totalKills += difference, this.client.StatsManager.kills = difference,
                this.client.StatsManager.totalKills = difference, this.client.owner.StatsManager.globalKills = difference,
                this.client.isOwner) {
                    GameUI_default.updateTotalKills(this.totalKills);
                }
                return;
            }
            this.updateWeaponXP(difference);
        }
        updateWeaponXP(amount) {
            let {next: next} = this.getWeaponVariant(this.weapon.current), XP = this.weaponXP[DataHandler_default.getWeapon(this.weapon.current).itemType], maxXP = WeaponVariants[next].needXP;
            if (XP.current += amount, XP.max !== -1 && XP.current >= XP.max) {
                XP.current -= XP.max, XP.max = maxXP;
                return;
            }
            if (XP.max === -1) {
                XP.max = maxXP;
            }
            if (XP.current >= XP.max) {
                XP.current -= XP.max, XP.max = -1;
            }
        }
        resetResources() {
            this.resources.food = 100, this.resources.wood = 100, this.resources.stone = 100,
            this.resources.gold = 100, this.resources.kills = 0;
        }
        resetInventory() {
            this.inventory[0] = 0, this.inventory[1] = null, this.inventory[2] = 0, this.inventory[3] = 3,
            this.inventory[4] = 6, this.inventory[5] = 10, this.inventory[6] = null, this.inventory[7] = null,
            this.inventory[8] = null, this.inventory[9] = null;
        }
        resetWeaponXP() {
            for (let XP of this.weaponXP) {
                XP.current = 0, XP.max = -1;
            }
        }
        spawn(customName) {
            let name = customName || window.localStorage.getItem("moo_name") || "", skin = Number(window.localStorage.getItem("skin_color")) || 0;
            this.client.PacketManager.spawn(name, 1, skin === 10 ? "constructor" : skin);
        }
        handleJoinRequest(id, name) {
            this.joinRequests.push([ id, name ]);
        }
        reset(first = !1) {
            this.resetResources(), this.resetInventory(), this.resetWeaponXP();
            let {ModuleHandler: ModuleHandler, PlayerManager: PlayerManager} = this.client;
            if (ModuleHandler.reset(), this.inGame = !1, this.wasDead = !0, this.upgradeOrder.length = 0,
            this.upgradeIndex = 0, first) {
                return;
            }
            if (this.previousHealth = 100, this.currentHealth = 100, this.tempHealth = 100,
            this.shameActive = !1, this.shameCount = 0, this.shameTimer = 0, this.deathPosition.setVec(this.pos.current),
            this.diedOnce = !0, this.client.StatsManager.deaths = 1, this.deaths += 1, this.client.isOwner) {
                GameUI_default.reset(), GameUI_default.updateTotalDeaths(this.deaths);
            }
        }
    }

    const ClientPlayer_default = ClientPlayer;

    class PlayerManager {
        playerData=new Map;
        players=[];
        enemies=[];
        prevPlayers=new Set;
        animalData=new Map;
        clanData=new Map;
        start=Date.now();
        step=0;
        damagesByHits=[];
        lastEnemyReceivedDamage=[ 0, 0 ];
        nearestTeammate=null;
        client;
        constructor(client2) {
            this.client = client2;
        }
        get timeSinceTick() {
            return Date.now() - this.start;
        }
        getEntity(id, isPlayer) {
            if (isPlayer && this.playerData.has(id)) {
                return this.playerData.get(id);
            } else if (!isPlayer && this.animalData.has(id)) {
                return this.animalData.get(id);
            }
            return null;
        }
        createPlayer({socketID: socketID, id: id, nickname: nickname, health: health, skinID: skinID}) {
            let {myPlayer: myPlayer} = this.client;
            if (socketID === this.client.clientID && myPlayer.id === -1) {
                myPlayer.playerInit(id);
            }
            let player = this.playerData.get(id) || new Player_default(this.client);
            if (!this.playerData.has(id)) {
                this.playerData.set(id, player);
            }
            if (player.id = id, player.prevNickname = player.nickname, player.nickname = nickname || "",
            player.currentHealth = health || 100, player.skinID = typeof skinID > "u" ? -1 : skinID,
            player.init(), myPlayer.isMyPlayerByID(id)) {
                myPlayer.playerSpawn();
            }
            return player;
        }
        createClan(name, ownerID) {
            this.clanData.set(name, ownerID);
        }
        deleteClan(name) {
            this.clanData.delete(name);
        }
        clanExist(name) {
            return name !== null && this.clanData.has(name);
        }
        canHitTarget(player, weaponID, target) {
            let pos = target.pos.current, distance = player.pos.current.distance(pos), angle = player.pos.current.angle(pos), range = DataHandler_default.getWeapon(weaponID).range + target.hitScale;
            return distance <= range && getAngleDist(angle, player.angle) <= Config_default.gatherAngle;
        }
        attackPlayer(id, gathering, weaponID) {
            let player = this.playerData.get(id);
            if (player === void 0) {
                return;
            }
            let {hatID: hatID, reload: reload} = player, {myPlayer: myPlayer, ObjectManager: ObjectManager2} = this.client;
            if (player.lastAttacked = myPlayer.tickCount, myPlayer.isMyPlayerByID(id) && !myPlayer.inGame) {
                return;
            }
            let weapon = DataHandler_default.getWeapon(weaponID), type = weapon.itemType;
            if (player.updateMaxReload(reload[type], weaponID), player.resetCurrentReload(reload[type]),
            myPlayer.isEnemyByID(id)) {
                if (this.canHitTarget(player, weaponID, myPlayer)) {
                    let {isAble: isAble, count: count} = player.canDealPoison(weaponID);
                    if (isAble) {
                        myPlayer.poisonCount = count;
                    }
                }
            }
            if (gathering === 1) {
                let objects = ObjectManager2.attackedObjects;
                for (let [id2, data] of objects) {
                    let [hitAngle, object] = data;
                    if (this.canHitTarget(player, weaponID, object) && getAngleDist(hitAngle, player.angle) <= 1.25) {
                        if (objects.delete(id2), object instanceof PlayerObject) {
                            let damage = player.getBuildingDamage(weaponID);
                            object.health = Math.max(0, object.health - damage);
                        } else if (player === myPlayer) {
                            let amount = hatID === 9 ? 1 : 0;
                            if (object.type === 3) {
                                amount += weapon.gather + 4;
                            }
                            myPlayer.updateWeaponXP(amount);
                        }
                    }
                }
            }
        }
        updatePlayer(buffer) {
            this.players.length = 0, this.enemies.length = 0, this.damagesByHits.length = 0,
            this.nearestTeammate = null;
            let now = Date.now();
            this.step = now - this.start, this.start = now;
            let {myPlayer: myPlayer, isOwner: isOwner, EnemyManager: EnemyManager2} = this.client;
            for (let i = 0; i < buffer.length; i += 13) {
                let id = buffer[i], player = this.playerData.get(id);
                if (this.players.push(player), player.update(id, buffer[i + 1], buffer[i + 2], buffer[i + 3], buffer[i + 4], buffer[i + 5], buffer[i + 6], buffer[i + 7], buffer[i + 8], buffer[i + 9], buffer[i + 10]),
                !this.client.isBotByID(id) && !myPlayer.isMyPlayerByID(id) && myPlayer.isTeammateByID(id) && EnemyManager2.isNear(player, this.nearestTeammate, myPlayer)) {
                    this.nearestTeammate = player;
                } else if (myPlayer.isEnemyByID(id)) {
                    this.enemies.push(player);
                }
            }
        }
        updateAnimal(buffer) {
            let {EnemyManager: EnemyManager2} = this.client;
            for (let i = 0; i < buffer.length; i += 7) {
                let id = buffer[i];
                if (!this.animalData.has(id)) {
                    this.animalData.set(id, new Animal_default(this.client));
                }
                let animal = this.animalData.get(id);
                animal.update(id, buffer[i + 1], buffer[i + 2], buffer[i + 3], buffer[i + 4], buffer[i + 5], buffer[i + 6]),
                EnemyManager2.handleAnimal(animal);
            }
        }
        postTick() {
            let {EnemyManager: EnemyManager2, ProjectileManager: ProjectileManager, ObjectManager: ObjectManager2, myPlayer: myPlayer, isOwner: isOwner} = this.client;
            if (ProjectileManager.postTick(), EnemyManager2.handleEnemies(this.enemies),
            ObjectManager2.postTick(), myPlayer.inGame) {
                myPlayer.tickUpdate();
            }
            if (ObjectManager2.deletedObjects.clear(), (Settings_default._autospawn || !isOwner) && !myPlayer.inGame) {
                myPlayer.spawn();
            }
        }
        isEnemy(target1, target2) {
            return target1 == null || target2 == null || target1 !== target2 && (target1.clanName === null || target2.clanName === null || target1.clanName !== target2.clanName);
        }
        isEnemyByID(ownerID, target) {
            let player = this.playerData.get(ownerID);
            if (player == null) {
                throw Error("isEnemyByID Error: Failed to find an owner!");
            }
            if (player instanceof ClientPlayer_default) {
                return player.isEnemyByID(target.id);
            }
            if (target instanceof ClientPlayer_default) {
                return target.isEnemyByID(player.id);
            }
            return this.isEnemy(player, target);
        }
        isEnemyTarget(owner, target) {
            if (target instanceof Animal_default) {
                return !0;
            }
            return this.isEnemyByID(owner.id, target);
        }
        canShoot(ownerID, target) {
            return target instanceof Animal_default || this.isEnemyByID(ownerID, target);
        }
        canMoveOnTop(object) {
            if (object instanceof Resource) {
                return !1;
            }
            let item = DataHandler_default.getItem(object.type), isEnemyObject = this.isEnemyByID(object.ownerID, this.client.myPlayer);
            if ("ignoreCollision" in item && (object.type !== 15 || !isEnemyObject)) {
                return !0;
            }
            return !1;
        }
        lookingShield(owner, target) {
            if (owner instanceof Animal_default) {
                return !1;
            }
            if (owner.weapon.current !== 11) {
                return !1;
            }
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client, pos1 = owner.pos.current, pos2 = target.pos.current, angle = pos1.angle(pos2), ownerAngle = myPlayer.isMyPlayerByID(owner.id) ? ModuleHandler.mouse.sentAngle : owner.angle;
            return getAngleDist(angle, ownerAngle) <= Config_default.shieldAngle;
        }
    }

    const PlayerManager_default = PlayerManager;

    class ProjectileManager {
        client;
        projectiles=new Map;
        ignoreCreation=new Map;
        dangerProjectiles=new Set;
        toRemove=new Set;
        totalDamage=0;
        constructor(client2) {
            this.client = client2;
        }
        createProjectile(projectile) {
            let key = projectile.speed;
            if (!this.projectiles.has(key)) {
                this.projectiles.set(key, []);
            }
            this.projectiles.get(key).push(projectile);
        }
        foundProjectile(projectile) {
            let owner = projectile.owner;
            if (owner === null) {
                return;
            }
            let {PlayerManager: PlayerManager2, myPlayer: myPlayer} = this.client;
            if (PlayerManager2.isEnemyByID(owner.id, myPlayer)) {
                let pos1 = projectile.pos.current, pos2 = myPlayer.pos.current, distance = pos1.distance(pos2), angle = pos1.angle(pos2), offset = Math.asin(2 * myPlayer.scale / (2 * distance));
                if (getAngleDist(angle, projectile.angle) <= offset) {
                    this.dangerProjectiles.add(projectile);
                }
            }
        }
        foundProjectileThreat(projectile) {
            let owner = projectile.owner;
            if (owner === null) {
                return;
            }
            let {PlayerManager: PlayerManager2, myPlayer: myPlayer, SocketManager: SocketManager} = this.client;
            for (let enemy of PlayerManager2.enemies) {
                if (!PlayerManager2.isEnemyByID(owner.id, enemy)) {
                    continue;
                }
                let pos1 = projectile.pos.current, pos2 = enemy.pos.current, distance = pos1.distance(pos2), angle = pos1.angle(pos2), offset = Math.asin(2 * enemy.scale / (2 * distance));
                if (getAngleDist(angle, projectile.angle) <= offset) {
                    let tickDistance = Math.ceil(distance / (projectile.speed * SocketManager.TICK));
                    enemy.nextDamageTick = myPlayer.tickCount + tickDistance;
                }
            }
        }
        postTick() {
            this.projectiles.clear(), this.totalDamage = 0;
            for (let proj of this.dangerProjectiles) {
                if (proj.life -= 1, proj.shouldRemove() || this.toRemove.delete(proj.id)) {
                    this.dangerProjectiles.delete(proj);
                    continue;
                }
                this.totalDamage += proj.damage;
            }
            this.toRemove.clear();
        }
    }

    const ProjectileManager_default = ProjectileManager;

    class Projectile {
        pos={};
        angle;
        range;
        speed;
        type;
        onPlatform;
        id;
        isTurret;
        scale;
        maxRange;
        damage;
        owner=null;
        life=9;
        constructor(angle, range, speed, type, onPlatform, id, maxRange) {
            this.isTurret = type === 1, this.angle = angle, this.range = range, this.speed = speed,
            this.type = type, this.onPlatform = onPlatform, this.id = id, this.scale = Projectiles[type].scale,
            this.maxRange = maxRange || 0, this.damage = Projectiles[type].damage;
        }
        formatFromCurrent(pos, increase) {
            if (this.isTurret) {
                return pos;
            }
            return pos.addDirection(this.angle, increase ? 70 : -70);
        }
        shouldRemove() {
            return this.life <= 0;
        }
    }

    const Projectile_default = Projectile;

    const StoreHandler = new class {
        isOpened=!1;
        store=[ {
            previous: -1,
            current: -1,
            list: new Map
        }, {
            previous: -1,
            current: -1,
            list: new Map
        } ];
        currentType=0;
        isRightStore(type) {
            return this.isOpened && this.currentType === type;
        }
        createStore(type) {
            let storeContainer = document.createElement("div");
            storeContainer.id = "storeContainer", storeContainer.style.display = "none";
            let button = document.createElement("div");
            button.id = "toggleStoreType", button.textContent = type === 0 ? "Hats" : "Accessories",
            button.onmousedown = () => {
                if (this.currentType = this.currentType === 0 ? 1 : 0, button.textContent = this.currentType === 0 ? "Hats" : "Accessories",
                this.isOpened) {
                    this.fillStore(this.currentType);
                }
            }, storeContainer.appendChild(button);
            let itemHolder = document.createElement("div");
            itemHolder.id = "itemHolder", storeContainer.appendChild(itemHolder), itemHolder.addEventListener("wheel", event => {
                event.preventDefault();
                let scale = Math.sign(event.deltaY) * 50;
                itemHolder.scroll(0, itemHolder.scrollTop + scale);
            });
            let {gameUI: gameUI} = GameUI_default.getElements();
            gameUI.appendChild(storeContainer);
        }
        getTextEquip(type, id, price) {
            let {list: list, current: current} = this.store[type];
            if (current === id) {
                return "Unequip";
            }
            if (list.has(id) || price === 0) {
                return "Equip";
            }
            return "Buy";
        }
        generateStoreElement(type, id, name, price, isTop) {
            let src = [ [ "hats/hat", "accessories/access" ][type], id ];
            if (isTop) {
                src.push("p");
            }
            let html = `\n            <div class="storeItemContainer">\n                <img class="storeHat" src="./img/${src.join("_")}.png">\n                <span class="storeItemName">${name}</span>\n                <div class="equipButton" data-id="${id}">${this.getTextEquip(type, id, price)}</div>\n            </div>\n        `, div = document.createElement("div");
            div.innerHTML = html;
            let img = div.querySelector(".storeHat");
            img.src = `./img/${src.join("_")}.png`;
            let equipButton = div.querySelector(".equipButton");
            return equipButton.onmousedown = () => {
                client.ModuleHandler.equip(type, id, !0, !0);
            }, div.firstElementChild;
        }
        fillStore(type) {
            let {itemHolder: itemHolder} = GameUI_default.getElements();
            itemHolder.innerHTML = "";
            let items = Settings_default._storeItems[type];
            for (let id of items) {
                let item = DataHandler_default.getStoreItem(type, id), element = this.generateStoreElement(type, id, item.name, item.price, "topSprite" in item);
                itemHolder.appendChild(element);
            }
        }
        handleEquipUpdate(type, prev, curr, isBuy) {
            if (!this.isRightStore(type)) {
                return;
            }
            let current = document.querySelector(`.equipButton[data-id="${curr}"]`);
            if (current !== null) {
                current.textContent = isBuy ? "Equip" : "Unequip";
            }
            if (!isBuy && prev !== -1) {
                let previous = document.querySelector(`.equipButton[data-id="${prev}"]`);
                if (previous !== null) {
                    previous.textContent = "Equip";
                }
            }
        }
        updateStoreState(type, action, id) {
            let store2 = this.store[type];
            if (action === 0) {
                store2.previous = store2.current, store2.current = id;
                let {previous: previous, current: current, list: list} = store2;
                list.set(previous, 0), list.set(current, 1), this.handleEquipUpdate(type, store2.previous, id, !1);
            } else {
                store2.list.set(id, 0), this.handleEquipUpdate(type, store2.previous, id, !0);
            }
        }
        closeStore() {
            let {storeContainer: storeContainer, itemHolder: itemHolder} = GameUI_default.getElements();
            itemHolder.innerHTML = "", storeContainer.style.display = "none", this.isOpened = !1;
        }
        openStore() {
            GameUI_default.closePopups();
            let {storeContainer: storeContainer} = GameUI_default.getElements();
            this.fillStore(this.currentType), storeContainer.style.display = "", storeContainer.classList.remove("closedItem"),
            this.isOpened = !0;
        }
        toggleStore() {
            let {storeContainer: storeContainer, itemHolder: itemHolder} = GameUI_default.getElements();
            if (this.isOpened) {
                itemHolder.innerHTML = "";
            } else {
                GameUI_default.closePopups(), this.fillStore(this.currentType);
            }
            storeContainer.style.display = storeContainer.style.display === "none" ? "" : "none",
            this.isOpened = !this.isOpened;
        }
        init() {
            this.createStore(0);
        }
    }, StoreHandler_default = StoreHandler;

    class SocketManager {
        client;
        socket=null;
        socketSend=null;
        gameSend=null;
        hlmSpawned=!1;
        hlmPingStarted=!1;
        hlmState=null;
        PacketQueue=[];
        startPing=Date.now();
        pong=0;
        TICK=111.11111111111111;
        packetCount=0;
        action=null;
        constructor(client2) {
            this.client = client2;
        }
        get isSandbox() {
            return this.socket !== null && /localhost/.test(this.socket.url);
        }
        init(socket) {
            if (this.socket = socket, this.socketSend = socket.send.bind(socket), socket.addEventListener("message", event => this.handleMessage(event)),
            socket.addEventListener("close", event => {
                // Seule information qui dit POURQUOI le serveur coupe.
                console.error("[HLM] SOCKET FERME  code:", event.code, " raison:",
                    event.reason || "(vide)", " propre:", event.wasClean,
                    " paquets emis par nous:", this.hlmSent || 0,
                    " sequence du jeu:", (window.__glotusEnc && window.__glotusEnc())
                        ? window.__glotusEnc().seq : "n/a");
                console.error("[HLM] derniers types emis :", (this.hlmLog || []).join(" "),
                    " | retenus avant spawn :", this.hlmDropped || 0,
                    " | spawn parti :", this.hlmSpawned);
            }),
            !this.client.isOwner) {
                return;
            }
            // ==========================================================
            //  HLM - INTERCEPTION DES ENVOIS DU JEU
            //  Avant : on remplacait socket.send. Le jeu ne passe plus par
            //  la - il capture WebSocket.prototype.send au chargement de
            //  son bundle et appelle cette reference native. Le spawn
            //  n'etait donc plus intercepte.
            //  On enveloppe desormais la methode send de son objet reseau,
            //  que le bundle reecrit nous expose. Bonus decisif : ses
            //  paquets restent numerotes par SON compteur de sequence, et
            //  les notres empruntent le meme - il n'y en a qu'un.
            // ==========================================================
            let that = this, io = window.__glotusIO ? window.__glotusIO() : null;
            if (io === null) {
                Logger.error("Objet reseau du jeu introuvable (crochet exposeIO)");
                return;
            }
            let _send = io.send;
            this.gameSend = function() {
                return _send.apply(io, arguments);
            };
            io.send = function(type) {
                if (type === "M") {
                    that.hlmSpawned = !0;
                    let data2 = arguments[1];
                    data2.skin = GameUI_default.selectSkinColor(CustomStorage.get("skin_color") || 0),
                    that.client.PacketManager.spawn(data2.name, data2.moofoll, data2.skin);
                    return;
                }
                return _send.apply(this, arguments);
            };
        }
        pingTimeout;
        handlePing() {
            if (this.pong = Math.round(performance.now() - this.startPing), this.client.isOwner) {
                GameUI_default.updatePing(this.pong);
            }
            clearTimeout(this.pingTimeout), this.pingTimeout = setTimeout(() => {
                this.client.PacketManager.pingRequest();
            }, 3e3);
        }
        handleMessage(event) {
            let decoder = this.client.PacketManager.Decoder;
            if (decoder === null) {
                return;
            }
            let data = event.data, decoded = decoder.decode(new Uint8Array(data));
            // HLM : en mode chiffre le type arrive en NOMBRE. Sans traduction,
            // aucun cas du switch ne correspondait et le client restait vide.
            if (decoded[0] === "io-init" && !this.client.isOwner) {
                // Un bot a SA propre graine : on construit son etat a lui.
                this.hlmState = HLM.makeState(decoded[1]);
            }
            if (typeof decoded[0] === "number") {
                // Le proprietaire lit les tables du jeu, un bot les siennes.
                let s2c = null;
                if (this.client.isOwner) {
                    let enc = window.__glotusEnc ? window.__glotusEnc() : null;
                    if (enc !== null) s2c = enc.tables.s2c;
                } else if (this.hlmState !== null) {
                    s2c = this.hlmState.s2c;
                }
                if (s2c === null) return;
                decoded[0] = s2c.dec[decoded[0]];
                if (decoded[0] === undefined) return;
            }
            let temp = [ decoded[0], ...decoded[1] ], {myPlayer: myPlayer, EnemyManager: EnemyManager2, ModuleHandler: ModuleHandler, PlayerManager: PlayerManager2, ObjectManager: ObjectManager2, ProjectileManager: ProjectileManager2, LeaderboardManager: LeaderboardManager2, PacketManager: PacketManager2} = this.client;
            switch (temp[0]) {
              case "0":
                this.handlePing();
                break;

              case "io-init":
                // HLM : plus de ping ici. Le journal de fermeture l'a montre :
                // le premier paquet de la connexion etait un "0" (ping) envoye
                // des le io-init, avant le "M" de spawn. Le serveur fermait
                // proprement (code 1000) juste apres - la sequence du jeu etait
                // restee a 1, donc le spawn n'est jamais parti. Le ping demarre
                // maintenant a l'arrivee du paquet "C", donc apres le spawn.
                if (this.client.connectSuccess = !0, this.client.clientID = temp[1],
                this.client.isOwner) {
                    GameUI_default.loadGame(), Logger.staticLog("%c Glotus Client! ", "background: #f5d951; color: #000; font-weight: bold; font-size: 20px;"),
                    GameUI_default.handleMessageLog("GLOTUS"), Logger.test("Successfully connected to a server.. [Glotus Client!]"),
                    document.title = "Glotus Client";
                } else {
                    let originalName = window.localStorage.getItem("moo_name") || "Player";
                    this.client.myPlayer.spawn(originalName), this.socket.dispatchEvent(new Event("connected")),
                    Logger.test("Bot spawned.. [Glotus Client!]");
                }
                break;

              case "C":
                myPlayer.playerInit(temp[1]);
                if (!this.hlmPingStarted) {
                    this.hlmPingStarted = !0, PacketManager2.pingRequest();
                }
                break;

              case "P":
                myPlayer.reset(), this.client.InputHandler.reset();
                break;

              case "N":
                this.PacketQueue.push(() => {
                    let type = temp[1] === "points" ? "gold" : temp[1];
                    myPlayer.updateResources(type, temp[2]);
                });
                break;

              case "D":
                {
                    let data2 = temp[1];
                    PlayerManager2.createPlayer({
                        socketID: data2[0],
                        id: data2[1],
                        nickname: data2[2],
                        health: data2[6],
                        skinID: data2[9]
                    });
                    break;
                }

              case "O":
                {
                    let player = PlayerManager2.playerData.get(temp[1]);
                    if (player !== void 0) {
                        player.updateHealth(temp[2]);
                    }
                    break;
                }

              case "a":
                PlayerManager2.updatePlayer(temp[1]);
                for (let i = 0; i < this.PacketQueue.length; i++) {
                    this.PacketQueue[i]();
                }
                this.PacketQueue.length = 0, ObjectManager2.attackedObjects.clear(), EnemyManager2.preReset(),
                this.action = createAction(() => {
                    PlayerManager2.postTick();
                }, 1);
                break;

              case "I":
                PlayerManager2.updateAnimal(temp[1] || []);
                break;

              case "H":
                if (ObjectManager2.createObjects(temp[1]), this.action !== null) {
                    this.action();
                }
                break;

              case "Q":
                ObjectManager2.removeObjectByID(temp[1]);
                break;

              case "R":
                {
                    let player = PlayerManager2.playerData.get(temp[1]);
                    if (player !== void 0) {
                        ObjectManager2.removePlayerObjects(player);
                    }
                    break;
                }

              case "L":
                {
                    let object = ObjectManager2.objects.get(temp[2]);
                    if (object instanceof Resource || object && object.isDestroyable) {
                        ObjectManager2.attackedObjects.set(getUniqueID(), [ temp[1], object ]);
                    }
                    break;
                }

              case "K":
                this.PacketQueue.push(() => PlayerManager2.attackPlayer(temp[1], temp[2], temp[3]));
                break;

              case "M":
                {
                    let id = temp[1], angle = temp[2], turret = ObjectManager2.objects.get(id);
                    if (turret instanceof PlayerObject) {
                        let creations = ProjectileManager2.ignoreCreation, pos = turret.pos.current.makeString();
                        creations.set(pos + ":" + angle, turret);
                        let owner = PlayerManager2.playerData.get(turret.ownerID);
                        if (owner !== void 0) {
                            let projTurret = Projectiles[1], projectile = new Projectile_default(angle, projTurret.range, projTurret.speed, projTurret.index, projTurret.layer, -1);
                            if (projectile.pos.current = turret.pos.current.copy(), projectile.owner = owner,
                            turret.projectile = projectile, PlayerManager2.isEnemyByID(turret.ownerID, myPlayer)) {
                                ProjectileManager2.foundProjectile(projectile);
                            }
                            ProjectileManager2.foundProjectileThreat(projectile);
                        }
                    }
                    this.PacketQueue.push(() => ObjectManager2.resetTurret(id));
                    break;
                }

              case "X":
                {
                    let x = temp[1], y = temp[2], angle = temp[3], key = `${x}:${y}:${angle}`;
                    if (ProjectileManager2.ignoreCreation.has(key)) {
                        let proj = ProjectileManager2.ignoreCreation.get(key).projectile;
                        if (proj !== null) {
                            proj.id = temp[8];
                        }
                        ProjectileManager2.ignoreCreation.delete(key);
                        return;
                    }
                    let projectile = new Projectile_default(angle, temp[4], temp[5], temp[6], temp[7], temp[8]);
                    projectile.pos.current = projectile.formatFromCurrent(new Vector_default(x, y), !1),
                    ProjectileManager2.createProjectile(projectile);
                    break;
                }

              case "Y":
                {
                    let id = temp[1];
                    ProjectileManager2.toRemove.add(id);
                    break;
                }

              case "4":
                myPlayer.updateClanMembers(temp[1]);
                break;

              case "3":
                if (typeof temp[1] !== "string") {
                    myPlayer.teammates.clear();
                }
                break;

              case "g":
                break;

              case "2":
                myPlayer.handleJoinRequest(temp[1], temp[2]);
                break;

              case "T":
                if (temp.length === 4) {
                    myPlayer.updateAge(temp[3]);
                }
                break;

              case "U":
                myPlayer.newUpgrade(temp[1], temp[2]);
                break;

              case "S":
                myPlayer.updateItemCount(temp[1], temp[2]);
                break;

              case "G":
                LeaderboardManager2.update(temp[1]);
                break;

              case "5":
                {
                    let action = temp[1] === 0 ? 1 : 0;
                    if (StoreHandler_default.updateStoreState(temp[3], action, temp[2]), temp[1] === 0) {
                        let boughtStorage = ModuleHandler.bought[temp[3]];
                        if (boughtStorage !== void 0) {
                            boughtStorage.add(temp[2]);
                        }
                    }
                    break;
                }

              case "A":
                {
                    let teams = temp[1].teams;
                    for (let team of teams) {
                        PlayerManager2.createClan(team.sid, team.owner);
                    }
                    break;
                }

              case "g":
                PlayerManager2.createClan(temp[1].sid, temp[1].owner);
                break;

              case "1":
                PlayerManager2.deleteClan(temp[1]);
                break;

              case "6":
                {
                    let id = temp[1], message = temp[2], player = PlayerManager2.playerData.get(id);
                    if (this.client.isOwner && player) {
                        GameUI_default.handleMessageLog(`${player.nickname}: ${message}`);
                    }
                    break;
                }

              case "7":
                break;

              default:
                break;
            }
        }
    }

    const SocketManager_default = SocketManager;

    class StatsManager {
        client;
        kills=0;
        _totalKills=0;
        _globalKills=0;
        _deaths=0;
        _autoSyncTimes=0;
        _velocityTickTimes=0;
        _spikeSyncHammerTimes=0;
        _spikeSyncTimes=0;
        _spikeTickTimes=0;
        _knockbackTickTrapTimes=0;
        _knockbackTickHammerTimes=0;
        _knockbackTickTimes=0;
        constructor(client2) {
            this.client = client2;
        }
        init() {
            this.totalKills = Settings_default._totalKills, this.globalKills = Settings_default._globalKills,
            this.deaths = Settings_default._deaths, this.autoSyncTimes = Settings_default._autoSyncTimes,
            this.velocityTickTimes = Settings_default._velocityTickTimes, this.spikeSyncHammerTimes = Settings_default._spikeSyncHammerTimes,
            this.spikeSyncTimes = Settings_default._spikeSyncTimes, this.spikeTickTimes = Settings_default._spikeTickTimes,
            this.knockbackTickTrapTimes = Settings_default._knockbackTickTrapTimes, this.knockbackTickHammerTimes = Settings_default._knockbackTickHammerTimes,
            this.knockbackTickTimes = Settings_default._knockbackTickTimes;
        }
        get totalKills() {
            return this._totalKills;
        }
        get globalKills() {
            return this._globalKills;
        }
        get deaths() {
            return this._deaths;
        }
        get autoSyncTimes() {
            return this._autoSyncTimes;
        }
        get velocityTickTimes() {
            return this._velocityTickTimes;
        }
        get spikeSyncHammerTimes() {
            return this._spikeSyncHammerTimes;
        }
        get spikeSyncTimes() {
            return this._spikeSyncTimes;
        }
        get spikeTickTimes() {
            return this._spikeTickTimes;
        }
        get knockbackTickTrapTimes() {
            return this._knockbackTickTrapTimes;
        }
        get knockbackTickHammerTimes() {
            return this._knockbackTickHammerTimes;
        }
        get knockbackTickTimes() {
            return this._knockbackTickTimes;
        }
        set totalKills(value) {
            if (this._totalKills += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_totalKills", this._totalKills);
        }
        set globalKills(value) {
            if (this._globalKills += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_globalKills", this._globalKills);
        }
        set deaths(value) {
            if (this._deaths += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_deaths", this._deaths);
        }
        set autoSyncTimes(value) {
            if (this._autoSyncTimes += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_autoSyncTimes", this._autoSyncTimes);
        }
        set velocityTickTimes(value) {
            if (this._velocityTickTimes += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_velocityTickTimes", this._velocityTickTimes);
        }
        set spikeSyncHammerTimes(value) {
            if (this._spikeSyncHammerTimes += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_spikeSyncHammerTimes", this._spikeSyncHammerTimes);
        }
        set spikeSyncTimes(value) {
            if (this._spikeSyncTimes += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_spikeSyncTimes", this._spikeSyncTimes);
        }
        set spikeTickTimes(value) {
            if (this._spikeTickTimes += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_spikeTickTimes", this._spikeTickTimes);
        }
        set knockbackTickTrapTimes(value) {
            if (this._knockbackTickTrapTimes += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_knockbackTickTrapTimes", this._knockbackTickTrapTimes);
        }
        set knockbackTickHammerTimes(value) {
            if (this._knockbackTickHammerTimes += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_knockbackTickHammerTimes", this._knockbackTickHammerTimes);
        }
        set knockbackTickTimes(value) {
            if (this._knockbackTickTimes += value, !this.client.isOwner) {
                return;
            }
            UI_default.updateStats("_knockbackTickTimes", this._knockbackTickTimes);
        }
    }

    class InputHandler {
        client;
        hotkeys=new Map;
        move;
        lastPosition=new Vector_default(0, 0);
        lockPosition=!1;
        mouse={
            x: 0,
            y: 0,
            angle: 0
        };
        rotation=!0;
        instaToggle=!1;
        instakillTarget=null;
        constructor(client2) {
            this.client = client2, this.reset();
        }
        instaReset() {
            this.instaToggle = !1, this.instakillTarget = null;
        }
        reset() {
            this.hotkeys.clear(), this.move = 0, this.instaReset();
        }
        init() {
            window.addEventListener("keydown", event => this.handleKeydown(event), !0),
            window.addEventListener("keyup", event => this.handleKeyup(event), !0), window.addEventListener("mousedown", event => this.handleMousedown(event), !0),
            window.addEventListener("mouseup", event => this.handleMouseup(event), !0),
            window.addEventListener("mousemove", event => this.handleMouseMove(event), !0),
            window.addEventListener("mouseover", event => this.handleMouseMove(event), !0),
            window.addEventListener("wheel", event => ZoomHandler_default.handler(event), !0);
        }
        placementHandler(type, code) {
            if (this.client.myPlayer.getItemByType(type) === null) {
                return;
            }
            this.hotkeys.set(code, type), this.client.ModuleHandler.startPlacement(type);
            let {isOwner: isOwner, clients: clients} = this.client;
            if (isOwner) {
                for (let client2 of clients) {
                    client2.ModuleHandler.startPlacement(type);
                }
            }
        }
        cursorPosition(force = !1) {
            if (!force && this.lockPosition) {
                return this.lastPosition;
            }
            let {myPlayer: myPlayer} = this.client, pos = myPlayer.pos.future, {w: w, h: h} = ZoomHandler_default.scale.current, scale = Math.max(window.innerWidth / w, window.innerHeight / h), cursorX = (this.mouse.x - window.innerWidth / 2) / scale, cursorY = (this.mouse.y - window.innerHeight / 2) / scale;
            return new Vector_default(pos.x + cursorX, pos.y + cursorY);
        }
        getMovePosition(force = !1) {
            if (!force && this.lockPosition) {
                return this.lastPosition;
            }
            if (Settings_default._followCursor) {
                return this.cursorPosition(!0);
            }
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client;
            if (ModuleHandler.move_dir !== null) {
                return myPlayer.pos.current.addDirection(ModuleHandler.move_dir, Settings_default._movementRadius);
            }
            return myPlayer.pos.future;
        }
        postTick() {}
        toggleBotPosition() {
            let state = !this.lockPosition;
            if (state) {
                this.lastPosition.setVec(this.getMovePosition(!0));
            }
            this.lockPosition = state;
        }
        handleMovement() {
            let angle = getAngleFromBitmask(this.move, !1);
            this.client.ModuleHandler.startMovement(angle);
        }
        toggleRotation() {
            if (this.rotation = !this.rotation, this.rotation) {
                this.client.ModuleHandler.currentAngle = this.mouse.angle;
            }
        }
        handleKeydown(event) {
            let target = event.target;
            if (event.code === "Space" && target.tagName === "BODY") {
                event.preventDefault();
            }
            if (event.ctrlKey && [ "KeyD", "KeyS", "KeyW" ].includes(event.code)) {
                event.preventDefault();
            }
            if (event.repeat) {
                return;
            }
            if (UI_default.isActiveButton()) {
                return;
            }
            let isInput = isActiveInput();
            if (event.code === Settings_default._toggleMenu && !isInput) {
                UI_default.toggleMenu();
            }
            if (event.code === Settings_default._toggleChat && !UI_default.isMenuOpened) {
                GameUI_default.handleEnter(event);
            }
            if (!this.client.myPlayer.inGame) {
                return;
            }
            if (isInput) {
                return;
            }
            let {ModuleHandler: ModuleHandler} = this.client;
            if (event.code === Settings_default._food) {
                this.placementHandler(2, event.code);
            }
            if (event.code === Settings_default._wall) {
                this.placementHandler(3, event.code);
            }
            if (event.code === Settings_default._spike) {
                this.placementHandler(4, event.code);
            }
            if (event.code === Settings_default._windmill) {
                this.placementHandler(5, event.code);
            }
            if (event.code === Settings_default._farm) {
                this.placementHandler(6, event.code);
            }
            if (event.code === Settings_default._trap) {
                this.placementHandler(7, event.code);
            }
            if (event.code === Settings_default._turret) {
                this.placementHandler(8, event.code);
            }
            if (event.code === Settings_default._spawn) {
                this.placementHandler(9, event.code);
            }
            let copyMove = this.move;
            if (event.code === Settings_default._up) {
                this.move |= 1;
            }
            if (event.code === Settings_default._left) {
                this.move |= 4;
            }
            if (event.code === Settings_default._down) {
                this.move |= 2;
            }
            if (event.code === Settings_default._right) {
                this.move |= 8;
            }
            if (copyMove !== this.move) {
                this.handleMovement();
            }
            if (event.code === Settings_default._autoattack) {
                ModuleHandler.toggleAutoattack();
            }
            if (event.code === Settings_default._lockrotation) {
                this.toggleRotation();
            }
            if (event.code === Settings_default._lockBotPosition) {
                this.toggleBotPosition();
            }
            if (event.code === Settings_default._instakill) {
                this.instaToggle = !this.instaToggle;
            }
            if (UI_default.isMenuOpened) {
                return;
            }
            if (event.code === Settings_default._toggleShop) {
                StoreHandler_default.toggleStore();
            }
            if (event.code === Settings_default._toggleClan) {
                GameUI_default.openClanMenu();
            }
        }
        handleKeyup(event) {
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler, isOwner: isOwner, clients: clients} = this.client;
            if (!myPlayer.inGame) {
                return;
            }
            let copyMove = this.move;
            if (event.code === Settings_default._up) {
                this.move &= -2;
            }
            if (event.code === Settings_default._left) {
                this.move &= -5;
            }
            if (event.code === Settings_default._down) {
                this.move &= -3;
            }
            if (event.code === Settings_default._right) {
                this.move &= -9;
            }
            if (copyMove !== this.move) {
                this.handleMovement();
            }
            if (ModuleHandler.currentType !== null && this.hotkeys.delete(event.code)) {
                let entry = [ ...this.hotkeys ].pop(), type = entry !== void 0 ? entry[1] : null;
                if (ModuleHandler.startPlacement(type), isOwner) {
                    for (let client2 of clients) {
                        client2.ModuleHandler.startPlacement(type);
                    }
                }
            }
        }
        handleMousedown(event) {
            if (!(event.target instanceof HTMLCanvasElement) || event.target.id === "mapDisplay") {
                return;
            }
            let button = formatButton(event.button);
            if (button === "MBTN") {
                this.instaToggle = !this.instaToggle;
                return;
            }
            let {isOwner: isOwner, clients: clients, ModuleHandler: ModuleHandler} = this.client, state = button === "LBTN" ? 1 : button === "RBTN" ? 2 : null;
            if (state !== null && ModuleHandler.attacking === 0) {
                if (ModuleHandler.attacking = state, ModuleHandler.attackingState = state, isOwner) {
                    for (let client2 of clients) {
                        client2.ModuleHandler.staticModules.tempData.setAttacking(state);
                    }
                }
            }
        }
        handleMouseup(event) {
            let button = formatButton(event.button), {isOwner: isOwner, clients: clients, ModuleHandler: ModuleHandler} = this.client;
            if ((button === "LBTN" || button === "RBTN") && ModuleHandler.attacking !== 0) {
                if (!ModuleHandler.autoattack) {
                    ModuleHandler.attacking = 0;
                }
                if (isOwner) {
                    for (let client2 of clients) {
                        client2.ModuleHandler.staticModules.tempData.setAttacking(0);
                    }
                }
            }
        }
        handleMouseMove(event) {
            let {clientX: x, clientY: y} = event, angle = getAngle(window.innerWidth / 2, window.innerHeight / 2, x, y);
            if (this.mouse.angle = angle, this.rotation) {
                this.mouse.x = x, this.mouse.y = y, this.client.ModuleHandler.currentAngle = angle;
            }
        }
    }

    class TempData {
        moduleName="tempData";
        client;
        store=[ 0, 0 ];
        constructor(client2) {
            this.client = client2;
        }
        setAttacking(attacking) {
            let {ModuleHandler: ModuleHandler} = this.client;
            if (ModuleHandler.attacking = attacking, attacking !== 0) {
                ModuleHandler.attackingState = attacking;
            }
        }
        setStore(type, id) {
            this.store[type] = id, this.handleBuy(type);
        }
        handleBuy(type) {
            let {ModuleHandler: ModuleHandler} = this.client, id = this.store[type];
            if (ModuleHandler.store[type].actual === id) {
                return;
            }
            if (ModuleHandler.sentHatEquip) {
                return;
            }
            let temp = ModuleHandler.canBuy(type, id) ? id : 0;
            ModuleHandler.equip(type, temp, !0);
        }
        postTick() {
            this.handleBuy(0), this.handleBuy(1);
        }
    }

    const TempData_default = TempData;

    class Movement {
        moduleName="movement";
        client;
        isStopped=!0;
        constructor(client2) {
            this.client = client2;
        }
        getMovePosition() {
            return this.client.owner.InputHandler.getMovePosition();
        }
        circlePosition(vec) {
            let totalBots = this.client.owner.clients.size;
            if (totalBots === 0) {
                return vec;
            }
            let {circleOffset: circleOffset} = this.client.owner.ModuleHandler, botIndex = this.client.owner.getClientIndex(this.client), angle = 2 * Math.PI * botIndex / totalBots + circleOffset;
            return vec.addDirection(angle, Settings_default._circleRadius);
        }
        getActualPosition() {
            let pos = this.getMovePosition();
            if (Settings_default._circleFormation) {
                return this.circlePosition(pos);
            }
            return pos;
        }
        someColliding(pos, radius) {
            let {myPlayer: myPlayer} = this.client, {previous: previous, current: current} = myPlayer.pos;
            return previous.distance(pos) <= radius || current.distance(pos) <= radius;
        }
        postTick() {
            let {InputHandler: InputHandler2} = this.client.owner, {myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client, pos1 = myPlayer.pos.current, walkPos = this.getActualPosition(), lookPos = InputHandler2.cursorPosition(), lookAt = pos1.angle(lookPos);
            if (ModuleHandler.currentAngle = lookAt, !this.someColliding(walkPos, Settings_default._movementRadius)) {
                let walkTo = pos1.angle(walkPos);
                this.isStopped = !ModuleHandler.startMovement(walkTo);
            } else if (!this.isStopped) {
                this.isStopped = !0, ModuleHandler.stopMovement();
            }
        }
    }

    const Movement_default = Movement;

    class ClanJoiner {
        moduleName="clanJoiner";
        client;
        joinCount=0;
        prevState=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {myPlayer: myPlayer, PacketManager: PacketManager2, owner: owner, PlayerManager: PlayerManager2} = this.client, ownerClan = owner.myPlayer.clanName, myClan = myPlayer.clanName, state = ownerClan !== myClan;
            if (this.prevState !== state) {
                this.prevState = state, this.joinCount = 0;
            }
            if (ownerClan === null || myClan === ownerClan || !PlayerManager2.clanExist(ownerClan)) {
                return;
            }
            if (this.joinCount === 3) {
                if (this.joinCount = 0, myClan !== null) {
                    PacketManager2.leaveClan();
                } else if (!owner.pendingJoins.has(myPlayer.id)) {
                    owner.pendingJoins.add(myPlayer.id), PacketManager2.joinClan(ownerClan);
                }
            }
            this.joinCount += 1;
        }
    }

    const ClanJoiner_default = ClanJoiner;

    class Autobreak {
        moduleName="autoBreak";
        client;
        constructor(client2) {
            this.client = client2;
        }
        getWeaponRange(id, target) {
            if (id === null) {
                return 0;
            }
            if (DataHandler_default.isMelee(id)) {
                return DataHandler_default.getWeapon(id).range + target.hitScale;
            }
            return 0;
        }
        getDestroyingObject() {
            let {EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client, pos0 = myPlayer.pos.current, primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1), isPrimary = primary !== 8 && primary !== 5, isHammer = secondary === 10, nearestTrap = EnemyManager2.nearestTrap || EnemyManager2.nearestEnemyObject, nearestSpike = EnemyManager2.nearestSpike || EnemyManager2.nearestEnemyObject;
            if (nearestSpike) {
                let pos2 = nearestSpike.pos.current, distPlayerSpike = pos0.distance(pos2), canUseHammer = isHammer && distPlayerSpike <= this.getWeaponRange(secondary, nearestSpike);
                if (nearestTrap) {
                    let canUsePrimary = isPrimary && distPlayerSpike <= this.getWeaponRange(primary, nearestSpike);
                    if (canUseHammer || canUsePrimary) {
                        return nearestSpike;
                    }
                    return nearestTrap;
                }
                if (canUseHammer) {
                    return nearestSpike;
                }
            }
            return nearestTrap;
        }
        getDestroyingWeapon(target) {
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client, pos0 = myPlayer.pos.current, pos1 = target.pos.current, distance = pos0.distance(pos1), primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1), inPrimaryRange = distance <= this.getWeaponRange(primary, target), inSecondaryRange = distance <= this.getWeaponRange(secondary, target), isHammer = secondary === 10, notStick = primary !== 8, notPolearm = primary !== 5, {reloading: reloading} = ModuleHandler.staticModules, primaryDamage = myPlayer.getBuildingDamage(primary, !1);
            if (inPrimaryRange && isHammer && notStick && notPolearm && (!reloading.isReloaded(1) || reloading.isFasterThan(0, 1)) && primaryDamage >= target.health) {
                return 0;
            }
            if (isHammer && inSecondaryRange) {
                return 1;
            }
            if (notStick && (notPolearm || !isHammer) && inPrimaryRange) {
                return 0;
            }
            return null;
        }
        postTick() {
            let {EnemyManager: EnemyManager2, myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client;
            if (!Settings_default._autobreak || ModuleHandler.moduleActive) {
                return;
            }
            let target = this.getDestroyingObject();
            if (target === null) {
                return;
            }
            let type = this.getDestroyingWeapon(target);
            if (type === null) {
                return;
            }
            let weapon = myPlayer.getItemByType(type), range = this.getWeaponRange(weapon, target), pos1 = myPlayer.pos.current, pos2 = target.pos.current;
            if (pos1.distance(pos2) > range) {
                return;
            }
            let angle = pos1.angle(pos2), buildingDamage = myPlayer.getBuildingDamage(weapon, !1), isEnoughDamage = target.health <= buildingDamage, nearestEnemy = EnemyManager2.nearestEnemy, totalDamage = EnemyManager2.primaryDamage + EnemyManager2.potentialSpikeDamage, shouldIgnore = EnemyManager2.instaThreat() || nearestEnemy !== null && nearestEnemy.reload[0].previous !== nearestEnemy.reload[0].current && myPlayer.currentHealth <= totalDamage && myPlayer.currentHealth > totalDamage * .75, {reloading: reloading} = ModuleHandler.staticModules;
            if (ModuleHandler.forceWeapon = type, reloading.isReloaded(type) && !shouldIgnore) {
                if (ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, !isEnoughDamage) {
                    ModuleHandler.forceHat = 40;
                }
                ModuleHandler.shouldAttack = !0;
            }
        }
    }

    class AutoPlacer {
        moduleName="autoPlacer";
        client;
        placementCount=0;
        angleList=new Map;
        constructor(client2) {
            this.client = client2;
        }
        canKnockbackSpike(newSpikePos, scale, enemy) {
            let pos1 = newSpikePos, pos2 = enemy.pos.current, knockbackAngle = pos1.angle(pos2);
            if (!(pos1.distance(pos2) <= enemy.collisionScale + scale)) {
                return !1;
            }
            let {ObjectManager: ObjectManager2, PlayerManager: PlayerManager2} = this.client;
            return ObjectManager2.grid2D.query(pos1.x, pos1.y, 3, id => {
                let object = ObjectManager2.objects.get(id);
                if (!object) {
                    return;
                }
                let pos3 = object.pos.current, isPlayerObject = object instanceof PlayerObject, isCactus = !isPlayerObject && object.isCactus, isSpike = isPlayerObject && object.itemGroup === 2;
                if (!((!isPlayerObject || PlayerManager2.isEnemyByID(object.ownerID, enemy)) && (isSpike || isCactus))) {
                    return;
                }
                let KBDistance = 200, spikeScale = object.collisionScale + enemy.collisionScale, angleToSpike = pos1.angle(pos3), distanceToTarget = pos2.distance(pos3), distanceToSpike = pos1.distance(pos3), offset = Math.asin(2 * spikeScale / (2 * distanceToSpike)), intersecting = getAngleDist(knockbackAngle, angleToSpike) <= offset, overlapping = distanceToTarget <= distanceToSpike, inRange2 = enemy.collidingObject(object, KBDistance);
                return intersecting && overlapping && inRange2;
            });
        }
        postTick() {
            if (!Settings_default._autoplacer) {
                return;
            }
            let {myPlayer: myPlayer, ObjectManager: ObjectManager2, ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2} = this.client, {currentType: currentType} = ModuleHandler, pos0 = myPlayer.pos.current;
            if (ModuleHandler.placedOnce) {
                return;
            }
            let nearestEnemy = EnemyManager2.nearestTrappedEnemy || EnemyManager2.nearestEnemy;
            if (nearestEnemy === null) {
                return;
            }
            if (!myPlayer.collidingSimple(nearestEnemy, Settings_default._autoplacerRadius)) {
                return;
            }
            if (myPlayer.speed > 5 || ObjectManager2.isDestroyedObject() || nearestEnemy.lastAttacked === myPlayer.tickCount) {
                this.angleList.clear();
            }
            let nearestAngle = pos0.angle(nearestEnemy.pos.current), itemType = null, spike = myPlayer.getItemByType(4), spikeAngles = ObjectManager2.getBestPlacementAngles({
                position: pos0,
                id: spike,
                targetAngle: nearestAngle,
                ignoreID: null,
                preplace: !0,
                reduce: !0,
                fill: !0
            }), spikeScale = Items[spike].scale, angles = [], length = myPlayer.getItemPlaceScale(spike);
            for (let angle of spikeAngles) {
                let newPos = pos0.addDirection(angle, length), shouldPlaceSpike = nearestEnemy.wasTrapped(), enemy = EnemyManager2.nearestTrappedEnemy;
                if (enemy !== null && !shouldPlaceSpike) {
                    let distanceToEnemy = newPos.distance(enemy.pos.current), enemyRange = spikeScale + enemy.collisionScale + 8, trap = enemy.trappedIn, distanceToTrap = newPos.distance(trap.pos.current), trapRange = spikeScale + trap.placementScale + 8;
                    if (distanceToEnemy <= enemyRange || distanceToTrap <= trapRange) {
                        shouldPlaceSpike = !0;
                    }
                }
                if (!shouldPlaceSpike && this.canKnockbackSpike(newPos, spikeScale, nearestEnemy)) {
                    shouldPlaceSpike = !0;
                }
                if (shouldPlaceSpike) {
                    angles = spikeAngles, itemType = 4;
                    break;
                }
            }
            if (angles.length === 0) {
                let type = currentType && currentType !== 2 ? currentType : 7;
                if (!myPlayer.canPlace(type)) {
                    return;
                }
                let id = myPlayer.getItemByType(type);
                if (id === 16) {
                    return;
                }
                if (this.placementCount >= 4) {
                    type = 4;
                }
                if (angles = ObjectManager2.getBestPlacementAngles({
                    position: pos0,
                    id: id,
                    targetAngle: nearestAngle,
                    ignoreID: null,
                    preplace: !0,
                    reduce: !0,
                    fill: !0
                }), itemType = type, type === 4 && angles.length !== 0) {
                    this.placementCount = 0;
                }
            }
            if (itemType === null || angles.length === 0) {
                return;
            }
            ModuleHandler.placeAngles[0] = itemType, ModuleHandler.placedOnce = !0;
            for (let angle of angles) {
                if (!this.angleList.has(angle)) {
                    this.angleList.set(angle, 0);
                }
                let angleCount = this.angleList.get(angle);
                if (angleCount >= 4) {
                    continue;
                }
                this.angleList.set(angle, angleCount + 1), ModuleHandler.place(itemType, angle),
                ModuleHandler.placeAngles[1].push(angle);
            }
            if (itemType !== 4) {
                this.placementCount += 1;
            }
        }
    }

    const AutoPlacer_default = AutoPlacer;

    class AutoSync {
        moduleName="autoSync";
        client;
        useTurret=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._autoSync) {
                this.useTurret = !1;
                return;
            }
            let {nearestEnemy: nearestEnemy, nearestEnemyToNearestEnemy: nearestEnemyToNearestEnemy} = EnemyManager2;
            if (nearestEnemy === null || nearestEnemyToNearestEnemy === null) {
                return;
            }
            let reloading = ModuleHandler.staticModules.reloading, turretReloaded = reloading.isReloaded(2);
            if (this.useTurret) {
                if (this.useTurret = !1, turretReloaded) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
                }
                return;
            }
            let primary1 = myPlayer.getItemByType(0), primaryDamage1 = myPlayer.getMaxWeaponDamage(primary1, !1), range1 = DataHandler_default.getWeapon(primary1).range + nearestEnemy.hitScale, isPrimaryReloaded1 = reloading.isReloaded(0), primary2 = nearestEnemyToNearestEnemy.weapon.primary, primaryDamage2 = nearestEnemyToNearestEnemy.getMaxWeaponDamage(primary2, !1), range2 = DataHandler_default.getWeapon(primary2).range + nearestEnemy.hitScale, isPrimaryReloaded2 = nearestEnemyToNearestEnemy.isReloaded(0, 0), soldierDefense = Hats[6].dmgMult;
            if ((primaryDamage1 + primaryDamage2) * soldierDefense < 100) {
                return;
            }
            let inWeaponRange1 = myPlayer.collidingSimple(nearestEnemy, range1, myPlayer.getFuturePosition(myPlayer.speed / 3)), inWeaponRange2 = nearestEnemyToNearestEnemy.collidingSimple(nearestEnemy, range2, nearestEnemyToNearestEnemy.getFuturePosition(nearestEnemyToNearestEnemy.speed / 3));
            if (!inWeaponRange1 || !inWeaponRange2) {
                return;
            }
            let pos1 = myPlayer.pos.future, pos2 = nearestEnemy.pos.future, angleToEnemy = pos1.angle(pos2);
            if (!isPrimaryReloaded1) {
                if (ModuleHandler.forceWeapon = 0, isPrimaryReloaded2) {
                    ModuleHandler.moduleActive = !0;
                }
            }
            if (isPrimaryReloaded1 && isPrimaryReloaded2) {
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angleToEnemy, ModuleHandler.forceHat = 7,
                ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, this.useTurret = !0,
                this.client.StatsManager.autoSyncTimes = 1;
            }
        }
    }

    class Instakill {
        moduleName="instakill";
        client;
        targetEnemy=null;
        constructor(client2) {
            this.client = client2;
        }
        reset() {
            this.targetEnemy = null;
        }
        postTick() {
            let {myPlayer: myPlayer, EnemyManager: EnemyManager2, PlayerManager: PlayerManager2, ModuleHandler: ModuleHandler, InputHandler: InputHandler2} = this.client;
            if (!InputHandler2.instaToggle) {
                this.reset(), InputHandler2.instaReset();
                return;
            }
            let nearestEnemy = EnemyManager2.nearestEnemy;
            if (nearestEnemy === null) {
                return;
            }
            let lookingShield = PlayerManager2.lookingShield(nearestEnemy, myPlayer), primary = myPlayer.getItemByType(0), primaryDamage = myPlayer.getMaxWeaponDamage(primary, lookingShield), secondary = myPlayer.getItemByType(1);
            if (secondary === null || !DataHandler_default.isShootable(secondary)) {
                return;
            }
            let secondaryDamage = myPlayer.getMaxWeaponDamage(secondary, lookingShield);
            if ((primaryDamage + secondaryDamage + 25) * .75 < 100) {
                return;
            }
            let pos1 = myPlayer.pos.future, pos2 = nearestEnemy.pos.future, angle = pos1.angle(pos2);
            if (this.targetEnemy !== null) {
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 53,
                ModuleHandler.forceWeapon = 1, ModuleHandler.shouldAttack = !0, this.targetEnemy = null,
                InputHandler2.instaReset();
                return;
            }
            InputHandler2.instakillTarget = nearestEnemy;
            let {reloading: reloading} = ModuleHandler.staticModules, primaryReloaded = reloading.isReloaded(0), secondaryReloaded = reloading.isReloaded(1), turretReloaded = reloading.isReloaded(2), range = DataHandler_default.getWeapon(primary).range + nearestEnemy.hitScale;
            if (!primaryReloaded || !secondaryReloaded || !turretReloaded || !myPlayer.collidingSimple(nearestEnemy, range)) {
                return;
            }
            ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 7,
            ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, this.targetEnemy = nearestEnemy;
        }
    }

    class AntiRetrap {
        moduleName="antiRetrap";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._antiRetrap) {
                return;
            }
            let {reloading: reloading} = ModuleHandler.staticModules, nearestTrap = EnemyManager2.nearestTrap, primary = myPlayer.getItemByType(0), isReloadedPrimary = reloading.isReloaded(0), isHammer = myPlayer.getItemByType(1) === 10, isReloadedSecondary = reloading.isReloaded(1), damage = myPlayer.getBuildingDamage(10, !0), turretReloaded = reloading.isReloaded(2), nearestEnemy = EnemyManager2.nearestEnemy;
            if (nearestEnemy === null || nearestTrap === null || nearestTrap.health > damage || !isHammer || !isReloadedSecondary) {
                return;
            }
            let range = DataHandler_default.getWeapon(primary).range + nearestEnemy.hitScale;
            if (!myPlayer.collidingEntity(nearestEnemy, range)) {
                return;
            }
            let pos1 = myPlayer.pos.current, pos2 = nearestEnemy.pos.current, angle = pos1.angle(pos2);
            if (isReloadedPrimary) {
                if (ModuleHandler.moduleActive = !0, ModuleHandler.forceWeapon = 0, ModuleHandler.useAngle = angle,
                ModuleHandler.shouldAttack = !0, turretReloaded) {
                    ModuleHandler.forceHat = 53;
                }
            }
        }
    }

    class KnockbackTick {
        moduleName="knockbackTick";
        client;
        useTurret=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._knockbackTick || EnemyManager2.shouldIgnoreModule()) {
                this.useTurret = !1;
                return;
            }
            let {nearestEnemySpikeCollider: nearestEnemySpikeCollider, spikeCollider: spikeCollider} = EnemyManager2, reloading = ModuleHandler.staticModules.reloading, primary = myPlayer.getItemByType(0), primaryReloaded = reloading.isReloaded(0);
            reloading.isReloaded(2);
            if (this.useTurret) {
                this.useTurret = !1, ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
                return;
            }
            if (nearestEnemySpikeCollider !== null && !nearestEnemySpikeCollider.isTrapped && spikeCollider !== null && primaryReloaded) {
                let pos1 = myPlayer.pos.current, pos2 = nearestEnemySpikeCollider.pos.current, pos3 = spikeCollider.pos.current, angleToEnemy = pos1.angle(pos2), distanceToSpike2 = pos2.distance(pos3), primaryKnockback = DataHandler_default.getWeapon(primary).knockback, knockback = primaryKnockback + 60, collisionScale = spikeCollider.collisionScale + nearestEnemySpikeCollider.collisionScale, collisionRangeTurret = collisionScale + knockback, isPrimaryEnough = distanceToSpike2 <= collisionScale + primaryKnockback;
                if (distanceToSpike2 <= collisionRangeTurret) {
                    let hitRange = DataHandler_default.getWeapon(primary).range + nearestEnemySpikeCollider.hitScale;
                    if (myPlayer.collidingSimple(nearestEnemySpikeCollider, hitRange)) {
                        if (ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angleToEnemy,
                        ModuleHandler.forceHat = 7, ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0,
                        !isPrimaryEnough) {
                            this.useTurret = !0;
                        }
                        this.client.StatsManager.knockbackTickTimes = 1;
                    }
                }
            }
        }
    }

    class KnockbackTickHammer {
        moduleName="knockbackTickHammer";
        client;
        targetEnemy=null;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._knockbackTickHammer || EnemyManager2.shouldIgnoreModule()) {
                this.targetEnemy = null;
                return;
            }
            let {nearestEnemySpikeCollider: nearestEnemySpikeCollider, spikeCollider: spikeCollider} = EnemyManager2, reloading = ModuleHandler.staticModules.reloading, primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1), isHammer = secondary !== null && secondary !== 11, primaryReloaded = reloading.isReloaded(0), secondaryReloaded = reloading.isReloaded(1), turretReloaded = reloading.isReloaded(2), pos1 = myPlayer.pos.current;
            if (this.targetEnemy !== null) {
                let pos2 = this.targetEnemy.pos.current, angleToEnemy = pos1.angle(pos2);
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angleToEnemy, ModuleHandler.forceHat = 7,
                ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, this.targetEnemy = null,
                EnemyManager2.attemptSpikePlacement();
                return;
            }
            if (nearestEnemySpikeCollider !== null && !nearestEnemySpikeCollider.isTrapped && spikeCollider !== null && isHammer && primaryReloaded && secondaryReloaded && turretReloaded) {
                let pos2 = nearestEnemySpikeCollider.pos.current, pos3 = spikeCollider.pos.current, angleToEnemy = pos1.angle(pos2), distanceToSpike2 = pos2.distance(pos3), {knockback: primaryKnockback, range: primaryRange} = DataHandler_default.getWeapon(primary), {knockback: secondaryKnockback, range: secondaryRange} = DataHandler_default.getWeapon(secondary), weaponRange = Math.min(primaryRange, secondaryRange) + nearestEnemySpikeCollider.hitScale, minKB = primaryKnockback + 60, maxKB = primaryKnockback + secondaryKnockback + 60, spikeRange = spikeCollider.collisionScale + nearestEnemySpikeCollider.collisionScale;
                if (inRange(distanceToSpike2, spikeRange + minKB, spikeRange + maxKB) && myPlayer.collidingSimple(nearestEnemySpikeCollider, weaponRange)) {
                    let hitRange = DataHandler_default.getWeapon(secondary).range + nearestEnemySpikeCollider.hitScale;
                    if (myPlayer.collidingSimple(nearestEnemySpikeCollider, hitRange)) {
                        ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angleToEnemy, ModuleHandler.forceHat = 53,
                        ModuleHandler.forceWeapon = 1, ModuleHandler.shouldAttack = !0, this.targetEnemy = nearestEnemySpikeCollider,
                        this.client.StatsManager.knockbackTickHammerTimes = 1;
                    }
                }
            }
        }
    }

    class KnockbackTickTrap {
        moduleName="knockbackTickTrap";
        client;
        targetEnemy=null;
        useTurret=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._knockbackTickTrap || EnemyManager2.shouldIgnoreModule()) {
                this.targetEnemy = null, this.useTurret = !1;
                return;
            }
            let {nearestEnemySpikeCollider: nearestEnemySpikeCollider, nearestTrappedEnemy: nearestTrappedEnemy, spikeCollider: spikeCollider} = EnemyManager2, reloading = ModuleHandler.staticModules.reloading, primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1), isHammer = secondary === 10, primaryReloaded = reloading.isReloaded(0), secondaryReloaded = reloading.isReloaded(1), turretReloaded = reloading.isReloaded(2);
            if (this.useTurret) {
                if (turretReloaded) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
                }
                this.useTurret = !1;
                return;
            }
            let pos1 = myPlayer.pos.current;
            if (this.targetEnemy !== null) {
                let pos2 = this.targetEnemy.pos.current, angleToEnemy = pos1.angle(pos2);
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angleToEnemy, ModuleHandler.forceHat = 7,
                ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, this.targetEnemy = null,
                this.useTurret = !0;
                return;
            }
            if (nearestEnemySpikeCollider !== null && nearestTrappedEnemy !== null && nearestTrappedEnemy === nearestEnemySpikeCollider && spikeCollider !== null && isHammer && primaryReloaded && secondaryReloaded) {
                let nearestTrap = nearestTrappedEnemy.trappedIn, hammer = DataHandler_default.getWeapon(secondary), playerRange = hammer.range + nearestTrappedEnemy.hitScale, trapRange = hammer.range + nearestTrap.hitScale, canAttackEnemy = myPlayer.collidingSimple(nearestTrappedEnemy, playerRange), canAttackTrap = myPlayer.collidingSimple(nearestTrap, trapRange), buildingDamage = myPlayer.getBuildingDamage(secondary, !0);
                if (!canAttackEnemy || !canAttackTrap || nearestTrap.health > buildingDamage) {
                    return;
                }
                let pos12 = myPlayer.pos.current, pos2 = nearestTrappedEnemy.pos.current, pos3 = nearestTrap.pos.current, pos4 = spikeCollider.pos.current, angleToEnemy = pos12.angle(pos2), angleToTrap = pos12.angle(pos3), middleAngle = findMiddleAngle(angleToEnemy, angleToTrap), distanceToSpike2 = pos2.distance(pos4), turretKnockback = 60, knockback = DataHandler_default.getWeapon(primary).knockback + turretKnockback, collisionRange = spikeCollider.collisionScale + nearestEnemySpikeCollider.collisionScale + knockback;
                if (distanceToSpike2 <= collisionRange) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = middleAngle, ModuleHandler.forceHat = 40,
                    ModuleHandler.forceWeapon = 1, ModuleHandler.shouldAttack = !0, this.targetEnemy = nearestTrappedEnemy,
                    this.client.StatsManager.knockbackTickTrapTimes = 1;
                }
            }
        }
    }

    class SpikeSync {
        moduleName="spikeSync";
        client;
        useTurret=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._spikeSync) {
                this.useTurret = !1;
                return;
            }
            let {nearestEnemy: nearest, nearestSpikePlacerAngle: placementAngles} = EnemyManager2, reloading = ModuleHandler.staticModules.reloading, primary = myPlayer.getItemByType(0), isPolearm = primary !== 8, primaryReloaded = reloading.isReloaded(0), turretReloaded = reloading.isReloaded(2);
            if (this.useTurret) {
                if (this.useTurret = !1, turretReloaded && !EnemyManager2.shouldIgnoreModule()) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
                }
                return;
            }
            if (!EnemyManager2.shouldIgnoreModule() && nearest !== null && EnemyManager2.canSpikeSync && placementAngles !== null && isPolearm && primaryReloaded) {
                let range = DataHandler_default.getWeapon(primary).range + nearest.hitScale;
                if (!myPlayer.collidingSimple(nearest, range)) {
                    return;
                }
                let pos1 = myPlayer.pos.current, pos2 = nearest.pos.current, angleTo = pos1.angle(pos2), itemType = 4;
                for (let angle of placementAngles) {
                    ModuleHandler.place(itemType, angle);
                }
                ModuleHandler.placedOnce = !0, ModuleHandler.placeAngles[0] = itemType, ModuleHandler.placeAngles[1] = placementAngles,
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angleTo, ModuleHandler.forceHat = 7,
                ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, this.client.StatsManager.spikeSyncTimes = 1,
                this.useTurret = !0;
            }
        }
    }

    class SpikeSyncHammer {
        moduleName="spikeSyncHammer";
        client;
        targetEnemy=null;
        useTurret=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer, ObjectManager: ObjectManager2} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._spikeSyncHammer || EnemyManager2.shouldIgnoreModule()) {
                this.targetEnemy = null, this.useTurret = !1;
                return;
            }
            let nearestSyncEnemy = EnemyManager2.nearestSyncEnemy, reloading = ModuleHandler.staticModules.reloading, primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1), isPolearm = primary !== 8, isHammer = secondary === 10, primaryReloaded = reloading.isReloaded(0), secondaryReloaded = reloading.isReloaded(1), turretReloaded = reloading.isReloaded(2);
            if (this.useTurret) {
                if (turretReloaded) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
                }
                this.useTurret = !1;
                return;
            }
            if (this.targetEnemy !== null) {
                let nearest = this.targetEnemy, pos1 = myPlayer.pos.current, pos2 = nearest.pos.current, itemType = 4, spikeID = myPlayer.getItemByType(itemType), placeLength = myPlayer.getItemPlaceScale(spikeID), angleToNearest = pos1.angle(pos2), spikePos = pos1.addDirection(angleToNearest, placeLength), angleFromSpike = spikePos.angle(pos2), futureEnemyPos = spikePos.addDirection(angleFromSpike, 140), futureAngle = pos1.angle(futureEnemyPos), placementAngles = EnemyManager2.nearestSpikePlacerAngle;
                if (placementAngles !== null) {
                    for (let angle of placementAngles) {
                        ModuleHandler.place(itemType, angle);
                    }
                    ModuleHandler.placedOnce = !0, ModuleHandler.placeAngles[0] = itemType, ModuleHandler.placeAngles[1] = placementAngles,
                    ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = futureAngle, ModuleHandler.forceHat = 7,
                    ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0;
                }
                this.targetEnemy = null, this.useTurret = !0;
                return;
            }
            if (nearestSyncEnemy !== null && isPolearm && primaryReloaded && isHammer && secondaryReloaded) {
                let nearestLowHPObject = EnemyManager2.nearestLowHPObject;
                if (nearestLowHPObject === null) {
                    return;
                }
                let hammer = DataHandler_default.getWeapon(secondary), playerRange = hammer.range + nearestSyncEnemy.hitScale, trapRange = hammer.range + nearestLowHPObject.hitScale, canAttackEnemy = myPlayer.collidingSimple(nearestSyncEnemy, playerRange), canAttackTrap = myPlayer.collidingSimple(nearestLowHPObject, trapRange), buildingDamage = myPlayer.getBuildingDamage(secondary, !0);
                if (!canAttackEnemy || !canAttackTrap || nearestLowHPObject.health > buildingDamage) {
                    return;
                }
                let itemType = 4, spikeID = myPlayer.getItemByType(itemType), placeLength = myPlayer.getItemPlaceScale(spikeID), pos1 = myPlayer.pos.current, pos2 = nearestSyncEnemy.pos.current, pos3 = nearestLowHPObject.pos.current, angleToEnemy = pos1.angle(pos2), angleToTrap = pos1.angle(pos3), middleAngle = findMiddleAngle(angleToEnemy, angleToTrap), angles = ObjectManager2.getBestPlacementAngles({
                    position: pos1,
                    id: spikeID,
                    targetAngle: angleToEnemy,
                    ignoreID: nearestLowHPObject.id,
                    preplace: !1,
                    reduce: !1,
                    fill: !1
                }), spikeScale = Items[spikeID].scale, possibleAngles = angles.filter(angle => {
                    let spikePos = pos1.addDirection(angle, placeLength), distance = pos2.distance(spikePos), range = nearestSyncEnemy.collisionScale + spikeScale;
                    return distance <= range;
                });
                if (possibleAngles.length !== 0) {
                    ModuleHandler.placeAngles[0] = itemType, ModuleHandler.placeAngles[1] = possibleAngles,
                    ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = middleAngle, ModuleHandler.forceHat = 40,
                    ModuleHandler.forceWeapon = 1, ModuleHandler.shouldAttack = !0, this.targetEnemy = nearestSyncEnemy,
                    this.client.StatsManager.spikeSyncHammerTimes = 1;
                }
            }
        }
    }

    class SpikeTick {
        moduleName="spikeTick";
        client;
        useTurret=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._spikeTick) {
                return;
            }
            let reloading = ModuleHandler.staticModules.reloading, primary = myPlayer.getItemByType(0), isPrimary = primary !== 8, primaryReloaded = reloading.isReloaded(0), turretReloaded = reloading.isReloaded(2), spikeCollider = EnemyManager2.enemySpikeCollider;
            if (this.useTurret) {
                if (this.useTurret = !1, turretReloaded) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
                    return;
                }
            }
            if (EnemyManager2.shouldIgnoreModule() || !isPrimary || !primaryReloaded || spikeCollider === null) {
                return;
            }
            let range = DataHandler_default.getWeapon(primary).range + spikeCollider.hitScale;
            if (!myPlayer.collidingEntity(spikeCollider, range, !0)) {
                return;
            }
            let pos1 = myPlayer.pos.future, pos2 = spikeCollider.pos.future, angle = pos1.angle(pos2);
            ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 7,
            ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, EnemyManager2.attemptSpikePlacement(),
            this.useTurret = !0, this.client.StatsManager.spikeTickTimes = 1;
        }
    }

    const SpikeTick_default = SpikeTick;

    class ToolHammerSpearInsta {
        moduleName="toolHammerSpearInsta";
        client;
        nearestTarget=null;
        useTurret=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer, EnemyManager: EnemyManager2} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._toolSpearInsta) {
                this.nearestTarget = null;
                return;
            }
            let nearestEnemy = EnemyManager2.nearestEnemy;
            if (nearestEnemy === null || !ModuleHandler.canBuy(0, 7)) {
                return;
            }
            if (this.useTurret) {
                if (ModuleHandler.canBuy(0, 53)) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
                }
                this.useTurret = !1;
                return;
            }
            if (myPlayer.upgradeAge !== 2) {
                return;
            }
            let pos1 = myPlayer.pos.current;
            if (this.nearestTarget !== null) {
                let pos22 = this.nearestTarget.pos.current, angle2 = pos1.angle(pos22);
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle2, ModuleHandler.forceHat = 7,
                ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, ModuleHandler.upgradeItem(5),
                this.nearestTarget = null, this.useTurret = !0, EnemyManager2.attemptSpikePlacement();
                return;
            }
            let pos2 = nearestEnemy.pos.current, angle = pos1.angle(pos2), {reloading: reloading} = ModuleHandler.staticModules, primaryReloaded = reloading.isReloaded(0), turretReloaded = reloading.isReloaded(2), range = DataHandler_default.getWeapon(0).range + nearestEnemy.hitScale;
            if (!primaryReloaded || !turretReloaded || !myPlayer.collidingSimple(nearestEnemy, range)) {
                return;
            }
            ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 7,
            ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, this.nearestTarget = nearestEnemy;
        }
    }

    class VelocityTick {
        moduleName="velocityTick";
        client;
        nearestTarget=null;
        target=null;
        minKB=220;
        maxKB=245;
        constructor(client2) {
            this.client = client2;
        }
        isValidHat(hatID) {
            return hatID !== null && hatID !== 6 && hatID !== 22;
        }
        postTick() {
            let {EnemyManager: EnemyManager2, myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client;
            if (this.target = null, ModuleHandler.moduleActive || !Settings_default._velocityTick || ModuleHandler.moveTo !== "disable" || EnemyManager2.shouldIgnoreModule()) {
                this.nearestTarget = null;
                return;
            }
            let {reloading: reloading} = ModuleHandler.staticModules, nearestEnemy = EnemyManager2.nearestEnemy, primary = myPlayer.getItemByType(0), isPolearm = primary === 5, isDiamond = myPlayer.getWeaponVariant(primary).current >= 2, isReloadedPrimary = reloading.isReloaded(0), isReloadedTurret = reloading.isReloaded(2);
            if (this.nearestTarget !== null) {
                let pos1 = myPlayer.pos.current, pos22 = this.nearestTarget.pos.current, angle2 = pos1.angle(pos22);
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle2, ModuleHandler.forceHat = 7,
                ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, ModuleHandler.moveTo = angle2,
                this.nearestTarget = null;
                return;
            }
            if (nearestEnemy === null || !isPolearm || !isDiamond || !isReloadedPrimary || !isReloadedTurret) {
                return;
            }
            this.target = nearestEnemy;
            let pos0 = myPlayer.pos.current, pos2 = nearestEnemy.pos.future, distance = pos0.distance(pos2), angle = pos0.angle(pos2), {current: current} = nearestEnemy.weapon, type = DataHandler_default.getWeapon(current).type, almostReloaded = DataHandler_default.isMelee(current) && nearestEnemy.atExact(type, 1), detectFutureHat = this.isValidHat(nearestEnemy.futureHat), canSend = almostReloaded || detectFutureHat;
            if (inRange(distance, this.minKB, this.maxKB) && canSend) {
                ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53, ModuleHandler.moveTo = angle,
                this.nearestTarget = nearestEnemy, this.client.StatsManager.velocityTickTimes = 1;
            }
        }
    }

    class Placer {
        moduleName="placer";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer} = this.client, {currentType: currentType, placedOnce: placedOnce, healedOnce: healedOnce, currentAngle: currentAngle} = ModuleHandler;
            if (!myPlayer.canPlace(currentType)) {
                return;
            }
            if (currentType === 2) {
                if (healedOnce) {
                    return;
                }
                if (myPlayer.shameCount < 7) {
                    ModuleHandler.heal(), ModuleHandler.healedOnce = !0, ModuleHandler.didAntiInsta = !0;
                }
                return;
            }
            if (placedOnce) {
                return;
            }
            ModuleHandler.place(currentType, currentAngle), ModuleHandler.placedOnce = !0;
        }
    }

    const Placer_default = Placer;

    class PreAttack {
        moduleName="preAttack";
        client;
        constructor(client2) {
            this.client = client2;
        }
        isReloadedByType(type) {
            let {weapon: weapon, staticModules: staticModules} = this.client.ModuleHandler, weaponType = type !== null ? type : weapon;
            return staticModules.reloading.isReloaded(weaponType);
        }
        postTick() {
            let {ModuleHandler: ModuleHandler} = this.client, {useWeapon: useWeapon, weapon: weapon, forceWeapon: forceWeapon} = ModuleHandler, nextWeapon = forceWeapon !== null ? forceWeapon : useWeapon, forceReloaded = this.isReloadedByType(nextWeapon), canAttack = ModuleHandler.shouldAttack && (forceReloaded && this.isReloadedByType(weapon) || forceWeapon !== null && forceReloaded);
            ModuleHandler.shouldAttack = canAttack;
        }
    }

    const PreAttack_default = PreAttack;

    class Reloading {
        moduleName="reloading";
        client;
        clientReload=[ {}, {}, {} ];
        constructor(client2) {
            this.client = client2, this.reset();
        }
        reset() {
            let [primary, secondary, turret] = this.clientReload;
            primary.current = primary.max = 0, secondary.current = secondary.max = 0, turret.current = turret.max = 23;
        }
        get currentReload() {
            return this.clientReload[this.client.ModuleHandler.weapon];
        }
        getReload(type) {
            return this.clientReload[type];
        }
        updateMaxReload(type) {
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler, SocketManager: SocketManager2} = this.client, reload = this.getReload(type), id = myPlayer.getItemByType(type), store2 = ModuleHandler.getHatStore(), pingAccount = Math.floor(SocketManager2.pong / SocketManager2.TICK), speed = myPlayer.getWeaponSpeed(id, store2.last) - pingAccount;
            reload.current = speed, reload.max = speed;
        }
        resetReload(reload) {
            reload.current = -1;
        }
        resetByType(type) {
            this.resetReload(this.getReload(type));
        }
        isReloaded(type, ticks = 0) {
            let reload = this.clientReload[type];
            return reload.current >= reload.max - ticks;
        }
        isFasterThan(type1, type2) {
            let reload1 = this.clientReload[type1], reload2 = this.clientReload[type2], data1 = reload1.max - reload1.current, data2 = reload2.max - reload2.current;
            return Math.abs(data1) <= Math.abs(data2);
        }
        isEmptyReload(type) {
            return this.clientReload[type].current === 0;
        }
        postTick() {
            let {myPlayer: myPlayer} = this.client, primaryReload = myPlayer.reload[0].current, secondaryReload = myPlayer.reload[1].current;
            if (primaryReload !== -1) {
                this.clientReload[0].current = primaryReload;
            }
            if (secondaryReload !== -1) {
                this.clientReload[1].current = secondaryReload;
            }
            this.clientReload[2].current = myPlayer.reload[2].current;
        }
    }

    const Reloading_default = Reloading;

    class UpdateAngle {
        moduleName="updateAngle";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {sentAngle: sentAngle, currentAngle: currentAngle} = this.client.ModuleHandler;
            if (sentAngle > 1) {
                return;
            }
            this.client.ModuleHandler.updateAngle(currentAngle);
        }
    }

    const UpdateAngle_default = UpdateAngle;

    class UpdateAttack {
        moduleName="updateAttack";
        client;
        didReset=!1;
        constructor(client2) {
            this.client = client2;
        }
        getAttackAngle() {
            let {useAngle: useAngle, currentAngle: currentAngle} = this.client.ModuleHandler;
            if (useAngle !== null) {
                return useAngle;
            }
            return currentAngle;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer} = this.client, {useWeapon: useWeapon, forceWeapon: forceWeapon, weapon: weapon, attacking: attacking, useItem: useItem, sentAngle: sentAngle, staticModules: staticModules} = ModuleHandler, {reloading: reloading} = staticModules, nextWeapon = forceWeapon !== null ? forceWeapon : useWeapon;
            if (nextWeapon !== null && (nextWeapon !== weapon || ModuleHandler.currentHolding !== nextWeapon || myPlayer.currentItem !== -1)) {
                if (reloading.isReloaded(weapon) || forceWeapon !== null) {
                    ModuleHandler.whichWeapon(nextWeapon);
                }
            }
            if (useItem !== null) {
                ModuleHandler.selectItem(useItem);
            }
            if (ModuleHandler.shouldAttack) {
                let angle = this.getAttackAngle();
                ModuleHandler.attack(angle), ModuleHandler.stopAttack();
                let weaponType = ModuleHandler.weapon;
                if (ModuleHandler.attacked) {
                    reloading.updateMaxReload(weaponType);
                }
                reloading.resetByType(weaponType);
            } else if (!attacking && sentAngle !== 0) {
                ModuleHandler.stopAttack(), this.didReset = !0;
            } else if (this.didReset) {
                this.didReset = !1, ModuleHandler.stopAttack();
            }
        }
    }

    const UpdateAttack_default = UpdateAttack;

    class UseAttacking {
        moduleName="useAttacking";
        client;
        constructor(client2) {
            this.client = client2;
        }
        getWeaponType() {
            let {EnemyManager: EnemyManager2, myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client, pos1 = myPlayer.pos.future, nearestEntity = EnemyManager2.nearestEntity, nearestObject = EnemyManager2.nearestObject, primaryID = myPlayer.getItemByType(0), secondaryID = myPlayer.getItemByType(1), range = DataHandler_default.getWeapon(primaryID).range;
            if (nearestEntity !== null) {
                let pos2 = nearestEntity.pos.future, angle = pos1.angle(pos2);
                if (myPlayer.collidingEntity(nearestEntity, range + nearestEntity.hitScale)) {
                    return [ 0, angle ];
                }
                if (DataHandler_default.isShootable(secondaryID) && !ModuleHandler.autoattack) {
                    return [ 1, angle ];
                }
            }
            if (nearestObject === null) {
                return null;
            }
            if (myPlayer.colliding(nearestObject, range + nearestObject.hitScale)) {
                return [ 0, null ];
            }
            return null;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || ModuleHandler.attackingState !== 1 || ModuleHandler.forceWeapon !== null) {
                return;
            }
            let weaponType = this.getWeaponType();
            if (weaponType === null) {
                return;
            }
            let [type, angle] = weaponType;
            if (ModuleHandler.forceWeapon = type, angle !== null) {
                ModuleHandler.useAngle = angle;
            }
            ModuleHandler.shouldAttack = !0;
        }
    }

    class UseDestroying {
        moduleName="useDestroying";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2} = this.client;
            if (ModuleHandler.moduleActive || ModuleHandler.attackingState !== 2 || ModuleHandler.forceWeapon !== null) {
                return;
            }
            let nearestObject = EnemyManager2.nearestPlayerObject, type = myPlayer.getBestDestroyingWeapon(nearestObject);
            ModuleHandler.forceWeapon = type, ModuleHandler.shouldAttack = !0;
        }
    }

    class UseFastest {
        moduleName="useFastest";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client;
            if (ModuleHandler.moduleActive) {
                return;
            }
            let {reloading: reloading} = ModuleHandler.staticModules, type = myPlayer.getFastestWeapon(), reverse_type = type === 0 ? 1 : 0;
            if (!reloading.isReloaded(type)) {
                ModuleHandler.useWeapon = type;
            } else if (!reloading.isReloaded(reverse_type) && myPlayer.getItemByType(reverse_type) !== null) {
                ModuleHandler.useWeapon = reverse_type;
            } else {
                ModuleHandler.useWeapon = type;
            }
        }
    }

    class UtilityHat {
        moduleName="utilityHat";
        client;
        constructor(client2) {
            this.client = client2;
        }
        getBestUtilityHat(weaponType) {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client, id = myPlayer.getItemByType(weaponType);
            if (id === 11) {
                return null;
            }
            if (DataHandler_default.isShootable(id)) {
                return ModuleHandler.canHitEntity = !0, 20;
            }
            let weapon = DataHandler_default.getWeapon(id), range = weapon.range;
            if (weapon.damage <= 1) {
                return null;
            }
            if (ModuleHandler.attackingState === 1) {
                let nearest = EnemyManager2.nearestEntity;
                if (nearest !== null && myPlayer.collidingEntity(nearest, range + nearest.hitScale)) {
                    return ModuleHandler.canHitEntity = !0, 7;
                }
            }
            if (ModuleHandler.attackingState !== 0) {
                let nearestObject = EnemyManager2.nearestPlayerObject;
                if (nearestObject === null) {
                    return null;
                }
                if (myPlayer.colliding(nearestObject, range + nearestObject.hitScale)) {
                    return 40;
                }
            }
            return null;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive) {
                return;
            }
            let {forceWeapon: forceWeapon, useWeapon: useWeapon, weapon: weapon} = ModuleHandler, weaponType = forceWeapon !== null ? forceWeapon : useWeapon !== null ? useWeapon : weapon, hat = this.getBestUtilityHat(weaponType), {reloading: reloading} = ModuleHandler.staticModules, isReloaded = reloading.isReloaded(weaponType), isEmptyReload = reloading.isEmptyReload(weaponType), turretReloaded = reloading.isReloaded(2);
            if (!isReloaded) {
                hat = null;
            }
            if (ModuleHandler.canHitEntity && isEmptyReload && turretReloaded) {
                let nearest = EnemyManager2.nearestEntity;
                if (nearest !== null && myPlayer.collidingEntity(nearest, 700)) {
                    hat = 53;
                }
            }
            if (hat !== null) {
                ModuleHandler.useHat = hat;
            }
        }
    }

    class AntiInsta {
        moduleName="antiInsta";
        client;
        toggleAnti=!1;
        healingCount=0;
        constructor(client2) {
            this.client = client2;
        }
        isSaveHealTime() {
            let {myPlayer: myPlayer, SocketManager: SocketManager2} = this.client, startHit = myPlayer.receivedDamage || 0;
            return Date.now() - startHit + SocketManager2.pong >= 125;
        }
        isSaveHealTick() {
            let {tickCount: tickCount, damageTick: damageTick} = this.client.myPlayer;
            return tickCount - damageTick > 0;
        }
        isSaveHeal() {
            return this.isSaveHealTime();
        }
        postTick() {
            if (!Settings_default._autoheal) {
                return;
            }
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, ProjectileManager: ProjectileManager2} = this.client;
            if (myPlayer.shameActive) {
                return;
            }
            let foodID = myPlayer.getItemByType(2), restore = Items[foodID].restore, needTimes = Math.ceil((myPlayer.maxHealth - myPlayer.tempHealth) / restore), healingTimes = null, forceHeal = !1;
            if (EnemyManager2.velocityTickThreat || EnemyManager2.reverseInsta || EnemyManager2.rangedBowInsta || EnemyManager2.detectedDangerEnemy || EnemyManager2.detectedEnemy || myPlayer.tempHealth <= 20 || ModuleHandler.shouldEquipSoldier && ModuleHandler.forceHat !== 6 || EnemyManager2.dangerWithoutSoldier) {
                forceHeal = !0;
            }
            if (myPlayer.shameCount < 7 && forceHeal && myPlayer.tempHealth < 95) {
                ModuleHandler.didAntiInsta = !0, healingTimes = needTimes || 1;
            } else if (this.isSaveHeal() && myPlayer.tempHealth < 100) {
                healingTimes = needTimes || 1;
            }
            if (healingTimes !== null) {
                ModuleHandler.healedOnce = !0;
                for (let i = 0; i <= healingTimes; i++) {
                    ModuleHandler.heal();
                }
            }
        }
    }

    const AntiInsta_default = AntiInsta;

    class Autohat {
        moduleName="autoHat";
        client;
        constructor(client2) {
            this.client = client2;
        }
        handleEquip(type, use) {
            let {ModuleHandler: ModuleHandler} = this.client;
            if (type === 0 && ModuleHandler.forceHat !== null) {
                use = ModuleHandler.forceHat;
            }
            if (use !== null && ModuleHandler.equip(type, use)) {
                return !0;
            }
            return !1;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler} = this.client;
            if (!ModuleHandler.sentHatEquip) {
                this.handleEquip(0, ModuleHandler.useHat);
            }
            if (!ModuleHandler.sentAccEquip && !ModuleHandler.sentHatEquip) {
                this.handleEquip(1, ModuleHandler.useAcc);
            }
        }
    }

    const Autohat_default = Autohat;

    class DefaultAcc {
        moduleName="defaultAcc";
        client;
        constructor(client2) {
            this.client = client2;
        }
        shouldUseTail() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer} = this.client, {reloading: reloading} = ModuleHandler.staticModules, primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1);
            return DataHandler_default.isMelee(primary) && primary !== 8 && !reloading.isReloaded(0, 2) || DataHandler_default.isMelee(secondary) && !reloading.isReloaded(1, 2);
        }
        getBestCurrentAcc() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2} = this.client, {actual: actual} = ModuleHandler.getAccStore(), useCorrupt = ModuleHandler.canBuy(1, 21), useShadow = ModuleHandler.canBuy(1, 19), useTail = ModuleHandler.canBuy(1, 11), useActual = ModuleHandler.canBuy(1, actual);
            if (EnemyManager2.detectedEnemy || EnemyManager2.nearestEnemyInRangeOf(300, EnemyManager2.nearestEntity)) {
                if (EnemyManager2.nearestEntity === EnemyManager2.nearestEnemy && useCorrupt && Settings_default._antienemy) {
                    return 21;
                }
                if (useShadow) {
                    return 19;
                }
                if (useActual && actual !== 11) {
                    return actual;
                }
                return 0;
            }
            if (useTail) {
                return 11;
            }
            return 0;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler} = this.client, acc = this.getBestCurrentAcc();
            ModuleHandler.useAcc = acc;
        }
    }

    class DefaultHat {
        moduleName="defaultHat";
        client;
        platformActivated=!1;
        constructor(client2) {
            this.client = client2;
        }
        getBestCurrentHat() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client, {current: current, future: future} = myPlayer.pos, {actual: actual} = ModuleHandler.getHatStore(), useFlipper = ModuleHandler.canBuy(0, 31), useSoldier = ModuleHandler.canBuy(0, 6), useWinter = ModuleHandler.canBuy(0, 15), useActual = ModuleHandler.canBuy(0, actual), useBooster = ModuleHandler.canBuy(0, 12), useBull = ModuleHandler.canBuy(0, 7), useEmp = ModuleHandler.canBuy(0, 22);
            if (useActual && !ModuleHandler.isMoving && myPlayer.speed <= 5 && actual !== 0) {
                return actual;
            }
            if (useSoldier) {
                if (Settings_default._antienemy) {
                    if (EnemyManager2.detectedDangerEnemy || EnemyManager2.detectedEnemy || EnemyManager2.velocityTickThreat || EnemyManager2.reverseInsta || EnemyManager2.rangedBowInsta) {
                        return ModuleHandler.shouldEquipSoldier = !0, ModuleHandler.forceHat = 6, 6;
                    }
                    if (useBull && myPlayer.shameCount > 0 || EnemyManager2.dangerWithoutSoldier) {
                        return 6;
                    }
                }
                if (Settings_default._antispike && EnemyManager2.willCollideSpike) {
                    return 6;
                }
            }
            if (Settings_default._biomehats && useFlipper) {
                if (pointInRiver(current) || pointInRiver(future)) {
                    return 31;
                }
            }
            if (useSoldier) {
                if (Settings_default._antianimal && EnemyManager2.nearestDangerAnimal !== null) {
                    return 6;
                }
            }
            if (useEmp && Settings_default._empDefense && (!ModuleHandler.isMoving || myPlayer.speed <= 5)) {
                return 22;
            }
            if (Settings_default._biomehats && useWinter) {
                if (current.y <= 2400 || future.y <= 2400) {
                    return 15;
                }
            }
            if (useBooster) {
                return 12;
            }
            return 0;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler} = this.client, hat = this.getBestCurrentHat();
            ModuleHandler.useHat = hat;
        }
    }

    class SafeWalk {
        moduleName="safeWalk";
        client;
        movingState=!1;
        constructor(client2) {
            this.client = client2;
        }
        reset() {
            this.movingState = !1;
        }
        willGetHit(angle, speed, target) {
            if (angle === null || !Settings_default._safeWalk) {
                return !1;
            }
            let {myPlayer: myPlayer} = this.client, nearestCollider = target;
            if (nearestCollider === null) {
                return !1;
            }
            let distance = Vector_default.fromAngle(angle, speed + myPlayer.speed / 4).add(myPlayer.pos.current).distance(nearestCollider.pos.current), range = myPlayer.collisionScale + nearestCollider.collisionScale;
            if (distance > range) {
                return !1;
            }
            return !0;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer, ObjectManager: ObjectManager2, EnemyManager: EnemyManager2} = this.client, {prevMoveTo: prevMoveTo, moveTo: moveTo} = ModuleHandler;
            if (prevMoveTo !== moveTo) {
                let angle = moveTo === "disable" ? ModuleHandler.move_dir : moveTo;
                ModuleHandler.startMovement(angle, !0);
                return;
            }
            let offset = myPlayer.speed + 45;
            if (this.willGetHit(ModuleHandler.move_dir, offset, EnemyManager2.nearestCollider) || this.willGetHit(ModuleHandler.move_dir, offset, EnemyManager2.secondNearestCollider)) {
                if (!this.movingState) {
                    this.movingState = !0, ModuleHandler.stopMovement();
                }
                return;
            }
            if (this.movingState) {
                this.movingState = !1, ModuleHandler.startMovement();
            }
        }
    }

    class ShameReset {
        moduleName="shameReset";
        client;
        tickToggle=!1;
        constructor(client2) {
            this.client = client2;
        }
        isBullTickTime() {
            let {myPlayer: myPlayer} = this.client;
            return !myPlayer.shameActive && myPlayer.shameCount > 0 && myPlayer.poisonCount === 0 && myPlayer.isBullTickTime();
        }
        get shouldReset() {
            let {ModuleHandler: ModuleHandler} = this.client;
            return this.isBullTickTime() && ModuleHandler.canBuy(0, 7);
        }
        notSave() {
            let {EnemyManager: EnemyManager2, myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client;
            return ModuleHandler.forceHat === 40 || EnemyManager2.instaThreat() || EnemyManager2.collidingSpike || myPlayer.wasTrapped() || ModuleHandler.currentType === 2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler} = this.client;
            if (!this.notSave() && (this.shouldReset || this.tickToggle)) {
                this.tickToggle = !0, ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 7;
            }
        }
        healthUpdate() {
            if (this.client.myPlayer.isDmgOverTime) {
                this.tickToggle = !1;
            }
        }
    }

    const ShameReset_default = ShameReset;

    class AutoAccept {
        moduleName="autoAccept";
        client;
        prevClan=null;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {myPlayer: myPlayer, clientIDList: clientIDList, PacketManager: PacketManager2, isOwner: isOwner} = this.client, currentClan = myPlayer.clanName;
            if (currentClan !== this.prevClan) {
                this.prevClan = currentClan, myPlayer.joinRequests.length = 0, this.client.pendingJoins.clear();
            }
            if (!myPlayer.isLeader || myPlayer.joinRequests.length === 0) {
                return;
            }
            let id = myPlayer.joinRequests[0][0];
            if (Settings_default._autoaccept || this.client.pendingJoins.size !== 0) {
                if (PacketManager2.clanRequest(id, Settings_default._autoaccept || clientIDList.has(id)),
                myPlayer.joinRequests.shift(), this.client.pendingJoins.delete(id), isOwner) {
                    GameUI_default.clearNotication();
                }
            }
            let nextID = myPlayer.joinRequests[0];
            if (isOwner && nextID !== void 0) {
                GameUI_default.createRequest(nextID);
            }
        }
    }

    const AutoAccept_default = AutoAccept;

    class AutoBuy {
        moduleName="autoBuy";
        client;
        buyIndex=0;
        buyList=[ [ 1, 11 ], [ 0, 12 ], [ 0, 7 ], [ 0, 6 ], [ 0, 40 ], [ 0, 53 ], [ 1, 21 ], [ 0, 11 ], [ 1, 19 ], [ 0, 15 ], [ 0, 31 ], [ 0, 20 ], [ 0, 22 ] ];
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer} = this.client;
            if (this.buyIndex >= this.buyList.length || !myPlayer.isSandbox) {
                return;
            }
            let [type, id] = this.buyList[this.buyIndex];
            if (ModuleHandler.canBuy(type, id)) {
                ModuleHandler.buy(type, id);
            }
            if (ModuleHandler.bought[type].has(id)) {
                this.buyIndex += 1;
            }
        }
    }

    class AutoGrind {
        moduleName="autoGrind";
        client;
        constructor(client2) {
            this.client = client2;
        }
        isFullyUpgraded() {
            let {myPlayer: myPlayer} = this.client, primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1), upgradedSecondary = secondary === 10 && myPlayer.getWeaponVariant(secondary).current >= 1, upgradedPrimary = primary !== 8 && myPlayer.getWeaponVariant(primary).current >= 2;
            return upgradedSecondary && upgradedPrimary;
        }
        getGrindWeapon() {
            let {myPlayer: myPlayer, EnemyManager: EnemyManager2, ModuleHandler: ModuleHandler} = this.client, nearestObject = EnemyManager2.nearestPlayerObject, secondNearestObject = EnemyManager2.secondNearestPlayerObject;
            if (nearestObject === null) {
                return null;
            }
            let primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1);
            if (secondary === 10) {
                if (myPlayer.getWeaponVariant(secondary).current < 1) {
                    return 1;
                }
                let useTank = ModuleHandler.canBuy(0, 40), damage = myPlayer.getBuildingDamage(10, useTank), range = DataHandler_default.getWeapon(secondary).range, canHit1 = myPlayer.colliding(nearestObject, range + nearestObject.hitScale) && nearestObject.health > damage, canHit2 = secondNearestObject !== null && myPlayer.colliding(secondNearestObject, range + secondNearestObject.hitScale) && secondNearestObject.health > damage;
                if (canHit1 && canHit2) {
                    return 1;
                }
            }
            if (primary !== 8 && myPlayer.getWeaponVariant(primary).current < 2) {
                return 0;
            }
            return null;
        }
        placeTurret(angle) {
            let {myPlayer: myPlayer, ObjectManager: ObjectManager2, ModuleHandler: ModuleHandler} = this.client, id = myPlayer.getItemByType(8), position = myPlayer.getPlacePosition(myPlayer.pos.future, id, angle);
            if (!ObjectManager2.canPlaceItem(id, position)) {
                return !1;
            }
            let type = 8;
            return ModuleHandler.place(type, angle), ModuleHandler.placedOnce = !0, ModuleHandler.placeAngles[0] = 8,
            ModuleHandler.placeAngles[1].push(angle), !0;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (!Settings_default._autoGrind || ModuleHandler.moduleActive || ModuleHandler.placedOnce || ModuleHandler.healedOnce || ModuleHandler.isMoving || myPlayer.speed > 5 || this.isFullyUpgraded()) {
                return;
            }
            let {autoMill: autoMill, reloading: reloading} = ModuleHandler.staticModules;
            if (autoMill.isActive) {
                return;
            }
            let farmItem = myPlayer.getItemByType(8);
            if (farmItem !== 17 && farmItem !== 22) {
                return;
            }
            let nearestEnemy = EnemyManager2.nearestEnemy;
            if (nearestEnemy !== null && myPlayer.collidingSimple(nearestEnemy, 400)) {
                return;
            }
            let itemType = 8;
            if (!myPlayer.canPlace(itemType)) {
                return;
            }
            let item = DataHandler_default.getItem(farmItem), distance = myPlayer.getItemPlaceScale(item.id), angle = ModuleHandler.currentAngle, angleBetween = Math.asin((2 * item.scale + 15) / (2 * distance));
            this.placeTurret(angle - angleBetween), this.placeTurret(angle + angleBetween);
            let {nearestPlayerObject: nearestObject, secondNearestPlayerObject: secondNearestObject} = EnemyManager2;
            if (nearestObject === null || nearestObject.type !== 17 && nearestObject.type !== 22) {
                return;
            }
            let pos1 = myPlayer.pos.current, tempAngle = pos1.angle(nearestObject.pos.current), weaponType = this.getGrindWeapon();
            if (weaponType === null) {
                return;
            }
            let weapon = myPlayer.getItemByType(weaponType);
            if (secondNearestObject !== null && nearestObject !== secondNearestObject) {
                let pos3 = secondNearestObject.pos.current, distance2 = pos1.distance(pos3), range = DataHandler_default.getWeapon(weapon).range + secondNearestObject.hitScale, angle2 = pos1.angle(pos3), middleAngle = findMiddleAngle(tempAngle, angle2);
                if (distance2 <= range && getAngleDist(tempAngle, middleAngle) <= Config_default.gatherAngle && getAngleDist(angle2, middleAngle) <= Config_default.gatherAngle) {
                    tempAngle = middleAngle;
                }
            }
            if (reloading.isReloaded(weaponType)) {
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = tempAngle, ModuleHandler.useHat = 40,
                ModuleHandler.forceWeapon = weaponType, ModuleHandler.shouldAttack = !0;
            }
        }
    }

    class Automill {
        moduleName="autoMill";
        toggle=!1;
        active=!0;
        client;
        tickCount=0;
        constructor(client2) {
            this.client = client2;
        }
        get isActive() {
            return this.toggle && this.active;
        }
        reset() {
            this.active = !0;
        }
        get canAutomill() {
            let isOwner = this.client.isOwner, {attacking: attacking, placedOnce: placedOnce} = this.client.ModuleHandler;
            return Settings_default._automill && this.client.myPlayer.isSandbox && !placedOnce && (!isOwner || !attacking) && this.active;
        }
        canPlaceWindmill(angle) {
            return this.client.myPlayer.canPlaceObject(5, angle);
        }
        placeWindmill(angle) {
            let {ModuleHandler: ModuleHandler} = this.client, type = 5;
            ModuleHandler.place(type, angle), ModuleHandler.placedOnce = !0, ModuleHandler.placeAngles[0] = type,
            ModuleHandler.placeAngles[1].push(angle);
        }
        postTick() {
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler} = this.client;
            if (this.toggle = !0, !this.canAutomill) {
                this.toggle = !1;
                return;
            }
            if (!myPlayer.canPlace(5)) {
                this.toggle = !1, this.active = !1;
                return;
            }
            let angle = ModuleHandler.reverse_move_dir;
            if (angle === null) {
                return;
            }
            let item = Items[myPlayer.getItemByType(5)], distance = myPlayer.getItemPlaceScale(item.id), offset = Math.asin((2 * item.scale + 9e-13) / (2 * distance)) * 2, leftAngle = angle - offset, rightAngle = angle + offset;
            if (this.canPlaceWindmill(angle) && this.canPlaceWindmill(leftAngle) && this.canPlaceWindmill(rightAngle)) {
                this.placeWindmill(angle), this.placeWindmill(leftAngle), this.placeWindmill(rightAngle);
            }
        }
    }

    const Automill_default = Automill;

    class AutoSteal {
        moduleName="autoSteal";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._autoSteal) {
                return;
            }
            let nearestLowEntity = EnemyManager2.nearestLowEntity;
            if (nearestLowEntity === null) {
                return;
            }
            let {reloading: reloading} = ModuleHandler.staticModules, primary = myPlayer.getItemByType(0), range = DataHandler_default.getWeapon(primary).range + nearestLowEntity.hitScale;
            if (!myPlayer.collidingSimple(nearestLowEntity, range) || !reloading.isReloaded(0)) {
                return;
            }
            let canUseBull = ModuleHandler.canBuy(0, 7), pos1 = myPlayer.pos.current, pos2 = nearestLowEntity.pos.current, angle = pos1.angle(pos2), maxDamageBull = myPlayer.getMaxWeaponDamage(primary, !1, canUseBull), maxDamage = myPlayer.getMaxWeaponDamage(primary, !1, !1);
            if (!(maxDamageBull >= nearestLowEntity.currentHealth)) {
                return;
            }
            if (ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, maxDamage < nearestLowEntity.currentHealth) {
                ModuleHandler.forceHat = 7;
            }
            ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0;
        }
    }

    class AutoPush {
        moduleName="autoPush";
        client;
        pushPos=null;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {EnemyManager: EnemyManager2, myPlayer: myPlayer, ModuleHandler: ModuleHandler, ObjectManager: ObjectManager2, PlayerManager: PlayerManager2} = this.client;
            this.pushPos = null;
            let {nearestEnemyPush: nearestEnemyPush, nearestPushSpike: nearestPushSpike} = EnemyManager2;
            if (EnemyManager2.nearestEnemyPush = null, EnemyManager2.nearestPushSpike = null,
            ModuleHandler.moduleActive || !Settings_default._autoPush || ModuleHandler.moveTo !== "disable") {
                return;
            }
            if (nearestEnemyPush === null || nearestPushSpike === null) {
                return;
            }
            if (nearestEnemyPush.trappedIn === null || myPlayer.trappedIn) {
                return;
            }
            let pos0 = myPlayer.pos.current, pos1 = nearestEnemyPush.pos.current, pos2 = nearestPushSpike.pos.current;
            if (!myPlayer.collidingSimple(nearestEnemyPush, 250) || nearestEnemyPush.colliding(nearestPushSpike, nearestEnemyPush.collisionScale + nearestPushSpike.collisionScale + 1)) {
                return;
            }
            let distanceFromSpikeToEnemy = pos2.distance(pos1), angleFromSpikeToEnemy = pos2.angle(pos1), angleToEnemy = pos0.angle(pos1), angleToSpike = pos0.angle(pos2), distanceToSpike = pos0.distance(pos2), pushPos = pos2.addDirection(angleFromSpikeToEnemy, distanceFromSpikeToEnemy + nearestEnemyPush.collisionScale + 7), objectIDs = ObjectManager2.grid2D.queryFull(pushPos.x, pushPos.y, 1);
            for (let id of objectIDs) {
                let object = ObjectManager2.objects.get(id);
                if (PlayerManager2.canMoveOnTop(object)) {
                    continue;
                }
                let pos = object.pos.current, distance = pushPos.distance(pos), playerScale = myPlayer.collisionScale * 1.3, range = object.collisionScale + playerScale;
                if (distance <= range) {
                    return;
                }
            }
            this.pushPos = pos2.addDirection(angleFromSpikeToEnemy, distanceFromSpikeToEnemy + 250),
            ModuleHandler.moveTo = pos0.angle(this.pushPos), EnemyManager2.nearestEnemyPush = nearestEnemyPush,
            EnemyManager2.nearestPushSpike = nearestPushSpike;
            let activationScale2 = nearestEnemyPush.collisionScale * 3.2, offset2 = Math.asin(2 * activationScale2 / (2 * distanceToSpike));
            if (!(getAngleDist(angleToEnemy, angleToSpike) <= offset2)) {
                return;
            }
            this.pushPos = pushPos, ModuleHandler.moveTo = pos0.angle(this.pushPos);
        }
    }

    class ReverseInstakill {
        moduleName="reverseInstakill";
        client;
        targetEnemy=null;
        constructor(client2) {
            this.client = client2;
        }
        reset() {
            this.targetEnemy = null;
        }
        postTick() {
            let {myPlayer: myPlayer, EnemyManager: EnemyManager2, PlayerManager: PlayerManager2, ModuleHandler: ModuleHandler, InputHandler: InputHandler2} = this.client;
            if (!InputHandler2.instaToggle) {
                this.reset(), InputHandler2.instaReset();
                return;
            }
            let nearestEnemy = EnemyManager2.nearestEnemy;
            if (nearestEnemy === null) {
                return;
            }
            let lookingShield = PlayerManager2.lookingShield(nearestEnemy, myPlayer), primary = myPlayer.getItemByType(0), primaryDamage = myPlayer.getMaxWeaponDamage(primary, lookingShield), secondary = myPlayer.getItemByType(1);
            if (secondary !== 10) {
                return;
            }
            let secondaryDamage = myPlayer.getMaxWeaponDamage(secondary, lookingShield);
            if (primaryDamage + secondaryDamage + 25 < 100) {
                return;
            }
            let pos1 = myPlayer.pos.current, pos2 = nearestEnemy.pos.current, angle = pos1.angle(pos2);
            if (this.targetEnemy !== null) {
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 7,
                ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, this.targetEnemy = null,
                InputHandler2.instaReset(), EnemyManager2.attemptSpikePlacement();
                return;
            }
            InputHandler2.instakillTarget = nearestEnemy;
            let {reloading: reloading} = ModuleHandler.staticModules, primaryReloaded = reloading.isReloaded(0), secondaryReloaded = reloading.isReloaded(1), turretReloaded = reloading.isReloaded(2), range = DataHandler_default.getWeapon(primary).range + nearestEnemy.hitScale;
            if (!primaryReloaded || !secondaryReloaded || !turretReloaded || !myPlayer.collidingSimple(nearestEnemy, range)) {
                return;
            }
            ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 53,
            ModuleHandler.forceWeapon = 1, ModuleHandler.shouldAttack = !0, this.targetEnemy = nearestEnemy;
        }
    }

    class BowInsta {
        moduleName="bowInsta";
        client;
        targetEnemy=null;
        tickAction=0;
        distMin=660;
        distMax=700;
        active=!1;
        constructor(client2) {
            this.client = client2;
        }
        reset() {
            this.targetEnemy = null, this.tickAction = 0, this.active = !1;
        }
        postTick() {
            let {EnemyManager: EnemyManager2, ModuleHandler: ModuleHandler, myPlayer: myPlayer, InputHandler: InputHandler2} = this.client;
            if (!InputHandler2.instaToggle) {
                this.reset(), InputHandler2.instaReset();
                return;
            }
            let nearestEnemy = EnemyManager2.nearestEnemy, nearest = this.targetEnemy || nearestEnemy;
            if (nearest === null) {
                this.reset();
                return;
            }
            let pos1 = myPlayer.pos.current, pos2 = nearest.pos.current, angle = pos1.angle(pos2), distance = pos1.distance(pos2);
            if (InputHandler2.instakillTarget = nearest, this.targetEnemy !== null) {
                if (this.tickAction === 2) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceWeapon = 1,
                    ModuleHandler.shouldAttack = !0, ModuleHandler.moveTo = null, ModuleHandler.upgradeItem(15),
                    this.reset(), InputHandler2.instaReset();
                    return;
                }
                if (this.tickAction === 1) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceWeapon = 1,
                    ModuleHandler.shouldAttack = !0, ModuleHandler.moveTo = null, ModuleHandler.upgradeItem(12),
                    this.tickAction = 2;
                    return;
                }
                return;
            }
            if (!(inRange(myPlayer.upgradeAge, 6, 8) && myPlayer.age >= 9)) {
                return;
            }
            this.active = !0;
            let {reloading: reloading} = ModuleHandler.staticModules;
            if (!ModuleHandler.canBuy(0, 53) || !reloading.isReloaded(2) || !inRange(distance, this.distMin, this.distMax)) {
                return;
            }
            if (ModuleHandler.moveTo = null, ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle,
            ModuleHandler.forceHat = 53, ModuleHandler.forceWeapon = 1, ModuleHandler.shouldAttack = !0,
            myPlayer.upgradeAge === 6) {
                ModuleHandler.upgradeItem(9);
            }
            if (myPlayer.upgradeAge === 7) {
                ModuleHandler.upgradeItem(18, !0);
            }
            if (myPlayer.upgradeAge === 8 && myPlayer.getItemByType(8) === 18) {
                ModuleHandler.place(8, angle), ModuleHandler.place(8, angle - toRadians(90)),
                ModuleHandler.place(8, angle + toRadians(90)), ModuleHandler.place(8, reverseAngle(angle));
            }
            this.tickAction = 1, this.targetEnemy = nearestEnemy;
        }
    }

    class PlacementDefense {
        moduleName="placementDefense";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {EnemyManager: EnemyManager2, myPlayer: myPlayer, ModuleHandler: ModuleHandler, ProjectileManager: ProjectileManager2} = this.client, nearestEnemy = EnemyManager2.nearestEnemy;
            if (nearestEnemy === null || !Settings_default._placementDefense) {
                return;
            }
            if (EnemyManager2.rangedBowInsta || ProjectileManager2.totalDamage >= myPlayer.currentHealth) {
                let pos1 = myPlayer.pos.current, pos2 = nearestEnemy.pos.current, angle = pos1.angle(pos2), type = 3;
                if (myPlayer.canPlace(5)) {
                    type = 5;
                }
                ModuleHandler.place(type, angle), ModuleHandler.placedOnce = !0, ModuleHandler.placeAngles[0] = type,
                ModuleHandler.placeAngles[1] = [ angle ];
            }
        }
    }

    class TurretSteal {
        moduleName="turretSteal";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer, EnemyManager: EnemyManager2} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._turretSteal) {
                return;
            }
            let nearestEnemy = EnemyManager2.nearestTurretEntity;
            if (nearestEnemy === null || nearestEnemy.currentHealth > 25 || !ModuleHandler.canBuy(0, 53)) {
                return;
            }
            let pos0 = myPlayer.pos.current, pos1 = nearestEnemy.pos.current;
            if (pos0.distance(pos1) > 700) {
                return;
            }
            let {reloading: reloading} = ModuleHandler.staticModules;
            if (!reloading.isReloaded(2, 0)) {
                return;
            }
            ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
        }
    }

    class KillChat {
        moduleName="killChat";
        client;
        constructor(client2) {
            this.client = client2;
        }
        // Message de kill fige. Il ne depend plus d un reglage : ni le menu,
        // ni le stockage local, ni la console ne peuvent le changer.
        static get MESSAGE() { return "seldoom is goated"; }
        postTick() {
            let {myPlayer: myPlayer, PacketManager: PacketManager2} = this.client;
            if (!myPlayer.killedSomeone || myPlayer.resources.kills === 0) {
                return;
            }
            PacketManager2.chat(KillChat.MESSAGE);
        }
    }

    class SwordKatanaInsta {
        moduleName="swordKatanaInsta";
        client;
        nearestTarget=null;
        useTurret=!1;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {myPlayer: myPlayer, ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2} = this.client, nearestEnemy = EnemyManager2.nearestEnemy;
            if (ModuleHandler.moduleActive || !nearestEnemy) {
                this.nearestTarget = null, this.useTurret = !1;
                return;
            }
            let {reloading: reloading} = ModuleHandler.staticModules, primaryReloaded = reloading.isReloaded(0), turretReloaded = reloading.isReloaded(2);
            if (this.useTurret) {
                if (this.useTurret = !1, turretReloaded && ModuleHandler.canBuy(0, 53)) {
                    ModuleHandler.moduleActive = !0, ModuleHandler.forceHat = 53;
                }
                return;
            }
            let primary = myPlayer.getItemByType(0), isSword = primary === 3, pos1 = myPlayer.pos.current, target = this.nearestTarget;
            if (target !== null) {
                let pos22 = target.pos.current, angle2 = pos1.angle(pos22);
                if (ModuleHandler.useAngle = angle2, ModuleHandler.forceHat = 7, ModuleHandler.forceWeapon = 0,
                ModuleHandler.shouldAttack = !0, myPlayer.upgradeAge === 3) {
                    ModuleHandler.upgradeItem(1, !0);
                }
                if (myPlayer.upgradeAge === 4) {
                    ModuleHandler.upgradeItem(15, !0);
                }
                if (myPlayer.upgradeAge === 5) {
                    ModuleHandler.upgradeItem(7, !0);
                }
                if (myPlayer.upgradeAge === 6) {
                    ModuleHandler.upgradeItem(10);
                }
                if (myPlayer.upgradeAge === 7) {
                    ModuleHandler.upgradeItem(22, !0);
                }
                if (myPlayer.upgradeAge === 8) {
                    ModuleHandler.upgradeItem(4);
                }
                if (this.nearestTarget = null, ModuleHandler.canBuy(0, 53)) {
                    this.useTurret = !0;
                }
                EnemyManager2.attemptSpikePlacement();
            }
            if (myPlayer.age < 8 || !isSword || !primaryReloaded || !ModuleHandler.canBuy(0, 7)) {
                return;
            }
            let range = DataHandler_default.getWeapon(primary).range + nearestEnemy.hitScale;
            if (!myPlayer.collidingSimple(nearestEnemy, range)) {
                return;
            }
            let pos2 = nearestEnemy.pos.current, angle = pos1.angle(pos2);
            ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 7, ModuleHandler.forceWeapon = 0,
            ModuleHandler.shouldAttack = !0, this.nearestTarget = nearestEnemy;
        }
    }

    class SpikeGearInsta {
        moduleName="spikeGearInsta";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || EnemyManager2.instaThreat() || EnemyManager2.spikeSyncThreat || !Settings_default._spikeGearInsta) {
                return;
            }
            let nearestEnemy = EnemyManager2.nearestEnemy;
            if (nearestEnemy === null || !ModuleHandler.canBuy(0, 11) || !ModuleHandler.canBuy(1, 21) || myPlayer.accessoryID !== 21 || nearestEnemy.variant.primary !== 0) {
                return;
            }
            let pos1 = myPlayer.pos.current, pos2 = nearestEnemy.pos.current, angle = pos1.angle(pos2), primary1 = myPlayer.getItemByType(0), primary2 = nearestEnemy.weapon.primary;
            if (primary2 === null) {
                return;
            }
            let range1 = DataHandler_default.getWeapon(primary1).range + nearestEnemy.hitScale, range2 = DataHandler_default.getWeapon(primary2).range + myPlayer.hitScale;
            if (!myPlayer.collidingSimple(nearestEnemy, range1) || !nearestEnemy.collidingSimple(myPlayer, range2)) {
                return;
            }
            if (ModuleHandler.forceHat = 11, nearestEnemy.hatID !== 7 || !nearestEnemy.isEmptyReload(0) || myPlayer.hatID !== 11) {
                return;
            }
            ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 7,
            ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0;
        }
    }

    class TeammateSpikeTrap {
        moduleName="teammateSpikeTrap";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, InputHandler: InputHandler2, PlayerManager: PlayerManager2, myPlayer: myPlayer, PacketManager: PacketManager2} = this.client;
            if (ModuleHandler.moduleActive) {
                return;
            }
            if (!InputHandler2.instaToggle) {
                InputHandler2.instaReset();
                return;
            }
            let nearestTeammate = PlayerManager2.nearestTeammate;
            if (!nearestTeammate) {
                return;
            }
            let pos1 = myPlayer.pos.current, pos2 = nearestTeammate.pos.current, distance = pos1.distance(pos2), angle = pos1.angle(pos2);
            if (distance > 500) {
                return;
            }
            if (InputHandler2.instakillTarget = nearestTeammate, distance > 175) {
                return;
            }
            let angles = [ angle, angle - toRadians(90), angle + toRadians(90), angle + toRadians(180) ], id = myPlayer.getItemByType(4), distance2 = myPlayer.getPlacePosition(pos1, id, angle).distance(pos1);
            if (ModuleHandler.placeAngles[0] = 4, ModuleHandler.placeAngles[1] = angles,
            distance > distance2 || !angles.every(angle2 => myPlayer.canPlaceObject(4, angle2))) {
                return;
            }
            InputHandler2.instaReset(), PacketManager2.leaveClan();
            for (let angle2 of angles) {
                ModuleHandler.place(4, angle2);
            }
        }
    }

    class SpikeTrap {
        moduleName="spikeTrap";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer, EnemyManager: EnemyManager2} = this.client;
            if (ModuleHandler.moduleActive) {
                return;
            }
            let trapId = myPlayer.getItemByType(7), nearestEnemy = EnemyManager2.nearestEnemy;
            if (!nearestEnemy || myPlayer.isTrapped || trapId !== 16) {
                return;
            }
            let pos1 = myPlayer.pos.current, pos2 = nearestEnemy.pos.current, distance = pos1.distance(pos2), angle = pos1.angle(pos2);
            if (distance > 175) {
                return;
            }
            let angles = [ angle, angle - toRadians(90), angle + toRadians(90), angle + toRadians(180) ], id = myPlayer.getItemByType(4), len = ModuleHandler.currentType === 7 ? 30 : 0, distance2 = myPlayer.getPlacePosition(pos1, id, angle).distance(pos1) + len;
            if (ModuleHandler.placeAngles[0] = 4, ModuleHandler.placeAngles[1] = angles,
            distance > distance2) {
                return;
            }
            for (let angle2 of angles) {
                ModuleHandler.place(4, angle2);
            }
        }
    }

    class TurretSync {
        moduleName="turretSync";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._turretSync) {
                return;
            }
            let nearestEnemy = EnemyManager2.nearestEnemy;
            if (nearestEnemy === null) {
                return;
            }
            let primary = myPlayer.getItemByType(0), weapon = DataHandler_default.getWeapon(primary);
            if (weapon.damage < 20) {
                return;
            }
            let range = weapon.range + nearestEnemy.hitScale, {reloading: reloading} = ModuleHandler.staticModules;
            if (!myPlayer.collidingSimple(nearestEnemy, range) || !reloading.isReloaded(0) || nearestEnemy.nextDamageTick !== myPlayer.tickCount + 2) {
                return;
            }
            let pos1 = myPlayer.pos.current, pos2 = nearestEnemy.pos.current, angle = pos1.angle(pos2);
            ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angle, ModuleHandler.forceHat = 7,
            ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0;
        }
    }

    class DashMovement {
        moduleName="dashMovement";
        client;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, myPlayer: myPlayer} = this.client, {currentType: currentType, currentAngle: currentAngle} = ModuleHandler;
            if (!myPlayer.canPlace(currentType) || !Settings_default._dashMovement) {
                return;
            }
            let {reloading: reloading} = ModuleHandler.staticModules, primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1);
            if (myPlayer.getItemByType(7) !== 16 || !ModuleHandler.hasStoreItem(0, 40) || currentType !== 7 || ModuleHandler.placedOnce) {
                return;
            }
            let hasHammer = secondary === 10, canOneHit = myPlayer.getBuildingDamage(primary, !0) >= DataHandler_default.getItem(16).health, weaponType = null;
            if (canOneHit) {
                let primaryData = DataHandler_default.getWeapon(primary), secondaryData = DataHandler_default.isMelee(secondary) && DataHandler_default.getWeapon(secondary) || null;
                if (secondaryData === null || primaryData.speed < secondaryData.speed) {
                    weaponType = 0;
                }
            }
            if (weaponType === null && hasHammer) {
                weaponType = 1;
            }
            if (weaponType === null) {
                return;
            }
            if (ModuleHandler.placedOnce = !0, !reloading.isReloaded(weaponType)) {
                return;
            }
            ModuleHandler.place(currentType, currentAngle), ModuleHandler.useAngle = currentAngle,
            ModuleHandler.useHat = 40, ModuleHandler.forceWeapon = weaponType, ModuleHandler.shouldAttack = !0;
        }
    }

    class KBTickHammerV2 {
        moduleName="kbTickHammerV2";
        client;
        targetEnemy=null;
        constructor(client2) {
            this.client = client2;
        }
        postTick() {
            let {ModuleHandler: ModuleHandler, EnemyManager: EnemyManager2, myPlayer: myPlayer} = this.client;
            if (ModuleHandler.moduleActive || !Settings_default._knockbackTickHammer || EnemyManager2.shouldIgnoreModule()) {
                this.targetEnemy = null;
                return;
            }
            let {nearestEnemySpikeCollider: nearestEnemySpikeCollider, spikeCollider: spikeCollider} = EnemyManager2, reloading = ModuleHandler.staticModules.reloading, primary = myPlayer.getItemByType(0), secondary = myPlayer.getItemByType(1), isHammer = secondary !== null && secondary !== 11, primaryReloaded = reloading.isReloaded(0), secondaryReloaded = reloading.isReloaded(1), pos1 = myPlayer.pos.current;
            if (this.targetEnemy !== null) {
                let pos2 = this.targetEnemy.pos.current, angleToEnemy = pos1.angle(pos2);
                ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angleToEnemy, ModuleHandler.forceHat = 7,
                ModuleHandler.forceWeapon = 0, ModuleHandler.shouldAttack = !0, this.targetEnemy = null,
                EnemyManager2.attemptSpikePlacement();
                return;
            }
            if (nearestEnemySpikeCollider !== null && !nearestEnemySpikeCollider.isTrapped && spikeCollider !== null && isHammer && primaryReloaded && secondaryReloaded) {
                let pos2 = nearestEnemySpikeCollider.pos.current, pos3 = spikeCollider.pos.current, angleToEnemy = pos1.angle(pos2), distanceToSpike2 = pos2.distance(pos3), {knockback: primaryKnockback, range: primaryRange} = DataHandler_default.getWeapon(primary), {knockback: secondaryKnockback, range: secondaryRange} = DataHandler_default.getWeapon(secondary), weaponRange = Math.min(primaryRange, secondaryRange) + nearestEnemySpikeCollider.hitScale, minKB = primaryKnockback, maxKB = primaryKnockback + secondaryKnockback, spikeRange = spikeCollider.collisionScale + nearestEnemySpikeCollider.collisionScale;
                if (inRange(distanceToSpike2, spikeRange + minKB, spikeRange + maxKB) && myPlayer.collidingSimple(nearestEnemySpikeCollider, weaponRange)) {
                    let hitRange = DataHandler_default.getWeapon(secondary).range + nearestEnemySpikeCollider.hitScale;
                    if (myPlayer.collidingSimple(nearestEnemySpikeCollider, hitRange)) {
                        ModuleHandler.moduleActive = !0, ModuleHandler.useAngle = angleToEnemy, ModuleHandler.forceHat = 7,
                        ModuleHandler.forceWeapon = 1, ModuleHandler.shouldAttack = !0, this.targetEnemy = nearestEnemySpikeCollider,
                        this.client.StatsManager.knockbackTickHammerTimes = 1;
                    }
                }
            }
        }
    }

    class ModuleHandler {
        client;
        staticModules={};
        botModules;
        modules;
        store=[ {
            utility: new Map,
            lastUtility: null,
            current: 0,
            best: 0,
            actual: -1,
            last: 0
        }, {
            utility: new Map,
            lastUtility: null,
            current: 0,
            best: 0,
            actual: -1,
            last: 0
        } ];
        bought=[ new Set, new Set ];
        followTarget=new Vector_default(0, 0);
        lookTarget=new Vector_default(0, 0);
        endTarget=new Vector_default(0, 0);
        followPath=!1;
        tickCount=0;
        currentHolding=0;
        weapon;
        currentType;
        attacking;
        attackingState;
        sentAngle;
        sentHatEquip;
        sentAccEquip;
        needToHeal;
        didAntiInsta;
        placedOnce;
        healedOnce;
        totalPlaces;
        attacked;
        canHitEntity=!1;
        moduleActive=!1;
        useAngle=null;
        useWeapon=null;
        useItem=null;
        forceWeapon=null;
        useHat=null;
        forceHat=null;
        shouldEquipSoldier=!1;
        useAcc=null;
        previousWeapon=null;
        currentAngle=0;
        move_dir=null;
        reverse_move_dir=null;
        moveTo="disable";
        prevMoveTo="disable";
        autoattack=!1;
        shouldAttack=!1;
        mouse={
            sentAngle: 0
        };
        placeAngles=[ null, [] ];
        constructor(client2) {
            this.client = client2, this.staticModules = {
                tempData: new TempData_default(client2),
                movement: new Movement_default(client2),
                clanJoiner: new ClanJoiner_default(client2),
                autoAccept: new AutoAccept_default(client2),
                autoBuy: new AutoBuy(client2),
                defaultHat: new DefaultHat(client2),
                reloading: new Reloading_default(client2),
                defaultAcc: new DefaultAcc(client2),
                autoSync: new AutoSync(client2),
                spikeSyncHammer: new SpikeSyncHammer(client2),
                spikeSync: new SpikeSync(client2),
                spikeTick: new SpikeTick_default(client2),
                knockbackTickTrap: new KnockbackTickTrap(client2),
                knockbackTick: new KnockbackTick(client2),
                knockbackTickHammer: new KnockbackTickHammer(client2),
                kbTickHammerV2: new KBTickHammerV2(client2),
                antiRetrap: new AntiRetrap(client2),
                autoPush: new AutoPush(client2),
                velocityTick: new VelocityTick(client2),
                spikeTrap: new SpikeTrap(client2),
                teammateSpikeTrap: new TeammateSpikeTrap(client2),
                turretSync: new TurretSync(client2),
                toolHammerSpearInsta: new ToolHammerSpearInsta(client2),
                swordKatanaInsta: new SwordKatanaInsta(client2),
                bowInsta: new BowInsta(client2),
                instakill: new Instakill(client2),
                reverseInstakill: new ReverseInstakill(client2),
                autoBreak: new Autobreak(client2),
                autoSteal: new AutoSteal(client2),
                turretSteal: new TurretSteal(client2),
                spikeGearInsta: new SpikeGearInsta(client2),
                useFastest: new UseFastest(client2),
                useDestroying: new UseDestroying(client2),
                useAttacking: new UseAttacking(client2),
                utilityHat: new UtilityHat(client2),
                antiInsta: new AntiInsta_default(client2),
                shameReset: new ShameReset_default(client2),
                safeWalk: new SafeWalk(client2),
                placementDefense: new PlacementDefense(client2),
                dashMovement: new DashMovement(client2),
                autoPlacer: new AutoPlacer_default(client2),
                placer: new Placer_default(client2),
                autoMill: new Automill_default(client2),
                autoGrind: new AutoGrind(client2),
                preAttack: new PreAttack_default(client2),
                autoHat: new Autohat_default(client2),
                updateAttack: new UpdateAttack_default(client2),
                updateAngle: new UpdateAngle_default(client2),
                killChat: new KillChat(client2)
            }, this.botModules = [ this.staticModules.tempData, this.staticModules.clanJoiner, this.staticModules.movement ],
            this.modules = [ this.staticModules.autoAccept, this.staticModules.autoBuy, this.staticModules.defaultHat, this.staticModules.reloading, this.staticModules.defaultAcc, this.staticModules.autoSync, this.staticModules.spikeSyncHammer, this.staticModules.spikeSync, this.staticModules.spikeTick, this.staticModules.knockbackTickTrap, this.staticModules.knockbackTickHammer, this.staticModules.kbTickHammerV2, this.staticModules.knockbackTick, this.staticModules.antiRetrap, this.staticModules.autoPush, this.staticModules.velocityTick, this.staticModules.spikeTrap, this.staticModules.teammateSpikeTrap, this.staticModules.turretSync, this.staticModules.toolHammerSpearInsta, this.staticModules.swordKatanaInsta, this.staticModules.bowInsta, this.staticModules.instakill, this.staticModules.reverseInstakill, this.staticModules.autoBreak, this.staticModules.autoSteal, this.staticModules.turretSteal, this.staticModules.spikeGearInsta, this.staticModules.useFastest, this.staticModules.useDestroying, this.staticModules.useAttacking, this.staticModules.utilityHat, this.staticModules.antiInsta, this.staticModules.shameReset, this.staticModules.safeWalk, this.staticModules.placementDefense, this.staticModules.autoPlacer, this.staticModules.dashMovement, this.staticModules.placer, this.staticModules.autoMill, this.staticModules.autoGrind, this.staticModules.preAttack, this.staticModules.autoHat, this.staticModules.updateAttack, this.staticModules.updateAngle, this.staticModules.killChat ],
            this.reset();
        }
        movementReset() {
            this.currentHolding = 0, this.weapon = 0, this.currentType = null, this.attacking = 0,
            this.attackingState = 0, this.move_dir = null, this.reverse_move_dir = null;
        }
        reset() {
            let {isOwner: isOwner, clients: clients} = this.client;
            this.movementReset(), this.getHatStore().utility.clear(), this.getAccStore().utility.clear(),
            this.sentAngle = 0, this.sentHatEquip = !1, this.sentAccEquip = !1, this.needToHeal = !1,
            this.didAntiInsta = !1, this.placedOnce = !1, this.healedOnce = !1, this.totalPlaces = 0,
            this.attacked = !1, this.canHitEntity = !1, this.autoattack = !1;
            for (let module of this.modules) {
                if ("reset" in module) {
                    module.reset();
                }
            }
            if (isOwner) {
                for (let client2 of clients) {
                    client2.ModuleHandler.movementReset(), client2.ModuleHandler.toggleAutoattack(!1);
                }
            }
        }
        get holdingWeapon() {
            return this.currentHolding <= 1;
        }
        get isMoving() {
            return this.move_dir !== null;
        }
        setForceHat(hat) {
            if (this.forceHat !== null && hat !== null) {
                return;
            }
            this.forceHat = hat;
        }
        getHatStore() {
            return this.store[0];
        }
        getAccStore() {
            return this.store[1];
        }
        setFollowTarget(x, y) {
            this.followTarget.setXY(x, y);
        }
        setLookTarget(x, y) {
            this.lookTarget.setXY(x, y);
        }
        updateSentAngle(priority) {
            if (this.sentAngle >= priority) {
                return;
            }
            this.sentAngle = priority;
        }
        upgradeItem(id, isItem = !1) {
            if (isItem) {
                id += 16;
            }
            if (this.client.PacketManager.upgradeItem(id), this.client.myPlayer.upgradeItem(id),
            DataHandler_default.isWeapon(id)) {
                let type = DataHandler_default.getWeapon(id).type, {reloading: reloading} = this.staticModules;
                reloading.updateMaxReload(type);
            }
        }
        startMovement(angle = this.move_dir, ignore = !1) {
            if (!ignore) {
                if (this.move_dir = angle, this.reverse_move_dir = angle === null ? null : reverseAngle(angle),
                this.moveTo !== "disable") {
                    return;
                }
            }
            let {EnemyManager: EnemyManager2} = this.client, {safeWalk: safeWalk} = this.staticModules;
            if (safeWalk.willGetHit(angle, 45, EnemyManager2.nearestCollider) || safeWalk.willGetHit(angle, 45, EnemyManager2.secondNearestCollider)) {
                return !1;
            }
            return this.client.PacketManager.move(angle), !0;
        }
        stopMovement() {
            this.client.PacketManager.resetMoveDir();
        }
        startPlacement(type) {
            this.currentType = type;
        }
        canBuy(type, id) {
            if (id === -1) {
                return !1;
            }
            let price = DataHandler_default.getStore(type)[id].price;
            return this.bought[type].has(id) || this.client.myPlayer.tempGold >= price && this.client.myPlayer.isSandbox;
        }
        buy(type, id, force = !1) {
            let store2 = DataHandler_default.getStore(type), {isOwner: isOwner, clients: clients, myPlayer: myPlayer, PacketManager: PacketManager2} = this.client;
            if (!myPlayer.inGame) {
                return !1;
            }
            if (force) {
                if (isOwner) {
                    for (let client2 of clients) {
                        client2.ModuleHandler.buy(type, id, force);
                    }
                }
            }
            let price = store2[id].price, bought = this.bought[type];
            if (price === 0) {
                return bought.add(id), !0;
            }
            if (!bought.has(id) && myPlayer.tempGold >= price && (myPlayer.isSandbox || force)) {
                return PacketManager2.buy(type, id), myPlayer.tempGold -= price, !1;
            }
            return bought.has(id);
        }
        hasStoreItem(type, id) {
            return this.bought[type].has(id);
        }
        equip(type, id, force = !1, toggle = !1) {
            let store2 = this.store[type], {myPlayer: myPlayer, PacketManager: PacketManager2, EnemyManager: EnemyManager2, isOwner: isOwner, clients: clients} = this.client;
            if (toggle && store2.last === id && id !== 0) {
                id = 0;
            }
            if (!myPlayer.inGame || !this.buy(type, id, force)) {
                return !1;
            }
            if (store2.last === id && myPlayer.storeData[type] === id) {
                return !1;
            }
            if (store2.last = id, PacketManager2.equip(type, id), type === 0) {
                this.sentHatEquip = !0;
            } else {
                this.sentAccEquip = !0;
            }
            if (force) {
                if (store2.actual = id, isOwner) {
                    for (let client2 of clients) {
                        client2.ModuleHandler.staticModules.tempData.setStore(type, id);
                    }
                }
            }
            let nearest = EnemyManager2.nearestTurretEntity, reloading = this.staticModules.reloading;
            if (nearest !== null && reloading.isReloaded(2) && type === 0 && id === 53) {
                reloading.resetByType(2);
            }
            return !0;
        }
        updateAngle(angle, force = !1) {
            if (!force && angle === this.mouse.sentAngle) {
                return;
            }
            this.mouse.sentAngle = angle, this.updateSentAngle(3), this.client.PacketManager.updateAngle(angle);
        }
        selectItem(type) {
            let {myPlayer: myPlayer} = this.client, item = myPlayer.getItemByType(type);
            if (myPlayer.currentItem !== -1) {
                myPlayer.currentItem = -1, this.whichWeapon();
            }
            this.client.PacketManager.selectItemByID(item, !1), this.currentHolding = type;
        }
        attack(angle, priority = 2) {
            if (angle !== null) {
                this.mouse.sentAngle = angle;
            }
            if (this.updateSentAngle(priority), this.client.PacketManager.attack(angle),
            this.holdingWeapon) {
                this.attacked = !0;
            }
        }
        stopAttack() {
            this.client.PacketManager.stopAttack();
        }
        toggleAutoattack(state = !this.autoattack) {
            this.autoattack = state, this.attacking = state ? 1 : 0;
        }
        whichWeapon(type = this.weapon) {
            let weapon = this.client.myPlayer.getItemByType(type);
            if (weapon === null) {
                return;
            }
            this.currentHolding = type, this.weapon = type, this.client.PacketManager.selectItemByID(weapon, !0);
        }
        place(type, angle = this.currentAngle) {
            this.totalPlaces += 1, this.selectItem(type), this.attack(angle, 1), this.whichWeapon();
        }
        heal() {
            this.selectItem(2), this.attack(null, 1), this.whichWeapon();
        }
        circleOffset=0;
        targetSpeed=65;
        activeModule=null;
        postTick() {
            if (Settings_default._circleRotation && this.move_dir === null) {
                let rotationSpeed = this.targetSpeed / Settings_default._circleRadius;
                this.circleOffset = (this.circleOffset + rotationSpeed) % (Math.PI * 2);
            }
            let {isOwner: isOwner} = this.client;
            if (this.placeAngles[0] = null, this.placeAngles[1].length = 0, this.activeModule = null,
            this.tickCount += 1, this.sentAngle = 0, this.sentHatEquip = !1, this.sentAccEquip = !1,
            this.didAntiInsta = !1, this.placedOnce = !1, this.healedOnce = !1, this.totalPlaces = 0,
            this.attacked = !1, this.canHitEntity = !1, this.moduleActive = !1, this.useWeapon = null,
            this.useItem = null, this.forceWeapon = null, this.useHat = null, this.forceHat = null,
            this.shouldEquipSoldier = !1, this.useAcc = null, this.useAngle = null, this.shouldAttack = !1,
            this.prevMoveTo = this.moveTo, this.moveTo = "disable", !isOwner) {
                for (let botModule of this.botModules) {
                    botModule.postTick();
                }
            }
            for (let module of this.modules) {
                let prevg = this.moduleActive;
                if (module.postTick(), !prevg && this.moduleActive) {
                    this.activeModule = module.moduleName;
                }
            }
            if (this.attackingState = this.attacking, isOwner) {
                this.client.InputHandler.postTick(), GameUI_default.updateFastQ(this.didAntiInsta),
                GameUI_default.updatePlaces(this.totalPlaces), GameUI_default.updateActiveModule(this.activeModule + ", " + this.tickCount),
                GameUI_default.updateEquipHat(`${this.store[0].last},  ${this.shouldEquipSoldier}`);
            }
        }
    }

    const ModuleHandler_default = ModuleHandler;

    class PlayerClient {
        id=-1;
        connectSuccess=!1;
        clientID=null;
        owner;
        SocketManager;
        ObjectManager;
        PlayerManager;
        ProjectileManager;
        LeaderboardManager;
        EnemyManager;
        ModuleHandler;
        myPlayer;
        PacketManager;
        InputHandler;
        StatsManager;
        pendingJoins=new Set;
        clientIDList=new Set;
        clients=new Set;
        constructor(owner) {
            this.owner = owner || this, this.SocketManager = new SocketManager_default(this),
            this.ObjectManager = new ObjectManager_default(this), this.PlayerManager = new PlayerManager_default(this),
            this.ProjectileManager = new ProjectileManager_default(this), this.LeaderboardManager = new LeaderboardManager_default(this),
            this.EnemyManager = new EnemyManager_default(this), this.ModuleHandler = new ModuleHandler_default(this),
            this.myPlayer = new ClientPlayer_default(this), this.PacketManager = new PacketManager(this),
            this.InputHandler = new InputHandler(this), this.StatsManager = new StatsManager(this);
        }
        getClientIndex(client2) {
            return [ ...this.clients ].indexOf(client2);
        }
        get isOwner() {
            return this.owner === this;
        }
        isBotByID(id) {
            return this.clientIDList.has(id);
        }
        disconnect() {
            let socket = this.SocketManager.socket;
            if (socket !== null) {
                socket.close();
            }
        }
        removeBots() {
            for (let client2 of this.clients) {
                client2.disconnect();
            }
        }
        spawn() {
            this.myPlayer.spawn();
        }
    }

    const PlayerClient_default = PlayerClient;

    const UI = new class {
        frame;
        activeHotkeyInput=null;
        activeInput=null;
        toggleTimeout;
        menuOpened=!1;
        menuLoaded=!1;
        menuScale=1;
        get isMenuOpened() {
            return this.menuOpened;
        }
        isActiveButton() {
            return this.activeHotkeyInput || this.activeInput;
        }
        getFrameContent() {
            return `\n            <!DOCTYPE html>\n            <style>${styles_default}${Seldoom_style}</style>\n            <div id="menu-container" class="transparent">\n                <div id="menu-wrapper">\n                    ${Header_default}\n\n                    <main>\n                        ${Navbar_default}\n                        \n                        <div id="page-container">\n                            ${Home_default}\n                            ${Keybinds_default}\n                            ${Combat_default}\n                            ${Visuals_default}\n                            ${Misc_default}\n                            ${Devtool_default}\n                            ${Bots_default}\n                        </div>\n                    </main>\n                </div>\n            </div>\n        `;
        }
        injectStyles() {
            let style = document.createElement("style");
            style.innerHTML = Game_default + Store_default, document.head.appendChild(style);
        }
        createFrame() {
            this.injectStyles();
            let iframe = document.createElement("iframe"), blob = new Blob([ this.getFrameContent() ], {
                type: "text/html; charset=utf-8"
            });
            return iframe.src = URL.createObjectURL(blob), iframe.id = "iframe-container",
            iframe.style.display = "none", document.body.appendChild(iframe), new Promise(resolve => {
                iframe.onload = () => {
                    let iframeWindow = iframe.contentWindow, iframeDocument = iframeWindow.document;
                    URL.revokeObjectURL(iframe.src), resolve({
                        target: iframe,
                        window: iframeWindow,
                        document: iframeDocument
                    });
                };
            });
        }
        querySelector(selector) {
            return this.frame.document.querySelector(selector);
        }
        querySelectorAll(selector) {
            return this.frame.document.querySelectorAll(selector);
        }
        getElements() {
            let that = this;
            return {
                menuContainer: this.querySelector("#menu-container"),
                menuWrapper: this.querySelector("#menu-wrapper"),
                pageContainer: this.querySelector("#page-container"),
                hotkeyInputs: this.querySelectorAll(".hotkeyInput[id]"),
                checkboxes: this.querySelectorAll("input[type='checkbox'][id]"),
                colorPickers: this.querySelectorAll("input[type='color'][id]"),
                textInputs: this.querySelectorAll("input[type='text'][id]"),
                sliders: this.querySelectorAll("input[type='range'][id]"),
                closeButton: this.querySelector("#close-button"),
                openMenuButtons: this.querySelectorAll(".open-menu[data-id]"),
                menuPages: this.querySelectorAll(".menu-page[data-id]"),
                buttons: this.querySelectorAll(".option-button[id]"),
                botContainer: this.querySelector("#bot-container"),
                connectingBot: this.querySelector("#connectingBot"),
                scriptDescription: this.querySelector("#script-description"),
                author: this.querySelector("#author"),
                optionDescriptions: this.querySelectorAll(".option-description"),
                addBot: this.querySelector("#add-bot"),
                resetSettings: this.querySelector("#resetSettings"),
                botOption(id) {
                    let option = that.querySelector(`.content-option[data-bot-id="${id}"]`), title = option.querySelector(".option-title"), disconnect = option.querySelector(".disconnect-button");
                    return {
                        option: option,
                        title: title,
                        disconnect: disconnect
                    };
                }
            };
        }
        updateStats(id, value) {
            let stats = this.querySelector("#" + id);
            if (stats == null) {
                throw Error(`updateStats Error: can't find an element with ID: '${id}'`);
            }
            if (stats.textContent = value, id in Settings_default) {
                Settings_default[id] = value, SaveSettings();
            }
        }
        handleResize() {
            let {menuContainer: menuContainer} = this.getElements(), scale = Math.min(.9, Math.min(window.innerWidth / 1280, window.innerHeight / 720));
            this.menuScale = scale, menuContainer.style.transform = `translate(-50%, -50%) scale(${scale})`;
        }
        createRipple(selector) {
            let buttons = this.frame.document.querySelectorAll(selector);
            for (let button of buttons) {
                button.addEventListener("click", event => {
                    let {width: width, height: height} = button.getBoundingClientRect(), size = Math.max(width, height) * 2, ripple = document.createElement("span");
                    ripple.style.width = size + "px", ripple.style.height = size + "px", ripple.style.marginTop = -size / 2 + "px",
                    ripple.style.marginLeft = -size / 2 + "px", ripple.style.left = event.offsetX + "px",
                    ripple.style.top = event.offsetY + "px", ripple.classList.add("ripple"), button.appendChild(ripple),
                    setTimeout(() => ripple.remove(), 750);
                });
            }
        }
        attachHotkeyInputs() {
            let {hotkeyInputs: hotkeyInputs} = this.getElements();
            for (let hotkeyInput of hotkeyInputs) {
                let id = hotkeyInput.id, value = Settings_default[id];
                if (id in Settings_default && typeof value === "string") {
                    hotkeyInput.textContent = formatCode(value);
                } else {
                    Logger.error(`attachHotkeyInputs Error: Property "${id}" does not exist in settings`);
                }
            }
        }
        checkForRepeats() {
            let {hotkeyInputs: hotkeyInputs} = this.getElements(), list = new Map;
            for (let hotkeyInput of hotkeyInputs) {
                let id = hotkeyInput.id;
                if (id in Settings_default) {
                    let value = Settings_default[id], [count, inputs] = list.get(value) || [ 0, [] ];
                    list.set(value, [ (count || 0) + 1, [ ...inputs, hotkeyInput ] ]), hotkeyInput.classList.remove("red");
                } else {
                    Logger.error(`checkForRepeats Error: Property "${id}" does not exist in settings`);
                }
            }
            for (let data of list) {
                let [number, hotkeyInputs2] = data[1];
                if (number === 1) {
                    continue;
                }
                for (let hotkeyInput of hotkeyInputs2) {
                    hotkeyInput.classList.add("red");
                }
            }
        }
        applyCode(code) {
            if (this.activeHotkeyInput === null) {
                return;
            }
            let deleting = code === "Backspace", isCode = typeof code === "string", keyText = isCode ? formatCode(code) : formatButton(code), keySetting = isCode ? code : keyText, id = this.activeHotkeyInput.id;
            if (id in Settings_default) {
                Settings_default[id] = deleting ? "..." : keySetting, SaveSettings();
            } else {
                Logger.error(`applyCode Error: Property "${id}" does not exist in settings`);
            }
            this.activeHotkeyInput.textContent = deleting ? "..." : keyText, this.activeHotkeyInput.blur(),
            this.activeHotkeyInput.classList.remove("active"), this.activeHotkeyInput = null,
            this.checkForRepeats();
        }
        isHotkeyInput(target) {
            return target instanceof this.frame.window.HTMLButtonElement && target.classList.contains("hotkeyInput") && target.hasAttribute("id");
        }
        handleCheckboxToggle(id, checked) {
            switch (id) {
              case "_menuTransparency":
                {
                    let {menuContainer: menuContainer} = this.getElements();
                    menuContainer.classList.toggle("transparent");
                    break;
                }

              case "_hideHUD":
                {
                    let {gameUI: gameUI} = GameUI_default.getElements();
                    if (checked) {
                        gameUI.classList.add("hidden");
                    } else {
                        gameUI.classList.remove("hidden");
                    }
                    break;
                }

              case "_chatLog":
                GameUI_default.toggleChatLog();
                break;
            }
        }
        attachCheckboxes() {
            let {checkboxes: checkboxes} = this.getElements();
            for (let checkbox of checkboxes) {
                let id = checkbox.id;
                if (!(id in Settings_default)) {
                    Logger.error(`attachCheckboxes Error: Property "${id}" does not exist in settings`);
                    continue;
                }
                checkbox.checked = Settings_default[id], this.handleCheckboxToggle(id, checkbox.checked),
                checkbox.onchange = () => {
                    if (id in Settings_default) {
                        Settings_default[id] = checkbox.checked, SaveSettings(), this.handleCheckboxToggle(id, checkbox.checked);
                    } else {
                        Logger.error(`attachCheckboxes Error: Property "${id}" was deleted from settings`);
                    }
                };
            }
        }
        attachColorPickers() {
            let {colorPickers: colorPickers} = this.getElements();
            for (let picker of colorPickers) {
                let id = picker.id;
                if (!(id in Settings_default)) {
                    Logger.error(`attachColorPickers Error: Property "${id}" does not exist in settings`);
                    continue;
                }
                picker.value = Settings_default[id], picker.onchange = () => {
                    if (id in Settings_default) {
                        Settings_default[id] = picker.value, SaveSettings(), picker.blur();
                    } else {
                        Logger.error(`attachColorPickers Error: Property "${id}" was deleted from settings`);
                    }
                };
                let resetColor = picker.previousElementSibling;
                if (resetColor instanceof this.frame.window.HTMLButtonElement) {
                    resetColor.style.setProperty("--data-color", defaultSettings[id]), resetColor.onclick = () => {
                        if (id in Settings_default) {
                            picker.value = defaultSettings[id], Settings_default[id] = defaultSettings[id],
                            SaveSettings();
                        } else {
                            Logger.error(`resetColor Error: Property "${id}" was deleted from settings`);
                        }
                    };
                }
            }
        }
        attachSliders() {
            let {sliders: sliders} = this.getElements();
            for (let slider of sliders) {
                let id = slider.id;
                if (!(id in Settings_default)) {
                    Logger.error(`attachSliders Error: Property "${id}" does not exist in settings`);
                    continue;
                }
                let updateSliderValue = () => {
                    let sliderValue = slider.previousElementSibling;
                    if (sliderValue instanceof this.frame.window.HTMLSpanElement) {
                        sliderValue.textContent = slider.value;
                    }
                };
                slider.value = Settings_default[id].toString(), updateSliderValue(), slider.oninput = () => {
                    if (id in Settings_default) {
                        Settings_default[id] = Number(slider.value), SaveSettings(), updateSliderValue();
                    } else {
                        Logger.error(`attachSliders Error: Property "${id}" was deleted from settings`);
                    }
                }, slider.onchange = () => slider.blur();
            }
        }
        attachTextInputs() {
            let {textInputs: textInputs} = this.getElements();
            for (let input of textInputs) {
                let id = input.id;
                if (!(id in Settings_default)) {
                    Logger.error(`attachTextInputs Error: Property "${id}" does not exist in settings`);
                    continue;
                }
                input.value = Settings_default[id], input.oninput = () => {
                    input.value = input.value.replace(/[^\x20-\x7E]/g, "");
                }, input.onfocus = () => {
                    this.activeInput = input;
                }, input.onblur = () => {
                    this.activeInput = null;
                }, input.onchange = () => {
                    if (id in Settings_default) {
                        let value = input.value;
                        Settings_default[id] = value, input.value = value, SaveSettings();
                    } else {
                        Logger.error(`attachTextInputs Error: Property "${id}" was deleted from settings`);
                    }
                };
            }
        }
        attachDescriptions() {
            let {optionDescriptions: optionDescriptions, menuWrapper: menuWrapper} = this.getElements();
            for (let description of optionDescriptions) {
                let parent = description.parentElement;
                parent.onmouseenter = () => {
                    description.classList.add("description-show");
                }, parent.onmouseleave = () => {
                    description.classList.remove("description-show");
                }, parent.onmousemove = event => {
                    let target = event.target;
                    if (target !== null && target.className !== "content-option" && target.className !== "option-title") {
                        description.classList.remove("description-show");
                        return;
                    }
                    description.classList.add("description-show");
                    let bounds = menuWrapper.getBoundingClientRect(), x = (event.clientX - bounds.left + 10) / this.menuScale, y = (event.clientY - bounds.top + 10) / this.menuScale;
                    description.style.left = x + "px", description.style.top = y + "px";
                };
            }
        }
        createBotOption(player) {
            let {botContainer: botContainer, botOption: botOption, pageContainer: pageContainer} = this.getElements(), html = `\n            <div class="content-option" data-bot-id="${player.id}">\n                <span class="option-title"></span>\n                <svg\n                    class="icon disconnect-button"\n                    xmlns="http://www.w3.org/2000/svg"\n                    viewBox="0 0 30 30"\n                    title="Kick bot"\n                >\n                    <path d="M 7 4 C 6.744125 4 6.4879687 4.0974687 6.2929688 4.2929688 L 4.2929688 6.2929688 C 3.9019687 6.6839688 3.9019687 7.3170313 4.2929688 7.7070312 L 11.585938 15 L 4.2929688 22.292969 C 3.9019687 22.683969 3.9019687 23.317031 4.2929688 23.707031 L 6.2929688 25.707031 C 6.6839688 26.098031 7.3170313 26.098031 7.7070312 25.707031 L 15 18.414062 L 22.292969 25.707031 C 22.682969 26.098031 23.317031 26.098031 23.707031 25.707031 L 25.707031 23.707031 C 26.098031 23.316031 26.098031 22.682969 25.707031 22.292969 L 18.414062 15 L 25.707031 7.7070312 C 26.098031 7.3170312 26.098031 6.6829688 25.707031 6.2929688 L 23.707031 4.2929688 C 23.316031 3.9019687 22.682969 3.9019687 22.292969 4.2929688 L 15 11.585938 L 7.7070312 4.2929688 C 7.5115312 4.0974687 7.255875 4 7 4 z"/>\n                </svg>\n            </div>\n        `, div = document.createElement("div");
            div.innerHTML = html, botContainer.appendChild(div.firstElementChild), pageContainer.scrollTop = pageContainer.scrollHeight;
            let option = botOption(player.id);
            option.disconnect.onclick = () => {
                player.disconnect();
            };
        }
        deleteBotOption(player) {
            if (!player.connectSuccess) {
                return;
            }
            let {botOption: botOption} = this.getElements();
            botOption(player.id).option.remove();
        }
        updateBotOption(player, type) {
            if (!player.connectSuccess) {
                return;
            }
            let {botOption: botOption} = this.getElements(), option = botOption(player.id);
            switch (type) {
              case "title":
                option.title.textContent = `[${player.id}]: ${player.myPlayer.nickname}`;
                break;
            }
        }
        addBotConnecting() {
            let {botContainer: botContainer} = this.getElements(), div = document.createElement("div");
            div.id = "connectingBot", div.textContent = "Connecting...", botContainer.appendChild(div);
        }
        removeBotConnecting() {
            let {connectingBot: connectingBot} = this.getElements();
            if (connectingBot !== null) {
                connectingBot.remove();
            }
        }
        createBot() {
            let {addBot: addBot} = this.getElements();
            addBot.click();
        }
        handleBotCreation(button) {
            let id = 0;
            button.onclick = async () => {
                let ws = client.SocketManager.socket;
                if (ws === null) {
                    return;
                }
                this.addBotConnecting();
                let socket = await createSocket_default(ws.url);
                socket.addEventListener("close", () => {
                    this.removeBotConnecting();
                }), socket.onopen = () => {
                    let player = new PlayerClient_default(client);
                    player.PacketManager.Encoder = client.PacketManager.Encoder, player.PacketManager.Decoder = client.PacketManager.Decoder,
                    player.SocketManager.init(socket);
                    let onconnect = () => {
                        player.id = id++, client.clients.add(player), this.createBotOption(player),
                        this.removeBotConnecting();
                    };
                    socket.addEventListener("connected", onconnect);
                    let handleClose = () => {
                        socket.removeEventListener("connected", onconnect), client.clients.delete(player),
                        client.clientIDList.delete(player.myPlayer.id), client.pendingJoins.delete(player.myPlayer.id),
                        this.deleteBotOption(player), this.removeBotConnecting();
                    };
                    socket.addEventListener("error", handleClose), socket.addEventListener("close", handleClose);
                };
            };
        }
        handleResetSettings(button) {
            button.onclick = () => {
                resetSettings();
            };
        }
        attachButtons() {
            let {buttons: buttons} = this.getElements();
            for (let button of buttons) {
                switch (button.id) {
                  case "add-bot":
                    this.handleBotCreation(button);
                    break;

                  case "resetSettings":
                    this.handleResetSettings(button);
                    break;
                }
            }
        }
        closeMenu() {
            let {menuWrapper: menuWrapper} = this.getElements();
            menuWrapper.classList.remove("toopen"), menuWrapper.classList.add("toclose"),
            this.menuOpened = !1, clearTimeout(this.toggleTimeout), this.toggleTimeout = setTimeout(() => {
                menuWrapper.classList.remove("toclose"), this.frame.target.style.display = "none";
            }, 150);
        }
        openMenu() {
            let {menuWrapper: menuWrapper} = this.getElements();
            this.frame.target.removeAttribute("style"), menuWrapper.classList.remove("toclose"),
            menuWrapper.classList.add("toopen"), this.menuOpened = !0, clearTimeout(this.toggleTimeout),
            this.toggleTimeout = setTimeout(() => {
                menuWrapper.classList.remove("toopen");
            }, 150);
        }
        toggleMenu() {
            if (!this.menuLoaded) {
                return;
            }
            if (this.menuOpened) {
                this.closeMenu();
            } else {
                this.openMenu();
            }
        }
        attachOpenMenu() {
            let {openMenuButtons: openMenuButtons, menuPages: menuPages} = this.getElements();
            for (let i = 0; i < openMenuButtons.length; i++) {
                let button = openMenuButtons[i], id = button.getAttribute("data-id"), menuPage = this.querySelector(`.menu-page[data-id='${id}']`);
                button.onclick = () => {
                    if (menuPage instanceof this.frame.window.HTMLDivElement) {
                        removeClass(openMenuButtons, "active"), button.classList.add("active"), removeClass(menuPages, "opened"),
                        menuPage.classList.add("opened");
                    } else {
                        Logger.error(`attachOpenMenu Error: Cannot find "${button.textContent}" menu`);
                    }
                };
            }
        }
        attachListeners() {
            let {closeButton: closeButton, scriptDescription: scriptDescription} = this.getElements();
            closeButton.onclick = () => {
                this.closeMenu();
            };
            let preventDefaults = target => {
                target.addEventListener("contextmenu", event => event.preventDefault()), target.addEventListener("mousedown", event => {
                    if (event.button === 1) {
                        event.preventDefault();
                    }
                }), target.addEventListener("mouseup", event => {
                    if (event.button === 3 || event.button === 4) {
                        event.preventDefault();
                    }
                });
            };
            preventDefaults(window), preventDefaults(this.frame.window);
            let description = "v" + Glotus.version + " by Murka \u00b7 fixed by seldoom";
            scriptDescription.textContent = description, this.handleResize(), window.addEventListener("resize", () => this.handleResize()),
            this.frame.document.addEventListener("mouseup", event => {
                if (this.activeHotkeyInput) {
                    this.applyCode(event.button);
                } else if (this.isHotkeyInput(event.target) && event.button === 0) {
                    event.target.textContent = "Wait...", this.activeHotkeyInput = event.target,
                    event.target.classList.add("active");
                }
            }), this.frame.document.addEventListener("keyup", event => {
                if (this.activeHotkeyInput && this.isHotkeyInput(event.target)) {
                    this.applyCode(event.code);
                }
            }), this.frame.window.addEventListener("keydown", event => client.InputHandler.handleKeydown(event)),
            this.frame.window.addEventListener("keyup", event => client.InputHandler.handleKeyup(event)),
            this.openMenu();
            let watermark = document.createElement("div");
            watermark.id = "Glotus Client!", watermark.textContent = "GLOTUS",
            document.body.appendChild(watermark);
        }
        resetFrame() {
            this.frame.target.remove(), this.init();
        }
        async init() {
            try {
                this.frame = await this.createFrame(), this.attachListeners(), this.attachHotkeyInputs(),
                this.checkForRepeats(), this.attachCheckboxes(), this.attachColorPickers(),
                this.attachSliders(), this.attachTextInputs(), this.attachDescriptions(), this.attachButtons(),
                this.attachOpenMenu(), this.createRipple(".open-menu"), client.StatsManager.init();
                let {menuContainer: menuContainer} = this.getElements();
                if (Settings_default._menuTransparency) {
                    menuContainer.classList.add("transparent");
                }
                this.menuLoaded = !0, this.frame.window.focus(), Logger.test("Successfully injected iframe menu..");
            } catch (err) {
                Logger.error("Failed to inject iframe.. " + err);
            }
        }
    }, UI_default = UI;

    const defaultSettings = {
        _primary: "Digit1",
        _secondary: "Digit2",
        _food: "KeyQ",
        _wall: "Digit4",
        _spike: "KeyC",
        _windmill: "KeyV",
        _farm: "KeyT",
        _trap: "Space",
        _turret: "KeyF",
        _spawn: "KeyG",
        _up: "KeyW",
        _left: "KeyA",
        _down: "KeyS",
        _right: "KeyD",
        _autoattack: "KeyE",
        _lockrotation: "KeyX",
        _lockBotPosition: "KeyZ",
        _toggleChat: "Enter",
        _toggleShop: "ShiftLeft",
        _toggleClan: "ControlLeft",
        _toggleMenu: "Escape",
        _instakill: "KeyR",
        _biomehats: !0,
        _autoemp: !0,
        _antienemy: !0,
        _soldierDefault: !0,
        _antianimal: !0,
        _antispike: !0,
        _empDefense: !0,
        _autoheal: !0,
        _autoSync: !0,
        _velocityTick: !0,
        _spikeSyncHammer: !0,
        _spikeSync: !0,
        _spikeTick: !0,
        _knockbackTickTrap: !0,
        _knockbackTickHammer: !0,
        _knockbackTick: !0,
        _toolSpearInsta: !0,
        _autoSteal: !0,
        _autoPush: !0,
        _turretSteal: !0,
        _spikeGearInsta: !0,
        _antiRetrap: !0,
        _turretSync: !0,
        _automill: !0,
        _autoplacer: !0,
        _placementDefense: !0,
        _preplacer: !1,
        _autoplacerRadius: 325,
        _placeAttempts: 4,
        _autobreak: !0,
        _safeWalk: !0,
        _dashMovement: !0,
        _autoGrind: !1,
        _enemyTracers: !1,
        _enemyTracersColor: "#cc5151",
        _teammateTracers: !1,
        _teammateTracersColor: "#8ecc51",
        _animalTracers: !1,
        _animalTracersColor: "#518ccc",
        _notificationTracers: !0,
        _notificationTracersColor: "#f5d951",
        _itemMarkers: !0,
        _itemMarkersColor: "#84bd4b",
        _teammateMarkers: !0,
        _teammateMarkersColor: "#bdb14b",
        _enemyMarkers: !0,
        _enemyMarkersColor: "#ba4949",
        _weaponXPBar: !0,
        _playerTurretReloadBar: !0,
        _playerTurretReloadBarColor: "#cf7148",
        _weaponReloadBar: !0,
        _weaponReloadBarColor: "#5155cc",
        _renderHP: !0,
        _stackedDamage: !0,
        _objectTurretReloadBar: !1,
        _objectTurretReloadBarColor: "#66d9af",
        _itemHealthBar: !1,
        _itemHealthBarColor: "#6b449e",
        _displayPlayerAngle: !1,
        _weaponHitbox: !1,
        _collisionHitbox: !1,
        _placementHitbox: !1,
        _possiblePlacement: !0,
        // _killMessage et _killMessageText retires : le message est fige
        // dans le module KillChat, il n y a plus rien a regler.
        _autospawn: !1,
        _autoaccept: !1,
        _texturepack: !1,
        _hideHUD: !1,
        _smoothRendering: 160,
        _menuTransparency: !0,
        _chatLog: !1,
        _followCursor: !0,
        _movementRadius: 150,
        _circleFormation: !1,
        _circleRotation: !0,
        _circleRadius: 100,
        _storeItems: [ [ 15, 31, 6, 7, 22, 12, 26, 11, 53, 20, 40, 56 ], [ 11, 17, 16, 13, 19, 18, 21 ] ],
        _totalKills: 0,
        _globalKills: 0,
        _deaths: 0,
        _autoSyncTimes: 0,
        _velocityTickTimes: 0,
        _spikeSyncHammerTimes: 0,
        _spikeSyncTimes: 0,
        _spikeTickTimes: 0,
        _knockbackTickTrapTimes: 0,
        _knockbackTickHammerTimes: 0,
        _knockbackTickTimes: 0
    }, settings = {
        ...defaultSettings,
        ...CustomStorage.get("Glotus")
    };

    for (let iterator in settings) {
        let key = iterator;
        if (!defaultSettings.hasOwnProperty(key)) {
            delete settings[key];
        }
    }

    const SaveSettings = () => {
        CustomStorage.set("Glotus", settings);
    };

    SaveSettings();

    const resetSettings = () => {
        for (let iterator in defaultSettings) {
            let key = iterator;
            settings[key] = defaultSettings[key];
        }
        SaveSettings(), UI_default.resetFrame();
    }, Settings_default = settings;

    const GameUI = new class {
        getElements() {
            let querySelector = document.querySelector.bind(document), querySelectorAll = document.querySelectorAll.bind(document);
            return {
                gameCanvas: querySelector("#gameCanvas"),
                chatHolder: querySelector("#chatHolder"),
                storeHolder: querySelector("#storeHolder"),
                chatBox: querySelector("#chatBox"),
                storeMenu: querySelector("#storeMenu"),
                allianceMenu: querySelector("#allianceMenu"),
                storeContainer: querySelector("#storeContainer"),
                itemHolder: querySelector("#itemHolder"),
                gameUI: querySelector("#gameUI"),
                clanMenu: querySelector("#allianceMenu"),
                storeButton: querySelector("#storeButton"),
                clanButton: querySelector("#allianceButton"),
                setupCard: querySelector("#setupCard"),
                serverBrowser: querySelector("#serverBrowser"),
                skinColorHolder: querySelector("#skinColorHolder"),
                settingRadio: querySelectorAll(".settingRadio"),
                pingDisplay: querySelector("#pingDisplay"),
                enterGame: querySelector("#enterGame"),
                nameInput: querySelector("#nameInput"),
                allianceInput: querySelector("#allianceInput"),
                allianceButton: querySelector("#allianceButton"),
                noticationDisplay: querySelector("#noticationDisplay"),
                nativeResolution: querySelector("#nativeResolution"),
                showPing: querySelector("#showPing"),
                mapDisplay: querySelector("#mapDisplay"),
                chatLog: querySelector("#chatLog")
            };
        }
        selectSkinColor(skin) {
            let skinValue = skin === 10 ? "toString" : skin;
            CustomStorage.set("skin_color", skinValue);
            let selectSkin = getTargetValue(window, "selectSkinColor");
            if (selectSkin !== void 0) {
                selectSkin(skinValue);
            }
            return skinValue;
        }
        createSkinColors() {
            let skin_color = CustomStorage.get("skin_color") || 0, index = skin_color === "toString" ? 10 : skin_color, {setupCard: setupCard} = this.getElements(), skinHolder = document.createElement("div");
            skinHolder.id = "skinHolder";
            let prevIndex = index;
            for (let i = 0; i < Config_default.skinColors.length; i++) {
                let color = Config_default.skinColors[i], div = document.createElement("div");
                if (div.classList.add("skinColorItem"), i === index) {
                    div.classList.add("activeSkin");
                }
                div.style.backgroundColor = color, div.onclick = () => {
                    let colorButton = skinHolder.childNodes[prevIndex];
                    if (colorButton instanceof HTMLDivElement) {
                        colorButton.classList.remove("activeSkin");
                    }
                    div.classList.add("activeSkin"), prevIndex = i, this.selectSkinColor(i);
                }, skinHolder.appendChild(div);
            }
            setupCard.appendChild(skinHolder);
        }
        formatMainMenu() {
            let {setupCard: setupCard, serverBrowser: serverBrowser, settingRadio: settingRadio, gameUI: gameUI} = this.getElements();
            setupCard.appendChild(serverBrowser), setupCard.querySelector("br")?.remove(),
            this.createSkinColors();
            let radio = settingRadio[0];
            if (radio) {
                setupCard.appendChild(radio);
            }
            let div = document.createElement("div");
            div.id = "glotusStats", div.innerHTML = '\n            <span>PING: <span id="glotusPing"></span>ms</span>\n            <span>FPS: <span id="glotusFPS"></span></span>\n            <span>PACKETS: <span id="glotusPackets"></span></span>\n            <span>FastQ: <span id="glotusFastQ">false</span></span>\n            <span>Places: <span id="glotusPlaces">0</span></span>\n            <span>Total Kills: <span id="glotusTotalKills">0</span></span>\n            <span>Deaths: <span id="glotusTotalDeaths">0</span></span>\n            <span>Module: <span id="glotusActiveModule">null</span></span>\n            <span>SpikeDmg: <span id="glotusSpikeDamage"></span></span>\n            <span>PotDmg: <span id="glotusPotentialDamage"></span></span>\n            <span>Danger: <span id="glotusDangerState"></span></span>\n            <span>Hat: <span id="glotusEquipHat">0</span></span>\n            <span>CollideSpike: <span id="glotusCollideSpike"></span></span>\n            <span style="color: #f5d951; margin-top: 5px; display: block;">Glotus Client!</span>\n        ',
            gameUI.appendChild(div);
        }
        attachItemCount() {
            let actionBar = document.querySelectorAll("div[id*='actionBarItem'");
            for (let i = 19; i < 39; i++) {
                let item = Items[i - 16];
                if (actionBar[i] instanceof HTMLDivElement && item !== void 0 && "itemGroup" in item) {
                    let group = item.itemGroup, span = document.createElement("span");
                    span.classList.add("itemCounter"), span.setAttribute("data-id", group + "");
                    let {count: count, limit: limit} = client.myPlayer.getItemCount(group);
                    span.textContent = `${count}/${limit}`, actionBar[i].appendChild(span);
                }
            }
        }
        modifyInputs() {
            let {chatHolder: chatHolder, chatBox: chatBox, nameInput: nameInput} = this.getElements();
            chatBox.onblur = () => {
                chatHolder.style.display = "none";
                let value = chatBox.value;
                if (value.length > 0) {
                    client.PacketManager.chat(value);
                }
                chatBox.value = "";
            }, nameInput.onchange = () => {
                CustomStorage.set("moo_name", nameInput.value, !1);
            };
        }
        updateItemCount(group) {
            let items = document.querySelectorAll(`span.itemCounter[data-id='${group}']`), {count: count, limit: limit} = client.myPlayer.getItemCount(group);
            for (let item of items) {
                item.textContent = `${count}/${limit}`;
            }
        }
        interceptEnterGame() {
            let enterGame = document.querySelector("#enterGame"), observer = new MutationObserver(() => {
                observer.disconnect(), this.load();
            });
            observer.observe(enterGame, {
                attributes: !0
            });
        }
        updatePing(ping) {
            let span = document.querySelector("#glotusPing");
            if (span !== null) {
                span.textContent = ping.toString();
            }
        }
        updateFPS(fps) {
            let span = document.querySelector("#glotusFPS");
            if (span !== null) {
                span.textContent = fps.toString();
            }
        }
        updatePackets(packets) {
            let span = document.querySelector("#glotusPackets");
            if (span !== null) {
                span.textContent = packets.toString();
            }
        }
        updateFastQ(state) {
            let span = document.querySelector("#glotusFastQ");
            if (span !== null) {
                span.textContent = state.toString();
            }
        }
        updatePlaces(count) {}
        updateTotalKills(kills) {
            let span = document.querySelector("#glotusTotalKills");
            if (span !== null) {
                span.textContent = kills.toString();
            }
        }
        updateTotalDeaths(deaths) {
            let span = document.querySelector("#glotusTotalDeaths");
            if (span !== null) {
                span.textContent = deaths.toString();
            }
        }
        updateActiveModule(name) {
            let span = document.querySelector("#glotusActiveModule");
            if (span !== null) {
                span.textContent = name + "";
            }
        }
        updateSpikeDamage(state) {
            let span = document.querySelector("#glotusSpikeDamage");
            if (span !== null) {
                span.textContent = state + "";
            }
        }
        updatePotentialDamage(state) {
            let span = document.querySelector("#glotusPotentialDamage");
            if (span !== null) {
                span.textContent = state + "";
            }
        }
        updateCollideSpike(state) {
            let span = document.querySelector("#glotusCollideSpike");
            if (span !== null) {
                span.textContent = state + "";
            }
        }
        updateDangerState(state) {
            let span = document.querySelector("#glotusDangerState");
            if (span !== null) {
                span.textContent = state + "";
            }
        }
        updateEquipHat(state) {
            let span = document.querySelector("#glotusEquipHat");
            if (span !== null) {
                span.textContent = state + "";
            }
        }
        init() {
            this.formatMainMenu(), this.modifyInputs(), this.interceptEnterGame();
        }
        load() {
            let {nativeResolution: nativeResolution, enterGame: enterGame} = this.getElements();
            if (!nativeResolution.checked) {
                nativeResolution.click();
            }
            this.selectSkinColor(CustomStorage.get("skin_color") || 0);
            let enterGameButton = enterGame, _enterGame = enterGameButton.onclick;
            enterGameButton.onclick = function() {
                delete enterGameButton.onclick, Glotus.startGame(), enterGameButton.onclick = _enterGame;
            }, Object.defineProperty(enterGameButton, "onclick", {
                set(callback) {
                    _enterGame = callback;
                },
                configurable: !0
            });
        }
        loadGame() {
            this.attachItemCount();
            let {storeButton: storeButton, allianceButton: allianceButton, mapDisplay: mapDisplay} = this.getElements(), that = this, _storeClick = storeButton.onclick;
            storeButton.onclick = function(...args) {
                that.reset(), _storeClick.apply(this, args);
            };
            let _allianceClick = allianceButton.onclick;
            allianceButton.onclick = function(...args) {
                that.reset(), _allianceClick.apply(this, args);
            };
            let _mapClick = mapDisplay.onclick;
            mapDisplay.onclick = function(event) {
                let bounds = mapDisplay.getBoundingClientRect(), scale = 14400 / bounds.width, posX = (event.clientX - bounds.left) * scale, posY = (event.clientY - bounds.top) * scale;
                client.ModuleHandler.endTarget.setXY(posX, posY), client.ModuleHandler.followPath = !0,
                _mapClick.call(this, event);
            }, this.createChatLog();
        }
        isOpened(element) {
            return element.style.display !== "none";
        }
        closePopups(element) {
            let {allianceMenu: allianceMenu, clanButton: clanButton} = this.getElements();
            if (this.isOpened(allianceMenu) && element !== allianceMenu) {
                clanButton.click();
            }
            let popups = document.querySelectorAll("#chatHolder, #storeMenu, #allianceMenu, #storeContainer");
            for (let popup of popups) {
                if (popup === element) {
                    continue;
                }
                popup.style.display = "none";
            }
            if (element instanceof HTMLElement) {
                element.style.display = this.isOpened(element) ? "none" : "";
            }
        }
        createAcceptButton(type) {
            let data = [ [ "#cc5151", "&#xE14C;" ], [ "#8ecc51", "&#xE876;" ] ], [color, code] = data[type], button = document.createElement("div");
            return button.classList.add("notifButton"), button.innerHTML = `<i class="material-icons" style="font-size:28px; color:${color};">${code}</i>`,
            button;
        }
        resetNotication(noticationDisplay) {
            noticationDisplay.innerHTML = "", noticationDisplay.style.display = "none";
        }
        clearNotication() {
            let {noticationDisplay: noticationDisplay} = this.getElements();
            this.resetNotication(noticationDisplay);
        }
        createRequest(user) {
            let [id, name] = user, {noticationDisplay: noticationDisplay} = this.getElements();
            if (noticationDisplay.style.display !== "none") {
                return;
            }
            noticationDisplay.innerHTML = "", noticationDisplay.style.display = "block";
            let text = document.createElement("div");
            text.classList.add("notificationText"), text.textContent = name, noticationDisplay.appendChild(text);
            let handleClick = type => {
                let button = this.createAcceptButton(type);
                button.onclick = () => {
                    this.resetNotication(noticationDisplay), client.PacketManager.clanRequest(id, !!type),
                    client.myPlayer.joinRequests.shift(), client.pendingJoins.delete(id);
                }, noticationDisplay.appendChild(button);
            };
            handleClick(0), handleClick(1);
        }
        clientSpawn() {
            let {enterGame: enterGame} = this.getElements();
            enterGame.click();
        }
        handleEnter(event) {
            let {allianceInput: allianceInput, allianceButton: allianceButton} = this.getElements(), active = document.activeElement;
            if (client.myPlayer.inGame) {
                if (active === allianceInput) {
                    allianceButton.click();
                } else {
                    this.toggleChat(event);
                }
                return;
            }
            this.clientSpawn();
        }
        toggleChat(event) {
            let {chatHolder: chatHolder, chatBox: chatBox} = this.getElements();
            if (this.closePopups(chatHolder), this.isOpened(chatHolder)) {
                event.preventDefault(), chatBox.focus();
            } else {
                chatBox.blur();
            }
        }
        reset() {
            StoreHandler_default.closeStore();
        }
        openClanMenu() {
            let {clanButton: clanButton} = this.getElements();
            this.reset(), clanButton.click();
        }
        logCache=[];
        chatLog=null;
        addLogMessage(cache) {
            let [type, message] = cache, div = document.createElement("div");
            div.className = "logMessage", div.innerHTML = `\n            <span class="darken">${formatDate()}</span>\n            <span class="messageContent ${type}"></span>\n        `,
            div.querySelector(".messageContent").textContent = message;
            let messageContainer = document.querySelector("#messageContainer");
            if (messageContainer !== null) {
                messageContainer.appendChild(div), messageContainer.scrollTop = messageContainer.scrollHeight;
            }
        }
        addCacheMessage(cache) {
            if (this.chatLog === null) {
                this.logCache.push(cache);
            } else {
                this.addLogMessage(cache);
            }
        }
        createChatLog() {
            if (this.chatLog !== null) {
                return;
            }
            let container = document.createElement("div");
            container.id = "chatLog", container.innerHTML = '\n            <h1 id="chatLogHeader">DevTools Chat Log</h1>\n            <div id="messageContainer"></div>\n        ',
            document.body.appendChild(container), this.chatLog = container;
            for (let log of this.logCache) {
                this.addLogMessage(log);
            }
        }
        toggleChatLog() {
            if (this.chatLog === null) {
                this.createChatLog();
            }
            if (Settings_default._chatLog) {
                this.chatLog.classList.remove("hidden");
            } else {
                this.chatLog.classList.add("hidden");
            }
        }
        lastMessages=[];
        handleMessageLog(message) {
            if (message = message.trim().replace(/\s+/g, " "), this.lastMessages.length > 3) {
                this.lastMessages.shift();
            }
            if (this.lastMessages.includes(message)) {
                return;
            }
            this.lastMessages.push(message), this.addLogMessage([ "log", message ]);
        }
    }, GameUI_default = GameUI;

    class Logger {
        static staticLog=console.log;
        static staticError=console.error;
        static staticWarn=console.warn;
        static log(msg) {
            if (GameUI_default.addCacheMessage([ "log", msg ]), isProd) {
                return;
            }
            this.staticLog(msg);
        }
        static error(msg) {
            if (GameUI_default.addCacheMessage([ "error", msg ]), isProd) {
                return;
            }
            this.staticError(msg);
        }
        static warn(msg) {
            if (GameUI_default.addCacheMessage([ "warn", msg ]), isProd) {
                return;
            }
            this.staticWarn(msg);
        }
        static test(msg) {
            if (GameUI_default.addCacheMessage([ "log", msg ]), isProd) {
                return;
            }
            this.staticLog(msg);
        }
    }

    /* ==================================================================
     *  HLM - COUCHE CRYPTO PAR SOCKET (pour les bots)
     *
     *  La connexion principale emprunte le canal du jeu, qui signe et
     *  numerote pour nous. Chaque bot, lui, ouvre SA connexion : il recoit
     *  son propre io-init, donc sa propre graine, sa propre cle et son
     *  propre compteur de sequence. Il faut donc un etat par socket.
     * ================================================================== */
    const HLM_C2S = ["M", "D", "9", "e", "F", "z", "H", "K", "L", "N", "b", "P", "Q", "c", "6", "S", "0"];
    const HLM_S2C = ["A", "B", "C", "D", "E", "a", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
        "Q", "R", "S", "T", "U", "V", "X", "Y", "Z", "g", "1", "2", "3", "4", "5", "6",
        "7", "8", "9", "0"];
    const HLM_K = new Uint32Array([
        1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221,
        3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580,
        3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
        2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895,
        666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037,
        2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344,
        430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779,
        1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298
    ]);
    const HLM = {
        rotr(x, n) { return x >>> n | x << 32 - n; },
        sha256(bytes) {
            const h = new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762,
                1359893119, 2600822924, 528734635, 1541459225]);
            const len = bytes.length, bitLen = 8 * len, padded = len + 9;
            const buf = new Uint8Array(64 * Math.ceil(padded / 64));
            buf.set(bytes); buf[len] = 128;
            const view = new DataView(buf.buffer);
            view.setUint32(buf.length - 4, bitLen >>> 0, false);
            view.setUint32(buf.length - 8, Math.floor(bitLen / 4294967296), false);
            const w = new Uint32Array(64);
            for (let off = 0; off < buf.length; off += 64) {
                for (let i = 0; i < 16; i++) w[i] = view.getUint32(off + 4 * i, false);
                for (let i = 16; i < 64; i++) {
                    const s0 = this.rotr(w[i - 15], 7) ^ this.rotr(w[i - 15], 18) ^ w[i - 15] >>> 3;
                    const s1 = this.rotr(w[i - 2], 17) ^ this.rotr(w[i - 2], 19) ^ w[i - 2] >>> 10;
                    w[i] = w[i - 16] + s0 + w[i - 7] + s1 | 0;
                }
                let a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f = h[5], g = h[6], hh = h[7];
                for (let i = 0; i < 64; i++) {
                    const t1 = hh + (this.rotr(e, 6) ^ this.rotr(e, 11) ^ this.rotr(e, 25)) + (e & f ^ ~e & g) + HLM_K[i] + w[i] | 0;
                    const maj = a & b ^ a & c ^ b & c;
                    hh = g; g = f; f = e; e = d + t1 | 0; d = c; c = b; b = a;
                    a = t1 + ((this.rotr(a, 2) ^ this.rotr(a, 13) ^ this.rotr(a, 22)) + maj | 0) | 0;
                }
                h[0] = h[0] + a | 0; h[1] = h[1] + b | 0; h[2] = h[2] + c | 0; h[3] = h[3] + d | 0;
                h[4] = h[4] + e | 0; h[5] = h[5] + f | 0; h[6] = h[6] + g | 0; h[7] = h[7] + hh | 0;
            }
            const out = new Uint8Array(32), ov = new DataView(out.buffer);
            for (let k = 0; k < 8; k++) ov.setUint32(4 * k, h[k], false);
            return out;
        },
        hmac6(key, message) {
            let k = key;
            if (k.length > 64) k = this.sha256(k);
            const padKey = new Uint8Array(64); padKey.set(k);
            const inner = new Uint8Array(64 + message.length);
            const outer = new Uint8Array(96);
            for (let i = 0; i < 64; i++) { inner[i] = 54 ^ padKey[i]; outer[i] = 92 ^ padKey[i]; }
            inner.set(message, 64);
            outer.set(this.sha256(inner), 64);
            return this.sha256(outer).subarray(0, 6);
        },
        hexToBytes(hex) {
            const out = new Uint8Array(hex.length / 2);
            for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.substr(2 * i, 2), 16);
            return out;
        },
        buildTable(list, seed) {
            const n = list.length;
            const idx = list.map((_, i) => i);
            const rand = (s => () => {
                s = (s |= 0) + 1831565813 | 0;
                let t = Math.imul(s ^ s >>> 15, 1 | s);
                return (((t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t) ^ t >>> 14) >>> 0) / 4294967296;
            })(seed >>> 0);
            for (let i = n - 1; i > 0; i--) {
                const jj = Math.floor(rand() * (i + 1));
                const tmp = idx[i]; idx[i] = idx[jj]; idx[jj] = tmp;
            }
            const enc = {}, dec = {};
            for (let i = 0; i < n; i++) { enc[list[i]] = idx[i]; dec[idx[i]] = list[i]; }
            return { enc: enc, dec: dec };
        },
        // Construit l etat a partir des donnees du paquet io-init
        makeState(data) {
            if (!data || data[3] !== 1) return null;
            const seed = data[1] >>> 0;
            const mixed = (seed ^ Math.imul(1, 2654435761)) >>> 0;
            return {
                key: this.hexToBytes(data[2]),
                c2s: this.buildTable(HLM_C2S, mixed),
                s2c: this.buildTable(HLM_S2C, (2246822507 ^ mixed) >>> 0),
                seq: 0
            };
        },
        // msgpack([type, args, seq]) prefixe du HMAC tronque a 6 octets
        encode(state, encoder, type, args) {
            const encType = state.c2s.enc[type];
            if (encType === undefined) return null;
            const body = encoder.encode([ encType, args, ++state.seq ]);
            const sig = this.hmac6(state.key, body);
            const out = new Uint8Array(6 + body.length);
            out.set(sig, 0); out.set(body, 6);
            return out;
        }
    };

    class Regexer {
        code;
        COPY_CODE;
        hookCount=0;
        hookAttempts=0;
        ANY_LETTER="(?:[^\\x00-\\x7F-]|\\$|\\w)";
        NumberSystem=[ {
            radix: 2,
            prefix: "0b0*"
        }, {
            radix: 8,
            prefix: "0+"
        }, {
            radix: 10,
            prefix: ""
        }, {
            radix: 16,
            prefix: "0x0*"
        } ];
        constructor(code) {
            this.code = code, this.COPY_CODE = code;
        }
        isRegExp(regex) {
            return regex instanceof RegExp;
        }
        generateNumberSystem(int) {
            return `(?:${this.NumberSystem.map(({radix: radix, prefix: prefix}) => prefix + int.toString(radix)).join("|")})`;
        }
        parseVariables(regex) {
            return regex = regex.replace(/{VAR}/g, "(?:let|var|const)"), regex = regex.replace(/{QUOTE{(\w+)}}/g, "(?:'$1'|\"$1\"|`$1`)"),
            regex = regex.replace(/NUM{(\d+)}/g, (...args) => this.generateNumberSystem(Number(args[1]))),
            regex = regex.replace(/\\w/g, this.ANY_LETTER), regex;
        }
        format(name, inputRegex, flags) {
            this.hookAttempts++;
            let regex = "";
            if (Array.isArray(inputRegex)) {
                regex = inputRegex.map(exp => this.isRegExp(exp) ? exp.source : exp).join("\\s*");
            } else if (this.isRegExp(inputRegex)) {
                regex = inputRegex.source;
            } else {
                regex = inputRegex + "";
            }
            regex = this.parseVariables(regex);
            let expression = RegExp(regex, flags);
            if (!expression.test(this.code)) {
                Logger.error("Failed to find: " + name);
            } else {
                this.hookCount++;
            }
            return expression;
        }
        match(name, regex, flags) {
            let expression = this.format(name, regex, flags);
            return this.code.match(expression) || [];
        }
        replace(name, regex, substr, flags) {
            let expression = this.format(name, regex, flags);
            return this.code = this.code.replace(expression, substr), expression;
        }
        insertAtIndex(index, str) {
            return this.code.slice(0, index) + str + this.code.slice(index, this.code.length);
        }
        template(name, regex, substr, getIndex) {
            let expression = this.format(name, regex), match = this.code.match(expression);
            if (match === null) {
                return;
            }
            let index = getIndex(match);
            this.code = this.insertAtIndex(index, substr.replace(/\$(\d+)/g, (...args) => match[args[1]]));
        }
        append(name, regex, substr) {
            this.template(name, regex, substr, match => (match.index || 0) + match[0].length);
        }
        prepend(name, regex, substr) {
            this.template(name, regex, substr, match => match.index || 0);
        }
        wrap(left, right) {
            // Le bundle du jeu est desormais un MODULE ES : il commence par des
            // instructions import de premier niveau. Les envelopper dans une
            // fonction est une erreur de syntaxe. On laisse donc le prologue
            // d'imports au niveau superieur et on n'encapsule que le reste.
            let prologue = "", body = this.code;
            let re = /^\s*import\s*(?:[^"';]*from\s*)?("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')\s*;?/;
            for (;;) {
                let m = body.match(re);
                if (m === null || m.index !== 0) break;
                prologue += m[0];
                body = body.slice(m[0].length);
            }
            this.code = prologue + left + body + right;
        }
    }

    const Regexer_default = Regexer;

    const formatCode2 = code => {
        let Hook = new Regexer_default(code);
        if (!isProd) {
            Hook.code = 'console.log("Loaded bundle..");' + Hook.code;
        }
        Hook.append("preRenderLoop", /\)\}\}\(\);function \w+\(\)\{/, "Glotus.Renderer.preRender();"),
        Hook.append("postRenderLoop", /\w+,\w+\(\),requestAnimFrame\(\w+\)/, ";Glotus.Renderer.postRender();"),
        Hook.append("mapPreRender", /(\w+)\.lineWidth=NUM{4};/, "Glotus.Renderer.mapPreRender($1);"),
        Hook.prepend("gameInit", /function (\w+)\(\w+\)\{\w+\.\w+\(\w+,f/, "Glotus.gameInit=function(a){$1(a);};"),
        Hook.prepend("LockRotationClient", /return \w+\?\(\!/, "return Glotus.myClient.ModuleHandler.currentAngle;"),
        Hook.replace("DisableResetMoveDir", /\w+=\{\},\w+\.send\("\w+"\)/, ""), Hook.append("offset", /\W170\W.+?(\w+)=\w+\-\w+\/2.+?(\w+)=\w+\-\w+\/2;/, "Glotus.myClient.myPlayer.offset.setXY($1,$2);"),
        Hook.prepend("renderEntity", /\w+\.health>NUM{0}.+?(\w+)\.fillStyle=(\w+)==(\w+)/, ";Glotus.hooks.EntityRenderer.render($1,$2,$3);false&&"),
        Hook.append("renderItemPush", /,(\w+)\.blocker,\w+.+?2\)\)/, ",Glotus.Renderer.renderObjects.push($1)"),
        Hook.append("renderItem", /70, 0.35\)",(\w+).+?\w+\)/, ",Glotus.hooks.ObjectRenderer.render($1)"),
        Hook.append("RemoveSendAngle", /clientSendRate\)/, "&&false"), Hook.replace("handleEquip", /\w+\.send\("\w+",0,(\w+),(\w+)\)/, "Glotus.myClient.ModuleHandler.equip($2,$1,true,true)"),
        Hook.replace("handleBuy", /\w+\.send\("\w+",1,(\w+),(\w+)\)/, "Glotus.myClient.ModuleHandler.buy($2,$1,true)"),
        Hook.prepend("RemovePingCall", /\w+&&clearTimeout/, "return;"), Hook.append("RemovePingState", /let \w+=-1;function \w+\(\)\{/, "return;"),
        Hook.prepend("preRender", /(\w+)\.lineWidth=NUM{4},/, "Glotus.hooks.ObjectRenderer.preRender($1);"),
        Hook.replace("RenderGrid", /("#91b2db".+?)(for.+?)(\w+\.stroke)/, "$1$3"), Hook.replace("upgradeItem", /(upgradeItem.+?onclick.+?)\w+\.send\("\w+",(\w+)\)\}/, "$1Glotus.myClient.ModuleHandler.upgradeItem($2)}");
        let data = Hook.match("DeathMarker", /99999.+?(\w+)=\{x:(\w+)/);
        Hook.append("playerDied", /NUM{99999};function \w+\(\)\{/, `if(Glotus.settings._autospawn){${data[1]}={x:${data[2]}.x,y:${data[2]}.y};return};`),
        Hook.append("updateNotificationRemove", /\w+=\[\],\w+=\[\];function \w+\(\w+,\w+\)\{/, "return;"),
        Hook.replace("checkTrusted", /checkTrusted:(\w+)/, "checkTrusted:(callback)=>(event)=>callback(event)"),
        Hook.replace("removeSkins", /(\(\)\{)(let \w+="";for\(let)/, "$1return;$2"),
        Hook.prepend("unlockedItems", /\w+\.list\[\w+\]\.pre==/, "true||"), Hook.replace("gameColor", /rgba\(0, 0, 70, 0.35\)/, "rgba(23, 6, 62, 0.6)"),
        Hook.prepend("renderPlayer", /function (\w+)\(\w+,\w+\)\{\w+=\w+\|\|\w+,/, "Glotus.hooks.renderPlayer=$1;"),
        Hook.replace("maskFRVR", /window\.FRVR/, "FRVR", "g"), Hook.replace("scaleWidth", /=1920/, "=Glotus.ZoomHandler.scale.smooth.w"),
        Hook.replace("scaleHeight", /=1080/, "=Glotus.ZoomHandler.scale.smooth.h"),
        Hook.replace("maskLerp", /Math\.lerpAngle/, "THIS_STORAGE.lerpAngle", "g"),
        Hook.replace("smoothRendering", /(\w+=)NUM{170};/, "$1Glotus._getSmoothRendering();");
        // ------------------------------------------------------------------
        //  HLM - trois crochets ajoutes
        //
        //  Le jeu capture WebSocket.prototype.send au chargement de son
        //  bundle et appelle ensuite cette reference native. Un Proxy sur
        //  window.WebSocket ne le verrait donc pas - et de toute facon
        //  window.WebSocket est devenu non modifiable.
        //  Comme on reecrit le bundle, on demande au jeu de nous donner
        //  directement son socket, son objet reseau et son etat de
        //  chiffrement. Un seul compteur de sequence pour tout le monde.
        // ------------------------------------------------------------------
        Hook.append("exposeSocket", /this\.socket=new \w+\(\w+\),this\.socket\.binaryType="arraybuffer"/,
            ",window.__glotusSocket&&window.__glotusSocket(this.socket)"),
        Hook.prepend("exposeIO", /let (\w+)=null;const (\w+)=\{socket:null,connected:!NUM{1},socketId:-NUM{1},/,
            "window.__glotusEnc=function(){return $1};window.__glotusIO=function(){return $2};");
        let addCode = isProd ? "const Glotus=window.Glotus;delete window.Glotus;" : "";
        return Hook.wrap("(function THIS_STORAGE(){const FRVR=window.FRVR;delete window.FRVR;" + addCode, "})();"),
        Logger.test(`Modified bundle, total amount of hooks: ${Hook.hookCount}/${Hook.hookAttempts}`),
        Hook.code;
    }, formatCode_default = formatCode2;

    const Injector = new class {
        init(node) {
            this.loadScript(node.src);
        }
        loadScript(src) {
            let xhr = new XMLHttpRequest;
            xhr.open("GET", src, !1), xhr.send();
            // HLM : si le bundle d'origine s'est deja execute, injecter une
            // seconde copie fait tourner le jeu en double - c'est ce que
            // signalaient "Turnstile already has been loaded" et "already been
            // rendered in this container", et c'est ce qui provoquait la
            // deconnexion. Mieux vaut s'arreter et le dire clairement.
            let alreadyRan = typeof window.loadedScript !== "undefined"
                || document.querySelector("#turnstileWidget iframe") !== null;
            console.log("[HLM] avant injection : jeu d'origine deja execute = " + alreadyRan);
            if (alreadyRan) {
                // On continue : en injection lente, l'instance d'origine est
                // gelee car Glotus intercepte son requestAnimFrame. Elle a
                // seulement eu le temps de dessiner le widget Turnstile, d'ou
                // le refus de rendu pour le notre - sans consequence, on lit
                // le jeton dans le champ cache.
                console.warn("[HLM] le bundle d'origine a demarre avant nous :"
                    + " son instance est gelee, on injecte quand meme.");
            }
            let code = formatCode_default(xhr.responseText);
            // Les specificateurs relatifs ("./vendor-xxxx.js") se resoudraient
            // par rapport a l'URL blob: et non au site : on les rend absolus.
            code = code.replace(/(\bfrom\s*|\bimport\s*\(\s*)("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/g, function (whole, kw, lit) {
                let spec = lit.slice(1, -1);
                if (!/^[.\/]/.test(spec)) return whole;
                try { return kw + JSON.stringify(new URL(spec, src).href); } catch (e) { return whole; }
            });
            // Function(code)() et un script classique ne peuvent pas executer un
            // import de premier niveau : on injecte desormais un module.
            let blob = new Blob([ code ], {
                type: "text/javascript"
            }), element = document.createElement("script");
            element.type = "module", element.src = URL.createObjectURL(blob),
            this.waitForBody(function () {
                document.head.appendChild(element);
            });
        }
        waitForBody(callback) {
            if (document.readyState !== "loading") {
                callback(), Logger.test("Page already loaded, instant inject..");
                return;
            }
            document.addEventListener("readystatechange", () => {
                if (document.readyState !== "loading") {
                    callback();
                }
            }, {
                once: !0
            });
        }
    }, Injector_default = Injector;

    const resetGame = loadedFast => {
        let scriptExecuteHandler = node => {
            node.addEventListener("beforescriptexecute", event => {
                event.preventDefault();
            }, {
                once: !0
            }), node.remove();
        }, scriptBundle = null, hlmTurnstileApiSeen = !1, handleScriptElement = node => {
            // Le jeu ayant demarre deux fois, api.js de Turnstile etait injecte
            // deux fois : "Turnstile already has been loaded", puis les deux
            // instances se disputaient le widget et aucun jeton ne sortait.
            if (node instanceof HTMLScriptElement && /challenges\.cloudflare\.com\/turnstile/.test(node.src)) {
                if (hlmTurnstileApiSeen) {
                    console.warn("[HLM] second chargement de l'api Turnstile ignore"), node.remove();
                    return;
                }
                hlmTurnstileApiSeen = !0;
                return;
            }
            let isScript = node instanceof HTMLScriptElement, isLink = node instanceof HTMLLinkElement, regex = /frvr|jquery|howler|assets|cookie|securepubads|google|ads/i;
            if (isScript && regex.test(node.src) || isLink && regex.test(node.href) || regex.test(node.innerHTML)) {
                scriptExecuteHandler(node);
            }
            if (isScript && /assets.+\.js$/.test(node.src) && scriptBundle === null) {
                if (scriptBundle = node, Logger.test("Found script element, resolving.."), scriptExecuteHandler(node),
                loadedFast) {
                    Injector_default.init(node);
                }
            }
        };
        new MutationObserver(mutations => {
            for (let mutation of mutations) {
                for (let node of mutation.addedNodes) {
                    if (node instanceof HTMLScriptElement || node instanceof HTMLLinkElement) {
                        handleScriptElement(node);
                    }
                }
            }
        }).observe(document, {
            childList: !0,
            subtree: !0
        }), document.querySelectorAll("script").forEach(handleScriptElement), document.querySelectorAll("link").forEach(handleScriptElement),
        document.querySelectorAll("iframe").forEach(iframe => {
            iframe.remove();
        });
        let resolvePromise = data => new Promise(function(resolve) {
            resolve(data);
        }), win = window;
        if (blockProperty(win, "onbeforeunload"), win.frvrSdkInitPromise = resolvePromise(),
        blockProperty(win, "frvrSdkInitPromise"), win.FRVR = {
            bootstrapper: {
                complete() {}
            },
            tracker: {
                levelStart() {}
            },
            ads: {
                show() {
                    return resolvePromise();
                }
            },
            channelCharacteristics: {
                allowNavigation: !0
            },
            setChannel() {}
        }, blockProperty(win, "FRVR"), !loadedFast) {
            let _define = win.customElements.define;
            win.customElements.define = function() {
                win.customElements.define = _define;
            }, win.requestAnimFrame = function() {
                if (delete win.requestAnimFrame, scriptBundle !== null) {
                    Injector_default.init(scriptBundle);
                }
            }, blockProperty(win, "requestAnimFrame");
        }
        let _fetch = window.fetch;
        if (window.fetch = new Proxy(_fetch, {
            apply(target, _this, args) {
                let link = args[0];
                if (typeof link === "string") {
                    if (/ping/.test(link)) {
                        return resolvePromise();
                    }
                }
                return target.apply(_this, args);
            }
        }), CustomStorage.set("moofoll", 1), CustomStorage.get("skin_color") === null) {
            CustomStorage.set("skin_color", "toString");
        }
        window.addEventListener = new Proxy(window.addEventListener, {
            apply(target, _this, args) {
                if ([ "keydown", "keyup" ].includes(args[0]) && args[2] === void 0) {
                    if (args[0] === "keyup" && loadedFast) {
                        window.addEventListener = target;
                    }
                    return null;
                }
                return target.apply(_this, args);
            }
        });
        let proto = HTMLDivElement.prototype;
        proto.addEventListener = new Proxy(proto.addEventListener, {
            apply(target, _this, args) {
                if (_this.id === "touch-controls-fullscreen" && /^mouse/.test(args[0]) && args[2] === !1) {
                    if (/up$/.test(args[0]) && loadedFast) {
                        proto.addEventListener = target;
                    }
                    return null;
                }
                return target.apply(_this, args);
            }
        }), window.setInterval = new Proxy(window.setInterval, {
            apply(target, _this, args) {
                if (/cordova/.test(args[0].toString()) && args[1] === 1e3) {
                    if (loadedFast) {
                        window.setInterval = target;
                    }
                    return null;
                }
                return target.apply(_this, args);
            }
        });
        let deleteProp = (target, name) => {
            delete target[name];
        };
        Hooker_default.createRecursiveHook(window, "config", (that, config) => (deleteProp(that, "openLink"),
        deleteProp(that, "aJoinReq"), deleteProp(that, "follmoo"), deleteProp(that, "kickFromClan"),
        deleteProp(that, "sendJoin"), deleteProp(that, "leaveAlliance"), deleteProp(that, "createAlliance"),
        deleteProp(that, "storeBuy"), deleteProp(that, "storeEquip"), deleteProp(that, "showItemInfo"),
        deleteProp(that, "selectSkinColor"), deleteProp(that, "config"), deleteProp(that, "altchaCreateWorker"),
        deleteProp(that, "captchaCallbackHook"), deleteProp(that, "showPreAd"), deleteProp(that, "setUsingTouch"),
        that.addEventListener("blur", that.onblur), deleteProp(that, "onblur"), that.addEventListener("focus", that.onfocus),
        deleteProp(that, "onfocus"), Glotus.config = config, loadedFast)), Hooker_default.createRecursiveHook(Object.prototype, "initialBufferSize", _this => (client.PacketManager.Encoder = _this,
        !0)), Hooker_default.createRecursiveHook(Object.prototype, "maxExtLength", _this => (client.PacketManager.Decoder = _this,
        !0));
        let patterns = {
            "./img/hats/hat_12.png": "https://i.postimg.cc/BQPfhPwD/Booster-V2.png",
            "./img/hats/hat_23.png": "https://i.postimg.cc/WpHP6wST/Anti-Venom-Gear.png",
            "./img/hats/hat_6.png": "https://i.postimg.cc/662BPP8y/Soldier-Helmet.png",
            "./img/hats/hat_15.png": "https://i.postimg.cc/pXKRWnYv/Winter-Cap.png",
            "./img/hats/hat_7.png": "https://i.postimg.cc/zGnZNZNG/Bull-Helmet-V2.png",
            "./img/hats/hat_58.png": "https://i.postimg.cc/B67RpJTM/Bushido-Armor.png",
            "./img/hats/hat_8.png": "https://i.postimg.cc/XJYT9rCr/Bummel-Hat.png",
            "./img/hats/hat_5.png": "https://i.postimg.cc/hvJ63NMg/Cowboy-Hat.png",
            "./img/hats/hat_50.png": "https://i.postimg.cc/y8h55mhJ/Honeycrisp-Hat.png",
            "./img/hats/hat_18.png": "https://i.postimg.cc/RhjyrGbt/Explorer-Hat-V2.png",
            "./img/hats/hat_27.png": "https://i.postimg.cc/mkFpSC2g/Scavenger-Gear.png",
            "./img/hats/hat_26.png": "https://i.postimg.cc/t40Q8RLc/Barbarian-Armor.png",
            "./img/hats/hat_20.png": "https://i.postimg.cc/Dmkjp08d/Samurai-Hat.png",
            "./img/hats/hat_22.png": "https://i.postimg.cc/5t3hHB6c/Emp-Helmet.png",
            "./img/hats/hat_13.png": "https://i.postimg.cc/BvqyGjNm/Medic-Gear-V2.png",
            "./img/hats/hat_9.png": "https://i.postimg.cc/g0N7cGTm/Miner.png",
            "./img/hats/hat_4.png": "https://i.postimg.cc/Tw14pBzm/Ranger-Hat.png",
            "./img/hats/hat_31.png": "https://i.postimg.cc/2SNM2cWR/Flipper-Hat.png",
            "./img/hats/hat_1.png": "https://i.postimg.cc/fWF60TTb/Fiddler-Hat.png",
            "./img/hats/hat_11.png": "https://i.postimg.cc/7PFqrNzX/Spike-V2.png",
            "./img/hats/hat_11_p.png": "https://i.postimg.cc/7PFqrNzX/Spike-V2.png",
            "./img/hats/hat_11_top.png": ""
        };
        if (Settings_default._texturepack) {
            let imageDesc = Object.getOwnPropertyDescriptor(Image.prototype, "src");
            Object.defineProperty(Image.prototype, "src", {
                get() {
                    return imageDesc.get?.call(this);
                },
                set(value) {
                    if (value in patterns) {
                        value = patterns[value];
                    }
                    if (value === "") {
                        return;
                    }
                    return imageDesc.set?.call(this, value);
                },
                configurable: !0
            });
        }
        let _proto_ = Object.prototype;
        Object.defineProperty(_proto_, "processServers", {
            set(value) {
                delete _proto_.processServers, this.processServers = function(data) {
                    for (let server of data) {
                        server.playerCapacity += 1;
                    }
                    return value.call(this, data);
                };
            },
            configurable: !0
        });
    }, resetGame_default = resetGame;

    class DeadPlayer {
        moveAngle;
        skinColor;
        angle;
        weapon;
        variant;
        hatID;
        accID;
        rotation;
        baseTime=2e3;
        elapsedTime=0;
        pos=new Vector_default;
        lerpPos=new Vector_default;
        acc=7;
        velocity=0;
        opacity=1;
        shortSign;
        constructor(startPos, moveAngle, skin, rotation, weapon, variant, hatID, accID, impulse) {
            this.moveAngle = moveAngle, this.skinColor = skin, this.angle = rotation, this.weapon = weapon,
            this.variant = variant, this.hatID = hatID, this.accID = accID, this.rotation = rotation,
            this.pos.setVec(startPos), this.lerpPos.setVec(startPos), this.shortSign = Math.sign(shortAngle(this.angle, this.moveAngle)),
            this.acc = (impulse || 10) / 10 * 75;
        }
        update(delta) {
            this.elapsedTime += delta;
            let progress = Math.min(this.elapsedTime / this.baseTime, 1), easedProgress = easeOutQuad(progress);
            this.opacity = 1 - easedProgress;
            let dt = delta / 1e3, blend = 1 - Math.exp(-10 * dt), PI3 = Math.PI, rotationSpeed = (1 - easedProgress) / PI3 * blend;
            this.rotation += rotationSpeed * this.shortSign, this.velocity = this.acc * (1 - easedProgress),
            this.pos.add(Vector_default.fromAngle(this.moveAngle, this.velocity * dt)),
            this.lerpPos.x = lerp(this.lerpPos.x, this.pos.x, blend), this.lerpPos.y = lerp(this.lerpPos.y, this.pos.y, blend);
        }
        isFinished() {
            return this.elapsedTime >= this.baseTime;
        }
    }

    const DeadPlayerHandler = new class {
        deadPlayers=new Set;
        start=Date.now();
        add(player) {
            this.deadPlayers.add(player);
        }
        update(ctx) {
            let now = Date.now(), delta = now - this.start;
            this.start = now;
            let offset = client.myPlayer.offset;
            for (let player of this.deadPlayers) {
                if (player.update(delta), ctx.save(), ctx.translate(player.lerpPos.x - offset.x, player.lerpPos.y - offset.y),
                ctx.rotate(player.rotation), ctx.globalAlpha = player.opacity, ctx.strokeStyle = "#525252",
                Glotus.hooks.renderPlayer({
                    weaponIndex: player.weapon,
                    buildIndex: -1,
                    tailIndex: player.accID,
                    skinIndex: player.hatID,
                    weaponVariant: player.variant,
                    skinColor: player.skinColor,
                    scale: 35
                }, ctx), ctx.restore(), player.isFinished()) {
                    this.deadPlayers.delete(player);
                }
            }
        }
    };

    const ObjectRenderer = new class {
        healthBar(ctx, entity, object) {
            if (!(Settings_default._itemHealthBar && object.seenPlacement && object.isDestroyable)) {
                return 0;
            }
            let {health: health, maxHealth: maxHealth, angle: angle} = object, perc = health / maxHealth, color = Settings_default._itemHealthBarColor;
            return Renderer_default.circularBar(ctx, entity, perc, angle, color);
        }
        renderTurret(ctx, entity, object, scale) {
            if (object.type !== 17) {
                return;
            }
            if (Settings_default._objectTurretReloadBar) {
                let {reload: reload, maxReload: maxReload, angle: angle} = object, perc = reload / maxReload, color = Settings_default._objectTurretReloadBarColor;
                Renderer_default.circularBar(ctx, entity, perc, angle, color, scale);
            }
        }
        renderWindmill(entity) {
            if (Items[entity.id].itemType === 5) {
                entity.turnSpeed = 0;
            }
        }
        renderCollisions(ctx, entity, object) {
            let x = entity.x + entity.xWiggle, y = entity.y + entity.yWiggle;
            if (Settings_default._collisionHitbox) {
                Renderer_default.circle(ctx, x, y, object.collisionScale, "#c7fff2", .5, 1),
                Renderer_default.rect(ctx, new Vector_default(x, y), object.collisionScale, "#ecffbd", 1, .5);
            }
            if (Settings_default._weaponHitbox) {
                Renderer_default.circle(ctx, x, y, object.hitScale, "#3f4ec4", .5, 1);
            }
            if (Settings_default._placementHitbox) {
                Renderer_default.circle(ctx, x, y, object.placementScale, "#73b9ba", .5, 1);
            }
            let spikeCollider = client.EnemyManager.spikeCollider;
            if (spikeCollider === object) {
                let scale = spikeCollider.scale * .3;
                Renderer_default.fillCircle(ctx, x, y, scale, "#bf3d59", .6);
            }
            if (object instanceof PlayerObject && object.canBeDestroyed) {
                Renderer_default.fillCircle(ctx, x, y, 10, "#f88a41ff", .3);
            }
        }
        render(ctx) {
            if (Renderer_default.renderObjects.length === 0) {
                return;
            }
            let {ObjectManager: ObjectManager2, ModuleHandler: ModuleHandler2, myPlayer: myPlayer} = client;
            for (let entity of Renderer_default.renderObjects) {
                let object = ObjectManager2.objects.get(entity.sid);
                if (object === void 0) {
                    continue;
                }
                if (Renderer_default.renderMarker(ctx, entity), object instanceof PlayerObject) {
                    let scale = this.healthBar(ctx, entity, object);
                    this.renderTurret(ctx, entity, object, scale), this.renderWindmill(entity);
                }
                this.renderCollisions(ctx, entity, object);
            }
            Renderer_default.renderObjects.length = 0;
        }
        volcanoBoxSize=940;
        volcanoAggressionRadius=1440;
        volcanoBoxPos=new Vector_default(14400, 14400).sub(this.volcanoBoxSize);
        volcanoPos=new Vector_default(13960, 13960);
        preRender(ctx) {
            if (Renderer_default.rect(ctx, this.volcanoBoxPos, this.volcanoBoxSize, "red", 1, .5),
            Renderer_default.circle(ctx, this.volcanoPos.x, this.volcanoPos.y, this.volcanoAggressionRadius, "red", 1, .4),
            client.myPlayer.diedOnce) {
                let {x: x, y: y} = client.myPlayer.deathPosition;
                Renderer_default.cross(ctx, x, y, 50, 15, "#cc5151");
            }
            DeadPlayerHandler.update(ctx);
        }
    }, ObjectRenderer_default = ObjectRenderer;

    const isProd = !0;

    const loadedFast = document.head === null;

    // HLM : ce mode conditionne TOUT. En injection lente, le bundle
    // d'origine a le temps de demarrer et le jeu tourne en double :
    // deux widgets Turnstile, deux connexions, et le serveur coupe.
    console.log("%c[HLM] injection rapide : " + loadedFast
        + " | document.head deja present : " + (document.head !== null),
        loadedFast ? "color:#6f6" : "color:#f66;font-weight:bold");
    if (!loadedFast) {
        console.error("[HLM] INJECTION LENTE. Dans Tampermonkey : Reglages > General >"
            + " Mode de config = Avance, puis Securite > Content Script API ="
            + " UserScripts API Dynamic, puis Sauvegarder et recharger.");
        Logger.warn("Glotus Client loading warning! It is generally recommended to use faster injection mode.");
    }

    Logger.test("Glotus Client initialization [Glotus Client!]..");

    // HLM : plus de jeton altcha fabrique au chargement. Le jeton
    // Cloudflare est lu au moment du clic sur Play (voir startGame).
    let hlmTurnstileToken = null;
    // Point d'extension officiel du jeu : appele des que le jeton arrive.
    window.captchaCallbackHook = function() {
        let f = document.querySelector('[name="cf-turnstile-response"]');
        if (f && f.value) hlmTurnstileToken = f.value;
        // Un bot attend peut-etre ce jeton (voir hlmFreshToken).
        if (window.__hlmTokenDelivery) window.__hlmTokenDelivery(hlmTurnstileToken);
    };
    const client = new PlayerClient_default;

    // ==================================================================
    //  HLM - CAPTURE DU SOCKET SANS TOUCHER A window.WebSocket
    //  moomoo.io a rendu window.WebSocket non modifiable : le Proxy levait
    //  une TypeError qui interrompait tout le script. Le bundle reecrit
    //  nous transmet desormais son socket a la creation (crochet
    //  exposeSocket), c'est-a-dire avant meme le io-init.
    // ==================================================================
    window.__glotusSocket = function(socket) {
        window.__glotusSocket = null;
        Logger.test("Found socket! Socket initialization.."), client.SocketManager.init(socket);
    };

    const win = window, Glotus = {
        myClient: client,
        settings: Settings_default,
        Renderer: Renderer_default,
        DataHandler: DataHandler_default,
        ZoomHandler: ZoomHandler_default,
        hooks: {
            EntityRenderer: EntityRenderer_default,
            ObjectRenderer: ObjectRenderer_default,
            renderPlayer: function() {},
            showText: function() {}
        },
        _getSmoothRendering() {
            return Settings_default._smoothRendering;
        },
        version: "5.3",
        hash: "{HASH}",
        config: {},
        gameInit(token) {},
        async startGame() {
            // Le jeu attend desormais un jeton de la forme "cf:<jeton>".
            // L'ancien prefixe "alt:" n'est plus reconnu par le serveur.
            if (hlmTurnstileToken === null) {
                let f = document.querySelector('[name="cf-turnstile-response"]');
                if (f && f.value) hlmTurnstileToken = f.value;
            }
            if (hlmTurnstileToken === null) {
                Logger.error("Jeton Cloudflare absent : attends la fin de la verification");
                return;
            }
            this.gameInit("cf:" + hlmTurnstileToken);
        }
    };

    win.Glotus = Glotus;

    resetGame_default(loadedFast);

    const contentLoaded = () => {
        Logger.test("Menu initialization.."), client.InputHandler.init(), GameUI_default.init(),
        UI_default.init(), StoreHandler_default.init();
    };

    window.addEventListener("DOMContentLoaded", contentLoaded);

    if (document.readyState !== "loading") {
        contentLoaded();
    }

    const onload = () => {
        Logger.test("Page loaded..");
        let {enterGame: enterGame} = GameUI_default.getElements();
        enterGame.classList.remove("disabled");
    };

    window.addEventListener("load", onload);

    if (document.readyState === "complete") {
        onload();
    }
})();