diff --git a/package-lock.json b/package-lock.json
index 6667c0493..534c6f462 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -85,6 +85,7 @@
"lit": "^3.3.1",
"lit-markdown": "^1.3.2",
"mrmime": "^2.0.0",
+ "msdf-bmfont-xml": "^2.8.0",
"pixi-filters": "^6.1.5",
"pixi.js": "^8.18.1",
"prettier": "^3.5.3",
@@ -1105,6 +1106,16 @@
"node": ">=18"
}
},
+ "node_modules/@borewit/text-codec": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz",
+ "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==",
+ "dev": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
"node_modules/@colors/colors": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
@@ -2036,6 +2047,562 @@
"url": "https://github.com/sponsors/nzakas"
}
},
+ "node_modules/@jimp/core": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/core/-/core-1.6.1.tgz",
+ "integrity": "sha512-+BoKC5G6hkrSy501zcJ2EpfnllP+avPevcBfRcZe/CW+EwEfY6X1EZ8QWyT7NpDIvEEJb1fdJnMMfUnFkxmw9A==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/file-ops": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "await-to-js": "^3.0.0",
+ "exif-parser": "^0.1.12",
+ "file-type": "^21.3.3",
+ "mime": "3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/diff": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/diff/-/diff-1.6.1.tgz",
+ "integrity": "sha512-YkKDPdHjLgo1Api3+Bhc0GLAygldlpt97NfOKoNg1U6IUNXA6X2MgosCjPfSBiSvJvrrz1fsIR+/4cfYXBI/HQ==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/plugin-resize": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "pixelmatch": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/file-ops": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/file-ops/-/file-ops-1.6.1.tgz",
+ "integrity": "sha512-T+gX6osHjprbDRad0/B71Evyre7ZdVY1z/gFGEG9Z8KOtZPKboWvPeP2UjbZYWQLy9UKCPQX1FNAnDiOPkJL7w==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/js-bmp": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/js-bmp/-/js-bmp-1.6.1.tgz",
+ "integrity": "sha512-xzWzNT4/u5zGrTT3Tme9sGU7YzIKxi13+BCQwLqACbt5DXf9SAfdzRkopZQnmDko+6In5nqaT89Gjs43/WdnYQ==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "bmp-ts": "^1.0.9"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/js-gif": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/js-gif/-/js-gif-1.6.1.tgz",
+ "integrity": "sha512-YjY2W26rQa05XhanYhRZ7dingCiNN+T2Ymb1JiigIbABY0B28wHE3v3Cf1/HZPWGu0hOg36ylaKgV5KxF2M58w==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "gifwrap": "^0.10.1",
+ "omggif": "^1.0.10"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/js-jpeg": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/js-jpeg/-/js-jpeg-1.6.1.tgz",
+ "integrity": "sha512-HT9H3yOmlOFzYmdI15IYdfy6ggQhSRIaHeA+OTJSEORXBqEo97sUZu/DsgHIcX5NJ7TkJBTgZ9BZXsV6UbsyMg==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "jpeg-js": "^0.4.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/js-png": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/js-png/-/js-png-1.6.1.tgz",
+ "integrity": "sha512-SZ/KVhI5UjcSzzlXsXdIi/LhJ7UShf2NkMOtVrbZQcGzsqNtynAelrOXeoTxcanfVqmNhAoVHg8yR2cYoqrYjA==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "pngjs": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/js-tiff": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/js-tiff/-/js-tiff-1.6.1.tgz",
+ "integrity": "sha512-jDG/eJquID1M4MBlKMmDRBmz2TpXMv7TUyu2nIRUxhlUc2ogC82T+VQUkca9GJH1BBJ9dx5sSE5dGkWNjIbZxw==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "utif2": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-blit": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-1.6.1.tgz",
+ "integrity": "sha512-MwnI7C7K81uWddY9FLw1fCOIy6SsPIUftUz36Spt7jisCn8/40DhQMlSxpxTNelnZb/2SnloFimQfRZAmHLOqQ==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-blit/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-blur": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-1.6.1.tgz",
+ "integrity": "sha512-lIo7Tzp5jQu30EFFSK/phXANK3citKVEjepDjQ6ljHoIFtuMRrnybnmI2Md24ulvWlDaz+hh3n6qrMb8ydwhZQ==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-circle": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-1.6.1.tgz",
+ "integrity": "sha512-kK1PavY6cKHNNKce37vdV4Tmpc1/zDKngGoeOV3j+EMatoHFZUinV3s6F9aWryPs3A0xhCLZgdJ6Zeea1d5LCQ==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/types": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-circle/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-color": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-1.6.1.tgz",
+ "integrity": "sha512-LtUN1vAP+LRlZAtTNVhDRSiXx+26Kbz3zJaG6a5k59gQ95jgT5mknnF8lxkHcqJthM4MEk3/tPxkdJpEybyF/A==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "tinycolor2": "^1.6.0",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-color/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-contain": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-1.6.1.tgz",
+ "integrity": "sha512-m0qhrfA8jkTqretGv4w+T/ADFR4GwBpE0sCOC2uJ0dzr44/ddOMsIdrpi89kabqYiPYIrxkgdCVCLm3zn1Vkkg==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/plugin-blit": "1.6.1",
+ "@jimp/plugin-resize": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-contain/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-cover": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-1.6.1.tgz",
+ "integrity": "sha512-hZytnsth0zoll6cPf434BrT+p/v569Wr5tyO6Dp0dH1IDPhzhB5F38sZGMLDo7bzQiN9JFVB3fxkcJ/WYCJ3Mg==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/plugin-crop": "1.6.1",
+ "@jimp/plugin-resize": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-cover/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-crop": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-1.6.1.tgz",
+ "integrity": "sha512-EerRSLlclXyKDnYc/H9w/1amZW7b7v3OGi/VlerPd2M/pAu5X8TkyYWtfqYCXnNp1Ixtd8oCo9zGfY9zoXT4rg==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-crop/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-displace": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-1.6.1.tgz",
+ "integrity": "sha512-K07QVl7xQwIfD6KfxRV/c3E9e7ZBXxUXdWuvoTWcKHL2qV48MOF5Nqbz/aJW4ThnQARIsxvYlZjPFiqkCjlU+g==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-displace/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-dither": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-1.6.1.tgz",
+ "integrity": "sha512-+2V+GCV2WycMoX1/z977TkZ8Zq/4MVSKElHYatgUqtwXMi2fDK2gKYU2g9V39IqFvTJsTIsK0+58VFz/ROBVew==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/types": "1.6.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-fisheye": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-1.6.1.tgz",
+ "integrity": "sha512-XtS5ZyoZ0vxZxJ6gkqI63SivhtI58vX95foMPM+cyzYkRsJXMOYCr8DScxF5bp4Xr003NjYm/P+7+08tibwzHA==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-fisheye/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-flip": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-1.6.1.tgz",
+ "integrity": "sha512-ws38W/sGj7LobNRayQ83garxiktOyWxM5vO/y4a/2cy9v65SLEUzVkrj+oeAaUSSObdz4HcCEla7XtGlnAGAaA==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/types": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-flip/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-hash": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-hash/-/plugin-hash-1.6.1.tgz",
+ "integrity": "sha512-sZt6ZcMX6i8vFWb4GYnw0pR/o9++ef0dTVcboTB5B/g7nrxCODIB4wfEkJ/YqZM5wUvol77K1qeS0/rVO6z21A==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/js-bmp": "1.6.1",
+ "@jimp/js-jpeg": "1.6.1",
+ "@jimp/js-png": "1.6.1",
+ "@jimp/js-tiff": "1.6.1",
+ "@jimp/plugin-color": "1.6.1",
+ "@jimp/plugin-resize": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "any-base": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-mask": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-1.6.1.tgz",
+ "integrity": "sha512-SIG0/FcmEj3tkwFxc7fAGLO8o4uNzMpSOdQOhbCgxefQKq5wOVMk9BQx/sdMPBwtMLr9WLq0GzLA/rk6t2v20A==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/types": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-mask/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-print": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-1.6.1.tgz",
+ "integrity": "sha512-BYVz/X3Xzv8XYilVeDy11NOp0h7BTDjlOtu0BekIFHP1yHVd24AXNzbOy52XlzYZWQ0Dl36HOHEpl/nSNrzc6w==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/js-jpeg": "1.6.1",
+ "@jimp/js-png": "1.6.1",
+ "@jimp/plugin-blit": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "parse-bmfont-ascii": "^1.0.6",
+ "parse-bmfont-binary": "^1.0.6",
+ "parse-bmfont-xml": "^1.1.6",
+ "simple-xml-to-json": "^1.2.2",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-print/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-quantize": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-quantize/-/plugin-quantize-1.6.1.tgz",
+ "integrity": "sha512-J2En9PLURfP+vwYDtuZ9T8yBW6BWYZBScydAjRiPBmJfEhTcNQqiiQODrZf7EqbbX/Sy5H6dAeRiqkgoV9N6Ww==",
+ "dev": true,
+ "dependencies": {
+ "image-q": "^4.0.0",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-quantize/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-resize": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-1.6.1.tgz",
+ "integrity": "sha512-CLkrtJoIz2HdWnpYiN6p8KYcPc00rCH/SUu6o+lfZL05Q4uhecJlnvXuj9x+U6mDn3ldPmJj6aZqMHuUJzdVqg==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-resize/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-rotate": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-1.6.1.tgz",
+ "integrity": "sha512-nOjVjbbj705B02ksysKnh0POAwEBXZtJ9zQ5qC+X7Tavl3JNn+P3BzQovbBxLPSbUSld6XID9z5ijin4PtOAUg==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/plugin-crop": "1.6.1",
+ "@jimp/plugin-resize": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-rotate/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/plugin-threshold": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-1.6.1.tgz",
+ "integrity": "sha512-JOKv9F8s6tnVLf4sB/2fF0F339EFnHvgEdFYugO6VhowKLsap0pEZmLyE/DlRnYtIj2RddHZVxVMp/eKJ04l2Q==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/plugin-color": "1.6.1",
+ "@jimp/plugin-hash": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1",
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/plugin-threshold/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/types": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/types/-/types-1.6.1.tgz",
+ "integrity": "sha512-leI7YbveTNi565m910XgIOwXyuu074H5qazAD1357HImJSv2hqxnWXpwxQbadGWZ7goZRYBDZy5lpqud0p7q5w==",
+ "dev": true,
+ "dependencies": {
+ "zod": "^3.23.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jimp/types/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@jimp/utils": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-1.6.1.tgz",
+ "integrity": "sha512-veFPRd93FCnS7AgmCkPgARVGoDRrJ9cm1ujuNyA+UfQ5VKbED2002sm5XfFLFwTsKC8j04heTrwe+tU1dluXOw==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/types": "1.6.1",
+ "tinycolor2": "^1.6.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
@@ -2576,6 +3143,47 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@pnpm/config.env-replace": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
+ "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz",
+ "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "4.2.10"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "node_modules/@pnpm/npm-conf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-3.0.2.tgz",
+ "integrity": "sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==",
+ "dev": true,
+ "dependencies": {
+ "@pnpm/config.env-replace": "^1.1.0",
+ "@pnpm/network.ca-file": "^1.0.1",
+ "config-chain": "^1.1.11"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@polka/url": {
"version": "1.0.0-next.29",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
@@ -4133,6 +4741,29 @@
"vite": "^5.2.0 || ^6 || ^7"
}
},
+ "node_modules/@tokenizer/inflate": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz",
+ "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.4.3",
+ "token-types": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/@tokenizer/token": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
+ "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
+ "dev": true
+ },
"node_modules/@tsconfig/node10": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
@@ -5337,6 +5968,15 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/ansi-align": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
+ "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.1.0"
+ }
+ },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -5363,6 +6003,12 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/any-base": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
+ "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==",
+ "dev": true
+ },
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@@ -5377,6 +6023,12 @@
"node": ">= 8"
}
},
+ "node_modules/arabic-persian-reshaper": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arabic-persian-reshaper/-/arabic-persian-reshaper-1.0.1.tgz",
+ "integrity": "sha512-VYBjkhz6o4W1Xt4mD2LAReljJpLSw5CUZMqSBDIQRvFgUSlTKEYghapgBWvkeMWF4W+KF3Fm+/z8EywJU4PBeg==",
+ "dev": true
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -5428,6 +6080,16 @@
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
"license": "MIT"
},
+ "node_modules/atomically": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.1.1.tgz",
+ "integrity": "sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==",
+ "dev": true,
+ "dependencies": {
+ "stubborn-fs": "^2.0.0",
+ "when-exit": "^2.1.4"
+ }
+ },
"node_modules/autoprefixer": {
"version": "10.4.21",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
@@ -5466,6 +6128,15 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/await-to-js": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz",
+ "integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -5540,6 +6211,12 @@
"readable-stream": "^4.2.0"
}
},
+ "node_modules/bmp-ts": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/bmp-ts/-/bmp-ts-1.0.9.tgz",
+ "integrity": "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==",
+ "dev": true
+ },
"node_modules/body-parser": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
@@ -5592,6 +6269,90 @@
"integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==",
"license": "MIT"
},
+ "node_modules/boxen": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz",
+ "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==",
+ "dev": true,
+ "dependencies": {
+ "ansi-align": "^3.0.1",
+ "camelcase": "^8.0.0",
+ "chalk": "^5.3.0",
+ "cli-boxes": "^3.0.0",
+ "string-width": "^7.2.0",
+ "type-fest": "^4.21.0",
+ "widest-line": "^5.0.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/boxen/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/boxen/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true
+ },
+ "node_modules/boxen/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/brace-expansion": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz",
@@ -5738,6 +6499,18 @@
"tslib": "^2.0.3"
}
},
+ "node_modules/camelcase": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
+ "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/caniuse-lite": {
"version": "1.0.30001762",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz",
@@ -5876,6 +6649,18 @@
"node": ">= 10.0"
}
},
+ "node_modules/cli-boxes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
+ "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/cli-cursor": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
@@ -5892,6 +6677,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/cli-progress": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz",
+ "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.3"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/cli-truncate": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
@@ -5978,38 +6775,6 @@
"node": ">=12"
}
},
- "node_modules/cliui/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cliui/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cliui/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/cliui/node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
@@ -6223,6 +6988,34 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/configstore": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-7.1.0.tgz",
+ "integrity": "sha512-N4oog6YJWbR9kGyXvS7jEykLDXIE2C0ILYqNBZBp9iwiJpoCBWYsuAdW6PPFn6w06jjnC+3JstVvWHO4cZqvRg==",
+ "dev": true,
+ "dependencies": {
+ "atomically": "^2.0.3",
+ "dot-prop": "^9.0.0",
+ "graceful-fs": "^4.2.11",
+ "xdg-basedir": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/consola": {
"version": "2.15.3",
"resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
@@ -7010,6 +7803,21 @@
"tslib": "^2.0.3"
}
},
+ "node_modules/dot-prop": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz",
+ "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^4.18.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/dotenv": {
"version": "16.5.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
@@ -7081,6 +7889,12 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
"node_modules/enabled": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
@@ -7232,6 +8046,18 @@
"node": ">=6"
}
},
+ "node_modules/escape-goat": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz",
+ "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -7550,6 +8376,12 @@
"node": ">=0.8.x"
}
},
+ "node_modules/exif-parser": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz",
+ "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==",
+ "dev": true
+ },
"node_modules/expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -7760,6 +8592,24 @@
"node": ">=16.0.0"
}
},
+ "node_modules/file-type": {
+ "version": "21.3.4",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz",
+ "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==",
+ "dev": true,
+ "dependencies": {
+ "@tokenizer/inflate": "^0.4.1",
+ "strtok3": "^10.3.4",
+ "token-types": "^6.1.1",
+ "uint8array-extras": "^1.4.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/file-type?sponsor=1"
+ }
+ },
"node_modules/filelist": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@@ -8001,6 +8851,16 @@
"js-binary-schema-parser": "^2.0.3"
}
},
+ "node_modules/gifwrap": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz",
+ "integrity": "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==",
+ "dev": true,
+ "dependencies": {
+ "image-q": "^4.0.0",
+ "omggif": "^1.0.10"
+ }
+ },
"node_modules/github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
@@ -8078,6 +8938,30 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/global-directory": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
+ "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
+ "dev": true,
+ "dependencies": {
+ "ini": "4.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/global-directory/node_modules/ini": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+ "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
"node_modules/globals": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz",
@@ -8117,6 +9001,27 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/handlebars": {
+ "version": "4.7.9",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz",
+ "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -8294,6 +9199,21 @@
"node": ">= 4"
}
},
+ "node_modules/image-q": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz",
+ "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "16.9.1"
+ }
+ },
+ "node_modules/image-q/node_modules/@types/node": {
+ "version": "16.9.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz",
+ "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==",
+ "dev": true
+ },
"node_modules/import-fresh": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
@@ -8439,6 +9359,58 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-in-ci": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-1.0.0.tgz",
+ "integrity": "sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==",
+ "dev": true,
+ "bin": {
+ "is-in-ci": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-installed-globally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-1.0.0.tgz",
+ "integrity": "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==",
+ "dev": true,
+ "dependencies": {
+ "global-directory": "^4.0.1",
+ "is-path-inside": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-invalid-path": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-1.0.2.tgz",
+ "integrity": "sha512-6KLcFrPCEP3AFXMfnWrIFkZpYNBVzZAoBJJDEZKtI3LXkaDjM3uFMJQjxiizUuZTZ9Oh9FNv/soXbx5TcpaDmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/is-npm": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.1.0.tgz",
+ "integrity": "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -8449,6 +9421,18 @@
"node": ">=0.12.0"
}
},
+ "node_modules/is-path-inside": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
+ "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
@@ -8569,6 +9553,44 @@
"node": ">=10"
}
},
+ "node_modules/jimp": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/jimp/-/jimp-1.6.1.tgz",
+ "integrity": "sha512-hNQh6rZtWfSVWSNVmvq87N5BPJsNH7k7I7qyrXf9DOma9xATQk3fsyHazCQe51nCjdkoWdTmh0vD7bjVSLoxxw==",
+ "dev": true,
+ "dependencies": {
+ "@jimp/core": "1.6.1",
+ "@jimp/diff": "1.6.1",
+ "@jimp/js-bmp": "1.6.1",
+ "@jimp/js-gif": "1.6.1",
+ "@jimp/js-jpeg": "1.6.1",
+ "@jimp/js-png": "1.6.1",
+ "@jimp/js-tiff": "1.6.1",
+ "@jimp/plugin-blit": "1.6.1",
+ "@jimp/plugin-blur": "1.6.1",
+ "@jimp/plugin-circle": "1.6.1",
+ "@jimp/plugin-color": "1.6.1",
+ "@jimp/plugin-contain": "1.6.1",
+ "@jimp/plugin-cover": "1.6.1",
+ "@jimp/plugin-crop": "1.6.1",
+ "@jimp/plugin-displace": "1.6.1",
+ "@jimp/plugin-dither": "1.6.1",
+ "@jimp/plugin-fisheye": "1.6.1",
+ "@jimp/plugin-flip": "1.6.1",
+ "@jimp/plugin-hash": "1.6.1",
+ "@jimp/plugin-mask": "1.6.1",
+ "@jimp/plugin-print": "1.6.1",
+ "@jimp/plugin-quantize": "1.6.1",
+ "@jimp/plugin-resize": "1.6.1",
+ "@jimp/plugin-rotate": "1.6.1",
+ "@jimp/plugin-threshold": "1.6.1",
+ "@jimp/types": "1.6.1",
+ "@jimp/utils": "1.6.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/jiti": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
@@ -8588,6 +9610,12 @@
"url": "https://github.com/sponsors/panva"
}
},
+ "node_modules/jpeg-js": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz",
+ "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==",
+ "dev": true
+ },
"node_modules/js-binary-schema-parser": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/js-binary-schema-parser/-/js-binary-schema-parser-2.0.3.tgz",
@@ -8607,6 +9635,15 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/js2xmlparser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-5.0.0.tgz",
+ "integrity": "sha512-ckXs0Fzd6icWurbeAXuqo+3Mhq2m8pOPygsQjTPh8K5UWgKaUgDSHrdDxAfexmT11xvBKOQ6sgYwPkYc5RW/bg==",
+ "dev": true,
+ "dependencies": {
+ "xmlcreate": "^2.0.4"
+ }
+ },
"node_modules/jsdom": {
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz",
@@ -8710,6 +9747,33 @@
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==",
"license": "MIT"
},
+ "node_modules/ky": {
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.3.tgz",
+ "integrity": "sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/ky?sponsor=1"
+ }
+ },
+ "node_modules/latest-version": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-9.0.0.tgz",
+ "integrity": "sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==",
+ "dev": true,
+ "dependencies": {
+ "package-json": "^10.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -9073,91 +10137,6 @@
"node": ">=18.0.0"
}
},
- "node_modules/listr2/node_modules/ansi-regex": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
- "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/listr2/node_modules/ansi-styles": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
- "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/listr2/node_modules/emoji-regex": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
- "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/listr2/node_modules/string-width": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
- "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^10.3.0",
- "get-east-asian-width": "^1.0.0",
- "strip-ansi": "^7.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/listr2/node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/listr2/node_modules/wrap-ansi": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
- "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^6.2.1",
- "string-width": "^7.0.0",
- "strip-ansi": "^7.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
"node_modules/lit": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/lit/-/lit-3.3.1.tgz",
@@ -9321,13 +10300,6 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/log-update/node_modules/emoji-regex": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
- "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/log-update/node_modules/is-fullwidth-code-point": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz",
@@ -9361,24 +10333,6 @@
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
- "node_modules/log-update/node_modules/string-width": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
- "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^10.3.0",
- "get-east-asian-width": "^1.0.0",
- "strip-ansi": "^7.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/log-update/node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
@@ -9395,24 +10349,6 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
- "node_modules/log-update/node_modules/wrap-ansi": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
- "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^6.2.1",
- "string-width": "^7.0.0",
- "strip-ansi": "^7.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
"node_modules/logform": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
@@ -9507,6 +10443,24 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"license": "ISC"
},
+ "node_modules/map-limit": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/map-limit/-/map-limit-0.0.1.tgz",
+ "integrity": "sha512-pJpcfLPnIF/Sk3taPW21G/RQsEEirGaFpCW3oXRwH9dnFHPHNGjNyvh++rdmC2fNqEaTw2MhYJraoJWAHx8kEg==",
+ "dev": true,
+ "dependencies": {
+ "once": "~1.3.0"
+ }
+ },
+ "node_modules/map-limit/node_modules/once": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
+ "integrity": "sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
"node_modules/marked": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
@@ -9529,6 +10483,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/maxrects-packer": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/maxrects-packer/-/maxrects-packer-2.7.3.tgz",
+ "integrity": "sha512-bG6qXujJ1QgttZVIH4WDanhoJtvbud/xP/XPyf6A69C9RdA61BM4TomFALCq2nrTa+tARRIBB4LuIFsnUQU2wA==",
+ "dev": true
+ },
"node_modules/mdn-data": {
"version": "2.12.2",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
@@ -9581,6 +10541,18 @@
"node": ">=8.6"
}
},
+ "node_modules/mime": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
+ "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
+ "dev": true,
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
@@ -9709,6 +10681,37 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
+ "node_modules/msdf-bmfont-xml": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/msdf-bmfont-xml/-/msdf-bmfont-xml-2.8.0.tgz",
+ "integrity": "sha512-VK6US7QqNhY9K5sq6TKlpKNlbBch1M2P1vLirf8mZLHK3j7X86fM4sqEyVnwCBYwZ/xiTbJeUWMEv5Ji+jQQMQ==",
+ "dev": true,
+ "dependencies": {
+ "arabic-persian-reshaper": "^1.0.1",
+ "cli-progress": "^3.12.0",
+ "commander": "^14.0.0",
+ "handlebars": "^4.7.8",
+ "is-invalid-path": "^1.0.2",
+ "jimp": "^1.6.0",
+ "js2xmlparser": "^5.0.0",
+ "map-limit": "0.0.1",
+ "maxrects-packer": "^2.7.3",
+ "opentype.js": "^1.3.4",
+ "update-notifier": "^7.3.1"
+ },
+ "bin": {
+ "msdf-bmfont": "cli.js"
+ }
+ },
+ "node_modules/msdf-bmfont-xml/node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "dev": true,
+ "engines": {
+ "node": ">=20"
+ }
+ },
"node_modules/nano-spawn": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-1.0.2.tgz",
@@ -9763,6 +10766,12 @@
"node": ">= 0.6"
}
},
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@@ -9868,6 +10877,12 @@
],
"license": "MIT"
},
+ "node_modules/omggif": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz",
+ "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==",
+ "dev": true
+ },
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -9907,6 +10922,22 @@
"fn.name": "1.x.x"
}
},
+ "node_modules/opentype.js": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz",
+ "integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==",
+ "dev": true,
+ "dependencies": {
+ "string.prototype.codepointat": "^0.2.1",
+ "tiny-inflate": "^1.0.3"
+ },
+ "bin": {
+ "ot": "bin/ot"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -9954,6 +10985,30 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/package-json": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-10.0.1.tgz",
+ "integrity": "sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==",
+ "dev": true,
+ "dependencies": {
+ "ky": "^1.2.0",
+ "registry-auth-token": "^5.0.2",
+ "registry-url": "^6.0.1",
+ "semver": "^7.6.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true
+ },
"node_modules/param-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
@@ -9978,6 +11033,28 @@
"node": ">=6"
}
},
+ "node_modules/parse-bmfont-ascii": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz",
+ "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==",
+ "dev": true
+ },
+ "node_modules/parse-bmfont-binary": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz",
+ "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==",
+ "dev": true
+ },
+ "node_modules/parse-bmfont-xml": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz",
+ "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==",
+ "dev": true,
+ "dependencies": {
+ "xml-parse-from-string": "^1.0.0",
+ "xml2js": "^0.5.0"
+ }
+ },
"node_modules/parse-srcset": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
@@ -10183,6 +11260,27 @@
"node": ">=0.10"
}
},
+ "node_modules/pixelmatch": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz",
+ "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==",
+ "dev": true,
+ "dependencies": {
+ "pngjs": "^6.0.0"
+ },
+ "bin": {
+ "pixelmatch": "bin/pixelmatch"
+ }
+ },
+ "node_modules/pixelmatch/node_modules/pngjs": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
+ "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.13.0"
+ }
+ },
"node_modules/pixi-filters": {
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/pixi-filters/-/pixi-filters-6.1.5.tgz",
@@ -10230,6 +11328,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/pngjs": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
+ "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.19.0"
+ }
+ },
"node_modules/postcss": {
"version": "8.5.10",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
@@ -10409,6 +11516,12 @@
"node": ">= 0.6.0"
}
},
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "dev": true
+ },
"node_modules/protobufjs": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.5.tgz",
@@ -10467,6 +11580,21 @@
"node": ">=6"
}
},
+ "node_modules/pupa": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz",
+ "integrity": "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==",
+ "dev": true,
+ "dependencies": {
+ "escape-goat": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/qs": {
"version": "6.15.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
@@ -10599,6 +11727,33 @@
"node": ">=8.10.0"
}
},
+ "node_modules/registry-auth-token": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.1.tgz",
+ "integrity": "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==",
+ "dev": true,
+ "dependencies": {
+ "@pnpm/npm-conf": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/registry-url": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz",
+ "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==",
+ "dev": true,
+ "dependencies": {
+ "rc": "1.2.8"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
@@ -10868,6 +12023,15 @@
"entities": "^4.4.0"
}
},
+ "node_modules/sax": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
+ "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
+ "dev": true,
+ "engines": {
+ "node": ">=11.0.0"
+ }
+ },
"node_modules/saxes": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
@@ -11157,6 +12321,15 @@
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
"license": "MIT"
},
+ "node_modules/simple-xml-to-json": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/simple-xml-to-json/-/simple-xml-to-json-1.2.7.tgz",
+ "integrity": "sha512-mz9VXphOxQWX3eQ/uXCtm6upltoN0DLx8Zb5T4TFC4FHB7S9FDPGre8CfLWqPWQQH/GrQYd2AXhhVM5LDpYx6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=20.12.2"
+ }
+ },
"node_modules/sinon": {
"version": "21.0.1",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.1.tgz",
@@ -11302,6 +12475,35 @@
"node": ">=0.6.19"
}
},
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.codepointat": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
+ "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
+ "dev": true
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -11340,6 +12542,37 @@
],
"license": "MIT"
},
+ "node_modules/strtok3": {
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz",
+ "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==",
+ "dev": true,
+ "dependencies": {
+ "@tokenizer/token": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
+ "node_modules/stubborn-fs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-2.0.0.tgz",
+ "integrity": "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==",
+ "dev": true,
+ "dependencies": {
+ "stubborn-utils": "^1.0.1"
+ }
+ },
+ "node_modules/stubborn-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stubborn-utils/-/stubborn-utils-1.0.2.tgz",
+ "integrity": "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==",
+ "dev": true
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -11520,6 +12753,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tiny-inflate": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+ "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
+ "dev": true
+ },
"node_modules/tiny-lru": {
"version": "11.4.7",
"resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.4.7.tgz",
@@ -11537,6 +12776,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tinycolor2": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz",
+ "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
+ "dev": true
+ },
"node_modules/tinyexec": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
@@ -11647,6 +12892,24 @@
"node": ">=0.6"
}
},
+ "node_modules/token-types": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz",
+ "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==",
+ "dev": true,
+ "dependencies": {
+ "@borewit/text-codec": "^0.2.1",
+ "@tokenizer/token": "^0.3.0",
+ "ieee754": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Borewit"
+ }
+ },
"node_modules/totalist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
@@ -11859,6 +13122,18 @@
"node": ">=4"
}
},
+ "node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/type-is": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
@@ -11910,6 +13185,31 @@
"typescript": ">=4.8.4 <6.1.0"
}
},
+ "node_modules/uglify-js": {
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
+ "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
+ "dev": true,
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/uint8array-extras": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz",
+ "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
@@ -11966,6 +13266,42 @@
"browserslist": ">= 4.21.0"
}
},
+ "node_modules/update-notifier": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-7.3.1.tgz",
+ "integrity": "sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==",
+ "dev": true,
+ "dependencies": {
+ "boxen": "^8.0.1",
+ "chalk": "^5.3.0",
+ "configstore": "^7.0.0",
+ "is-in-ci": "^1.0.0",
+ "is-installed-globally": "^1.0.0",
+ "is-npm": "^6.0.0",
+ "latest-version": "^9.0.0",
+ "pupa": "^3.1.0",
+ "semver": "^7.6.3",
+ "xdg-basedir": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/yeoman/update-notifier?sponsor=1"
+ }
+ },
+ "node_modules/update-notifier/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -11976,6 +13312,15 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/utif2": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz",
+ "integrity": "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==",
+ "dev": true,
+ "dependencies": {
+ "pako": "^1.0.11"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -12282,6 +13627,21 @@
}
}
},
+ "node_modules/vite-tsconfig-paths/node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
"node_modules/vite/node_modules/@esbuild/aix-ppc64": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
@@ -12939,6 +14299,12 @@
"node": ">=20"
}
},
+ "node_modules/when-exit": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.5.tgz",
+ "integrity": "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==",
+ "dev": true
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -12972,6 +14338,71 @@
"node": ">=8"
}
},
+ "node_modules/widest-line": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz",
+ "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/widest-line/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/widest-line/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true
+ },
+ "node_modules/widest-line/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/widest-line/node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/winston": {
"version": "3.17.0",
"resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
@@ -13046,6 +14477,91 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "dev": true
+ },
+ "node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -13073,6 +14589,18 @@
}
}
},
+ "node_modules/xdg-basedir": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz",
+ "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/xml-name-validator": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
@@ -13083,6 +14611,34 @@
"node": ">=18"
}
},
+ "node_modules/xml-parse-from-string": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz",
+ "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==",
+ "dev": true
+ },
+ "node_modules/xml2js": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
+ "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+ "dev": true,
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
@@ -13090,6 +14646,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/xmlcreate": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
+ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
+ "dev": true
+ },
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -13155,38 +14717,6 @@
"node": ">=12"
}
},
- "node_modules/yargs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/yargs/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
diff --git a/package.json b/package.json
index 5c234e22b..72e07af42 100644
--- a/package.json
+++ b/package.json
@@ -71,6 +71,7 @@
"lit": "^3.3.1",
"lit-markdown": "^1.3.2",
"mrmime": "^2.0.0",
+ "msdf-bmfont-xml": "^2.8.0",
"pixi-filters": "^6.1.5",
"pixi.js": "^8.18.1",
"prettier": "^3.5.3",
diff --git a/resources/fonts/namelayer_overpass.png b/resources/fonts/namelayer_overpass.png
index fd0364875..2dfb1db7b 100644
Binary files a/resources/fonts/namelayer_overpass.png and b/resources/fonts/namelayer_overpass.png differ
diff --git a/resources/fonts/namelayer_overpass.xml b/resources/fonts/namelayer_overpass.xml
index 2b316fe9d..506c88f57 100644
--- a/resources/fonts/namelayer_overpass.xml
+++ b/resources/fonts/namelayer_overpass.xml
@@ -1,96 +1,1158 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/images/namelayer-emojis.json b/resources/images/namelayer-emojis.json
index 655ac5e79..bd7f38fc8 100644
--- a/resources/images/namelayer-emojis.json
+++ b/resources/images/namelayer-emojis.json
@@ -4,1200 +4,1200 @@
"frame": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 64,
+ "x": 128,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π₯°": {
"frame": {
- "x": 128,
+ "x": 256,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 192,
+ "x": 384,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 256,
+ "x": 512,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 320,
+ "x": 640,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π₯Ί": {
"frame": {
- "x": 384,
+ "x": 768,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 448,
+ "x": 896,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π±": {
"frame": {
"x": 0,
- "y": 64,
- "w": 64,
- "h": 64
+ "y": 128,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π‘": {
"frame": {
- "x": 64,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 128,
+ "y": 128,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 128,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 128,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π€‘": {
"frame": {
- "x": 192,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 384,
+ "y": 128,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π₯±": {
"frame": {
- "x": 256,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 512,
+ "y": 128,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π«‘": {
"frame": {
- "x": 320,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 640,
+ "y": 128,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 384,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 768,
+ "y": 128,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 448,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 896,
+ "y": 128,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
"x": 0,
- "y": 128,
- "w": 64,
- "h": 64
+ "y": 256,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β": {
"frame": {
- "x": 64,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 128,
+ "y": 256,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 128,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 256,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"πͺ": {
"frame": {
- "x": 192,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 384,
+ "y": 256,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 256,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 512,
+ "y": 256,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 320,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 640,
+ "y": 256,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π«΄": {
"frame": {
- "x": 384,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 768,
+ "y": 256,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π€": {
"frame": {
- "x": 448,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 896,
+ "y": 256,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π€¦ββοΈ": {
"frame": {
"x": 0,
- "y": 192,
- "w": 64,
- "h": 64
+ "y": 384,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π€": {
"frame": {
- "x": 64,
- "y": 192,
- "w": 64,
- "h": 64
+ "x": 128,
+ "y": 384,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 128,
- "y": 192,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 384,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"ποΈ": {
"frame": {
- "x": 192,
- "y": 192,
- "w": 64,
- "h": 64
+ "x": 384,
+ "y": 384,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π³οΈ": {
"frame": {
- "x": 256,
- "y": 192,
- "w": 64,
- "h": 64
+ "x": 512,
+ "y": 384,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β³": {
"frame": {
- "x": 320,
- "y": 192,
- "w": 64,
- "h": 64
+ "x": 640,
+ "y": 384,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π₯": {
"frame": {
- "x": 384,
- "y": 192,
- "w": 64,
- "h": 64
+ "x": 768,
+ "y": 384,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π₯": {
"frame": {
- "x": 448,
- "y": 192,
- "w": 64,
- "h": 64
+ "x": 896,
+ "y": 384,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
"x": 0,
- "y": 256,
- "w": 64,
- "h": 64
+ "y": 512,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β’οΈ": {
"frame": {
- "x": 64,
- "y": 256,
- "w": 64,
- "h": 64
+ "x": 128,
+ "y": 512,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β οΈ": {
"frame": {
- "x": 128,
- "y": 256,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 512,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"βοΈ": {
"frame": {
- "x": 192,
- "y": 256,
- "w": 64,
- "h": 64
+ "x": 384,
+ "y": 512,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β¬οΈ": {
"frame": {
- "x": 256,
- "y": 256,
- "w": 64,
- "h": 64
+ "x": 512,
+ "y": 512,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"βοΈ": {
"frame": {
- "x": 320,
- "y": 256,
- "w": 64,
- "h": 64
+ "x": 640,
+ "y": 512,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 384,
- "y": 256,
- "w": 64,
- "h": 64
+ "x": 768,
+ "y": 512,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π₯": {
"frame": {
- "x": 448,
- "y": 256,
- "w": 64,
- "h": 64
+ "x": 896,
+ "y": 512,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β¬
οΈ": {
"frame": {
"x": 0,
- "y": 320,
- "w": 64,
- "h": 64
+ "y": 640,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π―": {
"frame": {
- "x": 64,
- "y": 320,
- "w": 64,
- "h": 64
+ "x": 128,
+ "y": 640,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β‘οΈ": {
"frame": {
- "x": 128,
- "y": 320,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 640,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π₯": {
"frame": {
- "x": 192,
- "y": 320,
- "w": 64,
- "h": 64
+ "x": 384,
+ "y": 640,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π₯": {
"frame": {
- "x": 256,
- "y": 320,
- "w": 64,
- "h": 64
+ "x": 512,
+ "y": 640,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"βοΈ": {
"frame": {
- "x": 320,
- "y": 320,
- "w": 64,
- "h": 64
+ "x": 640,
+ "y": 640,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β¬οΈ": {
"frame": {
- "x": 384,
- "y": 320,
- "w": 64,
- "h": 64
+ "x": 768,
+ "y": 640,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"βοΈ": {
"frame": {
- "x": 448,
- "y": 320,
- "w": 64,
- "h": 64
+ "x": 896,
+ "y": 640,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β€οΈ": {
"frame": {
"x": 0,
- "y": 384,
- "w": 64,
- "h": 64
+ "y": 768,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 64,
- "y": 384,
- "w": 64,
- "h": 64
+ "x": 128,
+ "y": 768,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π°": {
"frame": {
- "x": 128,
- "y": 384,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 768,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β": {
"frame": {
- "x": 192,
- "y": 384,
- "w": 64,
- "h": 64
+ "x": 384,
+ "y": 768,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β΅": {
"frame": {
- "x": 256,
- "y": 384,
- "w": 64,
- "h": 64
+ "x": 512,
+ "y": 768,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π‘": {
"frame": {
- "x": 320,
- "y": 384,
- "w": 64,
- "h": 64
+ "x": 640,
+ "y": 768,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π‘οΈ": {
"frame": {
- "x": 384,
- "y": 384,
- "w": 64,
- "h": 64
+ "x": 768,
+ "y": 768,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 448,
- "y": 384,
- "w": 64,
- "h": 64
+ "x": 896,
+ "y": 768,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
"x": 0,
- "y": 448,
- "w": 64,
- "h": 64
+ "y": 896,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"β": {
"frame": {
- "x": 64,
- "y": 448,
- "w": 64,
- "h": 64
+ "x": 128,
+ "y": 896,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 128,
- "y": 448,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 896,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
},
"π": {
"frame": {
- "x": 192,
- "y": 448,
- "w": 64,
- "h": 64
+ "x": 384,
+ "y": 896,
+ "w": 128,
+ "h": 128
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 128,
+ "h": 128
}
}
},
@@ -1206,8 +1206,8 @@
"image": "namelayer-emojis.png",
"format": "RGBA8888",
"size": {
- "w": 512,
- "h": 512
+ "w": 1024,
+ "h": 1024
},
"scale": "1"
}
diff --git a/resources/images/namelayer-emojis.png b/resources/images/namelayer-emojis.png
index 03e5276ac..869440c22 100644
Binary files a/resources/images/namelayer-emojis.png and b/resources/images/namelayer-emojis.png differ
diff --git a/resources/images/namelayer-icons.json b/resources/images/namelayer-icons.json
index 91124e703..f7cec5ee9 100644
--- a/resources/images/namelayer-icons.json
+++ b/resources/images/namelayer-icons.json
@@ -4,260 +4,260 @@
"frame": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"AllianceIconFaded.svg": {
"frame": {
- "x": 64,
+ "x": 256,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"AllianceRequestBlackIcon.svg": {
"frame": {
- "x": 128,
+ "x": 512,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"AllianceRequestWhiteIcon.svg": {
"frame": {
- "x": 192,
+ "x": 768,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"CrownIcon.svg": {
"frame": {
"x": 0,
- "y": 64,
- "w": 64,
- "h": 64
+ "y": 256,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"DisconnectedIcon.svg": {
"frame": {
- "x": 64,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 256,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"EmbargoBlackIcon.svg": {
"frame": {
- "x": 128,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 512,
+ "y": 256,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"EmbargoWhiteIcon.svg": {
"frame": {
- "x": 192,
- "y": 64,
- "w": 64,
- "h": 64
+ "x": 768,
+ "y": 256,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"NukeIconRed.svg": {
"frame": {
"x": 0,
- "y": 128,
- "w": 64,
- "h": 64
+ "y": 512,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"NukeIconWhite.svg": {
"frame": {
- "x": 64,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 256,
+ "y": 512,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"QuestionMarkIcon.svg": {
"frame": {
- "x": 128,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 512,
+ "y": 512,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"TargetIcon.svg": {
"frame": {
- "x": 192,
- "y": 128,
- "w": 64,
- "h": 64
+ "x": 768,
+ "y": 512,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
},
"TraitorIcon.svg": {
"frame": {
"x": 0,
- "y": 192,
- "w": 64,
- "h": 64
+ "y": 768,
+ "w": 256,
+ "h": 256
},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {
"x": 0,
"y": 0,
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
},
"sourceSize": {
- "w": 64,
- "h": 64
+ "w": 256,
+ "h": 256
}
}
},
@@ -266,8 +266,8 @@
"image": "namelayer-icons.png",
"format": "RGBA8888",
"size": {
- "w": 256,
- "h": 256
+ "w": 1024,
+ "h": 1024
},
"scale": "1"
}
diff --git a/resources/images/namelayer-icons.png b/resources/images/namelayer-icons.png
index 8d85df2d1..ff3902741 100644
Binary files a/resources/images/namelayer-icons.png and b/resources/images/namelayer-icons.png differ
diff --git a/scripts/build-namelayer-assets.mjs b/scripts/build-namelayer-assets.mjs
index 705338969..c409ffeff 100644
--- a/scripts/build-namelayer-assets.mjs
+++ b/scripts/build-namelayer-assets.mjs
@@ -1,8 +1,10 @@
import fs from "node:fs";
+import { createRequire } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const require = createRequire(import.meta.url);
const root = path.resolve(__dirname, "..");
const fontsDir = path.join(root, "resources", "fonts");
const imagesDir = path.join(root, "resources", "images");
@@ -19,7 +21,7 @@ const fontSourceCandidates = [
];
const glyphs = Array.from(
new Set(
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_ ΓΌΓ.[]+-=(),':!?/@#$%&\"".split(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_ \u00fc\u00dc.[]+-=(),':!?/@#$%&\"".split(
"",
),
),
@@ -46,7 +48,7 @@ fs.mkdirSync(imagesDir, { recursive: true });
const canvasApi = await loadCanvasApi();
-await buildBitmapFont();
+await buildMsdfFont();
await buildIconAtlas();
await buildEmojiAtlas();
@@ -83,8 +85,12 @@ async function loadCanvasApi() {
}
}
-async function buildBitmapFont() {
- if (!canvasApi) {
+async function buildMsdfFont() {
+ const fontPath = fontSourceCandidates
+ .map((fileName) => path.join(fontsDir, fileName))
+ .find((candidate) => fs.existsSync(candidate));
+
+ if (!fontPath) {
const fallbackXml = fs
.readFileSync(path.join(fontsDir, "round_6x6_modified.xml"), "utf8")
.replace(/face="round_6x6_modified"/g, `face="${fontFace}"`)
@@ -97,63 +103,46 @@ async function buildBitmapFont() {
return;
}
- const { createCanvas } = canvasApi;
- const cell = 64;
- const cols = 16;
- const rows = Math.ceil(glyphs.length / cols);
- const canvas = createCanvas(cols * cell, rows * cell);
- const ctx = canvas.getContext("2d");
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- ctx.fillStyle = "#ffffff";
- ctx.textBaseline = "alphabetic";
- ctx.textAlign = "left";
- ctx.font = '48px "OverpassNameLayer", Arial, sans-serif';
-
- const chars = [];
- glyphs.forEach((glyph, index) => {
- const col = index % cols;
- const row = Math.floor(index / cols);
- const x = col * cell;
- const y = row * cell;
- const metrics = ctx.measureText(glyph);
- const advance = glyph === " " ? 16 : Math.max(16, Math.ceil(metrics.width));
- const drawX = x + 4;
- const drawY = y + 48;
- if (glyph !== " ") {
- ctx.fillText(glyph, drawX, drawY);
- }
- chars.push({
- id: glyph.codePointAt(0),
- x,
- y,
- width: cell,
- height: cell,
- xadvance: advance,
- xoffset: 0,
- yoffset: 0,
- label: glyph,
- });
+ const generateBMFont = require("msdf-bmfont-xml");
+ const { textures, font } = await new Promise((resolve, reject) => {
+ generateBMFont(
+ fontPath,
+ {
+ filename: path.join(fontsDir, path.basename(fontPng, ".png")),
+ outputType: "xml",
+ charset: glyphs,
+ fontSize: 64,
+ textureSize: [2048, 2048],
+ texturePadding: 2,
+ distanceRange: 8,
+ fieldType: "msdf",
+ smartSize: true,
+ pot: true,
+ roundDecimal: 0,
+ },
+ (error, textures, font) => {
+ if (error) {
+ reject(error);
+ return;
+ }
+ resolve({ textures, font });
+ },
+ {
+ log: () => {},
+ warn: (message) => console.warn(`NameLayer MSDF font: ${message}`),
+ error: (message) => console.error(`NameLayer MSDF font: ${message}`),
+ },
+ );
});
- const xml = `
-
-
-
-
-
-
-
-${chars
- .map(
- (char) =>
- ` `,
- )
- .join("\n")}
-
-
-`;
+ for (const texture of textures) {
+ fs.writeFileSync(`${texture.filename}.png`, texture.texture);
+ }
- fs.writeFileSync(path.join(fontsDir, fontPng), canvas.toBuffer("image/png"));
+ const xml = String(font.data).replace(
+ /(]*face=")[^"]+(")/,
+ `$1${fontFace}$2`,
+ );
fs.writeFileSync(path.join(fontsDir, fontXml), xml);
}
@@ -164,7 +153,7 @@ async function buildIconAtlas() {
}
const { createCanvas, loadImage } = canvasApi;
- const cell = 64;
+ const cell = 256;
const cols = 4;
const rows = Math.ceil(iconSources.length / cols);
const canvas = createCanvas(cols * cell, rows * cell);
@@ -250,7 +239,7 @@ async function buildEmojiAtlas() {
const { createCanvas } = canvasApi;
const emojis = readEmojiTable();
- const cell = 64;
+ const cell = 128;
const cols = 8;
const rows = Math.max(1, Math.ceil(emojis.length / cols));
const canvas = createCanvas(cols * cell, rows * cell);
@@ -259,7 +248,7 @@ async function buildEmojiAtlas() {
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font =
- '48px "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif';
+ '96px "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif';
const frames = {};
emojis.forEach((emoji, index) => {
diff --git a/src/client/graphics/layers/NameLayer.ts b/src/client/graphics/layers/NameLayer.ts
index 92717bb2c..1fcf624f2 100644
--- a/src/client/graphics/layers/NameLayer.ts
+++ b/src/client/graphics/layers/NameLayer.ts
@@ -23,10 +23,9 @@ import { TransformHandler } from "../TransformHandler";
import { Layer } from "./Layer";
import { NameLayerAssets } from "./NameLayerAssets";
import {
- computeNameLayerFontSize,
computeNameLayerLayout,
+ computeNameLayerScreenMetrics,
computeNameLayerVisible,
- computeNameLayerWorldScale,
computeTraitorFlashAlpha,
replaceUnsupportedNameGlyphs,
} from "./NameLayerLayout";
@@ -41,7 +40,6 @@ interface PixiIconRender {
centered: boolean;
src?: string;
sprite?: PIXI.Sprite;
- text?: PIXI.Text;
alliance?: {
base: PIXI.Sprite;
colored: PIXI.Sprite;
@@ -55,6 +53,7 @@ class RenderInfo {
public location: Cell | null = null;
public baseSize = 1;
public fontSize = 0;
+ public iconSize = 0;
public fontColor = "";
public flagSrc = "";
public flagSprite: PIXI.Sprite | null = null;
@@ -325,11 +324,19 @@ export class NameLayer implements Layer {
}
render.baseSize = Math.max(1, Math.floor(nameLocation.size));
- const fontSize = computeNameLayerFontSize(render.baseSize);
- if (render.fontSize !== fontSize) {
- render.fontSize = fontSize;
+ const metrics = computeNameLayerScreenMetrics(
+ render.baseSize,
+ this.transformHandler.scale,
+ );
+ if (
+ render.fontSize !== metrics.fontSize ||
+ render.iconSize !== metrics.iconSize
+ ) {
+ render.fontSize = metrics.fontSize;
+ render.iconSize = metrics.iconSize;
this.updateText(render);
- this.layoutRender(render, Math.min(render.fontSize * 1.5, 48));
+ this.resizeIcons(render, render.iconSize);
+ this.layoutRender(render, render.iconSize);
}
render.location = new Cell(nameLocation.x, nameLocation.y);
const isOnScreen = this.transformHandler.isOnScreen(render.location);
@@ -348,12 +355,7 @@ export class NameLayer implements Layer {
render.location,
);
render.container.position.set(screenPos.x, screenPos.y);
- render.container.scale.set(
- computeNameLayerWorldScale(
- render.baseSize,
- this.transformHandler.scale,
- ),
- );
+ render.container.scale.set(1);
this.updateTraitorAlpha(render, now);
}
}
@@ -381,7 +383,6 @@ export class NameLayer implements Layer {
this.updateText(render);
this.updateFlag(render);
- const iconSize = Math.min(render.fontSize * 1.5, 48);
const icons = getPlayerIcons({
game: this.game,
player: render.player,
@@ -392,8 +393,8 @@ export class NameLayer implements Layer {
transitiveTargets,
});
- this.updateIcons(render, icons, iconSize);
- this.layoutRender(render, iconSize);
+ this.updateIcons(render, icons, render.iconSize);
+ this.layoutRender(render, render.iconSize);
}
private updateText(render: RenderInfo) {
@@ -506,6 +507,25 @@ export class NameLayer implements Layer {
}
}
+ private resizeIcons(render: RenderInfo, size: number) {
+ for (const iconRender of render.icons.values()) {
+ if (iconRender.sprite) {
+ iconRender.sprite.width = size;
+ iconRender.sprite.height = size;
+ }
+ if (iconRender.alliance) {
+ const refs = iconRender.alliance;
+ refs.base.width = size;
+ refs.base.height = size;
+ refs.colored.width = size;
+ refs.colored.height = size;
+ refs.questionMark.width = size;
+ refs.questionMark.height = size;
+ this.updateAllianceProgressMask(render, refs, size);
+ }
+ }
+ }
+
private updateImageIcon(
render: RenderInfo,
icon: PlayerIconDescriptor,
@@ -551,33 +571,38 @@ export class NameLayer implements Layer {
icon: PlayerIconDescriptor,
size: number,
) {
+ const text = icon.text ?? "";
+ const texture = text ? this.assets.getEmojiTexture(text) : null;
+ if (!texture) {
+ const existing = render.icons.get(icon.id);
+ if (existing) {
+ existing.container.visible = false;
+ }
+ return;
+ }
+
let iconRender = render.icons.get(icon.id);
- if (!iconRender || !iconRender.text) {
+ if (!iconRender || iconRender.src !== text || !iconRender.sprite) {
iconRender?.container.destroy({ children: true });
const container = new PIXI.Container();
container.alpha = 0.8;
- const text = new PIXI.Text({
- text: icon.text ?? "",
- style: {
- fontFamily: "sans-serif",
- fontSize: size,
- fill: "#ffffff",
- },
- });
- text.anchor.set(0.5);
- container.addChild(text);
+ const sprite = new PIXI.Sprite(texture);
+ sprite.anchor.set(0.5);
+ container.addChild(sprite);
render.container.addChild(container);
- iconRender = { container, centered: icon.center ?? false, text };
+ iconRender = {
+ container,
+ centered: icon.center ?? false,
+ src: text,
+ sprite,
+ };
render.icons.set(icon.id, iconRender);
}
iconRender.centered = icon.center ?? false;
- iconRender.text!.text = icon.text ?? "";
- iconRender.text!.style = {
- fontFamily: "sans-serif",
- fontSize: size,
- fill: "#ffffff",
- };
+ iconRender.sprite!.texture = texture;
+ iconRender.sprite!.width = size;
+ iconRender.sprite!.height = size;
iconRender.container.visible = true;
}
@@ -629,6 +654,26 @@ export class NameLayer implements Layer {
refs.colored.width = size;
refs.colored.height = size;
+ this.updateAllianceProgressMask(render, refs, size);
+
+ refs.questionMark.visible =
+ this.hasAllianceExtensionRequest(render) && questionTexture !== null;
+ if (questionTexture) {
+ refs.questionMark.texture = questionTexture;
+ refs.questionMark.width = size;
+ refs.questionMark.height = size;
+ }
+ }
+
+ private updateAllianceProgressMask(
+ render: RenderInfo,
+ refs: PixiIconRender["alliance"],
+ size: number,
+ ) {
+ if (!refs) {
+ return;
+ }
+
this.myPlayer ??= this.game.myPlayer();
const allianceView = this.myPlayer
?.alliances()
@@ -648,14 +693,14 @@ export class NameLayer implements Layer {
refs.mask
.rect(-size / 2, -size / 2 + topCut, size, Math.max(0, size - topCut))
.fill(0xffffff);
+ }
- refs.questionMark.visible =
- allianceView?.hasExtensionRequest === true && questionTexture !== null;
- if (questionTexture) {
- refs.questionMark.texture = questionTexture;
- refs.questionMark.width = size;
- refs.questionMark.height = size;
- }
+ private hasAllianceExtensionRequest(render: RenderInfo): boolean {
+ this.myPlayer ??= this.game.myPlayer();
+ return (
+ this.myPlayer?.alliances().find((a) => a.other === render.player.id())
+ ?.hasExtensionRequest === true
+ );
}
private layoutRender(render: RenderInfo, iconSize: number) {
diff --git a/src/client/graphics/layers/NameLayerAssets.ts b/src/client/graphics/layers/NameLayerAssets.ts
index 1075cd03f..be9ac4744 100644
--- a/src/client/graphics/layers/NameLayerAssets.ts
+++ b/src/client/graphics/layers/NameLayerAssets.ts
@@ -14,8 +14,11 @@ export class NameLayerAssets {
public fontReady = false;
private readonly textures = new Map();
+ private readonly atlasTextures = new Map();
+ private readonly emojiTextures = new Map();
private readonly pendingTextures = new Map>();
private readonly warnedTextureFailures = new Set();
+ private readonly warnedMissingEmojis = new Set();
private preloadPromise: Promise | null = null;
preload(): Promise {
@@ -24,6 +27,11 @@ export class NameLayerAssets {
}
getTexture(src: string): PIXI.Texture | null {
+ const atlasTexture = this.atlasTextures.get(textureKeyFromSrc(src));
+ if (atlasTexture) {
+ return atlasTexture;
+ }
+
const cached = this.textures.get(src);
if (cached) {
return cached;
@@ -49,6 +57,18 @@ export class NameLayerAssets {
return null;
}
+ getEmojiTexture(emoji: string): PIXI.Texture | null {
+ const texture = this.emojiTextures.get(emoji);
+ if (texture) {
+ return texture;
+ }
+ if (!this.warnedMissingEmojis.has(emoji)) {
+ this.warnedMissingEmojis.add(emoji);
+ console.warn(`NameLayer emoji omitted; atlas frame missing: ${emoji}`);
+ }
+ return null;
+ }
+
preloadTextures(srcs: Iterable): void {
for (const src of srcs) {
this.getTexture(src);
@@ -57,13 +77,18 @@ export class NameLayerAssets {
resetWarningsForTests(): void {
this.warnedTextureFailures.clear();
+ this.warnedMissingEmojis.clear();
}
private async loadBaseAssets(): Promise {
await this.loadFont();
await Promise.all([
- this.loadOptionalAtlas(iconAtlas, "static icon atlas"),
- this.loadOptionalAtlas(emojiAtlas, "emoji atlas"),
+ this.loadOptionalAtlas(
+ iconAtlas,
+ "static icon atlas",
+ this.atlasTextures,
+ ),
+ this.loadOptionalAtlas(emojiAtlas, "emoji atlas", this.emojiTextures),
]);
}
@@ -91,9 +116,18 @@ export class NameLayerAssets {
}
}
- private async loadOptionalAtlas(src: string, label: string): Promise {
+ private async loadOptionalAtlas(
+ src: string,
+ label: string,
+ target: Map,
+ ): Promise {
try {
- await PIXI.Assets.load(src);
+ const atlas = (await PIXI.Assets.load(src)) as {
+ textures?: Record;
+ };
+ for (const [key, texture] of Object.entries(atlas.textures ?? {})) {
+ target.set(key, texture);
+ }
} catch (error) {
console.warn(`NameLayer ${label} unavailable`, error);
}
@@ -107,3 +141,14 @@ export class NameLayerAssets {
console.warn(`NameLayer texture omitted after load failure: ${src}`, error);
}
}
+
+function textureKeyFromSrc(src: string): string {
+ const clean = src.split(/[?#]/, 1)[0] ?? src;
+ const slash = clean.lastIndexOf("/");
+ const key = slash >= 0 ? clean.slice(slash + 1) : clean;
+ try {
+ return decodeURIComponent(key);
+ } catch {
+ return key;
+ }
+}
diff --git a/src/client/graphics/layers/NameLayerLayout.ts b/src/client/graphics/layers/NameLayerLayout.ts
index 959ad0c3b..36e02a8f9 100644
--- a/src/client/graphics/layers/NameLayerLayout.ts
+++ b/src/client/graphics/layers/NameLayerLayout.ts
@@ -31,8 +31,13 @@ export interface NameLayerLayout {
rows: { iconsY: number | null; nameY: number; troopsY: number };
}
+export interface NameLayerScreenMetrics {
+ fontSize: number;
+ iconSize: number;
+}
+
const SUPPORTED_TEXT_CHARS = new Set(
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_ ΓΌΓ.[]+-=(),':!?/@#$%&\"".split(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_ \u00fc\u00dc.[]+-=(),':!?/@#$%&\"".split(
"",
),
);
@@ -74,6 +79,19 @@ export function computeNameLayerFontSize(baseSize: number): number {
return Math.max(4, Math.floor(baseSize * 0.4));
}
+export function computeNameLayerScreenMetrics(
+ baseSize: number,
+ transformScale: number,
+): NameLayerScreenMetrics {
+ const worldScale = computeNameLayerWorldScale(baseSize, transformScale);
+ const localFontSize = computeNameLayerFontSize(baseSize);
+ const localIconSize = Math.min(localFontSize * 1.5, 48);
+ return {
+ fontSize: Math.max(1, localFontSize * worldScale),
+ iconSize: Math.max(1, localIconSize * worldScale),
+ };
+}
+
export function computeNameLayerLayout({
fontSize,
iconSize,
diff --git a/tests/NameLayer.test.ts b/tests/NameLayer.test.ts
index 78c8a6192..049d64a18 100644
--- a/tests/NameLayer.test.ts
+++ b/tests/NameLayer.test.ts
@@ -4,6 +4,7 @@ import {
} from "../src/client/graphics/PlayerIcons";
import {
computeNameLayerLayout,
+ computeNameLayerScreenMetrics,
computeNameLayerWorldScale,
computeTraitorFlashAlpha,
computeTraitorFlashDurationSeconds,
@@ -102,6 +103,17 @@ describe("NameLayerLayout", () => {
expect(computeNameLayerWorldScale(20, 2)).toBeCloseTo(6);
});
+ test("computes final screen-space text and icon sizes", () => {
+ expect(computeNameLayerScreenMetrics(8, 2)).toEqual({
+ fontSize: 16,
+ iconSize: 24,
+ });
+ expect(computeNameLayerScreenMetrics(20, 2)).toEqual({
+ fontSize: 48,
+ iconSize: 72,
+ });
+ });
+
test("matches traitor flash duration thresholds and alpha extrema", () => {
expect(computeTraitorFlashDurationSeconds(156)).toBeNull();
expect(computeTraitorFlashDurationSeconds(150)).toBeCloseTo(1);