From 53d8bc32399f76dedfcf60313453ea3f9b5f4ebc Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 11:40:52 -0400 Subject: [PATCH 01/85] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20ESBuild?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .scripts/esbuild.ts | 1 + bun.lock | 355 ++++++++++++++++++++++++++++++++++++++++---- package.json | 2 +- 3 files changed, 331 insertions(+), 27 deletions(-) diff --git a/.scripts/esbuild.ts b/.scripts/esbuild.ts index f1416a36..aa04c20c 100644 --- a/.scripts/esbuild.ts +++ b/.scripts/esbuild.ts @@ -194,6 +194,7 @@ const COMMON_CONFIG: esbuild.BuildOptions = { platform: 'browser', external: ['node:*'], loader: { '.svg': 'dataurl', '.ttf': 'binary', '.css': 'text' }, + target: 'es2020', plugins: [ langPlugin({ languageFolder: 'src/lang', diff --git a/bun.lock b/bun.lock index 0a05cac1..64a7d06e 100644 --- a/bun.lock +++ b/bun.lock @@ -5,6 +5,7 @@ "": { "name": "animated_java", "dependencies": { + "block-model-renderer": "^2.1.0", "deepslate": "^0.19.2", "fflate": "^0.8.2", "generic-stream": "^3.0.1", @@ -26,7 +27,7 @@ "@typescript-eslint/parser": "^5.54.0", "blockbench-patch-manager": "^1.1.0", "book-and-quill": "^1.0.10", - "esbuild": "^0.17.10", + "esbuild": "^0.21.5", "esbuild-plugin-import-folder": "^1.0.1", "esbuild-plugin-import-glob": "^0.1.1", "esbuild-plugin-inline-image": "^0.0.9", @@ -69,57 +70,59 @@ "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-yTgnwQpFVYfvvo4SvRFB0SwrW8YjOxEoT7wfMT7Ol5v7v5LDNvSGo67aExmxOb87nQNeWPVvaGBNfQ7BXcrZ9w=="], + "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.17.19", "", { "os": "android", "cpu": "arm" }, "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.17.19", "", { "os": "android", "cpu": "arm64" }, "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.17.19", "", { "os": "android", "cpu": "x64" }, "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.17.19", "", { "os": "darwin", "cpu": "arm64" }, "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.17.19", "", { "os": "darwin", "cpu": "x64" }, "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.17.19", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.17.19", "", { "os": "freebsd", "cpu": "x64" }, "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.17.19", "", { "os": "linux", "cpu": "arm" }, "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.17.19", "", { "os": "linux", "cpu": "arm64" }, "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.17.19", "", { "os": "linux", "cpu": "ia32" }, "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.17.19", "", { "os": "linux", "cpu": "none" }, "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.17.19", "", { "os": "linux", "cpu": "none" }, "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.17.19", "", { "os": "linux", "cpu": "ppc64" }, "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.17.19", "", { "os": "linux", "cpu": "none" }, "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.17.19", "", { "os": "linux", "cpu": "s390x" }, "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.17.19", "", { "os": "linux", "cpu": "x64" }, "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.10", "", { "os": "none", "cpu": "arm64" }, "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.17.19", "", { "os": "none", "cpu": "x64" }, "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.10", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.17.19", "", { "os": "openbsd", "cpu": "x64" }, "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.10", "", { "os": "none", "cpu": "arm64" }, "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.17.19", "", { "os": "sunos", "cpu": "x64" }, "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.17.19", "", { "os": "win32", "cpu": "arm64" }, "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.17.19", "", { "os": "win32", "cpu": "ia32" }, "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.17.19", "", { "os": "win32", "cpu": "x64" }, "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], @@ -235,6 +238,56 @@ "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], + "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], + + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], + + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], + + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], + + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], + + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], + + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], + + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], + + "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], + + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], + + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], + + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], + + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], + + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], + + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], + + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], + + "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], + + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], + + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], + + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], + + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], + + "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], + + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], + + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], + + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], + "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="], "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="], @@ -261,6 +314,10 @@ "@novacbn/svelte-codejar": ["@novacbn/svelte-codejar@0.1.2", "", { "dependencies": { "codejar": "^3.5.0", "svelte": "^3.42.3" } }, "sha512-lZd6r+dbdU+zN8d4QW005QEmTT6WDKjpTXvbPIcqIWGSnbWBVoEMFPOwJ0C3PYM4hHAjb2GHF4DBywlWQogNLw=="], + "@npmcli/agent": ["@npmcli/agent@2.2.2", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og=="], + + "@npmcli/fs": ["@npmcli/fs@3.1.1", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg=="], + "@octokit/app": ["@octokit/app@16.1.0", "", { "dependencies": { "@octokit/auth-app": "^8.1.0", "@octokit/auth-unauthenticated": "^7.0.1", "@octokit/core": "^7.0.2", "@octokit/oauth-app": "^8.0.1", "@octokit/plugin-paginate-rest": "^13.0.0", "@octokit/types": "^14.0.0", "@octokit/webhooks": "^14.0.0" } }, "sha512-OdKHnm0CYLk8Setr47CATT4YnRTvWkpTYvE+B/l2B0mjszlfOIit3wqPHVslD2jfc1bD4UbO7Mzh6gjCuMZKsA=="], "@octokit/auth-app": ["@octokit/auth-app@8.1.0", "", { "dependencies": { "@octokit/auth-oauth-app": "^9.0.1", "@octokit/auth-oauth-user": "^6.0.0", "@octokit/request": "^10.0.2", "@octokit/request-error": "^7.0.0", "@octokit/types": "^14.0.0", "toad-cache": "^3.7.0", "universal-github-app-jwt": "^2.2.0", "universal-user-agent": "^7.0.0" } }, "sha512-6bWhyvLXqCSfHiqlwzn9pScLZ+Qnvh/681GR/UEEPCMIVwfpRDBw0cCzy3/t2Dq8B7W2X/8pBgmw6MOiyE0DXQ=="], @@ -311,6 +368,8 @@ "@octokit/webhooks-methods": ["@octokit/webhooks-methods@6.0.0", "", {}, "sha512-MFlzzoDJVw/GcbfzVC1RLR36QqkTLUf79vLVO3D+xn7r0QgxnFoLZgtrzxiQErAjFUOdH6fas2KeQJ1yr/qaXQ=="], + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], + "@polka/url": ["@polka/url@1.0.0-next.25", "", {}, "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ=="], "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="], @@ -473,10 +532,16 @@ "@vue/compiler-sfc": ["@vue/compiler-sfc@2.7.14", "", { "dependencies": { "@babel/parser": "^7.18.4", "postcss": "^8.4.14", "source-map": "^0.6.1" } }, "sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA=="], + "abbrev": ["abbrev@2.0.0", "", {}, "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ=="], + "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], "acorn-jsx": ["acorn-jsx@5.3.2", "", {}, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], + "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], @@ -497,8 +562,18 @@ "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + "before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], + "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="], + + "bit-twiddle": ["bit-twiddle@1.0.2", "", {}, "sha512-B9UhK0DKFZhoTFcfvAzhqsjStvGJp9vYWf3+6SNTtdSQnvIgfkHbgHrg/e4+TH71N2GDu8tpmCVoyfrL1d7ntA=="], + + "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], + + "block-model-renderer": ["block-model-renderer@2.1.0", "", { "dependencies": { "gl": "^8.1.6", "headless-three": "^1.8.0", "sharp": "^0.34.5", "skia-canvas": "^3.0.8" }, "peerDependencies": { "three": ">=0.152.0" }, "optionalPeers": ["three"] }, "sha512-XCE6vj9e3VG3k7r6i+38sJhkzFP8bD4aleKsXV65bhUu/w7c5P1GCQPCn9N4lQGO597om9raBF4DTJ45u1C8jg=="], + "blockbench-patch-manager": ["blockbench-patch-manager@1.1.0", "", { "dependencies": { "blockbench-types": "^5.1.0-beta.1", "simple-subpub": "^1.2.0", "svelte": "^5.46.3", "svelte-observable-store": "^1.0.1", "svelte-preprocess": "^6.0.3", "svelte-preprocess-esbuild": "^3.0.1" }, "peerDependencies": { "typescript": "^5" } }, "sha512-68FXezYJ3HdkVcam90r/MY8W2gS8jZeitfUz3XXnC/XyDkHJZlLr8dpFJmJrrUqUSBVRG7wweOhbs/tn+znotQ=="], "blockbench-types": ["blockbench-types@5.1.0", "", { "dependencies": { "@babel/types": "^7.20.7", "@types/dompurify": "^3.0.5", "@types/jquery": "^3.5.32", "@types/prismjs": "^1.26.0", "@types/three": "^0.129.2", "@types/tinycolor2": "^1.4.6", "dompurify": "^3.0.1", "electron": "^40.8.0", "prismjs": "^1.29.0", "tinycolor2": "^1.6.0", "typescript": "^5.8.3", "vue": "2.7.14", "wintersky": "^1.3.0" } }, "sha512-JLMHJZ+2J7aFQwSacfW4N/rvd56JRqvaBsHNH2R6sjyxkwKPuNPKYIeav/WtRXnq3dmlsEoH3rtg09s7yhe3sg=="], @@ -515,10 +590,14 @@ "braces": ["braces@3.0.2", "", { "dependencies": { "fill-range": "^7.0.1" } }, "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A=="], + "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + "buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + "cacache": ["cacache@18.0.4", "", { "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^4.0.0", "ssri": "^10.0.0", "tar": "^6.1.11", "unique-filename": "^3.0.0" } }, "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ=="], + "cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="], "cacheable-request": ["cacheable-request@7.0.4", "", { "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^6.0.1", "responselike": "^2.0.0" } }, "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg=="], @@ -533,6 +612,10 @@ "check-error": ["check-error@2.1.1", "", {}, "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw=="], + "chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + + "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], + "cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], "clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="], @@ -557,6 +640,8 @@ "console-clear": ["console-clear@1.1.1", "", {}, "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ=="], + "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "crypt": ["crypt@0.0.2", "", {}, "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow=="], @@ -573,6 +658,8 @@ "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], + "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], "deepslate": ["deepslate@0.19.2", "", { "dependencies": { "gl-matrix": "^3.3.0", "md5": "^2.3.0", "pako": "^2.0.3" } }, "sha512-sDOjpBXv5WBMmtsquJGNhOoZJKm4ra7pzzQP7FjNJHbZwoL+qlzrsfId4OU3C9WtfC6e0+2mcH+kd3KL5mjrSg=="], @@ -585,6 +672,8 @@ "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "detect-node": ["detect-node@2.1.0", "", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="], "devalue": ["devalue@5.7.1", "", {}, "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA=="], @@ -599,10 +688,14 @@ "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], + "end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="], "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + "err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], + "es-define-property": ["es-define-property@1.0.0", "", { "dependencies": { "get-intrinsic": "^1.2.4" } }, "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], @@ -611,7 +704,7 @@ "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], - "esbuild": ["esbuild@0.17.19", "", { "optionalDependencies": { "@esbuild/android-arm": "0.17.19", "@esbuild/android-arm64": "0.17.19", "@esbuild/android-x64": "0.17.19", "@esbuild/darwin-arm64": "0.17.19", "@esbuild/darwin-x64": "0.17.19", "@esbuild/freebsd-arm64": "0.17.19", "@esbuild/freebsd-x64": "0.17.19", "@esbuild/linux-arm": "0.17.19", "@esbuild/linux-arm64": "0.17.19", "@esbuild/linux-ia32": "0.17.19", "@esbuild/linux-loong64": "0.17.19", "@esbuild/linux-mips64el": "0.17.19", "@esbuild/linux-ppc64": "0.17.19", "@esbuild/linux-riscv64": "0.17.19", "@esbuild/linux-s390x": "0.17.19", "@esbuild/linux-x64": "0.17.19", "@esbuild/netbsd-x64": "0.17.19", "@esbuild/openbsd-x64": "0.17.19", "@esbuild/sunos-x64": "0.17.19", "@esbuild/win32-arm64": "0.17.19", "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw=="], + "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], "esbuild-plugin-import-folder": ["esbuild-plugin-import-folder@1.0.1", "", { "dependencies": { "eslint": "^9.38.0" } }, "sha512-vT3o+n7erSczdhTXpoL1Kuh0LCpysiEnLTMJYTgEI5MF72Rm22bJeM5AmltADBE8BM3ebG0l4+1CsDdwXoUh/A=="], @@ -651,8 +744,12 @@ "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], + "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], + "expect-type": ["expect-type@1.2.2", "", {}, "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA=="], + "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + "extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="], @@ -677,6 +774,8 @@ "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + "file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="], + "fill-range": ["fill-range@7.0.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ=="], "find-cache-dir": ["find-cache-dir@3.3.2", "", { "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" } }, "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig=="], @@ -689,12 +788,18 @@ "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], + "follow-redirects": ["follow-redirects@1.16.0", "", {}, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="], + "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], "form-data": ["form-data@2.5.2", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12", "safe-buffer": "^5.2.1" } }, "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q=="], + "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="], + "fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + "fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="], + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -709,8 +814,12 @@ "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="], + "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], + "gl": ["gl@8.1.6", "", { "dependencies": { "bindings": "^1.5.0", "bit-twiddle": "^1.0.2", "glsl-tokenizer": "^2.1.5", "nan": "^2.22.0", "node-abi": "^3.71.0", "node-gyp": "^10.2.0", "prebuild-install": "^7.1.2" } }, "sha512-BcvkgW+jWiX2SjTddgq4lOfkFmeiKE/n1N3zFnq/JlSwemIvQvH1rLURz5oMdfp4ZT5bzseuIOE608zQI0DRYA=="], + "gl-matrix": ["gl-matrix@3.4.3", "", {}, "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="], "glob": ["glob@11.0.3", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.0.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA=="], @@ -725,6 +834,8 @@ "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], + "glsl-tokenizer": ["glsl-tokenizer@2.1.5", "", { "dependencies": { "through2": "^0.6.3" } }, "sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA=="], + "gopd": ["gopd@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.1.3" } }, "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="], "got": ["got@11.8.6", "", { "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.2", "decompress-response": "^6.0.0", "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" } }, "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g=="], @@ -743,20 +854,38 @@ "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + "headless-three": ["headless-three@1.8.0", "", { "dependencies": { "gl": "^8.1.6", "sharp": "^0.34.5", "three": "0.162.0" } }, "sha512-xI9UOW4F0HVRIeWxVmqTdNMUyxjsotrlJjCdHNisX1E/OTAPZCCYfvDsXqfKPcaBzbWmIEXrzaeifCRVHR/EWQ=="], + "http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="], "http-parser-js": ["http-parser-js@0.5.8", "", {}, "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q=="], + "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + "http2-wrapper": ["http2-wrapper@1.0.3", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "idb": ["idb@7.1.1", "", {}, "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="], + "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + "ignore": ["ignore@5.3.1", "", {}, "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], + "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + + "ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="], + "is-buffer": ["is-buffer@1.1.6", "", {}, "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="], "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], @@ -765,10 +894,14 @@ "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + "is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="], + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], "is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="], + "isarray": ["isarray@0.0.1", "", {}, "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="], + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "jackspeak": ["jackspeak@4.1.1", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" } }, "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ=="], @@ -823,6 +956,8 @@ "make-dir": ["make-dir@3.1.0", "", { "dependencies": { "semver": "^6.0.0" } }, "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw=="], + "make-fetch-happen": ["make-fetch-happen@13.0.1", "", { "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", "http-cache-semantics": "^4.1.1", "is-lambda": "^1.0.1", "minipass": "^7.0.2", "minipass-fetch": "^3.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "proc-log": "^4.2.0", "promise-retry": "^2.0.1", "ssri": "^10.0.0" } }, "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA=="], + "marked": ["marked@4.3.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A=="], "marked-gfm-heading-id": ["marked-gfm-heading-id@3.1.3", "", { "dependencies": { "github-slugger": "^2.0.0" } }, "sha512-A0cRU4PCueX/5m8VE4mT8uTQ36l3xMYRojz3Eqnk4BmUFZ0T+9Xhn2KvHcANP4qbhfOeuMrWJCTQbASIBR5xeg=="], @@ -847,8 +982,26 @@ "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + "minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], + + "minipass-fetch": ["minipass-fetch@3.0.5", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg=="], + + "minipass-flush": ["minipass-flush@1.0.7", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA=="], + + "minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], + + "minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="], + + "minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + + "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], + "molangjs": ["molangjs@1.6.4", "", {}, "sha512-Evi2MbMcfDFwcG4HVjsX4MAj+jc7itlp1Ncd+sQ+4jel7N1pADUJpiWEdg3d9IIK+0RQwJw7EE3GrM+ERWbcQA=="], "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="], @@ -857,16 +1010,28 @@ "ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], + "nan": ["nan@2.27.0", "", {}, "sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ=="], + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="], + "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], "natural-compare-lite": ["natural-compare-lite@1.4.0", "", {}, "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g=="], + "negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], + + "node-abi": ["node-abi@3.92.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ=="], + "node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" } }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], + "node-gyp": ["node-gyp@10.3.1", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "glob": "^10.3.10", "graceful-fs": "^4.2.6", "make-fetch-happen": "^13.0.0", "nopt": "^7.0.0", "proc-log": "^4.1.0", "semver": "^7.3.5", "tar": "^6.2.1", "which": "^4.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ=="], + "node-modules-vscode-problems-patch": ["node-modules-vscode-problems-patch@1.0.9", "", { "dependencies": { "esbuild": "^0.25.0", "glob": "^11.0.1" }, "bin": { "node-modules-vscode-problems-patch": "dist/index.js" } }, "sha512-PYS8ozhWFbPvksJBIKbWrdrKOD2e+MZaxl75amn/oaVAzObgmGQeYnk4VT5tT/d5KHhWiuUwzWWSgbQ57GVMfA=="], + "nopt": ["nopt@7.2.1", "", { "dependencies": { "abbrev": "^2.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w=="], + "normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="], "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], @@ -883,6 +1048,8 @@ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + "p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="], + "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], @@ -891,6 +1058,8 @@ "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + "parenthesis": ["parenthesis@3.1.8", "", {}, "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw=="], + "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], @@ -923,14 +1092,20 @@ "postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], + "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], "prettier": ["prettier@3.8.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q=="], "prismjs": ["prismjs@1.29.0", "", {}, "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="], + "proc-log": ["proc-log@4.2.0", "", {}, "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA=="], + "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], + "promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], + "protobufjs": ["protobufjs@6.11.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/long": "^4.0.1", "@types/node": ">=13.7.0", "long": "^4.0.0" }, "bin": { "pbjs": "bin/pbjs", "pbts": "bin/pbts" } }, "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw=="], "pump": ["pump@3.0.0", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="], @@ -941,6 +1116,10 @@ "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], + "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], + + "readable-stream": ["readable-stream@1.0.34", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg=="], + "request-progress": ["request-progress@3.0.0", "", { "dependencies": { "throttleit": "^1.0.0" } }, "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg=="], "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], @@ -951,6 +1130,8 @@ "responselike": ["responselike@2.0.1", "", { "dependencies": { "lowercase-keys": "^2.0.0" } }, "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw=="], + "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], + "reusify": ["reusify@1.0.4", "", {}, "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="], "roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="], @@ -963,6 +1144,8 @@ "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + "semiver": ["semiver@1.1.0", "", {}, "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg=="], "semver": ["semver@7.6.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w=="], @@ -971,6 +1154,8 @@ "serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], + "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], @@ -979,28 +1164,46 @@ "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="], + + "simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="], + "simple-subpub": ["simple-subpub@1.2.0", "", {}, "sha512-cN0RBYgIydi0X+3oDYaEMY7/IfdopJjJZriLxXIiHDdsKW3eSVxDpyojAyBY5wWw0P8Z0NLOP93h0kCaeT/TuA=="], "sirv": ["sirv@1.0.19", "", { "dependencies": { "@polka/url": "^1.0.0-next.20", "mrmime": "^1.0.0", "totalist": "^1.0.0" } }, "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ=="], "sirv-cli": ["sirv-cli@1.0.14", "", { "dependencies": { "console-clear": "^1.1.0", "get-port": "^3.2.0", "kleur": "^3.0.0", "local-access": "^1.0.1", "sade": "^1.6.0", "semiver": "^1.0.0", "sirv": "^1.0.13", "tinydate": "^1.0.0" }, "bin": { "sirv": "bin.js" } }, "sha512-yyUTNr984ANKDloqepkYbBSqvx3buwYg2sQKPWjSU+IBia5loaoka2If8N9CMwt8AfP179cdEl7kYJ//iWJHjQ=="], + "skia-canvas": ["skia-canvas@3.0.8", "", { "dependencies": { "detect-libc": "^2.1.1", "follow-redirects": "^1.15.11", "https-proxy-agent": "^7.0.6", "string-split-by": "^1.0.0" } }, "sha512-FSYKxp8Ng2vOeeOBiyPhnn6ui6FirPJXMyjk4PKl8N/OWzVrkMawUgY9zubIWHMdYtyWFn0gfX3QlRwg6HBmdg=="], + "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], + "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], + + "socks": ["socks@2.8.9", "", { "dependencies": { "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" } }, "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw=="], + + "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + "ssri": ["ssri@10.0.6", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ=="], + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], "std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="], + "string-split-by": ["string-split-by@1.0.0", "", { "dependencies": { "parenthesis": "^3.1.5" } }, "sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A=="], + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="], + "strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -1035,10 +1238,18 @@ "svelte-preprocess-esbuild": ["svelte-preprocess-esbuild@3.0.1", "", {}, "sha512-OV4P/onki7hfuzIpYOd92TT0JSm4y67PvkAAM7RigLd869VEvNh2f6J+ewrEqAgTnZzVQcOWzuaU4hPISNPFpA=="], - "three": ["three@0.134.0", "", {}, "sha512-LbBerg7GaSPjYtTOnu41AMp7tV6efUNR3p4Wk5NzkSsNTBuA5mDGOfwwZL1jhhVMLx9V20HolIUo0+U3AXehbg=="], + "tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], + + "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="], + + "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], + + "three": ["three@0.162.0", "", {}, "sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ=="], "throttleit": ["throttleit@1.0.1", "", {}, "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ=="], + "through2": ["through2@0.6.5", "", { "dependencies": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" } }, "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg=="], + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], "tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="], @@ -1071,6 +1282,8 @@ "tsutils": ["tsutils@3.21.0", "", { "dependencies": { "tslib": "^1.8.1" } }, "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA=="], + "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="], + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], @@ -1081,6 +1294,10 @@ "undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "unique-filename": ["unique-filename@3.0.0", "", { "dependencies": { "unique-slug": "^4.0.0" } }, "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g=="], + + "unique-slug": ["unique-slug@4.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ=="], + "universal-github-app-jwt": ["universal-github-app-jwt@2.2.2", "", {}, "sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw=="], "universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="], @@ -1121,8 +1338,12 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="], "yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], @@ -1139,6 +1360,8 @@ "@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@emnapi/runtime/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@eslint/config-array/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], @@ -1215,6 +1438,10 @@ "@novacbn/svelte-codejar/svelte": ["svelte@3.59.2", "", {}, "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA=="], + "@npmcli/agent/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "@npmcli/fs/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + "@octokit/core/@octokit/types": ["@octokit/types@15.0.0", "", { "dependencies": { "@octokit/openapi-types": "^26.0.0" } }, "sha512-8o6yDfmoGJUIeR9OfYU0/TUJTnMPG2r68+1yEdUeG2Fdqpj8Qetg0ziKIgcBm0RW/j29H41WP37CYCEhp6GoHQ=="], "@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@15.0.0", "", { "dependencies": { "@octokit/openapi-types": "^26.0.0" } }, "sha512-8o6yDfmoGJUIeR9OfYU0/TUJTnMPG2r68+1yEdUeG2Fdqpj8Qetg0ziKIgcBm0RW/j29H41WP37CYCEhp6GoHQ=="], @@ -1249,12 +1476,20 @@ "@vue/compiler-sfc/postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], + "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "blockbench-patch-manager/svelte": ["svelte@5.55.4", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.4", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-q8DFohk6vUswSng95IZb9nzWJnbINZsK7OiM1snAa3qCjJBL0ZQpvMyAaVXjUukdM75J/m8UE8xwqat8Ors/zQ=="], "blockbench-types/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "book-and-quill/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + "cacache/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], + + "cacache/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], + + "cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + "chai/loupe": ["loupe@3.1.2", "", {}, "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg=="], "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -1291,8 +1526,14 @@ "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "glob/minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], + "http-proxy-agent/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "https-proxy-agent/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "is-reference/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], "magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], @@ -1301,6 +1542,22 @@ "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "node-abi/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "node-gyp/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], + + "node-gyp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "node-gyp/which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="], + "node-modules-vscode-problems-patch/esbuild": ["esbuild@0.25.10", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.10", "@esbuild/android-arm": "0.25.10", "@esbuild/android-arm64": "0.25.10", "@esbuild/android-x64": "0.25.10", "@esbuild/darwin-arm64": "0.25.10", "@esbuild/darwin-x64": "0.25.10", "@esbuild/freebsd-arm64": "0.25.10", "@esbuild/freebsd-x64": "0.25.10", "@esbuild/linux-arm": "0.25.10", "@esbuild/linux-arm64": "0.25.10", "@esbuild/linux-ia32": "0.25.10", "@esbuild/linux-loong64": "0.25.10", "@esbuild/linux-mips64el": "0.25.10", "@esbuild/linux-ppc64": "0.25.10", "@esbuild/linux-riscv64": "0.25.10", "@esbuild/linux-s390x": "0.25.10", "@esbuild/linux-x64": "0.25.10", "@esbuild/netbsd-arm64": "0.25.10", "@esbuild/netbsd-x64": "0.25.10", "@esbuild/openbsd-arm64": "0.25.10", "@esbuild/openbsd-x64": "0.25.10", "@esbuild/openharmony-arm64": "0.25.10", "@esbuild/sunos-x64": "0.25.10", "@esbuild/win32-arm64": "0.25.10", "@esbuild/win32-ia32": "0.25.10", "@esbuild/win32-x64": "0.25.10" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ=="], "periscopic/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], @@ -1309,8 +1566,14 @@ "protobufjs/@types/node": ["@types/node@20.12.12", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw=="], + "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], + "rollup/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + "sharp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "socks-proxy-agent/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -1323,6 +1586,12 @@ "svelte-patching-tools/svelte": ["svelte@5.55.4", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.4", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-q8DFohk6vUswSng95IZb9nzWJnbINZsK7OiM1snAa3qCjJBL0ZQpvMyAaVXjUukdM75J/m8UE8xwqat8Ors/zQ=="], + "tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], + + "tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], + + "tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.45.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/type-utils": "8.45.0", "@typescript-eslint/utils": "8.45.0", "@typescript-eslint/visitor-keys": "8.45.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" } }, "sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg=="], "typescript-eslint/@typescript-eslint/parser": ["@typescript-eslint/parser@8.45.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/types": "8.45.0", "@typescript-eslint/typescript-estree": "8.45.0", "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4" } }, "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ=="], @@ -1339,6 +1608,8 @@ "vitest/magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], + "wintersky/three": ["three@0.134.0", "", {}, "sha512-LbBerg7GaSPjYtTOnu41AMp7tV6efUNR3p4Wk5NzkSsNTBuA5mDGOfwwZL1jhhVMLx9V20HolIUo0+U3AXehbg=="], + "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "wrap-ansi/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], @@ -1373,12 +1644,20 @@ "@vitest/snapshot/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + "bl/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + "blockbench-patch-manager/svelte/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], "blockbench-patch-manager/svelte/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "book-and-quill/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + "cacache/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], + + "cacache/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "cacache/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "electron/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], @@ -1405,6 +1684,8 @@ "esbuild-plugin-import-folder/eslint/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + "esbuild-plugin-inline-worker/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-yTgnwQpFVYfvvo4SvRFB0SwrW8YjOxEoT7wfMT7Ol5v7v5LDNvSGo67aExmxOb87nQNeWPVvaGBNfQ7BXcrZ9w=="], + "esbuild-plugin-inline-worker/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.3", "", { "os": "android", "cpu": "arm" }, "sha512-bviJOLMgurLJtF1/mAoJLxDZDL6oU5/ztMHnJQRejbJrSc9FFu0QoUoFhvi6qSKJEw9y5oGyvr9fuDtzJ30rNQ=="], "esbuild-plugin-inline-worker/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.3", "", { "os": "android", "cpu": "arm64" }, "sha512-c+ty9necz3zB1Y+d/N+mC6KVVkGUUOcm4ZmT5i/Fk5arOaY3i6CA3P5wo/7+XzV8cb4GrI/Zjp8NuOQ9Lfsosw=="], @@ -1451,6 +1732,18 @@ "eslint/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "http-proxy-agent/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "https-proxy-agent/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "node-gyp/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], + + "node-gyp/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "node-gyp/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + + "node-gyp/which/isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="], + "node-modules-vscode-problems-patch/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.10", "", { "os": "aix", "cpu": "ppc64" }, "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw=="], "node-modules-vscode-problems-patch/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.10", "", { "os": "android", "cpu": "arm" }, "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w=="], @@ -1499,6 +1792,8 @@ "pkg-dir/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "socks-proxy-agent/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], @@ -1517,6 +1812,8 @@ "svelte-patching-tools/svelte/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + "tar-stream/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.45.0", "", { "dependencies": { "@typescript-eslint/types": "8.45.0", "@typescript-eslint/visitor-keys": "8.45.0" } }, "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA=="], @@ -1607,6 +1904,8 @@ "@grpc/grpc-js/@grpc/proto-loader/yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + "cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + "esbuild-plugin-import-folder/eslint/@eslint/config-array/@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="], "esbuild-plugin-import-folder/eslint/@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], @@ -1615,6 +1914,10 @@ "esbuild-plugin-import-folder/eslint/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "node-gyp/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "node-gyp/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + "pkg-dir/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], "svelte-multiselect/svelte/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], diff --git a/package.json b/package.json index 90fe060f..9c117905 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "@typescript-eslint/parser": "^5.54.0", "blockbench-patch-manager": "^1.1.0", "book-and-quill": "^1.0.10", - "esbuild": "^0.17.10", + "esbuild": "^0.21.5", "esbuild-plugin-import-folder": "^1.0.1", "esbuild-plugin-import-glob": "^0.1.1", "esbuild-plugin-inline-image": "^0.0.9", From 38d5a769efd3d5d1c51cfbcd04df7f1786367551 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 11:43:01 -0400 Subject: [PATCH 02/85] =?UTF-8?q?=F0=9F=90=9B=20Add=20Blueprint=20ID=20to?= =?UTF-8?q?=20anim=20objective=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/systems/datapackCompiler/1.20.4/main.mcb | 40 ++++++++++---------- src/systems/datapackCompiler/1.20.5/main.mcb | 40 ++++++++++---------- src/systems/datapackCompiler/1.21.0/main.mcb | 40 ++++++++++---------- src/systems/datapackCompiler/1.21.2/main.mcb | 40 ++++++++++---------- src/systems/datapackCompiler/1.21.4/main.mcb | 40 ++++++++++---------- src/systems/datapackCompiler/1.21.5/main.mcb | 40 ++++++++++---------- src/systems/datapackCompiler/objectives.ts | 5 ++- 7 files changed, 124 insertions(+), 121 deletions(-) diff --git a/src/systems/datapackCompiler/1.20.4/main.mcb b/src/systems/datapackCompiler/1.20.4/main.mcb index 6586e159..3654e8c7 100644 --- a/src/systems/datapackCompiler/1.20.4/main.mcb +++ b/src/systems/datapackCompiler/1.20.4/main.mcb @@ -12,7 +12,7 @@ function on_load { } <%% animations.forEach(animation => { - emit(`scoreboard objectives add ${OBJECTIVES.FRAME(animation.storage_name)} dummy`) + emit(`scoreboard objectives add ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)} dummy`) }) %%> } @@ -22,7 +22,7 @@ IF (has_animations) { function remove_animation_objectives { <%% animations.forEach(animation => { - emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(animation.storage_name)}`) + emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)}`) }) %%> tellraw @a <%TELLRAW.UNINSTALL()%> @@ -198,7 +198,7 @@ IF (has_animations) { data_manager prep read tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -211,7 +211,7 @@ IF (has_animations) { function <%blueprint_id%>/animations/pause_all tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -223,7 +223,7 @@ IF (has_animations) { data_manager prep read function <%blueprint_id%>/animations/pause_all - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -245,11 +245,11 @@ IF (has_animations) { debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> data_manager prep read - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 data remove storage <%temp_storage%> args - execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } function set_frame { @@ -259,7 +259,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/set_frame with storage <%temp_storage%> args } @@ -270,7 +270,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args } @@ -284,7 +284,7 @@ IF (has_animations) { tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> $scoreboard players set @s <%OBJECTIVES.TWEEN_DURATION()%> $(duration) - $scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(to_frame) + $scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(to_frame) scoreboard players operation #this <%OBJECTIVES.I()%> = @s <%OBJECTIVES.TWEEN_DURATION()%> tag @s add <%TAGS.TRANSFORMS_ONLY()%> @@ -304,45 +304,45 @@ IF (has_animations) { # Animation logic IF (animation.loop_mode === 'loop' && animation.loop_delay === 0) { # Makes sure function keyframes in the last frame of the animation are activated. - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches -1 run \ + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches -1 run \ block function_keyframe_loop_patch { function ./frames/last_frame_effects with storage <%temp_storage%> entry.data.uuids_by_name - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } } data remove storage <%temp_storage%> args execute store result storage <%temp_storage%> args.frame int 1 run \ - scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> function ./apply_frame with storage <%temp_storage%> args IF (animation.loop_mode === 'loop') { # Loop the animation back to the start once it reaches the last frame. # If loop_delay is 0, the animation will loop instantly, otherwise, it will wait for the specified amount of ticks. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-2 + animation.loop_delay%>.. \ run return run \ - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> } ELSE IF (animation.loop_mode === 'hold') { # Pause the animation at the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%>.. \ run return run \ function ../pause } ELSE IF (animation.loop_mode === 'once') { # Stop the animation once it reaches the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%> \ run return run block loop_mode_stop { - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> tag @s remove <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> } } - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } IF (use_storage_for_animation) { diff --git a/src/systems/datapackCompiler/1.20.5/main.mcb b/src/systems/datapackCompiler/1.20.5/main.mcb index 2a4ca6e0..540324c9 100644 --- a/src/systems/datapackCompiler/1.20.5/main.mcb +++ b/src/systems/datapackCompiler/1.20.5/main.mcb @@ -15,7 +15,7 @@ function on_load { } <%% animations.forEach(animation => { - emit(`scoreboard objectives add ${OBJECTIVES.FRAME(animation.storage_name)} dummy`) + emit(`scoreboard objectives add ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)} dummy`) }) %%> } @@ -25,7 +25,7 @@ IF (has_animations) { function remove_animation_objectives { <%% animations.forEach(animation => { - emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(animation.storage_name)}`) + emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)}`) }) %%> tellraw @a <%TELLRAW.UNINSTALL()%> @@ -201,7 +201,7 @@ IF (has_animations) { data_manager prep read tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -214,7 +214,7 @@ IF (has_animations) { function <%blueprint_id%>/animations/pause_all tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -226,7 +226,7 @@ IF (has_animations) { data_manager prep read function <%blueprint_id%>/animations/pause_all - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -248,11 +248,11 @@ IF (has_animations) { debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> data_manager prep read - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 data remove storage <%temp_storage%> args - execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } function set_frame { @@ -262,7 +262,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/set_frame with storage <%temp_storage%> args } @@ -273,7 +273,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args } @@ -287,7 +287,7 @@ IF (has_animations) { tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> $scoreboard players set @s <%OBJECTIVES.TWEEN_DURATION()%> $(duration) - $scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(to_frame) + $scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(to_frame) scoreboard players operation #this <%OBJECTIVES.I()%> = @s <%OBJECTIVES.TWEEN_DURATION()%> tag @s add <%TAGS.TRANSFORMS_ONLY()%> @@ -307,45 +307,45 @@ IF (has_animations) { # Animation logic IF (animation.loop_mode === 'loop' && animation.loop_delay === 0) { # Makes sure function keyframes in the last frame of the animation are activated. - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches -1 run \ + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches -1 run \ block function_keyframe_loop_patch { function ./frames/last_frame_effects with storage <%temp_storage%> entry.data.uuids_by_name - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } } data remove storage <%temp_storage%> args execute store result storage <%temp_storage%> args.frame int 1 run \ - scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> function ./apply_frame with storage <%temp_storage%> args IF (animation.loop_mode === 'loop') { # Loop the animation back to the start once it reaches the last frame. # If loop_delay is 0, the animation will loop instantly, otherwise, it will wait for the specified amount of ticks. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-2 + animation.loop_delay%>.. \ run return run \ - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> } ELSE IF (animation.loop_mode === 'hold') { # Pause the animation at the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%>.. \ run return run \ function ../pause } ELSE IF (animation.loop_mode === 'once') { # Stop the animation once it reaches the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%> \ run return run block loop_mode_stop { - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> tag @s remove <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> } } - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } IF (use_storage_for_animation) { diff --git a/src/systems/datapackCompiler/1.21.0/main.mcb b/src/systems/datapackCompiler/1.21.0/main.mcb index d5048c81..9dbef69c 100644 --- a/src/systems/datapackCompiler/1.21.0/main.mcb +++ b/src/systems/datapackCompiler/1.21.0/main.mcb @@ -16,7 +16,7 @@ function on_load { } <%% animations.forEach(animation => { - emit(`scoreboard objectives add ${OBJECTIVES.FRAME(animation.storage_name)} dummy`) + emit(`scoreboard objectives add ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)} dummy`) }) %%> } @@ -26,7 +26,7 @@ IF (has_animations) { function remove_animation_objectives { <%% animations.forEach(animation => { - emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(animation.storage_name)}`) + emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)}`) }) %%> tellraw @a <%TELLRAW.UNINSTALL()%> @@ -202,7 +202,7 @@ IF (has_animations) { data_manager prep read tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -215,7 +215,7 @@ IF (has_animations) { function <%blueprint_id%>/animations/pause_all tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -227,7 +227,7 @@ IF (has_animations) { data_manager prep read function <%blueprint_id%>/animations/pause_all - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -249,11 +249,11 @@ IF (has_animations) { debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> data_manager prep read - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 data remove storage <%temp_storage%> args - execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } function set_frame { @@ -263,7 +263,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/set_frame with storage <%temp_storage%> args } @@ -274,7 +274,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args } @@ -288,7 +288,7 @@ IF (has_animations) { tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> $scoreboard players set @s <%OBJECTIVES.TWEEN_DURATION()%> $(duration) - $scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(to_frame) + $scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(to_frame) scoreboard players operation #this <%OBJECTIVES.I()%> = @s <%OBJECTIVES.TWEEN_DURATION()%> tag @s add <%TAGS.TRANSFORMS_ONLY()%> @@ -308,45 +308,45 @@ IF (has_animations) { # Animation logic IF (animation.loop_mode === 'loop' && animation.loop_delay === 0) { # Makes sure function keyframes in the last frame of the animation are activated. - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches -1 run \ + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches -1 run \ block function_keyframe_loop_patch { function ./frames/last_frame_effects with storage <%temp_storage%> entry.data.uuids_by_name - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } } data remove storage <%temp_storage%> args execute store result storage <%temp_storage%> args.frame int 1 run \ - scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> function ./apply_frame with storage <%temp_storage%> args IF (animation.loop_mode === 'loop') { # Loop the animation back to the start once it reaches the last frame. # If loop_delay is 0, the animation will loop instantly, otherwise, it will wait for the specified amount of ticks. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-2 + animation.loop_delay%>.. \ run return run \ - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> } ELSE IF (animation.loop_mode === 'hold') { # Pause the animation at the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%>.. \ run return run \ function ../pause } ELSE IF (animation.loop_mode === 'once') { # Stop the animation once it reaches the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%> \ run return run block loop_mode_stop { - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> tag @s remove <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> } } - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } IF (use_storage_for_animation) { diff --git a/src/systems/datapackCompiler/1.21.2/main.mcb b/src/systems/datapackCompiler/1.21.2/main.mcb index 92252b33..09853d82 100644 --- a/src/systems/datapackCompiler/1.21.2/main.mcb +++ b/src/systems/datapackCompiler/1.21.2/main.mcb @@ -15,7 +15,7 @@ function on_load { } <%% animations.forEach(animation => { - emit(`scoreboard objectives add ${OBJECTIVES.FRAME(animation.storage_name)} dummy`) + emit(`scoreboard objectives add ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)} dummy`) }) %%> } @@ -25,7 +25,7 @@ IF (has_animations) { function remove_animation_objectives { <%% animations.forEach(animation => { - emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(animation.storage_name)}`) + emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)}`) }) %%> tellraw @a <%TELLRAW.UNINSTALL()%> @@ -201,7 +201,7 @@ IF (has_animations) { data_manager prep read tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -214,7 +214,7 @@ IF (has_animations) { function <%blueprint_id%>/animations/pause_all tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -226,7 +226,7 @@ IF (has_animations) { data_manager prep read function <%blueprint_id%>/animations/pause_all - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -248,11 +248,11 @@ IF (has_animations) { debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> data_manager prep read - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 data remove storage <%temp_storage%> args - execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } function set_frame { @@ -262,7 +262,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/set_frame with storage <%temp_storage%> args } @@ -273,7 +273,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args } @@ -287,7 +287,7 @@ IF (has_animations) { tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> $scoreboard players set @s <%OBJECTIVES.TWEEN_DURATION()%> $(duration) - $scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(to_frame) + $scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(to_frame) scoreboard players operation #this <%OBJECTIVES.I()%> = @s <%OBJECTIVES.TWEEN_DURATION()%> tag @s add <%TAGS.TRANSFORMS_ONLY()%> @@ -307,45 +307,45 @@ IF (has_animations) { # Animation logic IF (animation.loop_mode === 'loop' && animation.loop_delay === 0) { # Makes sure function keyframes in the last frame of the animation are activated. - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches -1 run \ + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches -1 run \ block function_keyframe_loop_patch { function ./frames/last_frame_effects with storage <%temp_storage%> entry.data.uuids_by_name - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } } data remove storage <%temp_storage%> args execute store result storage <%temp_storage%> args.frame int 1 run \ - scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> function ./apply_frame with storage <%temp_storage%> args IF (animation.loop_mode === 'loop') { # Loop the animation back to the start once it reaches the last frame. # If loop_delay is 0, the animation will loop instantly, otherwise, it will wait for the specified amount of ticks. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-2 + animation.loop_delay%>.. \ run return run \ - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> } ELSE IF (animation.loop_mode === 'hold') { # Pause the animation at the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%>.. \ run return run \ function ../pause } ELSE IF (animation.loop_mode === 'once') { # Stop the animation once it reaches the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%> \ run return run block loop_mode_stop { - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> tag @s remove <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> } } - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } IF (use_storage_for_animation) { diff --git a/src/systems/datapackCompiler/1.21.4/main.mcb b/src/systems/datapackCompiler/1.21.4/main.mcb index 2da1285d..05a5b18d 100644 --- a/src/systems/datapackCompiler/1.21.4/main.mcb +++ b/src/systems/datapackCompiler/1.21.4/main.mcb @@ -16,7 +16,7 @@ function on_load { } <%% animations.forEach(animation => { - emit(`scoreboard objectives add ${OBJECTIVES.FRAME(animation.storage_name)} dummy`) + emit(`scoreboard objectives add ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)} dummy`) }) %%> } @@ -26,7 +26,7 @@ IF (has_animations) { function remove_animation_objectives { <%% animations.forEach(animation => { - emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(animation.storage_name)}`) + emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)}`) }) %%> tellraw @a <%TELLRAW.UNINSTALL()%> @@ -249,7 +249,7 @@ IF (has_animations) { data_manager prep read tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -262,7 +262,7 @@ IF (has_animations) { function <%blueprint_id%>/animations/pause_all tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -274,7 +274,7 @@ IF (has_animations) { data_manager prep read function <%blueprint_id%>/animations/pause_all - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -296,11 +296,11 @@ IF (has_animations) { debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> data_manager prep read - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 data remove storage <%temp_storage%> args - execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } function set_frame { @@ -310,7 +310,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/set_frame with storage <%temp_storage%> args } @@ -321,7 +321,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args } @@ -335,7 +335,7 @@ IF (has_animations) { tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> $scoreboard players set @s <%OBJECTIVES.TWEEN_DURATION()%> $(duration) - $scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(to_frame) + $scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(to_frame) scoreboard players operation #this <%OBJECTIVES.I()%> = @s <%OBJECTIVES.TWEEN_DURATION()%> tag @s add <%TAGS.TRANSFORMS_ONLY()%> @@ -377,45 +377,45 @@ IF (has_animations) { # Animation logic IF (animation.loop_mode === 'loop' && animation.loop_delay === 0) { # Makes sure function keyframes in the last frame of the animation are activated. - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches -1 run \ + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches -1 run \ block function_keyframe_loop_patch { function ./frames/last_frame_effects with storage <%temp_storage%> entry.data.uuids_by_name - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } } data remove storage <%temp_storage%> args execute store result storage <%temp_storage%> args.frame int 1 run \ - scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> function ./apply_frame with storage <%temp_storage%> args IF (animation.loop_mode === 'loop') { # Loop the animation back to the start once it reaches the last frame. # If loop_delay is 0, the animation will loop instantly, otherwise, it will wait for the specified amount of ticks. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-2 + animation.loop_delay%>.. \ run return run \ - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> } ELSE IF (animation.loop_mode === 'hold') { # Pause the animation at the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%>.. \ run return run \ function ../pause } ELSE IF (animation.loop_mode === 'once') { # Stop the animation once it reaches the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%> \ run return run block loop_mode_stop { - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> tag @s remove <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> } } - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } IF (use_storage_for_animation) { diff --git a/src/systems/datapackCompiler/1.21.5/main.mcb b/src/systems/datapackCompiler/1.21.5/main.mcb index 47b1f078..8e7e5a03 100644 --- a/src/systems/datapackCompiler/1.21.5/main.mcb +++ b/src/systems/datapackCompiler/1.21.5/main.mcb @@ -15,7 +15,7 @@ function on_load { } <%% animations.forEach(animation => { - emit(`scoreboard objectives add ${OBJECTIVES.FRAME(animation.storage_name)} dummy`) + emit(`scoreboard objectives add ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)} dummy`) }) %%> } @@ -25,7 +25,7 @@ IF (has_animations) { function remove_animation_objectives { <%% animations.forEach(animation => { - emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(animation.storage_name)}`) + emit(`scoreboard objectives remove ${OBJECTIVES.FRAME(blueprint_id, animation.storage_name)}`) }) %%> tellraw @a <%TELLRAW.UNINSTALL()%> @@ -248,7 +248,7 @@ IF (has_animations) { data_manager prep read tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -261,7 +261,7 @@ IF (has_animations) { function <%blueprint_id%>/animations/pause_all tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -273,7 +273,7 @@ IF (has_animations) { data_manager prep read function <%blueprint_id%>/animations/pause_all - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> @@ -295,11 +295,11 @@ IF (has_animations) { debug assert executed_as_root_entity <%TAGS.PROJECT_ROOT(blueprint_id)%> data_manager prep read - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches <%animation.duration%>.. run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 data remove storage <%temp_storage%> args - execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } function set_frame { @@ -309,7 +309,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/set_frame with storage <%temp_storage%> args } @@ -320,7 +320,7 @@ IF (has_animations) { data_manager prep read data remove storage <%temp_storage%> args - $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(frame) + $execute store result storage <%temp_storage%> args.frame int 1 run scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(frame) execute at @s run function ./zzz/apply_frame with storage <%temp_storage%> args } @@ -334,7 +334,7 @@ IF (has_animations) { tag @s add <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> $scoreboard players set @s <%OBJECTIVES.TWEEN_DURATION()%> $(duration) - $scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> $(to_frame) + $scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> $(to_frame) scoreboard players operation #this <%OBJECTIVES.I()%> = @s <%OBJECTIVES.TWEEN_DURATION()%> tag @s add <%TAGS.TRANSFORMS_ONLY()%> @@ -376,45 +376,45 @@ IF (has_animations) { # Animation logic IF (animation.loop_mode === 'loop' && animation.loop_delay === 0) { # Makes sure function keyframes in the last frame of the animation are activated. - execute if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> matches -1 run \ + execute if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> matches -1 run \ block function_keyframe_loop_patch { function ./frames/last_frame_effects with storage <%temp_storage%> entry.data.uuids_by_name - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } } data remove storage <%temp_storage%> args execute store result storage <%temp_storage%> args.frame int 1 run \ - scoreboard players get @s <%OBJECTIVES.FRAME(animation.storage_name)%> + scoreboard players get @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> function ./apply_frame with storage <%temp_storage%> args IF (animation.loop_mode === 'loop') { # Loop the animation back to the start once it reaches the last frame. # If loop_delay is 0, the animation will loop instantly, otherwise, it will wait for the specified amount of ticks. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-2 + animation.loop_delay%>.. \ run return run \ - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> <%animation.loop_delay === 0 ? -1 : 0%> } ELSE IF (animation.loop_mode === 'hold') { # Pause the animation at the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%>.. \ run return run \ function ../pause } ELSE IF (animation.loop_mode === 'once') { # Stop the animation once it reaches the last frame. execute \ - if score @s <%OBJECTIVES.FRAME(animation.storage_name)%> \ + if score @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> \ matches <%animation.duration-1%> \ run return run block loop_mode_stop { - scoreboard players set @s <%OBJECTIVES.FRAME(animation.storage_name)%> 0 + scoreboard players set @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 0 tag @s add <%TAGS.TRANSFORMS_ONLY()%> execute at @s run function ./zzz/set_frame {frame: 0} tag @s remove <%TAGS.TRANSFORMS_ONLY()%> tag @s remove <%TAGS.ANIMATION_PLAYING(blueprint_id, animation.storage_name)%> } } - scoreboard players add @s <%OBJECTIVES.FRAME(animation.storage_name)%> 1 + scoreboard players add @s <%OBJECTIVES.FRAME(blueprint_id, animation.storage_name)%> 1 } IF (use_storage_for_animation) { diff --git a/src/systems/datapackCompiler/objectives.ts b/src/systems/datapackCompiler/objectives.ts index 70bd1ae7..223042c3 100644 --- a/src/systems/datapackCompiler/objectives.ts +++ b/src/systems/datapackCompiler/objectives.ts @@ -1,7 +1,10 @@ +import { makeTagSafe } from './tags' + namespace OBJECTIVES { export const I = () => 'aj.i' export const ID = () => 'aj.id' - export const FRAME = (animationName: string) => `aj.${animationName}.frame` + export const FRAME = (blueprintId: string, animationName: string) => + `${makeTagSafe(blueprintId)}.${animationName}.frame` export const IS_RIG_LOADED = () => 'aj.is_rig_loaded' export const TWEEN_DURATION = () => 'aj.tween_duration' } From b7551d4decc53be2515a3ece01286d4de557bac8 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 11:44:30 -0400 Subject: [PATCH 03/85] =?UTF-8?q?=F0=9F=90=9B=20Fix=20block=20atlas=20bein?= =?UTF-8?q?g=20overwritten=20on=20export?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/systems/resourcepackCompiler/1.20.4.ts | 2 +- src/systems/resourcepackCompiler/1.21.2.ts | 3 ++- src/systems/resourcepackCompiler/1.21.4.ts | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/systems/resourcepackCompiler/1.20.4.ts b/src/systems/resourcepackCompiler/1.20.4.ts index 162fc5a9..57e7647b 100644 --- a/src/systems/resourcepackCompiler/1.20.4.ts +++ b/src/systems/resourcepackCompiler/1.20.4.ts @@ -213,7 +213,7 @@ const compileResourcePack: ResourcePackCompiler = async ({ } // Texture atlas - const blockAtlasPath = PathModule.join('assets/minecraft/atlases/blocks.json') + const blockAtlasPath = PathModule.join(resourcePackPath, 'assets/minecraft/atlases/blocks.json') const blockAtlas: ITextureAtlas = await readFile(blockAtlasPath, 'utf-8') .catch(() => { console.log('Creating new block atlas...') diff --git a/src/systems/resourcepackCompiler/1.21.2.ts b/src/systems/resourcepackCompiler/1.21.2.ts index 79280607..c401d1b1 100644 --- a/src/systems/resourcepackCompiler/1.21.2.ts +++ b/src/systems/resourcepackCompiler/1.21.2.ts @@ -9,6 +9,7 @@ const compileResourcePack: ResourcePackCompiler = async ({ coreFiles, versionedFiles, rig, + resourcePackPath, textureExportFolder, modelExportFolder, }) => { @@ -28,7 +29,7 @@ const compileResourcePack: ResourcePackCompiler = async ({ const { readFile } = promises // Texture atlas - const blockAtlasPath = PathModule.join('assets/minecraft/atlases/blocks.json') + const blockAtlasPath = PathModule.join(resourcePackPath, 'assets/minecraft/atlases/blocks.json') const blockAtlas: ITextureAtlas = await readFile(blockAtlasPath, 'utf-8') .catch(() => { console.log('Creating new block atlas...') diff --git a/src/systems/resourcepackCompiler/1.21.4.ts b/src/systems/resourcepackCompiler/1.21.4.ts index 9f721163..91e00fe3 100644 --- a/src/systems/resourcepackCompiler/1.21.4.ts +++ b/src/systems/resourcepackCompiler/1.21.4.ts @@ -15,6 +15,7 @@ const compileResourcePack: ResourcePackCompiler = async ({ coreFiles, versionedFiles, rig, + resourcePackPath, textureExportFolder, modelExportFolder, }) => { @@ -40,7 +41,7 @@ const compileResourcePack: ResourcePackCompiler = async ({ const { readFile } = promises // Texture atlas - const blockAtlasPath = PathModule.join('assets/minecraft/atlases/blocks.json') + const blockAtlasPath = PathModule.join(resourcePackPath, 'assets/minecraft/atlases/blocks.json') const blockAtlas: ITextureAtlas = await readFile(blockAtlasPath, 'utf-8') .catch(() => { console.log('Creating new block atlas...') From e3ae33dbaa3c0086f43cb914ab7f95ed493424c5 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 11:45:42 -0400 Subject: [PATCH 04/85] =?UTF-8?q?=E2=9C=A8=20Improve=20entity=20UUID=20gen?= =?UTF-8?q?eration=20performance=20on=201.21.2+?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datapackCompiler/1.21.2/global.mcb | 360 ++++++++++++++++++ .../datapackCompiler/1.21.5/global.mcb | 14 + 2 files changed, 374 insertions(+) create mode 100644 src/systems/datapackCompiler/1.21.2/global.mcb diff --git a/src/systems/datapackCompiler/1.21.2/global.mcb b/src/systems/datapackCompiler/1.21.2/global.mcb new file mode 100644 index 00000000..6bad7aad --- /dev/null +++ b/src/systems/datapackCompiler/1.21.2/global.mcb @@ -0,0 +1,360 @@ +# DIFFERENCES FROM 1.20.4: +# - @n entity selector + +import ./global.mcbt + +dir global { + function on_load minecraft:load { + # Initialize Scoreboards + scoreboard objectives add <%OBJECTIVES.I()%> dummy + scoreboard objectives add <%OBJECTIVES.ID()%> dummy + scoreboard objectives add <%OBJECTIVES.IS_RIG_LOADED()%> dummy + scoreboard objectives add <%OBJECTIVES.TWEEN_DURATION()%> dummy + + scoreboard players add aj.last_id <%OBJECTIVES.ID()%> 0 + + # Enforce loading order. + function *global/gu/on_load + function *global/data_manager/on_load + function #*global/on_load + + IF (debug_mode) { + scoreboard players reset * <%OBJECTIVES.IS_RIG_LOADED()%> + execute as @e[type=item_display,tag=<%TAGS.GLOBAL_ROOT()%>] at @s run function *global/root/on_load + } + } + + function on_tick minecraft:tick { + execute as @e[type=item_display,tag=<%TAGS.GLOBAL_ROOT()%>] at @s run function *global/root/on_tick + } + + tag functions on_load { + <%blueprint_id%>/on_load + } + + dir root { + function on_tick { + data_manager prep read + IF (debug_mode) { + execute unless score @s <%OBJECTIVES.IS_RIG_LOADED()%> matches 1 run function *global/root/on_load + } + function *global/root/run_project_tick with storage <%temp_storage%> entry.data + } + + function run_project_tick { + $function $(blueprint_id)/root/on_tick + } + + IF (debug_mode) { + function on_load { + # Check if the rig is outdated by comparing the function's rig_hash of the rig to the rig_hash stored in the entity data. + execute if function animated_java:global/util/is_rig_outdated run block outdated_warning/modify_rig { + data remove storage <%temp_storage%> args + function *global/gu/get_entity_uuid_string + data modify storage <%temp_storage%> args.uuid set from storage <%gu_storage%> out + # Get position + execute store result storage <%temp_storage%> args.x double 1 run data get entity @s Pos[0] 1 + execute store result storage <%temp_storage%> args.y double 1 run data get entity @s Pos[1] 1 + execute store result storage <%temp_storage%> args.z double 1 run data get entity @s Pos[2] 1 + + # No need to read here, since is_rig_outdated already reads the data. + # data_manager prep read + + # Get export namespace + data modify storage <%temp_storage%> args.blueprint_id set from storage <%temp_storage%> entry.data.blueprint_id + # Overwrite the rig hash so the warning doesn't show again. + data modify storage <%temp_storage%> entry.data.rig_hash set value '<%rig_hash%>' + data_manager write + block run_print { with storage <%temp_storage%> entry.data + $function $(blueprint_id)/zzz/outdated_rig_warning with storage <%temp_storage%> args + } + + # Loop over rig entities and glow them red. + data modify storage <%temp_storage%> list set from storage <%temp_storage%> entry.data.uuids + block loop { + data modify storage <%temp_storage%> args.uuid set from storage <%temp_storage%> list[-1] + data remove storage <%temp_storage%> list[-1] + block as_uuid { with storage <%temp_storage%> args + $data merge entity $(uuid) {Glowing: 1b, glow_color_override: <%0xff0000%>} + } + + execute store result score #length <%OBJECTIVES.I()%> run data get storage <%temp_storage%> list + execute if score #length <%OBJECTIVES.I()%> matches 1.. run function ^0 + } + + summon minecraft:text_display ~ ~ ~ { \ + Tags:[ \ + '<%TAGS.GLOBAL_ENTITY()%>', \ + '<%TAGS.OUTDATED_RIG_TEXT_DISPLAY()%>', \ + '<%TAGS.NEW()%>' \ + ], \ + text:'<%TELLRAW.RIG_OUTDATED_TEXT_DISPLAY()%>', \ + alignment: 'center', \ + billboard: 'vertical', \ + shadow: true, \ + transformation:{ \ + translation:[0f,<%boundingBox[1]/16%>f,0f], \ + left_rotation:[0f,0f,0f,1f], \ + right_rotation:[0f,0f,0f,1f], \ + scale:[1f,1f,1f] \ + } \ + } + + ride @n[ \ + type=minecraft:text_display, \ + tag=<%TAGS.OUTDATED_RIG_TEXT_DISPLAY()%>, tag=<%TAGS.NEW()%>, \ + distance=..1 \ + ] mount @s + + tag @n[ \ + type=minecraft:text_display, \ + tag=<%TAGS.OUTDATED_RIG_TEXT_DISPLAY()%>, tag=<%TAGS.NEW()%>, \ + distance=..1 \ + ] remove <%TAGS.NEW()%> + } + scoreboard players set @s <%OBJECTIVES.IS_RIG_LOADED()%> 1 + } + } + } + + dir remove { + # Removes every entity related to Animated Java. + function everything { + kill @e[tag=<%TAGS.GLOBAL_ENTITY()%>] + } + + function entity_stack { + execute on passengers if entity @s[type=!player] run function ^0 + kill @s + } + + function entity_stack_by_uuid { + #ARGS: {uuid: string} + $execute as $(uuid) run function ./entity_stack + } + + # Removes locators and cameras owned by the rig, even if they're not included in the currently loaded export. + function outdated_rig { + data_manager prep read + + data remove storage <%temp_storage%> args + data remove storage <%temp_storage%> uuids + data modify storage <%temp_storage%> uuids set from entity @s data.uuids + execute store result score #aj.length <%OBJECTIVES.I()%> run data get storage <%temp_storage%> uuids + + execute if score #aj.length <%OBJECTIVES.I()%> matches 1.. run block loop_over_uuids { + data modify storage <%temp_storage%> args.current_uuid set from storage <%temp_storage%> uuids[-1].uuid + data remove storage <%temp_storage%> uuids[-1] + function ./entity_stack_by_uuid with storage <%temp_storage%> args + + scoreboard players remove #aj.length <%OBJECTIVES.I()%> 1 + execute if score #aj.length <%OBJECTIVES.I()%> matches 1.. run function ^0 + } + + function ./entity_stack + } + } + + dir util { + # Recurses through the passengers of the context entity and appends their UUIDs to `storage <%temp_storage%> uuids`. + function get_entity_stack_uuids { + data remove storage <%temp_storage%> uuids + execute on passengers run { + function *global/gu/get_entity_uuid_string + data modify storage <%temp_storage%> uuids append from storage <%gu_storage%> out + execute on passengers run function ^0 + } + } + # Returns 1 if the rig is outdated, else returns 0. + function is_rig_outdated { + data_manager prep read + return run block { with storage <%temp_storage%> entry.data + # REVIEW - The replace here is a bit hacky. + # Because this is a core function, I need to create a generic version of + # project_storage that uses a macro to get the blueprint ID instead of hardcoding it. + $execute if data storage <%project_storage.replace(blueprint_id, '$(blueprint_id)')%> {rig_hash:'$(rig_hash)'} run return 0 + return 1 + } + } + } + + # Thanks Gibbsly for the original code! https://github.com/gibbsly/gu + dir gu { + function on_load { + scoreboard players set 256 <%OBJECTIVES.I()%> 256 + data modify storage <%gu_storage%> hex_chars set value \ + <%JSON.stringify([...Array(0x100).keys()].map(v => {const x = v.toString(16); return x.length > 1 ? x : '0' + x}))%> + } + + item_modifier entity_uuid { + "function": "minecraft:set_name", + "entity": "this", + "target": "item_name", + "name": {"selector": "@s"} + } + + function get_entity_uuid_string { + execute if entity @s[type=!minecraft:player] run return run { + summon minecraft:item_display ~ ~ ~ {UUID:uuid('21e0f4fa-2970-4cba-be91-6a50cd9dd0eb'),item:{id:'minecraft:pufferfish'}} + item modify entity 21e0f4fa-2970-4cba-be91-6a50cd9dd0eb container.0 animated_java:global/gu/entity_uuid + data modify storage <%gu_storage%> out set from entity 21e0f4fa-2970-4cba-be91-6a50cd9dd0eb item.components.minecraft:item_name.insertion + kill 21e0f4fa-2970-4cba-be91-6a50cd9dd0eb + } + + data modify storage <%gu_storage%> temp set value {0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,a:0,b:0,c:0,d:0,e:0,f:0} + data modify storage <%gu_storage%> in set from entity @s UUID + + execute store result score 0= <%OBJECTIVES.I()%> store result score 1= <%OBJECTIVES.I()%> run data get storage <%gu_storage%> in[0] + execute store result storage <%gu_storage%> temp.0 int 1 run scoreboard players operation 0= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result score 2= <%OBJECTIVES.I()%> run scoreboard players operation 1= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.1 int 1 run scoreboard players operation 1= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result score 3= <%OBJECTIVES.I()%> run scoreboard players operation 2= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.2 int 1 run scoreboard players operation 2= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.3 int 1 run scoreboard players operation 3= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + + execute store result score 0= <%OBJECTIVES.I()%> store result score 1= <%OBJECTIVES.I()%> run data get storage <%gu_storage%> in[1] + execute store result storage <%gu_storage%> temp.4 int 1 run scoreboard players operation 0= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result score 2= <%OBJECTIVES.I()%> run scoreboard players operation 1= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.5 int 1 run scoreboard players operation 1= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result score 3= <%OBJECTIVES.I()%> run scoreboard players operation 2= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.6 int 1 run scoreboard players operation 2= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.7 int 1 run scoreboard players operation 3= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + + execute store result score 0= <%OBJECTIVES.I()%> store result score 1= <%OBJECTIVES.I()%> run data get storage <%gu_storage%> in[2] + execute store result storage <%gu_storage%> temp.8 int 1 run scoreboard players operation 0= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result score 2= <%OBJECTIVES.I()%> run scoreboard players operation 1= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.9 int 1 run scoreboard players operation 1= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result score 3= <%OBJECTIVES.I()%> run scoreboard players operation 2= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.a int 1 run scoreboard players operation 2= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.b int 1 run scoreboard players operation 3= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + + execute store result score 0= <%OBJECTIVES.I()%> store result score 1= <%OBJECTIVES.I()%> run data get storage <%gu_storage%> in[3] + execute store result storage <%gu_storage%> temp.c int 1 run scoreboard players operation 0= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result score 2= <%OBJECTIVES.I()%> run scoreboard players operation 1= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.d int 1 run scoreboard players operation 1= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result score 3= <%OBJECTIVES.I()%> run scoreboard players operation 2= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.e int 1 run scoreboard players operation 2= <%OBJECTIVES.I()%> %= 256 <%OBJECTIVES.I()%> + execute store result storage <%gu_storage%> temp.f int 1 run scoreboard players operation 3= <%OBJECTIVES.I()%> /= 256 <%OBJECTIVES.I()%> + + block { with storage <%gu_storage%> temp + REPEAT (0, 15) as i { + $data modify storage <%gu_storage%> temp.<%i.toString(16)%> set from storage <%gu_storage%> hex_chars[$(<%i.toString(16)%>)] + } + } + + block { with storage <%gu_storage%> temp + $data modify storage <%gu_storage%> out set value "$(3)$(2)$(1)$(0)-$(7)$(6)-$(5)$(4)-$(b)$(a)-$(9)$(8)$(f)$(e)$(d)$(c)" + } + } + } + + # Storage-based per-entity NBT storage. Thanks Xanbelor for the concept! + dir data_manager { + function on_load { + scoreboard players add #aj.data_manager.index <%OBJECTIVES.I()%> 0 + } + + function on_tick minecraft:tick { + execute store result storage <%temp_storage%> args.id int 1 run scoreboard players get #aj.data_manager.index <%OBJECTIVES.I()%> + block { with storage <%temp_storage%> args + $data modify storage <%temp_storage%> args.uuid set from storage <%data_storage%> "$(id)".uuid + scoreboard players set #success <%OBJECTIVES.I()%> 0 + block { with storage <%temp_storage%> args + $execute store success score #success <%OBJECTIVES.I()%> if score $(uuid) <%OBJECTIVES.ID()%> matches 1.. + $execute if score #success <%OBJECTIVES.I()%> matches 0 run data remove storage <%data_storage%> "$(id)" + } + } + scoreboard players add #aj.data_manager.index <%OBJECTIVES.I()%> 1 + execute \ + if score #aj.data_manager.index <%OBJECTIVES.I()%> > aj.last_id <%OBJECTIVES.ID()%> \ + run scoreboard players set #aj.data_manager.index <%OBJECTIVES.I()%> 0 + } + + function create_entry { + $data modify storage <%data_storage%> "$(id)" set value {uuid: "$(uuid)", data: {}} + } + + function read { + data remove storage <%temp_storage%> entry + $data modify storage <%temp_storage%> entry set from storage <%data_storage%> "$(id)" + } + + function write { + $data modify storage <%data_storage%> "$(id)" set from storage <%temp_storage%> entry + } + } + + dir interactions { + REPEAT (['interaction', 'attack']) as direction { + dir <%direction%> { + advancement trigger { + "criteria": { + "player_<%direction%>_clicked_interaction_entity": { + "trigger": "<%direction === 'interaction' ? 'minecraft:player_interacted_with_entity' : 'minecraft:player_hurt_entity'%>", + "conditions": { + "entity": { + "type": "minecraft:interaction" + } + } + } + }, + "rewards": { + "function": "<%context.namespace + ':' + context.path.join('/')%>/on" + } + } + + function on { + advancement revoke @s only <%context.namespace + ':' + context.path.join('/')%>/trigger + tag @s add <%TAGS.INTERACTING_PLAYER()%> + execute \ + as @e[type=interaction, tag=<%TAGS.GLOBAL_INTERACTION()%>, distance=..8] \ + if data entity @s <%direction%> \ + run function ./check + tag @s remove <%TAGS.INTERACTING_PLAYER()%> + } + + function check { + execute store result score #gametime <%OBJECTIVES.I()%> run time query gametime + execute \ + store result score #timestamp <%OBJECTIVES.I()%> \ + run data get entity @s <%direction%>.timestamp + + # Check that the interaction has a command to run, and + # if this interaction is from the player being processed. + scoreboard players set #check <%OBJECTIVES.I()%> 0 + execute \ + if score #timestamp <%OBJECTIVES.I()%> = #gametime <%OBJECTIVES.I()%> \ + if data entity @s data.animated_java.on_<%direction === 'interaction' ? 'interact' : 'attack'%>_function \ + store success score #check <%OBJECTIVES.I()%> \ + on <%direction === 'interaction' ? 'target' : 'attacker'%> \ + if entity @s[tag=<%TAGS.INTERACTING_PLAYER()%>] + + execute \ + if score #check <%OBJECTIVES.I()%> matches 1 \ + run function ./do + } + + function do { + scoreboard players set #check <%OBJECTIVES.I()%> 0 + block execute { with entity @s data.animated_java + $$(on_<%direction === 'interaction' ? 'interact' : 'attack'%>_function) + scoreboard players set #check <%OBJECTIVES.I()%> 1 + } + execute if score #check <%OBJECTIVES.I()%> matches 0 run tellraw @a [ \ + {text: '', color: red}, \ + {text:'ɪɴᴛᴇʀᴀᴄᴛɪᴏɴꜱ', color:'light_purple'}, \ + {text:'\n(<%global.root%>.mcb)', color:'dark_gray'}, \ + '\n→ ᴇʀʀᴏʀ:\n\sFailed to handle <%direction === 'interaction' ? 'right' : 'left'%> click interaction from ', \ + {selector: '@p[tag=<%TAGS.INTERACTING_PLAYER()%>]', color: gold}, \ + ':\n\s\sInvalid command: ', \ + {nbt: 'data.animated_java.on_<%direction === 'interaction' ? 'interact' : 'attack'%>_function', entity: '@s', color: aqua}, \ + '\n\s\sfrom ', \ + {text: 'data.animated_java.on_<%direction === 'interaction' ? 'interact' : 'attack'%>_function ', color: yellow}, \ + ] + # Only remove the interaction if it's consumed. + data remove entity @s <%direction%> + } + } + } + } +} diff --git a/src/systems/datapackCompiler/1.21.5/global.mcb b/src/systems/datapackCompiler/1.21.5/global.mcb index 926d375d..3c710990 100644 --- a/src/systems/datapackCompiler/1.21.5/global.mcb +++ b/src/systems/datapackCompiler/1.21.5/global.mcb @@ -186,7 +186,21 @@ dir global { <%JSON.stringify([...Array(0x100).keys()].map(v => {const x = v.toString(16); return x.length > 1 ? x : '0' + x}))%> } + item_modifier entity_uuid { + "function": "minecraft:set_name", + "entity": "this", + "target": "item_name", + "name": {"selector": "@s"} + } + function get_entity_uuid_string { + execute if entity @s[type=!minecraft:player] run return run { + summon minecraft:item_display ~ ~ ~ {UUID:uuid('21e0f4fa-2970-4cba-be91-6a50cd9dd0eb'),item:{id:'minecraft:pufferfish'}} + item modify entity 21e0f4fa-2970-4cba-be91-6a50cd9dd0eb container.0 animated_java:global/gu/entity_uuid + data modify storage <%gu_storage%> out set from entity 21e0f4fa-2970-4cba-be91-6a50cd9dd0eb item.components.minecraft:item_name.insertion + kill 21e0f4fa-2970-4cba-be91-6a50cd9dd0eb + } + data modify storage <%gu_storage%> temp set value {0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,a:0,b:0,c:0,d:0,e:0,f:0} data modify storage <%gu_storage%> in set from entity @s UUID From 447019dda1361d517527c7461c7c495c5b468455 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 11:47:49 -0400 Subject: [PATCH 05/85] =?UTF-8?q?=F0=9F=90=9B=20Fix=20a=20few=20minor=20is?= =?UTF-8?q?sues.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../releaseNoteTemplates/github_release_notes_template | 2 +- src/popups/installed/installed.svelte | 9 ++++++--- src/systems/datapackCompiler/index.ts | 4 ++-- src/systems/global.ts | 6 ++++++ src/systems/minecraft/blockstateManager.ts | 3 +++ src/systems/resourcepackCompiler/index.ts | 2 +- src/util/events.ts | 2 +- 7 files changed, 20 insertions(+), 8 deletions(-) diff --git a/.scripts/plugins/releaseNoteTemplates/github_release_notes_template b/.scripts/plugins/releaseNoteTemplates/github_release_notes_template index c26f0d77..d95ebd97 100644 --- a/.scripts/plugins/releaseNoteTemplates/github_release_notes_template +++ b/.scripts/plugins/releaseNoteTemplates/github_release_notes_template @@ -4,6 +4,6 @@ ## How to Install -Download `animated_java.js` from the [release page](https://github.com/Animated-Java/animated-java/releases/tag/v1.10.1), then [Follow this tutorial](https://animated-java.dev/docs/getting-started/installing#advanced-installation-url) +Download `animated_java.js` from the [release page](https://github.com/Animated-Java/animated-java/releases/tag/v1.10.2), then [Follow this tutorial](https://animated-java.dev/docs/getting-started/installing#advanced-installation-url) Once [this PR](https://github.com/JannisX11/blockbench-plugins/pull/930) has been merged, you can install the latest release of AJ directly from the Blockbench plugin list. diff --git a/src/popups/installed/installed.svelte b/src/popups/installed/installed.svelte index f192eb5b..cd01a2fe 100644 --- a/src/popups/installed/installed.svelte +++ b/src/popups/installed/installed.svelte @@ -1,14 +1,15 @@
- +

Welcome to Animated Java!

-

Effortlessly craft complex animations for Minecraft: Java Edition

+

{PACKAGE.description}

@@ -62,6 +63,9 @@ align-items: center; margin-top: 1rem; justify-content: center; + display: flex; + align-items: center; + gap: 16px; } .header-container div { display: flex; @@ -70,7 +74,6 @@ margin-left: 2rem; } .header-container img { - width: 128px; border-radius: 16px; box-shadow: 4px 4px 8px -4px black; } diff --git a/src/systems/datapackCompiler/index.ts b/src/systems/datapackCompiler/index.ts index 4bdeebe4..7d6bf3b3 100644 --- a/src/systems/datapackCompiler/index.ts +++ b/src/systems/datapackCompiler/index.ts @@ -509,8 +509,8 @@ async function removeFiles(ajmeta: AJMeta) { content.values = content.values.filter( v => typeof v === 'string' && - (!v.startsWith(`${aj.blueprint_id}/`) || - !v.startsWith(`${Project!.last_used_blueprint_id}/`)) + !v.startsWith(`${aj.blueprint_id}/`) && + !v.startsWith(`${Project!.last_used_blueprint_id}/`) ) await writeFile(file, autoStringify(content)) } else { diff --git a/src/systems/global.ts b/src/systems/global.ts index 7b56c46f..42806568 100644 --- a/src/systems/global.ts +++ b/src/systems/global.ts @@ -72,6 +72,12 @@ export class AJMeta { for (const file of lastNamespaceData.versionedFiles) { this.previousVersionedFiles.add(PathModule.join(this.rootFolder, file)) } + + if (!Array.isArray(lastNamespaceData.coreFiles)) lastNamespaceData.coreFiles = [] + for (const file of lastNamespaceData.coreFiles) { + this.previousCoreFiles.add(PathModule.join(this.rootFolder, file)) + } + delete this.previousAJMeta.rigs[this.lastUsedBlueprintId] } diff --git a/src/systems/minecraft/blockstateManager.ts b/src/systems/minecraft/blockstateManager.ts index cdea5296..e9edf501 100644 --- a/src/systems/minecraft/blockstateManager.ts +++ b/src/systems/minecraft/blockstateManager.ts @@ -70,12 +70,14 @@ export async function checkForRegistryUpdate() { if (!currentValueString) { console.log('No BlockState Registry found. Updating...') await updateLocalRegistry() + updateMemoryRegistry() return } const currentVersionString = localStorage.getItem('animated_java:blockStateRegistryVersion') if (!currentVersionString) { console.log('No BlockState Registry version found. Updating...') await updateLocalRegistry() + updateMemoryRegistry() return } const currentVersion = JSON.parse(currentVersionString) @@ -83,6 +85,7 @@ export async function checkForRegistryUpdate() { if (currentVersion.id !== latestVersion.id) { console.log('BlockState Registry is outdated. Updating...') await updateLocalRegistry() + updateMemoryRegistry() return } diff --git a/src/systems/resourcepackCompiler/index.ts b/src/systems/resourcepackCompiler/index.ts index 3b69684f..348633e9 100644 --- a/src/systems/resourcepackCompiler/index.ts +++ b/src/systems/resourcepackCompiler/index.ts @@ -193,7 +193,7 @@ export default async function compileResourcePack( } PROGRESS.set(PROGRESS.get() + 1) } - } else if (aj.data_pack_export_mode === 'zip') { + } else if (aj.resource_pack_export_mode === 'zip') { const data: AsyncZippable = {} for (const [path, file] of coreFiles.entries()) { diff --git a/src/util/events.ts b/src/util/events.ts index c6148e05..fbebcac5 100644 --- a/src/util/events.ts +++ b/src/util/events.ts @@ -1,5 +1,5 @@ import { subscribable } from 'simple-subpub' -import { Variant } from '../variants' +import type { Variant } from '../variants' // Plugin Events const EVENTS = { From 28125ef782e8e8e3137b8a1b8038073dc8dcaf13 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 11:48:30 -0400 Subject: [PATCH 06/85] =?UTF-8?q?=E2=9C=A8=20Remove=20recursion=20from=20r?= =?UTF-8?q?ig=20renderer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/systems/rigRenderer.ts | 252 +++++++++++++++++++------------------ 1 file changed, 127 insertions(+), 125 deletions(-) diff --git a/src/systems/rigRenderer.ts b/src/systems/rigRenderer.ts index 5e0a0577..ad6b4145 100644 --- a/src/systems/rigRenderer.ts +++ b/src/systems/rigRenderer.ts @@ -390,131 +390,132 @@ function renderNullObject(nullObject: NullObject, rig: IRenderedRig) { rig.nodes[nullObject.uuid] = renderedNullObject } -function renderGroup( - group: Group, - rig: IRenderedRig, - defaultVariant: IRenderedVariant -): INodeStructure | undefined { - if (!group.export) return - const parentId = group.parent instanceof Group ? group.parent.uuid : undefined - - const path = PathModule.join(rig.model_export_folder, group.name + `.json`) - const parsed = parseResourcePackPath(path) +function renderGroup(rootGroup: Group, rig: IRenderedRig, defaultVariant: IRenderedVariant): void { + const stack: Group[] = [rootGroup] - if (!parsed) { - console.error(group) - throw new Error(`Invalid bone path: ${group.name} -> ${path}`) - } + while (stack.length > 0) { + const group = stack.pop()! + if (!group.export) continue + const parentId = group.parent instanceof Group ? group.parent.uuid : undefined - const renderedBone: IRenderedNodes['Bone'] = { - type: 'bone', - name: group.name, - storage_name: sanitizeStorageKey(group.name), - uuid: group.uuid, - parent: parentId, - bounding_box: getNodeBoundingBox(group), - base_scale: 1, - configs: structuredClone(group.configs), - on_summon_function: group.onSummonFunction?.trim(), - itemModelProperties: group.itemModelProperties - ? structuredClone(group.itemModelProperties) - : undefined, - // This is a placeholder value that will be updated later once the animation renderer is run. - default_transform: {} as INodeTransform, - } - let groupModel = defaultVariant.models[group.uuid] - if (!groupModel) { - groupModel = defaultVariant.models[group.uuid] = { - model: { - textures: { - particle: 'minecraft:item/pufferfish', - }, - display: { head: { rotation: [0, 180, 0] } }, - }, - custom_model_data: -1, // This is calculated when constructing the resource pack. - resource_location: parsed.resourceLocation, - item_model: parsed.resourceLocation, - } - } + const path = PathModule.join(rig.model_export_folder, group.name + `.json`) + const parsed = parseResourcePackPath(path) - for (const node of group.children) { - if (!node.export) continue - switch (true) { - case node instanceof Group: { - renderGroup(node, rig, defaultVariant) - break - } - case node instanceof Locator: { - renderLocator(node, rig) - break - } - case node instanceof TextDisplay: { - renderTextDisplay(node, rig) - break - } - case OutlinerElement.types.camera && node instanceof OutlinerElement.types.camera: { - renderCamera(node as ICamera, rig) - break - } - case node instanceof VanillaItemDisplay: { - renderItemDisplay(node, rig) - break - } - case node instanceof VanillaBlockDisplay: { - renderBlockDisplay(node, rig) - break - } - case node instanceof Interaction: { - renderInteraction(node, rig) - break - } - case node instanceof Cube: { - renderCube(node, rig, groupModel.model!) - rig.includes_custom_models = true - break - } - case node instanceof NullObject: { - renderNullObject(node, rig) - break - } - default: - console.warn(`Encountered unknown node type:`, node) + if (!parsed) { + console.error(group) + throw new Error(`Invalid bone path: ${group.name} -> ${path}`) } - } - // Export a struct instead of a bone if no elements are present - if (!groupModel.model?.elements || groupModel.model.elements.length === 0) { - delete defaultVariant.models[group.uuid] - const struct: IRenderedNodes['Struct'] = { - type: 'struct', + const renderedBone: IRenderedNodes['Bone'] = { + type: 'bone', name: group.name, storage_name: sanitizeStorageKey(group.name), uuid: group.uuid, parent: parentId, + bounding_box: getNodeBoundingBox(group), + base_scale: 1, + configs: structuredClone(group.configs), + on_summon_function: group.onSummonFunction?.trim(), + itemModelProperties: group.itemModelProperties + ? structuredClone(group.itemModelProperties) + : undefined, default_transform: {} as INodeTransform, } - rig.nodes[group.uuid] = struct - return - } - - const diff = new THREE.Vector3().subVectors( - renderedBone.bounding_box.max, - renderedBone.bounding_box.min - ) - const max = Math.max(diff.x, diff.y, diff.z) - const scale = Math.min(1, 24 / max) - for (const element of groupModel.model.elements) { - element.from = element.from.map(v => v * scale + 8) - element.to = element.to.map(v => v * scale + 8) - if (element.rotation && !Array.isArray(element.rotation)) { - element.rotation.origin = element.rotation.origin.map( - v => v * scale + 8 - ) as ArrayVector3 + let groupModel = defaultVariant.models[group.uuid] + if (!groupModel) { + groupModel = defaultVariant.models[group.uuid] = { + model: { + textures: { + particle: 'minecraft:item/pufferfish', + }, + display: { head: { rotation: [0, 180, 0] } }, + }, + custom_model_data: -1, + resource_location: parsed.resourceLocation, + item_model: parsed.resourceLocation, + } } - } - renderedBone.base_scale = 1 / scale - rig.nodes[group.uuid] = renderedBone + const childGroups: Group[] = [] + for (const node of group.children) { + if (!node.export) continue + switch (true) { + case node instanceof Group: { + childGroups.push(node) + break + } + case node instanceof Locator: { + renderLocator(node, rig) + break + } + case node instanceof TextDisplay: { + renderTextDisplay(node, rig) + break + } + case OutlinerElement.types.camera && node instanceof OutlinerElement.types.camera: { + renderCamera(node as ICamera, rig) + break + } + case node instanceof VanillaItemDisplay: { + renderItemDisplay(node, rig) + break + } + case node instanceof VanillaBlockDisplay: { + renderBlockDisplay(node, rig) + break + } + case node instanceof Interaction: { + renderInteraction(node, rig) + break + } + case node instanceof Cube: { + renderCube(node, rig, groupModel.model!) + rig.includes_custom_models = true + break + } + case node instanceof NullObject: { + renderNullObject(node, rig) + break + } + default: + console.warn(`Encountered unknown node type:`, node) + } + } + for (let i = childGroups.length - 1; i >= 0; i--) stack.push(childGroups[i]) + + if (!groupModel.model?.elements || groupModel.model.elements.length === 0) { + delete defaultVariant.models[group.uuid] + const struct: IRenderedNodes['Struct'] = { + type: 'struct', + name: group.name, + storage_name: sanitizeStorageKey(group.name), + uuid: group.uuid, + parent: parentId, + default_transform: {} as INodeTransform, + } + rig.nodes[group.uuid] = struct + continue + } + + const diff = new THREE.Vector3().subVectors( + renderedBone.bounding_box.max, + renderedBone.bounding_box.min + ) + const max = Math.max(diff.x, diff.y, diff.z) + const scale = Math.min(1, 24 / max) + for (const element of groupModel.model.elements) { + element.from = element.from.map(v => v * scale + 8) + element.to = element.to.map(v => v * scale + 8) + if (element.rotation && !Array.isArray(element.rotation)) { + element.rotation.origin = element.rotation.origin.map( + v => v * scale + 8 + ) as ArrayVector3 + } + } + + renderedBone.base_scale = 1 / scale + rig.nodes[group.uuid] = renderedBone + } } function renderItemDisplay(display: VanillaItemDisplay, rig: IRenderedRig) { @@ -681,16 +682,12 @@ function renderCamera(camera: ICamera, rig: IRenderedRig) { function renderVariantModels(variant: Variant, rig: IRenderedRig) { const models: Record = {} - const defaultVariant = Variant.getDefault() - const defaultModels = rig.variants[defaultVariant.uuid].models - for (const [uuid, bone] of Object.entries(rig.nodes)) { if (bone.type !== 'bone') continue if (variant.excludedNodes.find(v => v.value === uuid)) continue const textures: IRenderedModel['textures'] = {} - let isOnlyTransparent = true - const unreplacedTextures = new Set(Object.keys(defaultModels[uuid].model!.textures)) + let hasTextureChanges = false for (const [fromUUID, toUUID] of variant.textureMap.map.entries()) { const fromTexture = Texture.all.find(t => t.uuid === fromUUID) @@ -699,23 +696,28 @@ function renderVariantModels(variant: Variant, rig: IRenderedRig) { if (!toTexture) throw new Error(`To texture not found: ${toUUID}`) textures[fromTexture.id] = getTextureResourceLocation(toTexture, rig).resourceLocation rig.textures[toTexture.id] = toTexture - isOnlyTransparent = false + hasTextureChanges = true } - // Don't export models without any texture changes - if (Object.keys(textures).length === 0) continue - - // Use empty model if all textures are transparent - if (isOnlyTransparent && unreplacedTextures.size === 0) { + // Use the default model if the variant doesn't have any texture changes for this bone + if (!hasTextureChanges) { + const path = PathModule.join(rig.model_export_folder, bone.storage_name + '.json') + const parsed = parseResourcePackPath(path) + if (!parsed) { + throw new Error(`Invalid Bone Name: '${bone.storage_name}' -> '${path}'`) + } models[uuid] = { model: null, custom_model_data: 1, - resource_location: 'animated_java:empty', - item_model: 'animated_java:empty', + resource_location: parsed.resourceLocation, + item_model: parsed.resourceLocation, } continue } + // Don't export models without any texture changes + if (Object.keys(textures).length === 0) continue + const modelParent = PathModule.join(rig.model_export_folder, bone.storage_name + '.json') const parsed = parseResourcePackPath(modelParent) if (!parsed) { From 7835f59d19701cbbedfa9012b7cb5df7c2ee6f31 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 11:48:56 -0400 Subject: [PATCH 07/85] =?UTF-8?q?=F0=9F=90=9B=20Fix=20cube=20rotation=20va?= =?UTF-8?q?lidation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/systems/util.ts | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/src/systems/util.ts b/src/systems/util.ts index d075bd2b..7992e9ba 100644 --- a/src/systems/util.ts +++ b/src/systems/util.ts @@ -93,36 +93,29 @@ export const unzip = (data: Uint8Array, options: AsyncUnzipOptions) => { } export function isCubeValid(cube: Cube): '1.21.6+' | 'valid' | 'invalid' { - if (projectTargetVersionIsAtLeast('1.21.11')) { - // Rotations are unrestricted on 1.21.11+ - return 'valid' - } - - const totalRotation = cube.rotation[0] + cube.rotation[1] + cube.rotation[2] + // Rotations are unrestricted on 1.21.11+ + if (projectTargetVersionIsAtLeast('1.21.11')) return 'valid' - if (totalRotation === 0) return 'valid' + const nonZeroRotations = cube.rotation.filter(v => v !== 0) + if (nonZeroRotations.length === 0) return 'valid' + // Multiple axes of rotation are not allowed on versions before 1.21.11 + if (nonZeroRotations.length > 1) return 'invalid' - const isSingleAxisRotation = - totalRotation === cube.rotation[0] || - totalRotation === cube.rotation[1] || - totalRotation === cube.rotation[2] + const rotation = nonZeroRotations[0] - if (isSingleAxisRotation && projectTargetVersionIsAtLeast('1.21.6')) { + if (projectTargetVersionIsAtLeast('1.21.6')) { // Rotation values still need to be within -45 and 45 degrees - if (totalRotation <= 45 && totalRotation >= -45) return '1.21.6+' - else return 'invalid' + return rotation <= 45 && rotation >= -45 ? '1.21.6+' : 'invalid' } const isRotationInAllowedSteps = - totalRotation === -45 || - totalRotation === -22.5 || - totalRotation === 0 || - totalRotation === 22.5 || - totalRotation === 45 - - if (isSingleAxisRotation && isRotationInAllowedSteps) return 'valid' + rotation === -45 || + rotation === -22.5 || + rotation === 0 || + rotation === 22.5 || + rotation === 45 - return 'invalid' + return isRotationInAllowedSteps ? 'valid' : 'invalid' } export async function sleepForAnimationFrame() { From a4acca53f9cc9354c2c3d6575065f32b5f8462a4 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 11:49:46 -0400 Subject: [PATCH 08/85] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Update=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blueprints/armor_stand_latest.ajblueprint | 1173 ++- .../blueprints/nullobj_debug.ajblueprint | 999 +++ .../datapacks/animated_java/pack.mcmeta | 8 +- test-packs/latest/resources/pack.mcmeta | 8 +- test_blueprints/Boat.ajblueprint | 7488 +++++++++++++++++ test_blueprints/Dummy.ajblueprint | 1264 +++ test_blueprints/amy-stand.png | Bin 0 -> 176 bytes test_blueprints/amy_stand.bbmodel | 1 + test_blueprints/armor_stand.ajblueprint | 197 +- 9 files changed, 10912 insertions(+), 226 deletions(-) create mode 100644 test-packs/latest/blueprints/nullobj_debug.ajblueprint create mode 100644 test_blueprints/Boat.ajblueprint create mode 100644 test_blueprints/Dummy.ajblueprint create mode 100644 test_blueprints/amy-stand.png create mode 100644 test_blueprints/amy_stand.bbmodel diff --git a/test-packs/latest/blueprints/armor_stand_latest.ajblueprint b/test-packs/latest/blueprints/armor_stand_latest.ajblueprint index 3dd599cd..9de67690 100644 --- a/test-packs/latest/blueprints/armor_stand_latest.ajblueprint +++ b/test-packs/latest/blueprints/armor_stand_latest.ajblueprint @@ -1,7 +1,7 @@ { "meta": { "format": "animated-java:format/blueprint", - "format_version": "1.10.0-beta.4", + "format_version": "1.10.2", "uuid": "167b27cd-b559-3f13-a97c-0841fe21f1d1", "save_location": "/var/mnt/ssd2/repos/animated-java/animated-java/test-packs/latest/blueprints/armor_stand_latest.ajblueprint", "last_used_blueprint_id": "aj_booth:rigs/armor_stand" @@ -13,12 +13,12 @@ "blueprint_settings": { "blueprint_id": "aj_booth:rigs/armor_stand", "render_box": [95, 32], - "resource_pack_export_mode": "zip", - "data_pack_export_mode": "zip", - "resource_pack": "/home/snavesutit/Prism Launcher Instances/AJ Testing 1.21.11/minecraft/resourcepacks/resources.zip", - "data_pack": "../datapacks/animated_java.zip", + "target_minecraft_version": "26.2", + "resource_pack": "../resources", + "data_pack": "../datapacks/animated_java", "on_summon_function": "say On-Summon!", "on_remove_function": "say On-Remove!", + "auto_update_rig_orientation": false, "baked_animations": false, "json_file": "../testPluginExport.json" }, @@ -922,10 +922,11 @@ "rotation": [0, 0, 0], "pivotOffset": [0, 0, 0], "scale": [1, 1, 1], + "color": 7, "visibility": true, "locked": false, "export": true, - "text": "[\n\t{0x00aced}yeah', 'I' '[{love light_purple}' 'text]{' displays''#FF5555'}\n\t'\\n'[{#55_FF_55}definitly' 'quite' 'cursed]\n\t'\\n'{what red}{amI #6395EE}{evenlookingat #c02c38}\n]", + "text": "[\n\t{0x00aced}yeah' 'I' '[{love light_purple}' 'text]{' displays''#FF5555'}\n\t'\\n'[{#55_FF_55}definitly' 'quite' 'cursed]\n\t'\\n'{what red}{amI #6395EE}{evenlookingat #c02c38}\n]", "lineWidth": 400, "backgroundColor": "#00000040", "align": "center", @@ -937,28 +938,30 @@ "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, "enchanted": false, "glowing": false, "override_glow_color": false, "glow_color": "#6f114b", "invisible": false, "shadow_radius": 0, - "shadow_strength": 1 + "shadow_strength": 1, + "sky_brightness": 0, + "block_brightness": 0 }, "variants": { "49521f4b-b970-e4bd-b594-2e05d2d46027": { "on_apply_function": "", "billboard": "vertical", "override_brightness": false, - "brightness_override": 0, "enchanted": false, "glowing": true, "override_glow_color": true, "glow_color": "#6f114b", "invisible": false, "shadow_radius": 0, - "shadow_strength": 1 + "shadow_strength": 1, + "sky_brightness": 0, + "block_brightness": 0 } } }, @@ -968,17 +971,47 @@ }, { "name": "camera", - "position": [0, 27, 0], - "rotation": [0, 0, 0], - "fov": 70, - "aspect_ratio": [16, 9], - "linked_preview": "", - "camera_linked": false, - "visibility": true, - "export": true, + "box_uv": false, + "render_order": "default", + "rescale": false, "locked": false, + "shade": true, + "light_emission": 0, + "export": true, "scope": 0, - "type": "camera", + "allow_mirror_modeling": true, + "from": [0, 0, 0], + "to": [1, 1, 1], + "autouv": 0, + "color": 4, + "origin": [0, 0, 0], + "faces": { + "north": { + "uv": [0, 0, 1, 1], + "texture": "eb6c49b8-8e8e-a039-9a6f-ef6a06bc7924" + }, + "east": { + "uv": [0, 0, 1, 1], + "texture": "eb6c49b8-8e8e-a039-9a6f-ef6a06bc7924" + }, + "south": { + "uv": [0, 0, 1, 1], + "texture": "eb6c49b8-8e8e-a039-9a6f-ef6a06bc7924" + }, + "west": { + "uv": [0, 0, 1, 1], + "texture": "eb6c49b8-8e8e-a039-9a6f-ef6a06bc7924" + }, + "up": { + "uv": [0, 0, 1, 1], + "texture": "eb6c49b8-8e8e-a039-9a6f-ef6a06bc7924" + }, + "down": { + "uv": [0, 0, 1, 1], + "texture": "eb6c49b8-8e8e-a039-9a6f-ef6a06bc7924" + } + }, + "type": "cube", "uuid": "3ffeee76-901e-f8a2-c29a-82f90e16fd1e" }, { @@ -987,6 +1020,7 @@ "rotation": [-90, 0, 0], "pivotOffset": [0, 0, 0], "scale": [0.5, 0.5, 0.5], + "color": 4, "visibility": true, "locked": false, "export": true, @@ -998,7 +1032,8 @@ "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, "glowing": false, "override_glow_color": false, @@ -1012,7 +1047,8 @@ "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": true, "glowing": true, "override_glow_color": true, @@ -1020,6 +1056,20 @@ "invisible": false, "shadow_radius": 0, "shadow_strength": 1 + }, + "bf2a6915-ec63-7ccf-3844-ea8be00b97e6": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": false, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 } } }, @@ -1033,6 +1083,7 @@ "rotation": [0, 0, 0], "pivotOffset": [0, 0, 0], "scale": [1, 1, 1], + "color": 1, "visibility": true, "locked": false, "export": true, @@ -1044,12 +1095,264 @@ "seeThrough": false, "onSummonFunction": "", "configs": { - "default": {}, + "default": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": false, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, "variants": {} }, "scope": 0, "uuid": "29d6057b-8ee5-0e57-405d-f2d71c816a43", "type": "animated_java:text_display" + }, + { + "name": "interaction", + "position": [0, 0, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [16, 32, 16], + "color": 5, + "visibility": true, + "locked": false, + "export": true, + "onSummonFunction": "", + "config": { + "response": true, + "on_interact_function": "say That tickles!", + "on_attack_function": "say Ouch!", + "on_summon_function": "say Summoned!", + "on_remove_function": "say Removed!", + "on_tick_function": "" + }, + "scope": 0, + "uuid": "23e0e18a-815e-9961-3090-320b8e026483", + "type": "animated_java:interaction" + }, + { + "name": "camera", + "position": [0, 32, 0], + "rotation": [0, 0, 0], + "fov": 70, + "aspect_ratio": [16, 9], + "linked_preview": "", + "camera_linked": false, + "visibility": true, + "export": true, + "locked": false, + "scope": 0, + "type": "camera", + "uuid": "23475e18-f4ec-683a-396a-963ca2da06a1" + }, + { + "name": "block_display", + "position": [8, 0, -8], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1.0625, 1], + "color": 9, + "visibility": true, + "locked": false, + "export": true, + "block": "minecraft:stone", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "857172ba-7e40-f659-9b57-c9e9030d5ebd", + "type": "animated_java:vanilla_block_display" + }, + { + "name": "block_display2", + "position": [24, 0, -8], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1.0625, 1], + "color": 9, + "visibility": true, + "locked": false, + "export": true, + "block": "minecraft:grass_block", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "10960a14-0305-4213-fc7b-d9cb56e30a49", + "type": "animated_java:vanilla_block_display" + }, + { + "name": "block_display4", + "position": [40, 0, -8], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1.0625, 1], + "color": 9, + "visibility": true, + "locked": false, + "export": true, + "block": "minecraft:oak_log", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "e1de5b7c-4e08-e515-6697-f24326e769c1", + "type": "animated_java:vanilla_block_display" + }, + { + "name": "item_display1", + "position": [-16, 8, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 2, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:orange_dye", + "itemDisplay": "ground", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "center", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": false, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "446c95f8-f3ba-c843-c9b9-7c06fbd62da7", + "type": "animated_java:vanilla_item_display" + }, + { + "name": "item_display3", + "position": [-26, 8, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 2, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:orange_dye", + "itemDisplay": "ground", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "vertical", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": false, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "0a0e0205-c124-0e26-3a2f-1d35f08b8790", + "type": "animated_java:vanilla_item_display" + }, + { + "name": "item_display5", + "position": [-36, 8, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 2, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:orange_dye", + "itemDisplay": "ground", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "horizontal", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": false, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "01475b0a-1cfb-55fc-f1f5-70dda0fc8d71", + "type": "animated_java:vanilla_item_display" } ], "groups": [ @@ -1067,23 +1370,27 @@ "origin": [0, 0, 0], "rotation": [0, 0, 0], "color": 0, - "onSummonFunction": "", + "onSummonFunction": "say Entityless bone on-summon", "configs": { "default": { + "on_apply_function": "say Entityless bone on-summon", "billboard": "fixed", - "brightness_override": 0, + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, - "glow_color": "#ffffff", "glowing": false, - "inherit_settings": true, + "override_glow_color": false, + "glow_color": "#ffffff", "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 }, "variants": {} }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1111,7 +1418,6 @@ "configs": { "default": { "billboard": "fixed", - "brightness_override": 0, "enchanted": false, "glow_color": "#ffffff", "glowing": false, @@ -1120,10 +1426,15 @@ "nbt": "{}", "shadow_radius": 0, "shadow_strength": 1, - "use_nbt": false + "use_nbt": false, + "sky_brightness": 0, + "block_brightness": 0 }, "variants": {} }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1147,22 +1458,41 @@ "origin": [0, 1, 6], "rotation": [0, 0, 0], "color": 0, - "onSummonFunction": "", + "onSummonFunction": "say Bone on-summon", "configs": { "default": { + "on_apply_function": "say Bone on-apply", "billboard": "fixed", - "brightness_override": 0, + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, - "glow_color": "#ffffff", "glowing": false, - "inherit_settings": true, + "override_glow_color": false, + "glow_color": "#ffffff", "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 }, - "variants": {} + "variants": { + "49521f4b-b970-e4bd-b594-2e05d2d46027": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + } + } + }, + "itemModelProperties": { + "tints": [] }, "children": [], "reset": false, @@ -1191,7 +1521,6 @@ "configs": { "default": { "billboard": "fixed", - "brightness_override": 0, "enchanted": false, "glowing": false, "override_glow_color": true, @@ -1201,10 +1530,15 @@ "nbt": "{}", "shadow_radius": 0, "shadow_strength": 1, - "use_nbt": false + "use_nbt": false, + "sky_brightness": 0, + "block_brightness": 0 }, "variants": {} }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1232,7 +1566,6 @@ "configs": { "default": { "billboard": "fixed", - "brightness_override": 0, "enchanted": false, "glowing": false, "override_glow_color": true, @@ -1242,12 +1575,17 @@ "nbt": "{}", "shadow_radius": 0, "shadow_strength": 1, - "use_nbt": false + "use_nbt": false, + "sky_brightness": 0, + "block_brightness": 0 }, "variants": { "5417306e-2c69-3f36-1e3c-edd904034a36": {} } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1275,7 +1613,6 @@ "configs": { "default": { "billboard": "fixed", - "brightness_override": 0, "enchanted": false, "glowing": false, "override_glow_color": true, @@ -1285,12 +1622,17 @@ "nbt": "{}", "shadow_radius": 0, "shadow_strength": 1, - "use_nbt": false + "use_nbt": false, + "sky_brightness": 0, + "block_brightness": 0 }, "variants": { "5417306e-2c69-3f36-1e3c-edd904034a36": {} } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1317,24 +1659,23 @@ "onSummonFunction": "", "configs": { "default": { + "on_apply_function": "", "billboard": "fixed", - "brightness_override": 0, + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, "glowing": false, "override_glow_color": true, "glow_color": "#ffffff", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 }, "variants": { "5417306e-2c69-3f36-1e3c-edd904034a36": { "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, "enchanted": false, "glowing": false, "override_glow_color": false, @@ -1344,25 +1685,29 @@ "nbt": "{}", "shadow_radius": 0, "shadow_strength": 1, - "use_nbt": false + "use_nbt": false, + "sky_brightness": 0, + "block_brightness": 0 }, "49521f4b-b970-e4bd-b594-2e05d2d46027": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, - "enchanted": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, "glowing": true, "override_glow_color": true, "glow_color": "#00ff06", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1389,38 +1734,39 @@ "onSummonFunction": "", "configs": { "default": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, "glowing": false, "override_glow_color": true, "glow_color": "#ffffff", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 }, "variants": { "49521f4b-b970-e4bd-b594-2e05d2d46027": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, - "enchanted": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, "glowing": true, "override_glow_color": true, "glow_color": "#c400ff", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1447,38 +1793,39 @@ "onSummonFunction": "", "configs": { "default": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, "glowing": false, "override_glow_color": true, "glow_color": "#ffffff", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 }, "variants": { "49521f4b-b970-e4bd-b594-2e05d2d46027": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, - "enchanted": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, "glowing": true, "override_glow_color": true, "glow_color": "#00ff9f", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1505,38 +1852,39 @@ "onSummonFunction": "", "configs": { "default": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, "glowing": false, "override_glow_color": true, "glow_color": "#ffffff", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 }, "variants": { "49521f4b-b970-e4bd-b594-2e05d2d46027": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, - "enchanted": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, "glowing": true, "override_glow_color": true, "glow_color": "#ff0000", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1563,36 +1911,39 @@ "onSummonFunction": "", "configs": { "default": { + "on_apply_function": "", "billboard": "fixed", - "brightness_override": 0, + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, - "glow_color": "#ffffff", "glowing": false, - "inherit_settings": true, + "override_glow_color": false, + "glow_color": "#ffffff", "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 }, "variants": { "49521f4b-b970-e4bd-b594-2e05d2d46027": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, - "enchanted": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, "glowing": true, "override_glow_color": true, "glow_color": "#ffee00", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1619,36 +1970,39 @@ "onSummonFunction": "", "configs": { "default": { + "on_apply_function": "", "billboard": "fixed", - "brightness_override": 0, + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, "enchanted": false, - "glow_color": "#ffffff", "glowing": false, - "inherit_settings": true, + "override_glow_color": false, + "glow_color": "#ffffff", "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 }, "variants": { "49521f4b-b970-e4bd-b594-2e05d2d46027": { + "on_apply_function": "", "billboard": "fixed", "override_brightness": false, - "brightness_override": 0, - "enchanted": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, "glowing": true, "override_glow_color": true, "glow_color": "#6e00ff", - "inherit_settings": true, "invisible": false, - "nbt": "{}", "shadow_radius": 0, - "shadow_strength": 1, - "use_nbt": false + "shadow_strength": 1 } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1738,7 +2092,15 @@ ] }, "c2e217f1-b50a-5c9a-b342-71a35e984046", - "29d6057b-8ee5-0e57-405d-f2d71c816a43" + "29d6057b-8ee5-0e57-405d-f2d71c816a43", + "23e0e18a-815e-9961-3090-320b8e026483", + "23475e18-f4ec-683a-396a-963ca2da06a1", + "857172ba-7e40-f659-9b57-c9e9030d5ebd", + "10960a14-0305-4213-fc7b-d9cb56e30a49", + "e1de5b7c-4e08-e515-6697-f24326e769c1", + "446c95f8-f3ba-c843-c9b9-7c06fbd62da7", + "0a0e0205-c124-0e26-3a2f-1d35f08b8790", + "01475b0a-1cfb-55fc-f1f5-70dda0fc8d71" ], "textures": [ { @@ -2241,12 +2603,6 @@ "rotation_global": false, "quaternion_interpolation": false }, - "3ffeee76-901e-f8a2-c29a-82f90e16fd1e": { - "name": "camera", - "type": "camera", - "rotation_global": false, - "quaternion_interpolation": false - }, "bc141119-7f51-9690-7e21-e119b34fb3a2": { "name": "item_display", "type": "animated_java:vanilla_item_display", @@ -2258,6 +2614,42 @@ "type": "animated_java:text_display", "rotation_global": false, "quaternion_interpolation": false + }, + "23e0e18a-815e-9961-3090-320b8e026483": { + "name": "interaction", + "type": "animated_java:interaction", + "rotation_global": false, + "quaternion_interpolation": false + }, + "23475e18-f4ec-683a-396a-963ca2da06a1": { + "name": "camera", + "type": "camera", + "rotation_global": false, + "quaternion_interpolation": false + }, + "857172ba-7e40-f659-9b57-c9e9030d5ebd": { + "name": "block_display", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "10960a14-0305-4213-fc7b-d9cb56e30a49": { + "name": "block_display2", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e1de5b7c-4e08-e515-6697-f24326e769c1": { + "name": "block_display4", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "446c95f8-f3ba-c843-c9b9-7c06fbd62da7": { + "name": "item_display1", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false } } }, @@ -2512,12 +2904,6 @@ "rotation_global": false, "quaternion_interpolation": false }, - "3ffeee76-901e-f8a2-c29a-82f90e16fd1e": { - "name": "camera", - "type": "camera", - "rotation_global": false, - "quaternion_interpolation": false - }, "bc141119-7f51-9690-7e21-e119b34fb3a2": { "name": "item_display", "type": "animated_java:vanilla_item_display", @@ -2529,6 +2915,42 @@ "type": "animated_java:text_display", "rotation_global": false, "quaternion_interpolation": false + }, + "23e0e18a-815e-9961-3090-320b8e026483": { + "name": "interaction", + "type": "animated_java:interaction", + "rotation_global": false, + "quaternion_interpolation": false + }, + "23475e18-f4ec-683a-396a-963ca2da06a1": { + "name": "camera", + "type": "camera", + "rotation_global": false, + "quaternion_interpolation": false + }, + "857172ba-7e40-f659-9b57-c9e9030d5ebd": { + "name": "block_display", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "10960a14-0305-4213-fc7b-d9cb56e30a49": { + "name": "block_display2", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e1de5b7c-4e08-e515-6697-f24326e769c1": { + "name": "block_display4", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "446c95f8-f3ba-c843-c9b9-7c06fbd62da7": { + "name": "item_display1", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false } } }, @@ -2539,7 +2961,7 @@ "override": false, "length": 1, "snapping": 20, - "selected": true, + "selected": false, "saved": true, "path": "", "scope": 0, @@ -2832,15 +3254,500 @@ "rotation_global": false, "quaternion_interpolation": false }, - "3ffeee76-901e-f8a2-c29a-82f90e16fd1e": { + "29d6057b-8ee5-0e57-405d-f2d71c816a43": { + "name": "keybinds", + "type": "animated_java:text_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "23e0e18a-815e-9961-3090-320b8e026483": { + "name": "interaction", + "type": "animated_java:interaction", + "rotation_global": false, + "quaternion_interpolation": false + }, + "23475e18-f4ec-683a-396a-963ca2da06a1": { "name": "camera", "type": "camera", "rotation_global": false, "quaternion_interpolation": false }, - "29d6057b-8ee5-0e57-405d-f2d71c816a43": { - "name": "keybinds", - "type": "animated_java:text_display", + "857172ba-7e40-f659-9b57-c9e9030d5ebd": { + "name": "block_display", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "10960a14-0305-4213-fc7b-d9cb56e30a49": { + "name": "block_display2", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e1de5b7c-4e08-e515-6697-f24326e769c1": { + "name": "block_display4", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "446c95f8-f3ba-c843-c9b9-7c06fbd62da7": { + "name": "item_display1", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "c8e3423a-e635-9b91-cf0e-6147a759c238", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "87345849-577a-499b-b464-d671a4eda812", + "time": 0.5, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + } + } + }, + { + "uuid": "fb8a8e54-971b-74b6-86ad-1a1af8a2d765", + "name": "camera", + "loop": "loop", + "override": false, + "length": 6, + "snapping": 20, + "selected": false, + "saved": true, + "path": "", + "scope": 0, + "anim_time_update": "", + "blend_weight": "", + "start_delay": "", + "loop_delay": "0", + "excluded_nodes": [], + "animators": { + "98795982-9c43-6e3e-eed9-2c776a957938": { + "name": "root", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "102db36a-eeda-0e6f-d5cc-c186ecda8165": { + "name": "baseplate_root", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "4f000ffc-11d6-3a4b-7c8d-6b5ba483228c": { + "name": "baseplate_pivot_a", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "5e08acae-d6ca-0dfd-9360-8cdb13c7a824": { + "name": "armor_stand_root", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "98a28100-07e8-849a-38b7-f56abc2c2e56": { + "name": "waist_pivot", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "49e67c2a-3d1d-792d-9c75-72ecbc0f92e0": { + "name": "body_waist_pivot", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "6c53311f-ffc8-e567-ff1b-65840698e9ba": { + "name": "body", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "808e3c26-7285-af3f-a079-d8b899176dd3": { + "name": "head", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "49024ded-4e1c-1f0b-9f1f-a80f64309897", + "time": 1, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "7612d738-ffab-d6ce-32e4-313937eff994", + "time": 2, + "color": -1, + "interpolation": "linear", + "easing": "easeInBounce", + "easingArgs": [0.25] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "16", + "z": "0" + } + ], + "uuid": "1e186185-2b6e-3841-382c-cc46aaa89074", + "time": 1.5, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "b5b52d2c-097c-08df-6457-372fbae12445": { + "name": "left_arm", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "215d1b02-0e64-a794-1b88-a9c5a6d7541c": { + "name": "right_arm", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "55b812fe-7e4c-b2a5-da5b-3a8c82f9fc69": { + "name": "left_leg", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "60d50d30-a018-429d-ba78-c5fb5804dd8a": { + "name": "right_leg", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "7de415a2-9fdd-e4b2-3455-c3bed72eb896": { + "name": "left_hand", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "7747736f-85e2-338f-207e-53f8d3d2fa39": { + "name": "right_hand", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "c2e217f1-b50a-5c9a-b342-71a35e984046": { + "name": "text_display", + "type": "animated_java:text_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "bc141119-7f51-9690-7e21-e119b34fb3a2": { + "name": "item_display", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "29d6057b-8ee5-0e57-405d-f2d71c816a43": { + "name": "keybinds", + "type": "animated_java:text_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "23e0e18a-815e-9961-3090-320b8e026483": { + "name": "interaction", + "type": "animated_java:interaction", + "rotation_global": false, + "quaternion_interpolation": false + }, + "23475e18-f4ec-683a-396a-963ca2da06a1": { + "name": "camera", + "type": "camera", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "position", + "data_points": [ + { + "x": "-64", + "y": "0", + "z": "0" + } + ], + "uuid": "94187f38-e3ff-e84b-8b7b-4398c35e2de9", + "time": 1, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutBack", + "easingArgs": [1] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "2b2389cb-48a0-72ee-3c30-a40d8e8cf9b9", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "-16", + "y": "32", + "z": "80" + } + ], + "uuid": "c3c2faab-015a-f34c-e189-77540085679e", + "time": 2, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutBack", + "easingArgs": [1] + }, + { + "channel": "position", + "data_points": [ + { + "x": "96", + "y": "-29", + "z": "-96" + } + ], + "uuid": "d073eed3-2fde-1231-f761-114237e42ac6", + "time": 3.5, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutBack", + "easingArgs": [1] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "-29", + "z": "-96" + } + ], + "uuid": "fcb9eb82-ff10-7baf-bc36-ad5181dc88e8", + "time": 5, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutBack", + "easingArgs": [1] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "1ed85be6-5b72-6256-5d3e-b74efab2b91b", + "time": 6, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "ab6e2bea-0e0e-2c67-38ec-04a8c60790e8", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "0", + "y": "-90", + "z": "0" + } + ], + "uuid": "04f0a0b2-8f7a-78e3-bf15-6ebf7582c77f", + "time": 1, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "-22.5", + "y": "0", + "z": "0" + } + ], + "uuid": "b587f2a5-01b7-640b-19db-cdd0004f54ec", + "time": 2, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "-167.7008", + "y": "61.3794", + "z": "-180" + } + ], + "uuid": "fa0df3b9-af62-023f-ee38-84ee2d1bf630", + "time": 3.5, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "-169.8404", + "y": "-6.643", + "z": "-184.0169" + } + ], + "uuid": "3154628c-a7d4-258f-5734-0703f3d3758b", + "time": 4.3, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "-169.8404", + "y": "-6.643", + "z": "-184.0169" + } + ], + "uuid": "a2675b1f-0246-6ae8-524a-21685b6a8cf2", + "time": 5, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "12f2731b-5459-a354-10ee-c7ba47a6af2f", + "time": 6, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "effects": { + "name": "Effects", + "type": "effect" + }, + "857172ba-7e40-f659-9b57-c9e9030d5ebd": { + "name": "block_display", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "10960a14-0305-4213-fc7b-d9cb56e30a49": { + "name": "block_display2", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e1de5b7c-4e08-e515-6697-f24326e769c1": { + "name": "block_display4", + "type": "animated_java:vanilla_block_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "446c95f8-f3ba-c843-c9b9-7c06fbd62da7": { + "name": "item_display1", + "type": "animated_java:vanilla_item_display", "rotation_global": false, "quaternion_interpolation": false } diff --git a/test-packs/latest/blueprints/nullobj_debug.ajblueprint b/test-packs/latest/blueprints/nullobj_debug.ajblueprint new file mode 100644 index 00000000..a0409cf2 --- /dev/null +++ b/test-packs/latest/blueprints/nullobj_debug.ajblueprint @@ -0,0 +1,999 @@ +{ + "meta": { + "format": "animated-java:format/blueprint", + "format_version": "1.10.0-beta.7", + "uuid": "c3cdebb1-18c7-5619-72da-93de2dde26f9", + "save_location": "/var/mnt/ssd2/repos/animated-java/animated-java/test-packs/latest/blueprints/nullobj_debug.ajblueprint", + "last_used_blueprint_id": "aj:nullobj_debug" + }, + "resolution": { + "width": 32, + "height": 32 + }, + "blueprint_settings": { + "blueprint_id": "aj:nullobj_debug", + "render_box": [48, 48], + "target_minecraft_version": "26.2", + "resource_pack": "../resources", + "data_pack": "../datapacks/animated_java", + "use_storage_for_animation": true + }, + "elements": [ + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [14, 0, -2], + "to": [18, 4, 2], + "autouv": 0, + "color": 1, + "origin": [15, 0, -1], + "faces": { + "north": { + "uv": [0, 0, 4, 4], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "east": { + "uv": [0, 4, 4, 8], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "south": { + "uv": [4, 0, 8, 4], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "west": { + "uv": [4, 4, 8, 8], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "up": { + "uv": [4, 12, 0, 8], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "down": { + "uv": [12, 0, 8, 4], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + } + }, + "type": "cube", + "uuid": "197eaf97-3bac-d0eb-130e-5771ed1c7f04" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [14, 4, -2], + "to": [18, 8, 2], + "autouv": 0, + "color": 1, + "origin": [15, 4, -1], + "faces": { + "north": { + "uv": [4, 8, 8, 12], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "east": { + "uv": [8, 4, 12, 8], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "south": { + "uv": [8, 8, 12, 12], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "west": { + "uv": [0, 12, 4, 16], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "up": { + "uv": [16, 4, 12, 0], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "down": { + "uv": [8, 12, 4, 16], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + } + }, + "type": "cube", + "uuid": "4ba74215-06cd-5424-c2c4-1d117fe0f040" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [14, 8, -2], + "to": [18, 12, 2], + "autouv": 0, + "color": 1, + "origin": [15, 8, -1], + "faces": { + "north": { + "uv": [12, 4, 16, 8], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "east": { + "uv": [8, 12, 12, 16], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "south": { + "uv": [12, 8, 16, 12], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "west": { + "uv": [12, 12, 16, 16], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "up": { + "uv": [4, 20, 0, 16], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "down": { + "uv": [20, 0, 16, 4], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + } + }, + "type": "cube", + "uuid": "7d07f208-0379-b160-7220-72e946d516f1" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [14, 12, -2], + "to": [18, 16, 2], + "autouv": 0, + "color": 1, + "origin": [15, 12, -1], + "faces": { + "north": { + "uv": [4, 16, 8, 20], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "east": { + "uv": [16, 4, 20, 8], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "south": { + "uv": [8, 16, 12, 20], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "west": { + "uv": [16, 8, 20, 12], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "up": { + "uv": [16, 20, 12, 16], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "down": { + "uv": [20, 12, 16, 16], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + } + }, + "type": "cube", + "uuid": "748a0277-c835-ba6a-d460-3f69ac625f3c" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [14, 16, -2], + "to": [18, 20, 2], + "autouv": 0, + "color": 1, + "origin": [15, 16, -1], + "faces": { + "north": { + "uv": [16, 16, 20, 20], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "east": { + "uv": [0, 20, 4, 24], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "south": { + "uv": [20, 0, 24, 4], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "west": { + "uv": [4, 20, 8, 24], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "up": { + "uv": [24, 8, 20, 4], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + }, + "down": { + "uv": [12, 20, 8, 24], + "texture": "3447a12a-7afa-d735-e734-2ba14a8bdfac" + } + }, + "type": "cube", + "uuid": "2b4e049e-ea8f-ddeb-54a5-4892e74b7566" + }, + { + "name": "ikset_a_end", + "position": [16, 20, 0], + "rotation": [0, 0, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": null, + "uuid": "c524c6f3-8ef0-4132-772d-adc30036891f", + "type": "locator" + }, + { + "name": "ikset_a_nullobj", + "position": [16, 21, 0], + "ik_target": "c524c6f3-8ef0-4132-772d-adc30036891f", + "ik_source": "", + "lock_ik_target_rotation": false, + "visibility": true, + "locked": false, + "scope": 0, + "uuid": "6090cbaf-91d9-4430-8671-ab0ca70197d5", + "type": "null_object" + }, + { + "name": "ikset_b_end", + "position": [-16, 65, 0], + "rotation": [0, 0, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": null, + "uuid": "78639e68-11d4-c191-d04f-413f3051ca99", + "type": "locator" + }, + { + "name": "ikset_b_nullobj", + "position": [-16, 67, 0], + "ik_target": "78639e68-11d4-c191-d04f-413f3051ca99", + "ik_source": "", + "lock_ik_target_rotation": false, + "visibility": true, + "locked": false, + "scope": 0, + "uuid": "a5db84bb-c6ec-044f-f3b7-49cb5f73671e", + "type": "null_object" + }, + { + "name": "item_display", + "position": [-16, 7, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 2, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:diamond", + "itemDisplay": "none", + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "scope": 0, + "uuid": "30c3409f-74cc-f580-05bc-253d1e176f15", + "type": "animated_java:vanilla_item_display" + }, + { + "name": "item_display2", + "position": [-16, 20, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 5, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:diamond", + "itemDisplay": "none", + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "scope": 0, + "uuid": "c1a1edc9-14cd-9e30-3d39-0dff91c0d95c", + "type": "animated_java:vanilla_item_display" + }, + { + "name": "item_display4", + "position": [-16, 33, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 0, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:diamond", + "itemDisplay": "none", + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "scope": 0, + "uuid": "0d5a51d0-b2fb-7617-35f7-9edc7e41b46e", + "type": "animated_java:vanilla_item_display" + }, + { + "name": "item_display6", + "position": [-16, 46, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 9, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:diamond", + "itemDisplay": "none", + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "scope": 0, + "uuid": "397a09d8-887a-71cc-e75a-285e2bf39dfb", + "type": "animated_java:vanilla_item_display" + }, + { + "name": "item_display8", + "position": [-16, 59, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 1, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:diamond", + "itemDisplay": "none", + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "scope": 0, + "uuid": "66f80e47-7e6b-fa92-234d-25fbea01d93f", + "type": "animated_java:vanilla_item_display" + } + ], + "groups": [ + { + "name": "ikset_a", + "uuid": "0693ff84-2af5-afaa-2cd3-1d5ac467288a", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [16, 0, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "ikset_a2", + "uuid": "d47d7df8-63b5-66db-9f5d-3b18ed73896c", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [16, 4, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": false, + "primary_selected": false + }, + { + "name": "ikset_a3", + "uuid": "77eb3316-510a-6904-ca65-02d741fa2dab", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [16, 8, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "ikset_a4", + "uuid": "2ed2eca6-eb9d-dcd6-5e66-0807499a1cf8", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [16, 12, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "ikset_a5", + "uuid": "32ae2984-8248-29c1-1266-167bd5c485d2", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [16, 16, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "ikset_b", + "uuid": "44029f19-2974-7928-a695-eeb60371df1f", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [-16, 0, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "ikset_b1", + "uuid": "498ccff4-2fe4-abad-79f1-3f59efbf1601", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [-16, 13, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": false, + "primary_selected": false + }, + { + "name": "ikset_b2", + "uuid": "16196f63-937f-bcd7-5646-a99495406380", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [-16, 26, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "ikset_b3", + "uuid": "0a999f31-27db-85f8-36c7-23175b246682", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [-16, 39, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "ikset_b4", + "uuid": "91e23e4b-e884-bbcf-c138-4fe640c7081b", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [-16, 52, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + } + ], + "outliner": [ + { + "uuid": "0693ff84-2af5-afaa-2cd3-1d5ac467288a", + "isOpen": true, + "children": [ + "197eaf97-3bac-d0eb-130e-5771ed1c7f04", + { + "uuid": "d47d7df8-63b5-66db-9f5d-3b18ed73896c", + "isOpen": false, + "children": [ + "4ba74215-06cd-5424-c2c4-1d117fe0f040", + { + "uuid": "77eb3316-510a-6904-ca65-02d741fa2dab", + "isOpen": true, + "children": [ + "7d07f208-0379-b160-7220-72e946d516f1", + { + "uuid": "2ed2eca6-eb9d-dcd6-5e66-0807499a1cf8", + "isOpen": true, + "children": [ + "748a0277-c835-ba6a-d460-3f69ac625f3c", + { + "uuid": "32ae2984-8248-29c1-1266-167bd5c485d2", + "isOpen": true, + "children": ["2b4e049e-ea8f-ddeb-54a5-4892e74b7566", "c524c6f3-8ef0-4132-772d-adc30036891f"] + } + ] + } + ] + } + ] + }, + "6090cbaf-91d9-4430-8671-ab0ca70197d5" + ] + }, + { + "uuid": "44029f19-2974-7928-a695-eeb60371df1f", + "isOpen": true, + "children": [ + "30c3409f-74cc-f580-05bc-253d1e176f15", + { + "uuid": "498ccff4-2fe4-abad-79f1-3f59efbf1601", + "isOpen": false, + "children": [ + "c1a1edc9-14cd-9e30-3d39-0dff91c0d95c", + { + "uuid": "16196f63-937f-bcd7-5646-a99495406380", + "isOpen": true, + "children": [ + "0d5a51d0-b2fb-7617-35f7-9edc7e41b46e", + { + "uuid": "0a999f31-27db-85f8-36c7-23175b246682", + "isOpen": true, + "children": [ + "397a09d8-887a-71cc-e75a-285e2bf39dfb", + { + "uuid": "91e23e4b-e884-bbcf-c138-4fe640c7081b", + "isOpen": true, + "children": ["66f80e47-7e6b-fa92-234d-25fbea01d93f", "78639e68-11d4-c191-d04f-413f3051ca99"] + } + ] + } + ] + } + ] + }, + "a5db84bb-c6ec-044f-f3b7-49cb5f73671e" + ] + } + ], + "textures": [ + { + "name": "texture", + "path": "", + "folder": "block", + "namespace": "", + "id": "0", + "group": "", + "scope": 0, + "width": 32, + "height": 32, + "uv_width": 32, + "uv_height": 32, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": false, + "uuid": "3447a12a-7afa-d735-e734-2ba14a8bdfac", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACU0lEQVR4AezUP2hUQRDH8XnbKFw6gzk5UQOCTWpJaWGn2Gh3hVjZKf6pUkgKwUYQ7FKo1SGCFop2ESyDdZqQhPwhB5cQQoocSSBw4Ttkwo9wybHwkkDIwYc3szv7dtl7u6k+vtFRW7MvO+rhk9cd9XtyoaO0j1jHEluPX6L/RrViIMaF2i0DMWoDVQMxhm9eNdjejz7spT5Wx0d7t6cvoFvHSbX5AuZbbUNMut2cMkTeXG4ZIp+YWTJETh8iZywiP+qZWkNjpna+9Ztaf3fF1NfWJVPaRzy++dzUUZPT5zswPHDZQAMqg9cMxKAPxOB7ATHoAzH4PkDciy+gV9Fx9vsCJpZXDDFRe27REDl9iJzvBZHTh/38wDcS7d2e6cXqI1NPbz8z9afdNPVp8I2pn5+3Td0ful6obpNqm+8A/xeig/8XkXOmcVjO94Loz3n6AnIGlF3rC+BMI17O/4vIOdM4LOd7QfTnPNOdXw1TW41RU/cqNVN6RxA/nl4zlTM5tb4D/H+gAdzrIAZnHMSgFsSgFsS5fAG5g8qs9wXw/yFezL2OyDnjiJxaRE4tIs95pn8P6qYu1kdN6R1ArLXEWkucMzm1vgPcAaAB3AEgBncAiEEtiEEtiHP5AnIHlVnvC+AOQLyYOwCRcwcgcmoRObWIPOeZPvR/NzX2/6Op+ttkSu954sbdvkLlTE6t7wBnHDSAMw5icMZBXDZfQNkvzXmfL4AzjhjIGUfknHFEXuYz/a2+KlTfyEihfnx5X6gyJ+ddvgMEp+V8Aec7cPZ3oNfp2gUAAP//frjhigAAAAZJREFUAwAvnqxQ0Gfj7QAAAABJRU5ErkJggg==" + } + ], + "variants": { + "default": { + "name": "default", + "display_name": "Default", + "uuid": "5e2203ee-567a-aa58-30e1-b09f0b6e9a1e", + "texture_map": {}, + "excluded_nodes": [], + "is_default": true + }, + "list": [] + }, + "animations": [ + { + "uuid": "4fed74cf-7353-d89d-10c2-219e39322ac1", + "name": "idle", + "loop": "loop", + "override": false, + "length": 2, + "snapping": 20, + "selected": true, + "saved": true, + "path": "", + "scope": 0, + "anim_time_update": "", + "blend_weight": "", + "start_delay": "", + "loop_delay": "0", + "excluded_nodes": [], + "animators": { + "0693ff84-2af5-afaa-2cd3-1d5ac467288a": { + "name": "ikset_a", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "d47d7df8-63b5-66db-9f5d-3b18ed73896c": { + "name": "ikset_a2", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "77eb3316-510a-6904-ca65-02d741fa2dab": { + "name": "ikset_a3", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "2ed2eca6-eb9d-dcd6-5e66-0807499a1cf8": { + "name": "ikset_a4", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "32ae2984-8248-29c1-1266-167bd5c485d2": { + "name": "ikset_a5", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "c524c6f3-8ef0-4132-772d-adc30036891f": { + "name": "ikset_a_end", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "6090cbaf-91d9-4430-8671-ab0ca70197d5": { + "name": "ikset_a_nullobj", + "type": "null_object", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "position", + "data_points": [ + { + "x": "math.sin(q.anim_time*360)*8", + "y": "-2", + "z": "math.cos(q.anim_time*360)*8" + } + ], + "uuid": "7a7e19bd-a0f7-386f-32e5-0daa3c7b256f", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "44029f19-2974-7928-a695-eeb60371df1f": { + "name": "ikset_b", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "498ccff4-2fe4-abad-79f1-3f59efbf1601": { + "name": "ikset_b1", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "16196f63-937f-bcd7-5646-a99495406380": { + "name": "ikset_b2", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "0a999f31-27db-85f8-36c7-23175b246682": { + "name": "ikset_b3", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "91e23e4b-e884-bbcf-c138-4fe640c7081b": { + "name": "ikset_b4", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "78639e68-11d4-c191-d04f-413f3051ca99": { + "name": "ikset_b_end", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "a5db84bb-c6ec-044f-f3b7-49cb5f73671e": { + "name": "ikset_b_nullobj", + "type": "null_object", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "position", + "data_points": [ + { + "x": "math.sin(q.anim_time*360)*32", + "y": "-14", + "z": "math.cos(q.anim_time*360)*32" + } + ], + "uuid": "763897ad-b2de-28ec-9a26-addd2310e365", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "30c3409f-74cc-f580-05bc-253d1e176f15": { + "name": "item_display", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "c1a1edc9-14cd-9e30-3d39-0dff91c0d95c": { + "name": "item_display2", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "0d5a51d0-b2fb-7617-35f7-9edc7e41b46e": { + "name": "item_display4", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "397a09d8-887a-71cc-e75a-285e2bf39dfb": { + "name": "item_display6", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false + }, + "66f80e47-7e6b-fa92-234d-25fbea01d93f": { + "name": "item_display8", + "type": "animated_java:vanilla_item_display", + "rotation_global": false, + "quaternion_interpolation": false + } + } + } + ] +} \ No newline at end of file diff --git a/test-packs/latest/datapacks/animated_java/pack.mcmeta b/test-packs/latest/datapacks/animated_java/pack.mcmeta index e18f2bf4..fd92acda 100644 --- a/test-packs/latest/datapacks/animated_java/pack.mcmeta +++ b/test-packs/latest/datapacks/animated_java/pack.mcmeta @@ -1,7 +1 @@ -{ - "pack": { - "description": "AJ Testing DP", - "min_format": 101, - "max_format": 101 - } -} \ No newline at end of file +{"pack":{"description":"AJ Testing DP","min_format":107,"max_format":107}} \ No newline at end of file diff --git a/test-packs/latest/resources/pack.mcmeta b/test-packs/latest/resources/pack.mcmeta index 95e4d0bf..1da31220 100644 --- a/test-packs/latest/resources/pack.mcmeta +++ b/test-packs/latest/resources/pack.mcmeta @@ -1,7 +1 @@ -{ - "pack": { - "min_format": 101, - "max_format": 101, - "description": "AJ Testing RP" - } -} \ No newline at end of file +{"pack":{"min_format":88,"max_format":88,"description":"AJ Testing RP"}} \ No newline at end of file diff --git a/test_blueprints/Boat.ajblueprint b/test_blueprints/Boat.ajblueprint new file mode 100644 index 00000000..cd5641cb --- /dev/null +++ b/test_blueprints/Boat.ajblueprint @@ -0,0 +1,7488 @@ +{ + "meta": { + "format": "animated-java:format/blueprint", + "format_version": "1.10.0-beta.6", + "uuid": "91138c0f-ad92-b88a-16f9-c433908bb3fe", + "save_location": "/var/mnt/ssd2/repos/animated-java/animated-java/test_blueprints/Boat.ajblueprint", + "last_used_blueprint_id": "aj_booth_rigs:boat" + }, + "resolution": { + "width": 256, + "height": 256 + }, + "blueprint_settings": { + "blueprint_id": "aj_booth_rigs:boat", + "auto_render_box": false, + "render_box": [6000, 400], + "target_minecraft_version": "26.1.1", + "resource_pack": "../test-packs/latest/resources", + "data_pack": "../test-packs/latest/datapacks/animated_java", + "custom_rig_entity_tags": "summit.booth_entity, summit.booth_entity.aj_booth", + "auto_update_rig_orientation": false, + "use_entity_stacking": true + }, + "elements": [ + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [127, 64, -96], + "to": [255, 128, 96], + "autouv": 0, + "color": 4, + "origin": [129, 0, 34], + "faces": { + "north": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 128, 128, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 64, 128, 0], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "5e659fb1-5bdb-c7b4-89f1-e324868eb2da" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-1, 0, 0], + "to": [127, 64, 96], + "autouv": 0, + "color": 4, + "rotation": [10, 0, 0], + "origin": [-1, 64, 96], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [128, 66, 0, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 128, 128, 66], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "9405d0f3-400c-d967-7fca-7a9f5ed775c4" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-1, 64, -96], + "to": [127, 128, 96], + "autouv": 0, + "color": 4, + "origin": [1, 0, 34], + "faces": { + "north": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 128, 128, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "64647b77-a18d-83cf-f2e7-d97e91afbd94" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-1, 0, -96], + "to": [127, 64, 0], + "autouv": 0, + "color": 4, + "rotation": [-10, 0, 0], + "origin": [-1, 64, -96], + "faces": { + "north": { + "uv": [0, 66, 128, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 66, 128, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "0f90c4e3-3436-4418-ec07-eeea5ff05a9f" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-129, 0, -96], + "to": [-1, 64, 0], + "autouv": 0, + "color": 4, + "rotation": [-10, 0, 0], + "origin": [-129, 64, -96], + "faces": { + "north": { + "uv": [0, 66, 128, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 66, 128, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "ca8a4af2-355f-dc9f-4dcc-c418a67910b1" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-129, 64, -96], + "to": [-1, 128, 96], + "autouv": 0, + "color": 4, + "origin": [-127, 0, 34], + "faces": { + "north": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 128, 128, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "9d2a11b5-aae7-088d-14bf-4d6699961114" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-129, 0, 0], + "to": [-1, 64, 96], + "autouv": 0, + "color": 4, + "rotation": [10, 0, 0], + "origin": [-129, 64, 96], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [128, 66, 0, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 128, 128, 66], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "be25ab78-6a24-1a90-2194-58d861886764" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-384, 0.9723, 11.11348], + "to": [-257, 64.9723, 107.11348], + "autouv": 0, + "color": 4, + "rotation": [10, -12.5, 0], + "origin": [-257, 128, 96], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [128, 66, 0, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 128, 128, 66], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "8041d0ef-b946-4b5e-bedd-65dc51ebaf16" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-385, 64, -96], + "to": [-257, 128.1, -69], + "autouv": 0, + "color": 4, + "rotation": [0, 12.5, 0], + "origin": [-257, 128, -96], + "faces": { + "north": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [128, 128, 0, 146], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "d5c49eed-0dc6-1730-455b-864ea49aeb6e" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-384, 0.9723, -107.11348], + "to": [-257, 64.9723, -11.11348], + "autouv": 0, + "color": 4, + "rotation": [-10, 12.5, 0], + "origin": [-257, 128, -96], + "faces": { + "north": { + "uv": [0, 66, 128, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 66, 128, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "0ed5962e-492b-aeba-360d-1c4c625654d7" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-257, 0, -96], + "to": [-129, 64, 0], + "autouv": 0, + "color": 4, + "rotation": [-10, 0, 0], + "origin": [-257, 64, -96], + "faces": { + "north": { + "uv": [0, 66, 128, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 66, 128, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "ed2969c0-90f2-b8da-f608-023c26a79148" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-257, 0, 0], + "to": [-129, 64, 96], + "autouv": 0, + "color": 4, + "rotation": [10, 0, 0], + "origin": [-257, 64, 96], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [128, 66, 0, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 128, 128, 66], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "670c4c56-2a4c-c6d8-9f6f-d9125163f473" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-381.96589, 64, -68.29573], + "to": [-256.96589, 128, 68.29573], + "autouv": 0, + "color": 4, + "origin": [-379.96589, 0, 61.70427], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 144, 128, 240], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "f5fe35d4-9104-62c1-70b9-9b5b2c63b0ad" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-380.98959, 0, -68.51217], + "to": [-365.98959, 64, -0.01217], + "autouv": 0, + "color": 4, + "rotation": [-9.9917, 0.9264, 2.37531], + "origin": [-380.98959, 64, -68.51217], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 64, 64, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [64, 64, 128, 79], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "f7457327-4f2a-9bb6-7ddd-8e7d4c157d5e" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-380.56101, 64, 55.46787], + "to": [-252.56101, 128.1, 82.46787], + "autouv": 0, + "color": 4, + "rotation": [0, -12.5, 0], + "origin": [-316.56101, 95.95, 68.96787], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [128, 146, 0, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "a708d731-8b77-7b96-7f53-1a0fd8648dd1" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [298.27889, 6.78701, -5.11058], + "to": [313.27889, 70.78701, 63.38942], + "autouv": 0, + "color": 4, + "rotation": [9.9917, 0.9264, -2.37531], + "origin": [305.77889, 38.78701, 29.13942], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [64, 66, 128, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 79, 64, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "a4ee4b85-cdb2-c7ac-9596-607b39e2b052" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [190, 0.9723, -107.11348], + "to": [318, 64.9723, -11.11348], + "autouv": 0, + "color": 4, + "rotation": [-10, -12.5, 0], + "origin": [190, 128, -96], + "faces": { + "north": { + "uv": [0, 66, 128, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 66, 128, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "bd75e803-c5e7-f378-ffd4-6d00f6aaf35a" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [190, 0.9723, 11.11348], + "to": [318, 64.9723, 107.11348], + "autouv": 0, + "color": 4, + "rotation": [10, 12.5, 0], + "origin": [190, 128, 96], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [128, 66, 0, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 128, 128, 66], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "b38defdc-e77e-fd79-9f75-12fd87ccac79" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [127, 0, -96], + "to": [190, 64, 0], + "autouv": 0, + "color": 4, + "rotation": [-10, 0, 0], + "origin": [62, 64, -96], + "faces": { + "north": { + "uv": [0, 64, 64, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 64, 64, 126], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "7ef38c32-220a-ad4a-b5d4-1b98c386d3fa" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [127, 0, 0], + "to": [190, 64, 96], + "autouv": 0, + "color": 4, + "rotation": [10, 0, 0], + "origin": [62, 64, 96], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [64, 64, 0, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 126, 64, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "87d42e52-9b74-f045-1eb5-d15cfecfacfb" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [255, 64, -96], + "to": [383, 128, 96], + "autouv": 0, + "color": 4, + "origin": [257, 0, 34], + "faces": { + "north": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 128, 128, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "208d76e5-f580-db23-4c91-73f7533120da" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-257, 64, -96], + "to": [-129, 128, 96], + "autouv": 0, + "color": 4, + "origin": [-255, 0, 34], + "faces": { + "north": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 128, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 128, 128, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "4317586b-ab40-7311-ab8f-7d7200a7ec86" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [298.27889, 6.78701, -63.38942], + "to": [313.27889, 70.78701, 5.11058], + "autouv": 0, + "color": 4, + "rotation": [-9.9917, -0.9264, -2.37531], + "origin": [305.77889, 38.78701, -29.13942], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [128, 66, 64, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [64, 79, 0, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "5b296704-86b7-e3dc-26a8-17b5a175a898" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-381.37584, -0.05999, 0.26503], + "to": [-366.37584, 63.94001, 68.76503], + "autouv": 0, + "color": 4, + "rotation": [9.9917, -0.9264, 2.37531], + "origin": [-381.37584, 63.94001, 68.76503], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [64, 64, 0, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [128, 64, 64, 79], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "6d4b8edc-e3f9-a8b3-5c21-f2ee27baf68e" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-382, 128, -68], + "to": [-382, 176, 0], + "autouv": 0, + "color": 4, + "origin": [-380, 128, -47], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [256, 0, 192, 48], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [192, 0, 256, 48], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "53d62d9c-aa71-2492-e1bd-55a574345e3d" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-382.68121, 128, -78.22007], + "to": [-254.68121, 176, -78.22007], + "autouv": 0, + "color": 4, + "rotation": [0, 12.5, 0], + "origin": [-335.68121, 128, -76.22007], + "faces": { + "north": { + "uv": [128, 0, 256, 48], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 0, 128, 48], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 270 + } + }, + "type": "cube", + "uuid": "5f4e0465-24fc-5565-ca07-ce77a822af1a" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-382.68121, 128, 78.22007], + "to": [-254.68121, 176, 78.22007], + "autouv": 0, + "color": 4, + "rotation": [0, -12.5, 0], + "origin": [-335.68121, 128, 76.22007], + "faces": { + "north": { + "uv": [128, 0, 256, 48], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 0, 128, 48], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 270 + } + }, + "type": "cube", + "uuid": "f461be6b-d6ea-cf20-2995-5c52f8c4044b" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-382, 128, 0], + "to": [-382, 176, 68], + "autouv": 0, + "color": 4, + "origin": [-380, 128, 47], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [192, 0, 256, 48], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [255, 0, 192, 48], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "18c6f2de-2804-2e68-40d1-f0e8cc06bc91" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-363.50931, 68, -68.3267], + "to": [-335.50931, 89, -68.3267], + "autouv": 0, + "color": 4, + "rotation": [0, 12.5, 0], + "origin": [-382.50931, 64, -66.1267], + "faces": { + "north": { + "uv": [128, 48, 156, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [128, 48, 156, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "2af25aa5-930a-9b58-b055-b59ebf35f5e8" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-363.50931, 68, 68.3267], + "to": [-335.50931, 89, 68.3267], + "autouv": 0, + "color": 4, + "rotation": [0, -12.5, 0], + "origin": [-382.50931, 64, 66.1267], + "faces": { + "north": { + "uv": [156, 48, 128, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [156, 48, 128, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "a86c36d3-9115-78dc-680d-d9eb21726dd2" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-128, 128, -93], + "to": [-2, 140, -93], + "autouv": 0, + "color": 4, + "origin": [-127, 128, -91], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "1e6b35ca-88e2-eecd-0088-12bc95b89724" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [128, 128, -93], + "to": [254, 140, -93], + "autouv": 0, + "color": 4, + "origin": [129, 128, -91], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "67482715-a85e-f6e9-faa7-102de2debd88" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [0, 128, -93], + "to": [126, 140, -93], + "autouv": 0, + "color": 4, + "origin": [1, 128, -91], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "6a07aa5c-b411-14c5-b43e-47228ee432aa" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [256, 128, -93], + "to": [382, 140, -93], + "autouv": 0, + "color": 4, + "origin": [257, 128, -91], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "55b5ef35-86f5-d349-849c-5a61f04157fe" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-256, 128, 93], + "to": [-192, 140, 93], + "autouv": 0, + "color": 4, + "origin": [-255, 128, 95], + "faces": { + "north": { + "uv": [191, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 191, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "472dbdf1-3181-bc2f-0efc-93e0583d25b1" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-128, 128, 93], + "to": [-2, 140, 93], + "autouv": 0, + "color": 4, + "origin": [-127, 128, 95], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "49e38cfe-0ac0-10c5-0682-98e11e2f8451" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [0, 128, 93], + "to": [126, 140, 93], + "autouv": 0, + "color": 4, + "origin": [1, 128, 95], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "f74cc783-17f6-45b7-4797-7e3084f43a22" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [128, 128, 93], + "to": [254, 140, 93], + "autouv": 0, + "color": 4, + "origin": [129, 128, 95], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "9ad4878f-6ca2-9e4c-e4a5-ac49053ee224" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [256, 128, 93], + "to": [382, 140, 93], + "autouv": 0, + "color": 4, + "origin": [257, 128, 95], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "eb4fa8a8-8299-df54-30f3-c88888ebf578" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-366.56101, 105, 55.71787], + "to": [-266.56101, 121, 82.71787], + "autouv": 0, + "color": 4, + "rotation": [0, -12.5, 0], + "origin": [-316.56101, 87.95, 68.96787], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [156, 48, 248, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [128, 146, 0, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "ca3e6a9b-3bb4-9e55-0d24-fdb02a0306c9" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-328.50931, 63, -68.3267], + "to": [-322.50931, 73, -68.3267], + "autouv": 0, + "color": 4, + "rotation": [0, 12.5, 0], + "origin": [-382.50931, 64, -66.1267], + "faces": { + "north": { + "uv": [176, 62, 186, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "c0e5275f-a058-ccb9-106a-ce4648679003" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-330.95632, 12.15192, -88.00675], + "to": [-324.95632, 63.15192, -88.00675], + "autouv": 0, + "color": 4, + "rotation": [-10, 12.5, 0], + "origin": [-285.95632, 53.15192, -88.00675], + "faces": { + "north": { + "uv": [176, 62, 227, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "aad6a689-3adb-715c-b55d-0070a2a8b177" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [259.95632, 12.15192, -88.00675], + "to": [265.95632, 63.15192, -88.00675], + "autouv": 0, + "color": 4, + "rotation": [-10, -12.5, 0], + "origin": [220.95632, 53.15192, -88.00675], + "faces": { + "north": { + "uv": [176, 62, 227, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "3cbd18c1-e818-2b4b-8891-92377bdde3d6" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [259.5, 63, -96.2], + "to": [265.5, 73, -78.2], + "autouv": 0, + "color": 4, + "origin": [382, 76.5, -96], + "faces": { + "north": { + "uv": [176, 62, 186, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [156, 69, 181, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "4f558bf0-2c57-395a-23b0-d04b16d3a86b" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-34.50931, 12.15192, -94.59022], + "to": [-28.50931, 63.15192, -94.59022], + "autouv": 0, + "color": 4, + "rotation": [-10, 0, 0], + "origin": [10.49069, 53.15192, -94.59022], + "faces": { + "north": { + "uv": [176, 62, 227, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "864ce9f0-00b5-8faa-2206-12d93dd1086c" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-34.50931, 63, -96.3267], + "to": [-28.50931, 73, -96.3267], + "autouv": 0, + "color": 4, + "origin": [-88.50931, 64, -94.1267], + "faces": { + "north": { + "uv": [176, 62, 186, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "d93c5c04-4213-8840-4246-37d76a5c279f" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [259.95632, 12.15192, 88.00675], + "to": [265.95632, 63.15192, 88.00675], + "autouv": 0, + "color": 4, + "rotation": [10, 12.5, 0], + "origin": [220.95632, 53.15192, 88.00675], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [176, 69, 227, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "a1248584-fe3a-e835-1174-7db17d2f10bb" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [259.5, 63, 78.2], + "to": [265.5, 73, 96.2], + "autouv": 0, + "color": 4, + "origin": [382, 76.5, 96], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [176, 69, 186, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [181, 69, 156, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "f9a82054-eaa9-72c1-9b6c-c84d9fd82005" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-34.50931, 63, 96.3267], + "to": [-28.50931, 73, 96.3267], + "autouv": 0, + "color": 4, + "origin": [-88.50931, 64, 94.1267], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [176, 69, 186, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "645422e9-affc-74fa-4dd5-5977fce9f170" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-34.50931, 12.15192, 94.59022], + "to": [-28.50931, 63.15192, 94.59022], + "autouv": 0, + "color": 4, + "rotation": [10, 0, 0], + "origin": [10.49069, 53.15192, 94.59022], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [176, 69, 227, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "15605b7e-0839-c58a-e5f6-bb8a12ecef89" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-330.95632, 12.15192, 88.00675], + "to": [-324.95632, 63.15192, 88.00675], + "autouv": 0, + "color": 4, + "rotation": [10, -12.5, 0], + "origin": [-285.95632, 53.15192, 88.00675], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [176, 69, 227, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "30654020-63e0-ab74-b948-540ad51276c0" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-328.50931, 63, 68.3267], + "to": [-322.50931, 73, 68.3267], + "autouv": 0, + "color": 4, + "rotation": [0, -12.5, 0], + "origin": [-382.50931, 64, 66.1267], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [176, 69, 186, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "a1a0f5c3-23c5-d9ca-c75e-c4a86243e5c7" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [319, 128, -30], + "to": [505, 140, -30], + "autouv": 0, + "color": 4, + "rotation": [0, -90, 0], + "origin": [382, 134, -30], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "0babf9ad-2cdb-aa0c-aabc-1804ff394379" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-241.50931, 63, -96.3267], + "to": [-237.50931, 88, 96.6733], + "autouv": 0, + "color": 4, + "origin": [-88.50931, 64, -94.1267], + "faces": { + "north": { + "uv": [227, 64, 256, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [227, 64, 256, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "44df66aa-25e1-0b68-1ed9-3a7acfb7b6a7" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-51.50931, 63, -96.3267], + "to": [-47.50931, 88, 96.6733], + "autouv": 0, + "color": 4, + "origin": [-88.50931, 64, -94.1267], + "faces": { + "north": { + "uv": [227, 64, 256, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [227, 64, 256, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "16f4580e-05d3-cdbb-ca69-0dd9f94d303e" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [138.49069, 63, -96.3267], + "to": [142.49069, 88, 96.6733], + "autouv": 0, + "color": 4, + "origin": [-88.50931, 64, -94.1267], + "faces": { + "north": { + "uv": [227, 64, 256, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [227, 64, 256, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "bd46870a-2ba0-dc71-4e55-d6518d0a198e" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [192, 128, -80], + "to": [314, 192, 80], + "autouv": 0, + "color": 4, + "origin": [50, 128, -336], + "faces": { + "north": { + "uv": [128, 192, 256, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [128, 192, 256, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [128, 192, 256, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [128, 192, 256, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "a6560fb3-700a-e736-d95a-bcb5b4f2acf7" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [192, 192, -80], + "to": [314, 256, 80], + "autouv": 0, + "color": 4, + "origin": [50, 128, -336], + "faces": { + "north": { + "uv": [128, 192, 256, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [128, 192, 256, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [128, 192, 256, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [128, 192, 256, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "ed011ccd-afec-40a5-2472-cadaa6a5a95c" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [226, 353, -25], + "to": [274, 369, 23], + "autouv": 0, + "color": 4, + "origin": [228, 353, -15], + "faces": { + "north": { + "uv": [184, 104, 220, 116], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [184, 104, 220, 116], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [184, 104, 220, 116], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [184, 104, 220, 116], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [175, 221, 211, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [175, 221, 211, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "d7ae32a6-b45f-ec04-8c42-e1c800cd0f08" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [215, 128, -92], + "to": [337, 160, 92], + "autouv": 0, + "color": 4, + "origin": [73, 128, -324], + "faces": { + "north": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [170.5, 225.5, 213.5, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "660d38e9-969b-5a03-b789-1909850737fa" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [215, 160, -92], + "to": [337, 192, 92], + "autouv": 0, + "color": 4, + "origin": [73, 160, -324], + "faces": { + "north": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [170.5, 225.5, 213.5, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "c8ffe271-56ee-96a1-8698-a69aeabb0944" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [215, 128, 92], + "to": [337, 160, -92], + "autouv": 0, + "color": 4, + "origin": [73, 128, -140], + "faces": { + "north": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [170.5, 225.5, 213.5, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "f034dcee-4408-ad30-cbe8-0bead11547fd" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [215, 160, 92], + "to": [337, 192, -92], + "autouv": 0, + "color": 4, + "origin": [73, 160, -140], + "faces": { + "north": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [128, 160, 256, 192], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [170.5, 225.5, 213.5, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "328971ae-0a5c-de0a-948e-f1abaacb83ad" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [252, 128, -87], + "to": [413, 148, -74], + "autouv": 0, + "color": 4, + "rotation": [0, -90, 0], + "origin": [252, 138, -80.5], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [128, 81, 141, 101], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [128, 81, 141, 101], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "1cf43ece-7175-22b3-fa72-6d6a63d4b1a3" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [252, 160, -87], + "to": [413, 180, -74], + "autouv": 0, + "color": 4, + "rotation": [0, -90, 0], + "origin": [252, 170, -80.5], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [128, 81, 141, 101], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [128, 81, 141, 101], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "2bd3f1e1-d48a-afde-aec6-09b7c78074d4" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [189, 256, -92], + "to": [317, 288, 92], + "autouv": 0, + "color": 4, + "origin": [50, 256, -324], + "faces": { + "north": { + "uv": [220, 128, 128, 160], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [128, 128, 256, 160], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [128, 128, 220, 160], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [128, 128, 256, 160], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [170.5, 225.5, 213.5, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [170.5, 225.5, 213.5, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "403fd41e-12c3-e013-f4cc-b57c2c5c4498" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [317, 256, -92], + "to": [189, 288, 92], + "autouv": 0, + "color": 4, + "origin": [178, 256, -324], + "faces": { + "north": { + "uv": [220, 128, 128, 160], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [128, 128, 256, 160], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [128, 128, 220, 160], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [128, 128, 256, 160], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [170.5, 225.5, 213.5, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [170.5, 225.5, 213.5, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "c900f1e8-0c17-1360-93fd-a2d806ef96cf" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [205, 256, -76], + "to": [301, 288, 76], + "autouv": 0, + "color": 4, + "origin": [50, 256, -324], + "faces": { + "north": { + "uv": [248, 48, 256, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [248, 48, 256, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [248, 48, 256, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [248, 48, 256, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + } + }, + "type": "cube", + "uuid": "0e040013-495f-3274-2014-3cac218ea9c5" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [185, 126, -13], + "to": [185, 128, 94], + "autouv": 0, + "color": 4, + "rotation": [57.54845, -1.87972, -2.95293], + "origin": [185, 126.5, 93], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [256, 62, 227, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [227, 62, 256, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "1c8e6436-392e-6a2d-01b9-6b95f7b7c676" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [185, 126, -94], + "to": [185, 128, 13], + "autouv": 0, + "color": 4, + "rotation": [-57.54845, 1.87972, -2.95293], + "origin": [185, 126.5, -93], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [227, 62, 256, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [256, 62, 227, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "92c433df-15ac-fdc7-d800-f5613474bd91" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [184, 126, 6], + "to": [184, 128, 94], + "autouv": 0, + "color": 4, + "rotation": [52.61746, -3.09502, -4.54287], + "origin": [184, 126.5, 93], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [256, 62, 227, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [227, 62, 256, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "67235805-4209-5be0-03a6-461d1e23821f" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [184, 126, -93], + "to": [184, 128, -5], + "autouv": 0, + "color": 4, + "rotation": [-52.61746, 3.09502, -4.54287], + "origin": [184, 126.5, -92], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [227, 62, 256, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [256, 62, 227, 64], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "6db36e10-8bbd-57a6-deb1-1be5d0fcf050" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [190, 288, 90], + "to": [316, 300, 90], + "autouv": 0, + "color": 4, + "origin": [191, 288, 92], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "02226c83-2ee9-e23b-212c-14407e3d46d9" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [190, 288, -89], + "to": [316, 300, -89], + "autouv": 0, + "color": 4, + "origin": [191, 288, -91], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "68e4336e-debe-ec0e-c69c-c2f52be52632" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [360, 0, -1], + "to": [407, 64, 7], + "autouv": 0, + "color": 4, + "rotation": [0, 0, -5], + "origin": [368.5, 50, 3], + "faces": { + "north": { + "uv": [0, 64, 47, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 64, 6, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 64, 47, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 64, 6, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 77, 47, 83], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 47, 47, 53], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + } + }, + "type": "cube", + "uuid": "951d7624-4623-f1df-566e-51a6f0001978" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [348, 36, -4.5], + "to": [372, 64, 10.5], + "autouv": 0, + "color": 4, + "origin": [337.5, 44.5, 1.5], + "faces": { + "north": { + "uv": [128, 104, 152, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [152, 104, 168, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [152, 104, 128, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [168, 104, 184, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [152, 104, 168, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [168, 104, 184, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "895b228c-99cd-9623-3ef8-3f3d09c7abef" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [328, 26, -24], + "to": [331, 48, 30], + "autouv": 0, + "color": 4, + "rotation": [90, 0, 0], + "origin": [329.5, 37, 3], + "faces": { + "north": { + "uv": [141, 103, 142, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [141, 81, 185, 103], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [141, 81, 142, 103], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [141, 103, 185, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [185, 81, 141, 82], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [141, 102, 185, 103], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "86120dd6-9cf4-3d9b-c087-faa2c75526f5" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [325, 29, -5], + "to": [334, 45, 11], + "autouv": 0, + "color": 4, + "origin": [329.5, 37, 3], + "faces": { + "north": { + "uv": [169, 85, 170, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [156, 85, 170, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [156, 85, 157, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [156, 85, 170, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [170, 85, 156, 86], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [156, 98, 170, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "78358566-ee17-b4b7-9cee-109c2df8d944" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [331, 26, -24], + "to": [328, 48, 30], + "autouv": 0, + "color": 4, + "rotation": [90, 0, 0], + "origin": [329.5, 37, 3], + "faces": { + "north": { + "uv": [141, 103, 142, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [141, 81, 185, 103], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [141, 81, 142, 103], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [141, 103, 185, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [185, 81, 141, 82], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [141, 102, 185, 103], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "7264eb57-316b-eed3-1db8-679270987a4b" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [303, 25, -3.5], + "to": [332, 54, 9.5], + "autouv": 0, + "color": 4, + "rotation": [0, 0, 135], + "origin": [315, 37, 3], + "faces": { + "north": { + "uv": [128, 104, 152, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [152, 104, 168, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [152, 104, 128, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [168, 104, 184, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [152, 104, 168, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [168, 104, 184, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "d09e4244-f9d0-79c1-f8f2-a67933d9fe79" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [311, 313, 48], + "to": [311, 326, 112], + "autouv": 0, + "color": 4, + "rotation": [-90, 0, 0], + "origin": [311, 319.5, 80], + "faces": { + "north": { + "uv": [0, 30, 0, 43], + "texture": null + }, + "east": { + "uv": [256, 116, 192, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 30, 0, 43], + "texture": null + }, + "west": { + "uv": [192, 116, 256, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 64], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 64], + "texture": null + } + }, + "type": "cube", + "uuid": "e5b4bf99-0c59-2816-cac8-5626aa443bb8" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [311, 313, 48], + "to": [311, 326, 112], + "autouv": 0, + "color": 4, + "rotation": [0, 90, 90], + "origin": [311, 319.5, 80], + "faces": { + "north": { + "uv": [0, 30, 0, 43], + "texture": null + }, + "east": { + "uv": [256, 116, 192, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 30, 0, 43], + "texture": null + }, + "west": { + "uv": [192, 116, 256, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 64], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 64], + "texture": null + } + }, + "type": "cube", + "uuid": "56c91558-fbc7-3d7b-f3ea-c35223265371" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [242, 288, -9], + "to": [258, 353, 7], + "autouv": 0, + "color": 4, + "origin": [229, 309, -22], + "faces": { + "north": { + "uv": [256, 200, 240, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [240, 200, 256, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [256, 200, 240, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [240, 200, 256, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "82b543bd-be60-a207-069c-4d24b1996a89" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [131, 288, -30], + "to": [310, 300, -30], + "autouv": 0, + "color": 4, + "rotation": [0, -90, 0], + "origin": [190, 294, -30], + "faces": { + "north": { + "uv": [128, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "0e159325-7c9a-ce19-af17-6cedd6f0d5fe" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [250, 333, -20], + "to": [250, 349, 18], + "autouv": 0, + "color": 4, + "rotation": [0, 45, 0], + "origin": [250, 341, -1], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [201, 81, 185, 93], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [185, 81, 201, 93], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "4670735b-1cc3-be02-06b3-4d47de832d81" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [250, 308, -20], + "to": [250, 324, 18], + "autouv": 0, + "color": 4, + "rotation": [0, -45, 0], + "origin": [250, 316, -1], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [201, 93, 185, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [185, 93, 201, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "517046e9-d030-e684-0296-15da06767164" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [267, 366, -22], + "to": [267, 379, 14], + "autouv": 0, + "color": 4, + "rotation": [-90, 0, 0], + "origin": [267, 372.5, -18], + "faces": { + "north": { + "uv": [0, 30, 0, 43], + "texture": null + }, + "east": { + "uv": [256, 116, 220, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 30, 0, 43], + "texture": null + }, + "west": { + "uv": [220, 116, 256, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 28, 0, 64], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 36], + "texture": null + } + }, + "type": "cube", + "uuid": "cb0b84e7-5764-1447-d3e8-66895418ed99" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [267, 366, -22], + "to": [267, 379, 14], + "autouv": 0, + "color": 4, + "rotation": [0, 90, 90], + "origin": [267, 372.5, -18], + "faces": { + "north": { + "uv": [0, 30, 0, 43], + "texture": null + }, + "east": { + "uv": [256, 116, 220, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 30, 0, 43], + "texture": null + }, + "west": { + "uv": [220, 116, 256, 128], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 28, 0, 64], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 36], + "texture": null + } + }, + "type": "cube", + "uuid": "56a45255-7a58-cd2f-6994-f0b2a747dbfb" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-366.56101, 105, -82.71787], + "to": [-266.56101, 121, -55.71787], + "autouv": 0, + "color": 4, + "rotation": [0, 12.5, 0], + "origin": [-316.56101, 87.95, -68.96787], + "faces": { + "north": { + "uv": [156, 48, 248, 62], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [128, 128, 0, 146], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "e2d226fd-e30b-85e6-2cc0-171f41efcb77" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [93, 68, 96.5], + "to": [121, 89, 96.5], + "autouv": 0, + "color": 4, + "origin": [106.50931, 78.5, 96.8267], + "faces": { + "north": { + "uv": [128, 48, 156, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [128, 48, 156, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "532ec260-eed1-6fd1-3053-f964741cee00" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [93, 68, -96.5], + "to": [121, 89, -96.5], + "autouv": 0, + "color": 4, + "origin": [106.50931, 78.5, -96.8267], + "faces": { + "north": { + "uv": [156, 48, 128, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [156, 48, 128, 69], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "00a138af-51f1-3f69-1d8e-211dbe60939d" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [54, 128, -92], + "to": [64, 130, 92], + "autouv": 0, + "color": 4, + "origin": [56, 128, -13], + "faces": { + "north": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "south": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "up": { + "uv": [55, 130, 64, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "b20352a1-9df8-bbbe-8fef-3d7bef4719fe" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [118, 128, -92], + "to": [128, 130, 92], + "autouv": 0, + "color": 4, + "origin": [120, 128, -13], + "faces": { + "north": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "south": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "up": { + "uv": [55, 130, 64, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "e48a8e89-8124-2b93-ac03-4859305975eb" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-44, 128, -92], + "to": [-34, 130, 92], + "autouv": 0, + "color": 4, + "origin": [-42, 128, -13], + "faces": { + "north": { + "uv": [85, 129, 94, 131], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [84, 129, 85, 251], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "south": { + "uv": [85, 129, 94, 131], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [84, 129, 85, 251], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "up": { + "uv": [85, 129, 94, 251], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "961d6fd9-c43d-c58d-203b-04d766d871fe" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [152, 128, -92], + "to": [162, 130, 92], + "autouv": 0, + "color": 4, + "origin": [154, 128, -13], + "faces": { + "north": { + "uv": [25, 134, 34, 136], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [24, 134, 25, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "south": { + "uv": [25, 134, 34, 136], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [24, 134, 25, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "up": { + "uv": [25, 134, 34, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "313dde48-2aea-335b-dc49-b90133747b9a" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-85, 128, -92], + "to": [-75, 130, 92], + "autouv": 0, + "color": 4, + "origin": [-83, 128, -13], + "faces": { + "north": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "south": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [54, 252, 55, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "up": { + "uv": [55, 252, 64, 130], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "51f8bb61-c665-84c6-91a9-ec5a105802ec" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-149, 128, -92], + "to": [-139, 130, 92], + "autouv": 0, + "color": 4, + "origin": [-147, 128, -13], + "faces": { + "north": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "south": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "up": { + "uv": [55, 130, 64, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "8cd2f934-21e3-4dab-f958-c226d655e924" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-213, 128, -92], + "to": [-203, 130, 92], + "autouv": 0, + "color": 4, + "origin": [-211, 128, -13], + "faces": { + "north": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "south": { + "uv": [55, 130, 64, 132], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [54, 130, 55, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "up": { + "uv": [55, 130, 64, 252], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "0aba89ac-e91a-de4f-fec3-ac092d02b787" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [194, 288, -84], + "to": [238, 311, -40], + "autouv": 0, + "color": 4, + "origin": [196, 288, -78], + "faces": { + "north": { + "uv": [170, 225, 214, 248], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [170, 225, 214, 248], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [170, 225, 214, 248], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [170, 225, 214, 248], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [170, 225, 214, 256], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "684c5a0c-59ea-7804-c770-7ab063d65451" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [203, 328, -87], + "to": [207, 330, -59], + "autouv": 0, + "color": 4, + "rotation": [0, 45, 0], + "origin": [205, 324.5, -73], + "faces": { + "north": { + "uv": [185, 97, 189, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [185, 97, 203, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [185, 97, 189, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [185, 97, 203, 99], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [185, 93, 203, 97], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "down": { + "uv": [185, 99, 203, 103], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + } + }, + "type": "cube", + "uuid": "e136b3d8-9cc1-52d0-ca43-bd3427e9e5aa" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [199, 319, -79], + "to": [211, 321, -67], + "autouv": 0, + "color": 4, + "rotation": [0, 45, 0], + "origin": [205, 324.5, -73], + "faces": { + "north": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + } + }, + "type": "cube", + "uuid": "443de56c-7843-d7e1-8eae-5819a60b1677" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [211, 319, -79], + "to": [199, 321, -67], + "autouv": 0, + "color": 4, + "rotation": [0, 45, 0], + "origin": [205, 324.5, -73], + "faces": { + "north": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + } + }, + "type": "cube", + "uuid": "821712b5-88f9-a56b-6daf-8542f86a9078" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [203.5, 311, -74], + "to": [206.5, 328, -71], + "autouv": 0, + "color": 4, + "origin": [190.5, 332, -100], + "faces": { + "north": { + "uv": [256, 220.30769, 253, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [253, 220.30769, 256, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [256, 220.30769, 253, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [253, 220.30769, 256, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "2c0c2309-2d4f-59e9-103b-b7942a3eba1d" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [199, 314, -79], + "to": [211, 316, -67], + "autouv": 0, + "color": 4, + "rotation": [0, 45, 0], + "origin": [205, 319.5, -73], + "faces": { + "north": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [185, 98, 203, 100], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null, + "rotation": 90 + } + }, + "type": "cube", + "uuid": "96125b72-933f-2334-514f-25bbf4fd031d" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [196, 311, -45], + "to": [196, 331, -43], + "autouv": 0, + "color": 4, + "origin": [195.5, 319.5, -44], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "10fb2bb5-e588-7d14-c893-f729e4348855" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [196, 311, -45], + "to": [196, 331, -43], + "autouv": 0, + "color": 4, + "rotation": [0, 90, 0], + "origin": [196, 324, -44], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "b42fa378-84a7-ac68-63b8-1919e14aa837" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [204, 311, -43], + "to": [204, 326, -41], + "autouv": 0, + "color": 4, + "rotation": [0, 90, 0], + "origin": [204, 324, -42], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "fd873c7a-d8e3-b1c9-4667-02baefa7c368" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [204, 311, -43], + "to": [204, 326, -41], + "autouv": 0, + "color": 4, + "origin": [203.5, 319.5, -42], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "522432b3-03a3-778d-bd80-b219f39a2b47" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [231, 369, 19], + "to": [231, 384, 21], + "autouv": 0, + "color": 4, + "origin": [230.5, 377.5, 20], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "72c34c0a-037a-9c9a-2e16-5663b9706c88" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [231, 369, 19], + "to": [231, 384, 21], + "autouv": 0, + "color": 4, + "rotation": [0, 90, 0], + "origin": [231, 382, 20], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "6d7a4c19-6432-3d5b-e39a-f83c142d3809" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [231, 369, 14], + "to": [231, 380, 16], + "autouv": 0, + "color": 4, + "rotation": [0, 90, 0], + "origin": [231, 382, 15], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "816816d4-9e48-678b-15da-cde47ff6b2f8" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [231, 369, 14], + "to": [231, 380, 16], + "autouv": 0, + "color": 4, + "origin": [230.5, 377.5, 15], + "faces": { + "north": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "east": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "south": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "west": { + "uv": [253, 220.30769, 255, 230], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "55625cd4-fbda-3caf-5da9-ee0b8b2c35f1" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-184, 65, -97], + "to": [-168, 128, 97], + "autouv": 0, + "color": 4, + "origin": [-182, 65, 59], + "faces": { + "north": { + "uv": [203, 81, 256, 97], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [203, 81, 256, 97], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "3fc23fd5-f5d1-2a23-9478-35b9cbf84a02" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-163, 128, 93], + "to": [-130, 140, 93], + "autouv": 0, + "color": 4, + "origin": [-255, 128, 95], + "faces": { + "north": { + "uv": [128, 69, 161, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [161, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "4fe4b76c-ae4d-1eee-2027-c71cd7ea59ea" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-163, 128, -93], + "to": [-130, 140, -93], + "autouv": 0, + "color": 4, + "origin": [-255, 128, -91], + "faces": { + "north": { + "uv": [128, 69, 161, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [161, 69, 128, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "993a7030-2fd0-f3f3-bcd3-258d7fbcd32a" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-256, 128, -93], + "to": [-192, 140, -93], + "autouv": 0, + "color": 4, + "origin": [-255, 128, -91], + "faces": { + "north": { + "uv": [191, 69, 256, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [256, 69, 191, 81], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "fc4497ad-fac8-8095-daa4-b81d07435bc5" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-316.21365, 68, 88.61987], + "to": [-296.21365, 88, 88.61987], + "autouv": 0, + "color": 4, + "rotation": [0, -12.5, 0], + "origin": [-291.21365, 75, 88.61987], + "faces": { + "north": { + "uv": [237, 97, 256, 116], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [237, 97, 256, 116], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "6f74c002-ab97-c12b-8cdb-81da5184cb61" + }, + { + "name": "dupe", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-184, 34, -97], + "to": [-168, 66, 97], + "autouv": 0, + "color": 4, + "origin": [-182, 65, 59], + "faces": { + "north": { + "uv": [209, 81, 238, 97], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [209, 81, 238, 97], + "texture": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "rotation": 90 + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "0335aad7-69a9-15ee-91d7-bb05d8e81065" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-142, 77, 97], + "to": [-78, 141, 91], + "autouv": 0, + "color": 3, + "origin": [-140, 137, 99], + "faces": { + "north": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "south": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "up": { + "uv": [0, 0, 64, 6], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 64, 6], + "texture": null + } + }, + "type": "cube", + "uuid": "4f39476c-661c-1f36-31cc-26a35c4ebd3f" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-142, 77, 91], + "to": [-78, 141, 97], + "autouv": 0, + "color": 3, + "origin": [-140, 137, 93], + "faces": { + "north": { + "uv": [2, 0, 66, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 256, 256], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 64, 6], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "140a0fdd-108f-29ca-cd59-a7b6362db4af" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-138, 77, -97], + "to": [-74, 141, -91], + "autouv": 0, + "color": 3, + "origin": [-76, 137, -93], + "faces": { + "north": { + "uv": [0, 0, 256, 256], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [2, 0, 66, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [64, 6, 0, 0], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "5c8efa09-d5e9-ce04-f270-42543da7b200" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-138, 77, -91], + "to": [-74, 141, -97], + "autouv": 0, + "color": 3, + "origin": [-76, 137, -99], + "faces": { + "north": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "south": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "up": { + "uv": [64, 6, 0, 0], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [64, 6, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "edc62167-2c52-763b-a77d-c0c1c6dda175" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [79, 77, -91], + "to": [143, 141, -97], + "autouv": 0, + "color": 3, + "origin": [141, 137, -99], + "faces": { + "north": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "south": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "up": { + "uv": [64, 6, 0, 0], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [64, 6, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "bef6c664-8859-9307-36bd-9acce530400e" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [79, 77, -97], + "to": [143, 141, -91], + "autouv": 0, + "color": 3, + "origin": [141, 137, -93], + "faces": { + "north": { + "uv": [0, 0, 256, 256], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [2, 0, 66, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [64, 6, 0, 0], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "75342bd4-bbfe-5955-6d94-63b680d61db1" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [79, 73, 91], + "to": [143, 141, 97], + "autouv": 0, + "color": 3, + "origin": [81, 137, 93], + "faces": { + "north": { + "uv": [2, 0, 66, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 256, 256], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 64, 6], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "74e7fc0c-5adb-610b-1360-c535dad30454" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [79, 73, 97], + "to": [143, 141, 91], + "autouv": 0, + "color": 3, + "origin": [81, 137, 99], + "faces": { + "north": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "south": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "up": { + "uv": [0, 0, 64, 6], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 64, 6], + "texture": null + } + }, + "type": "cube", + "uuid": "ade8717f-7ee9-9fd0-1ed7-0590f1622e00" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [292, 73, 97], + "to": [356, 141, 91], + "autouv": 0, + "color": 3, + "origin": [294, 137, 99], + "faces": { + "north": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "south": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "up": { + "uv": [0, 0, 64, 6], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 64, 6], + "texture": null + } + }, + "type": "cube", + "uuid": "c1e176bc-a46f-25b7-f557-87f4f99da252" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [292, 73, 91], + "to": [356, 141, 97], + "autouv": 0, + "color": 3, + "origin": [294, 137, 93], + "faces": { + "north": { + "uv": [2, 0, 66, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [0, 0, 256, 256], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [0, 0, 64, 6], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "fa56ea44-499b-270e-2d35-1519b7ef2610" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [284, 77, -91], + "to": [348, 141, -97], + "autouv": 0, + "color": 3, + "origin": [346, 137, -99], + "faces": { + "north": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "south": { + "uv": [0, 0, 64, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 6, 64], + "texture": null + }, + "up": { + "uv": [64, 6, 0, 0], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [64, 6, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "2dc0470c-f028-dcd5-710f-ab046404127c" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [284, 77, -97], + "to": [348, 141, -91], + "autouv": 0, + "color": 3, + "origin": [346, 137, -93], + "faces": { + "north": { + "uv": [0, 0, 256, 256], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "east": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "south": { + "uv": [2, 0, 66, 64], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "west": { + "uv": [0, 0, 0, 0], + "texture": null + }, + "up": { + "uv": [64, 6, 0, 0], + "texture": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd" + }, + "down": { + "uv": [0, 0, 0, 0], + "texture": null + } + }, + "type": "cube", + "uuid": "1884f5f7-aab5-3169-94d9-6f5a1ad4bf45" + }, + { + "name": "log_bundle0", + "position": [144, 128, 64], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "d05a4507-ac83-ecc3-420f-09ebdf736ded", + "type": "locator" + }, + { + "name": "log_bundle1", + "position": [144, 128, 0], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "e3580727-2d78-f3fb-efb7-2b0b997b281a", + "type": "locator" + }, + { + "name": "log_bundle2", + "position": [144, 128, -64], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "df46ff9a-a805-627d-78a2-9c32115e04f6", + "type": "locator" + }, + { + "name": "log_bundle3", + "position": [48, 128, 64], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "e6fc221b-3379-e512-6aaa-68fc3f81a352", + "type": "locator" + }, + { + "name": "log_bundle4", + "position": [48, 128, 0], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "c3a7e4c5-821b-73bb-870e-ba733aef979b", + "type": "locator" + }, + { + "name": "log_bundle5", + "position": [48, 128, -64], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "5f59bd5b-195c-f1c6-2ec3-a5a93adc1543", + "type": "locator" + }, + { + "name": "pallet0", + "position": [-32, 128, 32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": true, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "748f3069-102e-1d5b-7d68-7c10d5bb4433", + "type": "locator" + }, + { + "name": "pallet1", + "position": [-32, 128, -32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "b1c84038-3532-c80e-3011-daaaa9139c21", + "type": "locator" + }, + { + "name": "pallet2", + "position": [-96, 128, 32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "0c471e6c-8058-6e39-7e16-601bfa72888a", + "type": "locator" + }, + { + "name": "pallet3", + "position": [-96, 128, -32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "5a5f9256-7d27-0c00-5049-5ae8ec4e58ea", + "type": "locator" + }, + { + "name": "pallet4", + "position": [-160, 128, 32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "f0a4d6fa-9053-bc81-822a-55a1a3ff1a31", + "type": "locator" + }, + { + "name": "pallet5", + "position": [-160, 128, -32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "b61ecb2c-3d54-17f8-dac1-b00233f125f0", + "type": "locator" + }, + { + "name": "pallet6", + "position": [-224, 128, 32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "85dbb83c-acd6-1d4a-00d1-a250953f7d49", + "type": "locator" + }, + { + "name": "pallet7", + "position": [-224, 128, -32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "bc6d57b8-8d19-0b5d-8a31-fc892b5c25aa", + "type": "locator" + }, + { + "name": "pallet8", + "position": [-288, 128, 32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "2be20270-7928-b097-25ba-d24b2315ada6", + "type": "locator" + }, + { + "name": "pallet9", + "position": [-288, 128, -32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "428132cc-c956-ce76-fa38-4fba10c07e01", + "type": "locator" + }, + { + "name": "pallet10", + "position": [-352, 128, 32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "b6ce9f1b-8d78-5e13-60e4-c2d6f604c4de", + "type": "locator" + }, + { + "name": "pallet11", + "position": [-352, 128, -32], + "rotation": [0, 90, 0], + "ignore_inherited_scale": false, + "visibility": true, + "locked": false, + "scope": 0, + "config": { + "use_entity": true, + "entity_type": "minecraft:item_display", + "sync_passenger_rotation": false, + "on_summon_function": "", + "on_remove_function": "", + "on_tick_function": "" + }, + "uuid": "a508cf62-bae2-04d7-8e4c-6c4829c9168a", + "type": "locator" + } + ], + "groups": [ + { + "name": "body", + "uuid": "6783665d-6486-396e-2578-05e758fff2d4", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [66.22719, 145.76202, -2.32195], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "prop", + "uuid": "ab1a39ba-0a47-b98b-1c35-537948683b8c", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [329.5, 37, 3], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": false, + "primary_selected": false + } + ], + "outliner": [ + { + "uuid": "6783665d-6486-396e-2578-05e758fff2d4", + "isOpen": true, + "children": [ + "5e659fb1-5bdb-c7b4-89f1-e324868eb2da", + "9405d0f3-400c-d967-7fca-7a9f5ed775c4", + "64647b77-a18d-83cf-f2e7-d97e91afbd94", + "0f90c4e3-3436-4418-ec07-eeea5ff05a9f", + "ca8a4af2-355f-dc9f-4dcc-c418a67910b1", + "9d2a11b5-aae7-088d-14bf-4d6699961114", + "be25ab78-6a24-1a90-2194-58d861886764", + "8041d0ef-b946-4b5e-bedd-65dc51ebaf16", + "d5c49eed-0dc6-1730-455b-864ea49aeb6e", + "0ed5962e-492b-aeba-360d-1c4c625654d7", + "ed2969c0-90f2-b8da-f608-023c26a79148", + "670c4c56-2a4c-c6d8-9f6f-d9125163f473", + "f5fe35d4-9104-62c1-70b9-9b5b2c63b0ad", + "f7457327-4f2a-9bb6-7ddd-8e7d4c157d5e", + "a708d731-8b77-7b96-7f53-1a0fd8648dd1", + "ca3e6a9b-3bb4-9e55-0d24-fdb02a0306c9", + "e2d226fd-e30b-85e6-2cc0-171f41efcb77", + "a4ee4b85-cdb2-c7ac-9596-607b39e2b052", + "bd75e803-c5e7-f378-ffd4-6d00f6aaf35a", + "b38defdc-e77e-fd79-9f75-12fd87ccac79", + "7ef38c32-220a-ad4a-b5d4-1b98c386d3fa", + "87d42e52-9b74-f045-1eb5-d15cfecfacfb", + "208d76e5-f580-db23-4c91-73f7533120da", + "4317586b-ab40-7311-ab8f-7d7200a7ec86", + "5b296704-86b7-e3dc-26a8-17b5a175a898", + "6d4b8edc-e3f9-a8b3-5c21-f2ee27baf68e", + "53d62d9c-aa71-2492-e1bd-55a574345e3d", + "5f4e0465-24fc-5565-ca07-ce77a822af1a", + "f461be6b-d6ea-cf20-2995-5c52f8c4044b", + "18c6f2de-2804-2e68-40d1-f0e8cc06bc91", + "2af25aa5-930a-9b58-b055-b59ebf35f5e8", + "a86c36d3-9115-78dc-680d-d9eb21726dd2", + "6f74c002-ab97-c12b-8cdb-81da5184cb61", + "532ec260-eed1-6fd1-3053-f964741cee00", + "00a138af-51f1-3f69-1d8e-211dbe60939d", + "1e6b35ca-88e2-eecd-0088-12bc95b89724", + "67482715-a85e-f6e9-faa7-102de2debd88", + "55b5ef35-86f5-d349-849c-5a61f04157fe", + "0babf9ad-2cdb-aa0c-aabc-1804ff394379", + "0e159325-7c9a-ce19-af17-6cedd6f0d5fe", + "6a07aa5c-b411-14c5-b43e-47228ee432aa", + "472dbdf1-3181-bc2f-0efc-93e0583d25b1", + "4fe4b76c-ae4d-1eee-2027-c71cd7ea59ea", + "993a7030-2fd0-f3f3-bcd3-258d7fbcd32a", + "fc4497ad-fac8-8095-daa4-b81d07435bc5", + "49e38cfe-0ac0-10c5-0682-98e11e2f8451", + "f74cc783-17f6-45b7-4797-7e3084f43a22", + "9ad4878f-6ca2-9e4c-e4a5-ac49053ee224", + "02226c83-2ee9-e23b-212c-14407e3d46d9", + "68e4336e-debe-ec0e-c69c-c2f52be52632", + "eb4fa8a8-8299-df54-30f3-c88888ebf578", + "c0e5275f-a058-ccb9-106a-ce4648679003", + "aad6a689-3adb-715c-b55d-0070a2a8b177", + "864ce9f0-00b5-8faa-2206-12d93dd1086c", + "d93c5c04-4213-8840-4246-37d76a5c279f", + "44df66aa-25e1-0b68-1ed9-3a7acfb7b6a7", + "bd46870a-2ba0-dc71-4e55-d6518d0a198e", + "16f4580e-05d3-cdbb-ca69-0dd9f94d303e", + "3cbd18c1-e818-2b4b-8891-92377bdde3d6", + "4f558bf0-2c57-395a-23b0-d04b16d3a86b", + "a1248584-fe3a-e835-1174-7db17d2f10bb", + "f9a82054-eaa9-72c1-9b6c-c84d9fd82005", + "645422e9-affc-74fa-4dd5-5977fce9f170", + "15605b7e-0839-c58a-e5f6-bb8a12ecef89", + "30654020-63e0-ab74-b948-540ad51276c0", + "a1a0f5c3-23c5-d9ca-c75e-c4a86243e5c7", + "951d7624-4623-f1df-566e-51a6f0001978", + "1c8e6436-392e-6a2d-01b9-6b95f7b7c676", + "67235805-4209-5be0-03a6-461d1e23821f", + "6db36e10-8bbd-57a6-deb1-1be5d0fcf050", + "92c433df-15ac-fdc7-d800-f5613474bd91", + "a6560fb3-700a-e736-d95a-bcb5b4f2acf7", + "660d38e9-969b-5a03-b789-1909850737fa", + "c8ffe271-56ee-96a1-8698-a69aeabb0944", + "403fd41e-12c3-e013-f4cc-b57c2c5c4498", + "0e040013-495f-3274-2014-3cac218ea9c5", + "c900f1e8-0c17-1360-93fd-a2d806ef96cf", + "f034dcee-4408-ad30-cbe8-0bead11547fd", + "328971ae-0a5c-de0a-948e-f1abaacb83ad", + "ed011ccd-afec-40a5-2472-cadaa6a5a95c", + "1cf43ece-7175-22b3-fa72-6d6a63d4b1a3", + "2bd3f1e1-d48a-afde-aec6-09b7c78074d4", + "3fc23fd5-f5d1-2a23-9478-35b9cbf84a02", + "0335aad7-69a9-15ee-91d7-bb05d8e81065", + "e136b3d8-9cc1-52d0-ca43-bd3427e9e5aa", + "443de56c-7843-d7e1-8eae-5819a60b1677", + "96125b72-933f-2334-514f-25bbf4fd031d", + "821712b5-88f9-a56b-6daf-8542f86a9078", + "684c5a0c-59ea-7804-c770-7ab063d65451", + "b20352a1-9df8-bbbe-8fef-3d7bef4719fe", + "e48a8e89-8124-2b93-ac03-4859305975eb", + "961d6fd9-c43d-c58d-203b-04d766d871fe", + "51f8bb61-c665-84c6-91a9-ec5a105802ec", + "0aba89ac-e91a-de4f-fec3-ac092d02b787", + "313dde48-2aea-335b-dc49-b90133747b9a", + "8cd2f934-21e3-4dab-f958-c226d655e924", + "82b543bd-be60-a207-069c-4d24b1996a89", + "2c0c2309-2d4f-59e9-103b-b7942a3eba1d", + "10fb2bb5-e588-7d14-c893-f729e4348855", + "b42fa378-84a7-ac68-63b8-1919e14aa837", + "fd873c7a-d8e3-b1c9-4667-02baefa7c368", + "522432b3-03a3-778d-bd80-b219f39a2b47", + "72c34c0a-037a-9c9a-2e16-5663b9706c88", + "6d7a4c19-6432-3d5b-e39a-f83c142d3809", + "816816d4-9e48-678b-15da-cde47ff6b2f8", + "55625cd4-fbda-3caf-5da9-ee0b8b2c35f1", + "4670735b-1cc3-be02-06b3-4d47de832d81", + "517046e9-d030-e684-0296-15da06767164", + "d7ae32a6-b45f-ec04-8c42-e1c800cd0f08", + "e5b4bf99-0c59-2816-cac8-5626aa443bb8", + "56c91558-fbc7-3d7b-f3ea-c35223265371", + "56a45255-7a58-cd2f-6994-f0b2a747dbfb", + "cb0b84e7-5764-1447-d3e8-66895418ed99", + "895b228c-99cd-9623-3ef8-3f3d09c7abef", + "d09e4244-f9d0-79c1-f8f2-a67933d9fe79", + "74e7fc0c-5adb-610b-1360-c535dad30454", + "ade8717f-7ee9-9fd0-1ed7-0590f1622e00", + "c1e176bc-a46f-25b7-f557-87f4f99da252", + "fa56ea44-499b-270e-2d35-1519b7ef2610", + "4f39476c-661c-1f36-31cc-26a35c4ebd3f", + "140a0fdd-108f-29ca-cd59-a7b6362db4af", + "5c8efa09-d5e9-ce04-f270-42543da7b200", + "edc62167-2c52-763b-a77d-c0c1c6dda175", + "bef6c664-8859-9307-36bd-9acce530400e", + "75342bd4-bbfe-5955-6d94-63b680d61db1", + "2dc0470c-f028-dcd5-710f-ab046404127c", + "1884f5f7-aab5-3169-94d9-6f5a1ad4bf45", + { + "uuid": "ab1a39ba-0a47-b98b-1c35-537948683b8c", + "isOpen": false, + "children": ["78358566-ee17-b4b7-9cee-109c2df8d944", "86120dd6-9cf4-3d9b-c087-faa2c75526f5", "7264eb57-316b-eed3-1db8-679270987a4b"] + }, + "d05a4507-ac83-ecc3-420f-09ebdf736ded", + "e3580727-2d78-f3fb-efb7-2b0b997b281a", + "df46ff9a-a805-627d-78a2-9c32115e04f6", + "e6fc221b-3379-e512-6aaa-68fc3f81a352", + "c3a7e4c5-821b-73bb-870e-ba733aef979b", + "5f59bd5b-195c-f1c6-2ec3-a5a93adc1543", + "748f3069-102e-1d5b-7d68-7c10d5bb4433", + "b1c84038-3532-c80e-3011-daaaa9139c21", + "0c471e6c-8058-6e39-7e16-601bfa72888a", + "5a5f9256-7d27-0c00-5049-5ae8ec4e58ea", + "f0a4d6fa-9053-bc81-822a-55a1a3ff1a31", + "b61ecb2c-3d54-17f8-dac1-b00233f125f0", + "85dbb83c-acd6-1d4a-00d1-a250953f7d49", + "bc6d57b8-8d19-0b5d-8a31-fc892b5c25aa", + "2be20270-7928-b097-25ba-d24b2315ada6", + "428132cc-c956-ce76-fa38-4fba10c07e01", + "b6ce9f1b-8d78-5e13-60e4-c2d6f604c4de", + "a508cf62-bae2-04d7-8e4c-6c4829c9168a" + ] + } + ], + "textures": [ + { + "name": "ever-java.png", + "path": "", + "folder": "block", + "namespace": "", + "id": "0", + "group": "", + "scope": 0, + "width": 256, + "height": 256, + "uv_width": 256, + "uv_height": 256, + "particle": false, + "use_as_default": false, + "layers_enabled": true, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": false, + "uuid": "3fcb6d97-aa64-bbfc-5e49-4c1bbdf6ff09", + "layers": [ + { + "name": "layer", + "offset": [0, 0], + "scale": [1, 1], + "opacity": 100, + "visible": true, + "blend_mode": "default", + "width": 256, + "height": 256, + "data_url": "data:image/png;base64,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" + } + ], + "source": "data:image/png;base64,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" + }, + { + "name": "banner.png", + "path": "", + "folder": "", + "namespace": "", + "id": "1", + "group": "", + "scope": 0, + "width": 64, + "height": 64, + "uv_width": 64, + "uv_height": 64, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": false, + "uuid": "ca5b9b93-664b-8d17-bc4f-1fcccdb243dd", + "source": "data:image/png;base64,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" + }, + { + "name": "log_bundle.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/log_bundle.png", + "relative_path": "../../../snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/log_bundle.png", + "folder": "", + "namespace": "", + "id": "2", + "group": "", + "scope": 0, + "width": 128, + "height": 128, + "uv_width": 256, + "uv_height": 256, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "f0d648ab-d32f-f6c0-f05f-1d517f92f05e", + "source": "data:image/png;base64,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" + }, + { + "name": "oak_log_top.png", + "path": "/var/home/snavesutit/Downloads/minecraft-1.21.11-client/assets/minecraft/textures/block/oak_log_top.png", + "relative_path": "../../../../../../home/snavesutit/Downloads/minecraft-1.21.11-client/assets/minecraft/textures/block/oak_log_top.png", + "folder": "", + "namespace": "", + "id": "3", + "group": "", + "scope": 0, + "width": 16, + "height": 16, + "uv_width": 256, + "uv_height": 256, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "63964633-8d02-e614-29d9-7b2db2041ff4", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABpklEQVR4AXSSzyvDcRjHnyZl86O1OVhKOKjZJCWFnMxlSXIRFwdXR3+Fs6tyk4ucXDgyByKRufhZmmJrGZtamu/r4fn23bB6936e9/N8n8/zPHt8C8lYZXKspwIvzw8pm2+a1/faxH3ZQlmWZodlLjkoiZGo8uJMv/L0RK9MjccFH5scy8XmW1+4uV74pU6uBNzcPUjm8UUy+ZzydeZZ8u8fCjTiIOCvE7718bEhMRqTeLRLujs7JBIMiXGwsUF908gvlj4h0QKlclHaQgFBzL4WBN8LMs3H9gebNAdbd+CvDwgiAtARnDHc1h0bjRgo5d8gcXeg1R0RJvKUK0qkvVVoHWCjA8vh0aod0AEiSYwDWwfYxJV/urVCugMC/8HaNSbPa+sOEP+Ct33rwF4m390BjrcqPks7Pf++CUZBA4xpxX7tgATA0sBAn3MPnmUSA97HdASqEgBmw7UItzST4qJqBFROlHOlfexaXKRvBY1cileNYGdqi9MzdtpnFM4bBuiAIkD/xtXNQ9nYOVZs717K2taZax8c3cvK+r6gA3L3UmmNU+ALAAD//xiEUscAAAAGSURBVAMAgmwNLDeJNTQAAAAASUVORK5CYII=" + }, + { + "name": "transparent.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/transparent.png", + "relative_path": "../../../snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/transparent.png", + "folder": "", + "namespace": "", + "id": "4", + "group": "", + "scope": 0, + "width": 64, + "height": 64, + "uv_width": 256, + "uv_height": 256, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "0bc8f5c8-7fa3-bf37-391b-8d5a40dc8475", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAxUlEQVR4AezVMQ6EQAxDUbT3P/T2aaKICvvRjSYF/v6B31P+AFAuwMMABpQTsALlAvgIWgErUE7ACpQL4C9QtwLTeAAmkbYzA9oan3kZMIm0nRnQ1vjMy4BJpO3MgLbGZ14GTCJtZwakN77lY8BGKP2eAekNb/kYsBFKv2dAesNbPgZshNLvGZDe8JaPARuh9HsGpDV8zcOAK7G0eQakNXrNw4ArsbR5BqQ1es3DgCuxtHkGpDV6zcOAK7G0eQZ8vdG37/8HAAD//+byZ+UAAAAGSURBVAMAkXAAgX3QNkkAAAAASUVORK5CYII=" + } + ], + "variants": { + "default": { + "name": "default", + "display_name": "Default", + "uuid": "ed430407-af41-b379-dace-09fe6b4affd8", + "texture_map": {}, + "excluded_nodes": [], + "is_default": true + }, + "list": [] + }, + "animations": [ + { + "uuid": "f5f18082-76cc-4a56-bda9-b57a8c9d9a61", + "name": "leave", + "loop": "hold", + "override": false, + "length": 10.5, + "snapping": 20, + "selected": false, + "saved": true, + "path": "", + "scope": 0, + "anim_time_update": "", + "blend_weight": "", + "start_delay": "", + "loop_delay": "0", + "excluded_nodes": [], + "animators": { + "6783665d-6486-396e-2578-05e758fff2d4": { + "name": "body", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "5eb61c04-81d2-8c77-c4b2-3374048279d3", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "-2", + "y": "-10", + "z": "0" + } + ], + "uuid": "4f68dbe4-a74f-d88d-8896-f51c7f5af5c1", + "time": 2, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutSine", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "-5", + "y": "-45 ", + "z": "0" + } + ], + "uuid": "88c6b243-4492-8399-5a4c-5a9b5e052d0f", + "time": 4.2, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutSine", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "-2", + "y": "-90", + "z": "0" + } + ], + "uuid": "f8fe1fb0-74a9-aaaa-9302-36ef0e2e0d68", + "time": 6.65, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutSine", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "0", + "y": "-90", + "z": "0" + } + ], + "uuid": "7c582af8-9517-31f0-5c71-37f2ac380bfc", + "time": 8.85, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutSine", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "f68241df-6f9c-b6b3-fc46-cac0e281d8a7", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "64", + "y": "0", + "z": "-144" + } + ], + "uuid": "984ec95e-f2cc-78a9-d5ac-0677bd614cb2", + "time": 2, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutSine", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "-320", + "y": "0", + "z": "-432" + } + ], + "uuid": "a465feb2-1d7b-04b5-b100-7e98e3be9988", + "time": 5, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "-592", + "y": "0", + "z": "-1600" + } + ], + "uuid": "349a9138-2979-a8a4-1756-4a2c71084ecc", + "time": 7.85, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "-611.66", + "y": "0", + "z": "-3800" + } + ], + "uuid": "fa73b160-ef17-1ad9-0383-b04c5d41513f", + "time": 10.5, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "ab1a39ba-0a47-b98b-1c35-537948683b8c": { + "name": "prop", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "q.life_time * 360 * 2", + "y": "0", + "z": "0" + } + ], + "uuid": "a62b1dab-8272-61c3-4ebb-cc31cd6028a8", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "effects": { + "name": "Effects", + "type": "effect", + "keyframes": [ + { + "channel": "function", + "data_points": [ + { + "function": "playsound aj_booth:boat.horn block @a[distance=..100] ~ ~ ~ 25 1", + "execute_condition": "", + "repeat": false, + "repeat_frequency": 1 + } + ], + "uuid": "50b46da3-31ca-7e0c-5e24-6e22c09a42b3", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "d05a4507-ac83-ecc3-420f-09ebdf736ded": { + "name": "log_bundle0", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e3580727-2d78-f3fb-efb7-2b0b997b281a": { + "name": "log_bundle1", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "df46ff9a-a805-627d-78a2-9c32115e04f6": { + "name": "log_bundle2", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e6fc221b-3379-e512-6aaa-68fc3f81a352": { + "name": "log_bundle3", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "c3a7e4c5-821b-73bb-870e-ba733aef979b": { + "name": "log_bundle4", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "5f59bd5b-195c-f1c6-2ec3-a5a93adc1543": { + "name": "log_bundle5", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "748f3069-102e-1d5b-7d68-7c10d5bb4433": { + "name": "pallet0", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "b1c84038-3532-c80e-3011-daaaa9139c21": { + "name": "pallet1", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "0c471e6c-8058-6e39-7e16-601bfa72888a": { + "name": "pallet2", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "5a5f9256-7d27-0c00-5049-5ae8ec4e58ea": { + "name": "pallet3", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "f0a4d6fa-9053-bc81-822a-55a1a3ff1a31": { + "name": "pallet4", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "b61ecb2c-3d54-17f8-dac1-b00233f125f0": { + "name": "pallet5", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "85dbb83c-acd6-1d4a-00d1-a250953f7d49": { + "name": "pallet6", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "bc6d57b8-8d19-0b5d-8a31-fc892b5c25aa": { + "name": "pallet7", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "2be20270-7928-b097-25ba-d24b2315ada6": { + "name": "pallet8", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "428132cc-c956-ce76-fa38-4fba10c07e01": { + "name": "pallet9", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "b6ce9f1b-8d78-5e13-60e4-c2d6f604c4de": { + "name": "pallet10", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "a508cf62-bae2-04d7-8e4c-6c4829c9168a": { + "name": "pallet11", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + } + } + }, + { + "uuid": "bee3ba37-e74a-fdea-e6bc-70059637fd4e", + "name": "arrive", + "loop": "hold", + "override": false, + "length": 12.5, + "snapping": 20, + "selected": true, + "saved": true, + "path": "", + "scope": 0, + "anim_time_update": "", + "blend_weight": "", + "start_delay": "", + "loop_delay": "0", + "excluded_nodes": [], + "animators": { + "6783665d-6486-396e-2578-05e758fff2d4": { + "name": "body", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "-5", + "y": "10", + "z": "0" + } + ], + "uuid": "abd3bdda-1f2d-a2b1-4833-f9d532492111", + "time": 8.5, + "color": -1, + "interpolation": "linear", + "easing": "easeOutBack", + "easingArgs": [10] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "0", + "y": "90", + "z": "0" + } + ], + "uuid": "901b4d24-5503-d459-a14c-71b27f802375", + "time": 2.9, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutSine", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "-1", + "y": "0", + "z": "0" + } + ], + "uuid": "85eee4a8-ecd8-9feb-c07e-9eaae98e60fe", + "time": 10.55, + "color": -1, + "interpolation": "linear", + "easing": "easeOutSine", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "0", + "y": "100", + "z": "0" + } + ], + "uuid": "475030f1-0c53-c60c-dee1-b81bbbeb5eda", + "time": 0, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeInOutSine", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "0.25", + "y": "0", + "z": "0" + } + ], + "uuid": "1f64c9c9-c38f-80a8-7c9d-ac9b9eaf1492", + "time": 11.35, + "color": -1, + "interpolation": "linear", + "easing": "easeOutSine", + "easingArgs": [] + }, + { + "channel": "rotation", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "53b8a2be-5041-2006-7ba5-559a3500f887", + "time": 12.1, + "color": -1, + "interpolation": "linear", + "easing": "easeInOutBack", + "easingArgs": [1] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "6ff160ac-df4b-3a98-18f2-c4c9a07d6a94", + "time": 10.6, + "color": -1, + "interpolation": "catmullrom", + "easing": "easeOutBack", + "easingArgs": [0.25] + }, + { + "channel": "position", + "data_points": [ + { + "x": "611.66", + "y": "0", + "z": "-3800" + } + ], + "uuid": "4abf64ce-cda3-d9be-2019-e6765ffd6e60", + "time": 0, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "811.66", + "y": "0", + "z": "-2208.87" + } + ], + "uuid": "eddc76b1-e743-e0bd-7673-39855b9cc627", + "time": 2.9, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "318.16", + "y": "0", + "z": "-590.35" + } + ], + "uuid": "ffac7d03-a363-7ccb-30c9-6dbf46e3744c", + "time": 5.7, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "120.31", + "y": "0", + "z": "-181.49" + } + ], + "uuid": "61f1b3d9-c81d-2802-b296-ce00fb625d80", + "time": 8.25, + "color": -1, + "interpolation": "catmullrom", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "0", + "y": "0", + "z": "0" + } + ], + "uuid": "0807dc59-99cc-8d39-6ee0-0cc240f4ef3a", + "time": 12.5, + "color": -1, + "interpolation": "linear", + "easing": "easeInOutSine", + "easingArgs": [] + } + ] + }, + "ab1a39ba-0a47-b98b-1c35-537948683b8c": { + "name": "prop", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "q.life_time * 360 * 2", + "y": "0", + "z": "0" + } + ], + "uuid": "85b2cd89-1efe-74e0-9dcc-39332de2b1b7", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "effects": { + "name": "Effects", + "type": "effect", + "keyframes": [ + { + "channel": "function", + "data_points": [ + { + "function": "playsound aj_booth:boat.horn block @a[distance=..100] ~ ~ ~ 25 1", + "execute_condition": "", + "repeat": false, + "repeat_frequency": 1 + } + ], + "uuid": "d25618ef-7222-11ef-9513-7831b3809baf", + "time": 10, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "d05a4507-ac83-ecc3-420f-09ebdf736ded": { + "name": "log_bundle0", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e3580727-2d78-f3fb-efb7-2b0b997b281a": { + "name": "log_bundle1", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "df46ff9a-a805-627d-78a2-9c32115e04f6": { + "name": "log_bundle2", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e6fc221b-3379-e512-6aaa-68fc3f81a352": { + "name": "log_bundle3", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "c3a7e4c5-821b-73bb-870e-ba733aef979b": { + "name": "log_bundle4", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "5f59bd5b-195c-f1c6-2ec3-a5a93adc1543": { + "name": "log_bundle5", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "748f3069-102e-1d5b-7d68-7c10d5bb4433": { + "name": "pallet0", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "b1c84038-3532-c80e-3011-daaaa9139c21": { + "name": "pallet1", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "0c471e6c-8058-6e39-7e16-601bfa72888a": { + "name": "pallet2", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "5a5f9256-7d27-0c00-5049-5ae8ec4e58ea": { + "name": "pallet3", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "f0a4d6fa-9053-bc81-822a-55a1a3ff1a31": { + "name": "pallet4", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "b61ecb2c-3d54-17f8-dac1-b00233f125f0": { + "name": "pallet5", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "85dbb83c-acd6-1d4a-00d1-a250953f7d49": { + "name": "pallet6", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "bc6d57b8-8d19-0b5d-8a31-fc892b5c25aa": { + "name": "pallet7", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "2be20270-7928-b097-25ba-d24b2315ada6": { + "name": "pallet8", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "428132cc-c956-ce76-fa38-4fba10c07e01": { + "name": "pallet9", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "b6ce9f1b-8d78-5e13-60e4-c2d6f604c4de": { + "name": "pallet10", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + }, + "a508cf62-bae2-04d7-8e4c-6c4829c9168a": { + "name": "pallet11", + "type": "locator", + "rotation_global": false, + "quaternion_interpolation": false + } + } + } + ] +} \ No newline at end of file diff --git a/test_blueprints/Dummy.ajblueprint b/test_blueprints/Dummy.ajblueprint new file mode 100644 index 00000000..36ae4b40 --- /dev/null +++ b/test_blueprints/Dummy.ajblueprint @@ -0,0 +1,1264 @@ +{ + "meta": { + "format": "animated-java:format/blueprint", + "format_version": "1.10.0-beta.7", + "uuid": "ca2926c6-940e-ff1b-10ca-fab43fbf7a28", + "save_location": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/blueprints/Dummy.ajblueprint", + "last_used_blueprint_id": "aj_booth_rigs:dummy" + }, + "resolution": { + "width": 32, + "height": 32 + }, + "blueprint_settings": { + "blueprint_id": "aj_booth_rigs:dummy", + "target_minecraft_version": "26.1.1", + "resource_pack": "../resources", + "data_pack": "../datapacks/aj_booth_rigs", + "on_summon_function": "{\n\tdata modify entity @s teleport_duration set value 20\n\texecute on passengers run function ^0\n}", + "custom_rig_entity_tags": "summit.booth_entity, summit.booth_entity.aj_booth" + }, + "elements": [ + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-4, 24, -4], + "to": [4, 32, 4], + "autouv": 0, + "color": 3, + "origin": [0, 28, 0], + "faces": { + "north": { + "uv": [8, 8, 16, 16], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "east": { + "uv": [0, 8, 8, 16], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "south": { + "uv": [24, 8, 32, 16], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "west": { + "uv": [16, 8, 24, 16], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "up": { + "uv": [16, 8, 8, 0], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "down": { + "uv": [24, 0, 16, 8], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + } + }, + "type": "cube", + "uuid": "61f995ad-e94f-6d2f-d10d-720c2109de71" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-4, 12, -2], + "to": [4, 24, 2], + "autouv": 0, + "color": 2, + "origin": [0, 18, 0], + "uv_offset": [16, 16], + "faces": { + "north": { + "uv": [24, 20, 32, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "east": { + "uv": [16, 16, 28, 20], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0", + "rotation": 90 + }, + "south": { + "uv": [24, 20, 32, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "west": { + "uv": [16, 16, 28, 20], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0", + "rotation": 90 + }, + "up": { + "uv": [8, 4, 0, 0], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "down": { + "uv": [8, 4, 0, 8], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + } + }, + "type": "cube", + "uuid": "b5cc0ed1-20ad-af4f-0238-2d792bf80d7f" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [0, 0, -2], + "to": [4, 12, 2], + "autouv": 0, + "color": 9, + "origin": [2, 6, 0], + "uv_offset": [0, 16], + "faces": { + "north": { + "uv": [4, 20, 8, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "east": { + "uv": [0, 20, 4, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "south": { + "uv": [8, 20, 4, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "west": { + "uv": [8, 20, 12, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "up": { + "uv": [4, 20, 0, 16], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "down": { + "uv": [8, 16, 4, 20], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + } + }, + "type": "cube", + "uuid": "3efd8879-a96b-541a-8381-95dd143bbba6" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [4, 12, -2], + "to": [8, 24, 2], + "autouv": 0, + "color": 6, + "origin": [6, 18, 0], + "uv_offset": [32, 48], + "faces": { + "north": { + "uv": [16, 20, 20, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "east": { + "uv": [12, 20, 16, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "south": { + "uv": [20, 20, 16, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "west": { + "uv": [20, 20, 24, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "up": { + "uv": [12, 20, 8, 16], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "down": { + "uv": [16, 16, 12, 20], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + } + }, + "type": "cube", + "uuid": "c00689e9-015b-4b57-4d68-a311cb9e0aac" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-4, 0, -2], + "to": [0, 12, 2], + "autouv": 0, + "color": 9, + "origin": [-2, 6, 0], + "uv_offset": [0, 16], + "faces": { + "north": { + "uv": [8, 20, 4, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "east": { + "uv": [12, 20, 8, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "south": { + "uv": [4, 20, 8, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "west": { + "uv": [4, 20, 0, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "up": { + "uv": [0, 20, 4, 16], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "down": { + "uv": [4, 16, 8, 20], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + } + }, + "type": "cube", + "uuid": "fb589d43-fb89-c334-d97a-4f69a77edf7c" + }, + { + "name": "cube", + "box_uv": false, + "render_order": "default", + "rescale": false, + "locked": false, + "shade": true, + "light_emission": 0, + "export": true, + "scope": 0, + "allow_mirror_modeling": true, + "from": [-8, 12, -2], + "to": [-4, 24, 2], + "autouv": 0, + "color": 6, + "origin": [-6, 18, 0], + "uv_offset": [32, 48], + "faces": { + "north": { + "uv": [20, 20, 16, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "east": { + "uv": [24, 20, 20, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "south": { + "uv": [16, 20, 20, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "west": { + "uv": [16, 20, 12, 32], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "up": { + "uv": [8, 20, 12, 16], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + }, + "down": { + "uv": [12, 16, 16, 20], + "texture": "9230eadb-794f-c7ee-226c-9057fa3dbfc0" + } + }, + "type": "cube", + "uuid": "b5760ef4-2511-a5a3-aff2-ba663b567ec1" + } + ], + "groups": [ + { + "name": "root", + "uuid": "94423fd0-c142-7a22-b7e0-a0923dc09001", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [0, 0, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "hip", + "uuid": "e2925fd0-0e3a-a24e-6d46-78a88e0152cd", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [0, 12, 0], + "rotation": [0, 0, 0], + "color": 1, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "body", + "uuid": "541fe9f0-73c8-eb6a-9a04-cab1b4a35436", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [0, 24, 0], + "rotation": [0, 0, 0], + "color": 2, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "head", + "uuid": "7e88cca3-a783-43c2-bca9-d209d23c8267", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [0, 24, 0], + "rotation": [0, 0, 0], + "color": 3, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "right_arm", + "uuid": "c62aea43-e02d-1e4b-194d-290157b28f75", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [5, 22, 0], + "rotation": [0, 0, 0], + "color": 6, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "right_leg_up", + "uuid": "f7687416-3ab6-ac7e-db96-736a4aa7bbda", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [2, 12, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "right_leg_down", + "uuid": "de264961-27eb-a7ac-b42a-cf40a8d52d1e", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [2, 0, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "left_leg_up", + "uuid": "fd36d7de-e6a9-1b56-bcd4-e7c969415d2b", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [-2, 12, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "left_leg_down", + "uuid": "b1f5db33-1d58-996b-5840-30cac02aed11", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [-2, 0, 0], + "rotation": [0, 0, 0], + "color": 0, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + }, + { + "name": "left_arm", + "uuid": "ebba3cac-918d-1185-86aa-d7ce83935ef4", + "export": true, + "locked": false, + "scope": 0, + "selected": false, + "_static": { + "properties": {}, + "temp_data": {} + }, + "origin": [-5, 22, 0], + "rotation": [0, 0, 0], + "color": 6, + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "itemModelProperties": { + "tints": [] + }, + "children": [], + "reset": false, + "shade": true, + "mirror_uv": false, + "visibility": true, + "autouv": 0, + "isOpen": true, + "primary_selected": false + } + ], + "outliner": [ + { + "uuid": "94423fd0-c142-7a22-b7e0-a0923dc09001", + "isOpen": true, + "children": [ + { + "uuid": "e2925fd0-0e3a-a24e-6d46-78a88e0152cd", + "isOpen": true, + "children": [ + { + "uuid": "541fe9f0-73c8-eb6a-9a04-cab1b4a35436", + "isOpen": true, + "children": [ + { + "uuid": "7e88cca3-a783-43c2-bca9-d209d23c8267", + "isOpen": true, + "children": ["61f995ad-e94f-6d2f-d10d-720c2109de71"] + }, + { + "uuid": "c62aea43-e02d-1e4b-194d-290157b28f75", + "isOpen": true, + "children": ["c00689e9-015b-4b57-4d68-a311cb9e0aac"] + }, + { + "uuid": "ebba3cac-918d-1185-86aa-d7ce83935ef4", + "isOpen": true, + "children": ["b5760ef4-2511-a5a3-aff2-ba663b567ec1"] + }, + "b5cc0ed1-20ad-af4f-0238-2d792bf80d7f" + ] + } + ] + }, + { + "uuid": "f7687416-3ab6-ac7e-db96-736a4aa7bbda", + "isOpen": true, + "children": [ + { + "uuid": "de264961-27eb-a7ac-b42a-cf40a8d52d1e", + "isOpen": true, + "children": ["3efd8879-a96b-541a-8381-95dd143bbba6"] + } + ] + }, + { + "uuid": "fd36d7de-e6a9-1b56-bcd4-e7c969415d2b", + "isOpen": true, + "children": [ + { + "uuid": "b1f5db33-1d58-996b-5840-30cac02aed11", + "isOpen": true, + "children": ["fb589d43-fb89-c334-d97a-4f69a77edf7c"] + } + ] + } + ] + } + ], + "textures": [ + { + "name": "dummy-red.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/dummy-red.png", + "relative_path": "../resources/assets/aj_booth/textures/blueprint/dummy-red.png", + "folder": "", + "namespace": "", + "id": "0", + "group": "", + "scope": 0, + "width": 32, + "height": 32, + "uv_width": 32, + "uv_height": 32, + "particle": false, + "use_as_default": false, + "layers_enabled": true, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "56a7cab8-b8c2-7236-1e43-6d205a231cf9", + "layers": [ + { + "name": "layer", + "offset": [0, 0], + "scale": [1, 1], + "opacity": 100, + "visible": true, + "blend_mode": "default", + "width": 64, + "height": 64, + "data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAD9klEQVR4AexXPWgUQRR+t5CIEpVcECNqE0yEKAS5QiPhUOyMjYhiKdgpSiCVFkFEFBEhFhbaRFJoIEgsjBaCRQwqGNGACCrEQtTDnxONRkyQM9+QWYfJ3O3M7e3u3TAH3+2b7715896bN/vjjY2OF3Qw8+RGofBhkgGyzhzYUJX/PJ34clOTdPtxnoZvjjNABsfnQlaB66v5qlUAJNDc0kEiwNkArQIgcTlZFSfb1MJYqwC1kEi5MWoVAOdbXkDFyTa1MNYqABJBwiLA2QCtAuC879mWpv37uhggg0MBUBTIKkAHm2qGVgFKJYDEi+mhw7sAgHcH1XtEsblx8awA2CkVeBDvHo7Q+Sv36FTfJQbI4LheNRcc18N25NYEXb88yAAZHNcneWUF0AmgbXWjbybKPhkg1DW3kIgA89jUfgHQriLkCBD8po4MAZBlvTgXsqhX2as4cU5cMiuAHDAWFzlVsCIn2mIuoOLAVxs88azKwUEHyDwfQwfwsXyFDpB5Pi6l4zZRX1kH6C4yl5siQNe+Fuy0CoB2BtZv30sAZEA3QdiqoDu/knayLw+BieTctRPE8WVkgJrGhvzxi4s9oimT5fmMXPiDDlgYsku2uyvFceDY0RQjE/wL7ID23V2UbvyZYIjRLh1YgGiXT957YAFe3hmn/LeG5CONKAIP51rEq6+/6dFUiiH/fRnVHTrnY3NvP7sftH4aJUC8P+C+AT9ynL8u9BIw1neSgDOZbAG4u2NrAZDt4x57nRv++mtCZmgpUOc8fIUkoCsATs9+niWAj1XX9MoZnxZln0xIYEdgY9NSAuQYMsv/yFTJMTqmmAH8d2emCYBczC5unhXAZFEcERE4Lk+nl9DQ+zy9+fFxkav6VfWMQ4fkXtcTABkk10FOCsYFEHcPMo4KOuXg2jS1rlhDtfYzLkA5CWKnVSjHV6XnxFKASgddSX+sAPxMy47fev+fELLOZIwzr4KJj6hsPdyUuHPIAIJFUTgvXkUectBNEL4wXz4C4LgOclLwmttmiT37598HILdn1xEAThUUXoZEZE+fJeBw/wB1H1/8sYQuwlMChRp8niMAMjjoVGvEybEjIC6Yn//mB0QujIxC4tkP9OxsIAAyAF0Y35WYu6gAlXAq+8C3hAqyXRTjIJ/elqvPUsVw5P5Ein+761zxfS/bwfeu4QcpFaALCjBqfSwdEHUSYfy7AoSpng1zXQfYsIthcnAdEKZ6Nsx1HWDDLobJwXVAmOrZMNd1gA27GCYH1wFhqleNc01jch1gWjHb7F0H2Lajpvm4DjCtmG32rgNs21HTfFwHmFbMNnvXAbbtqGk+rgNMK2abveuAWt/RsPH/AwAA//8nKs+9AAAABklEQVQDAJdwKp/N35jeAAAAAElFTkSuQmCC" + } + ], + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC/ElEQVR4AbyVP2hTQRzHf33QilKVpogVdQm2QhU6ZNBKCLoaFxHFUXAUpdBJhyIiiohQBwenSgctiMTB6uAWggoqWBBBhTiIGvwT0WrFFInvc/TO43Lpu7TB0k/f932/v7v79e7lJSpOl+ohzD2+Ua+/n1GgQ8ZQIwk/UUKu4kp5Ru48qsrNWyUFGk+F8R+0jzhK/A1qgFn60kNig9cOghpgYXcxn+fWhNwHNRAy0VJrghrgfN0FfJ5bE3If1AATsaANXjsIaoDz3rczJQcPZBVoPBqgKbQPMmoWI6iBxSZg4WY5Ge8C4N3he4+oBujUh5747YOCXLh6X06PXVag8XTuG4unc2oLt5/I9SuTCjQeuWoAkcTA+h5TYmtjJojOvrTY6HLTANtlowv0lcHbhjICaO3rqz0WrX2uvnrtqQbcAQyyPV2Mr7E9u1bnPk9n9jWyz8oO0GSA9kEGvgyPDNA+yNQO+EKfN18pC/iypXpBDbCdsHnXfgE0hC5KrQ/GRwQIzfy1k6L5XJiQ3uKUuX9+aUSXmas73gSxIINYmt9cPtuhOXT8WEfiDgzuzUqq54eZoN0isYF2L+jOl9jAi7slqX7tdse17T7iXG1efvklD8sdiuq3VdJ55Lxh++i4eh76P04L2M8Hzw3zuJ39vDgqUBw7JXA2k6vDvd076hANb/ljxqAV6boMx5jAEewKaLv2qSag733X1No5Y9taHcHW3pUCpmJBZFb/XlBhF3asWSXz5zOzAmhdpxrQNyFXjsiG43o6u0Km3lXl9fcPDVN0retSHjtUedUlgMYka7kBu3s0R8VOHd6Ykv41G6TVn5YbaHUB6vlPfZD9lwZYqBmqAX2mbtGb6N8nxM1auefMfTBHxEOBADRQTFN4LraPTnoImYs53CPAI4v6BmqiPvvx+wA9mNskgEeRCy8jm9yZcwJHxyckf6Lxy4pd5FNCo5PPKgJoPDJ1BPYi1fg7H2xvOZp/hM8+jOzpFkADWUMDy1nMNxaP7xIfZH8BAAD//xUG92MAAAAGSURBVAMA9BsDAmo2lOAAAAAASUVORK5CYII=" + }, + { + "name": "dummy-unpainted.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/dummy-unpainted.png", + "relative_path": "../resources/assets/aj_booth/textures/blueprint/dummy-unpainted.png", + "folder": "", + "namespace": "", + "id": "1", + "group": "", + "scope": 0, + "width": 32, + "height": 32, + "uv_width": 32, + "uv_height": 32, + "particle": false, + "use_as_default": false, + "layers_enabled": true, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "9230eadb-794f-c7ee-226c-9057fa3dbfc0", + "layers": [ + { + "name": "layer", + "offset": [0, 0], + "scale": [1, 1], + "opacity": 100, + "visible": true, + "blend_mode": "default", + "width": 64, + "height": 64, + "data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAADsUlEQVR4AeyYv2sUQRTH505ESKUWGgNpUlgoksIfSAiCtTYiJ/gXWEgau0MRESxshIgWIlpYqBAlFlqlEQ0iGJAUWqYJxENQBCEgIiefgXdMJrO7M5fszd4ygS/z5vu+M/PmzZvN3jbfvVns+mD907Nud21ZA9tnDBpV8b+mT3ydlWX1+uNPNfdyUQMbTsZiuyD+KrdeCWADoxOTygRcHeCVADZub9bF2Zph6HslYBg20m+MXgngftsLuDhbMwx9rwSwETZsAq4O8EoA9/3syb2qdX5aAxuOBJAUbBfwoakyvBKQtwE2nuXHx7sA4N3B9R6RNXZQvE4AJ+WCBLH6YV7dfrCgblyf1cCGE79rLJz40c6/WlJP7z/RwIYTf8xWJ8AngIP79/Rkpt0jC4ydoxPKRIF8YO5eAihXE3YEBH948qgC2LbfHItt+l16F2eOGZStE2AHzOIm5wrW5EwtY4GLg68amuZdtYPDB2xe+viA9O0WH7B56ef5RFN2qyvAd5G/nRUFfPXDoPNKAOUMxqfOKYANfDeI1gXf8dups+dqEphNSh8fkL6rZE2/6KTFB6RPe+rMdENwYeZyAy4mCivg2L7VmPGVvnZhAkqPIPIChQlY+j4eOcRyl9f/BrnbJuZuXVEAzlxe7jPXAkhfNLZeeGmZc2bqxIZvkOKL1W54CLIhsHt0RIGsoKgKkOU3+YVH19SXx22NQwd2KSB9fKY2ht3MWnSs8U9/A8zyh/Br3R3KhZA5ytI6E8DmsxakzG1Q2sA15sjplvrVWdfABmbfNWaQnDMBeQFwRcSPDShrgC0+aeG4TgAbYANs0cVqMxNAycYKapDrOhMgm/f9aCH6kMDzrlnIPFvVOhPQz6R5SWCzQJ4d/cxf1hj9HiCTS4DykBLebNFIHxuIHlt8Zvv12x8FhENv9oWP0er3AB5GAr743n3xULWu3nHGgw4NwAZogWsA/x144IEfb58rgA3wucYMktt0BXjBef/5d24MaECuyHBy4nS5JgBbOOyY2JQAMxjzs5fJh9hUBmi3L6mb92Y1sOFAyFz9aIvGNOW3uavl97qLz+Ly9CPHLzYaY5Ma2DJHUYBl+3MroOzFqzB/SkAVTiFmDKkCYma/CmunCqjCKcSMIVVAzOxXYe1UAVU4hZgxpAqImf0qrJ0qoAqnsJ0xhM6VKiA0Y3XTpwqo24mG7idVQGjG6qZPFVC3Ew3dT6qA0IzVTZ8qoG4nGrqfVAGhGaubPlXAsJ/oVuP/DwAA//8o0e1lAAAABklEQVQDADwj/ZBnidh6AAAAAElFTkSuQmCC" + } + ], + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACvUlEQVR4AbSWsWtUQRDG505EsFILPYU0KSwUSaGIhCBYayNy/gsWksbuUEQECxshooWIFhYqRImFVmlEgwgGJIWWaQLxEBRBCIjImd9y3zH3bnK7xpz4y8x+3+zuZPfl8epvXi10Slj78KTTWV1KkJfMocYy/+oZP9nt5SV7+f67zT5fSJCjJXP9B3nEupX9X9QAqzTGJ8yDthUUNcDG1c0irVpTMi5qoGShzdYUNcD9VjeItGpNybioARZiQw/aVlDUAPd95sQea56bSpCj0QBNkUfgUTOMogaGLcDGG/l4vAuAd0f0HkkN0GmEFl55N2c3783btaszCXI0+dFcNPnUzr1YtMd3HyXI0fBTAyQ5Du7b3SvxeU/MJNsb4+ZRea8BjsujAkUmH544akAuXdHPJZdOjOqlpQaqE5jkNRWjC6/5WvmRJs/Hur8rb5DjAXkEHkQeGh6QR+ClE4jMSPvdXjaIvM1qRQ1wnDA2edaAHEo3pTaC+XUMkgg8kMeRKVf0vjRFPNCYePL0VE2cn75Yy57Asb0rzBsZ2QZGtnN34WwDi1/HuqWjCenPkLv1zN64ZIDmt9V9ci2gsWqq9dIVWXN68njfN2jfQ8iCsKux00ATq5FTgaoejecfXLFPD1uJQ/t3GGiMV48moR2o/UnfgOT/y2pnm0WwbtgAm2NGcMxVOFqI6o+catqP9lqCHPw4bCBaSBpX5HPGHCuQy1NE4zqBHMiBfMMGODItMsoYNqDN9dGQa0D1uTrv65rDBnxhaT6sCTYDPTt+zfQekKACPSTSfaRGY3JQPbk8Hz9/+WUgjXqN03uAh0HwxXv72X1rXr6l+r5IHTVADtRCX2F3wF8HDxx8e/3UgBzwBq6AF8zbjz+70+NADcTuoMpvjMo1Abm0gQYwhf/skvavkZOBVuuCXb8zkyBHg78AAAD//x7EiykAAAAGSURBVAMAqunlDvY2U44AAAAASUVORK5CYII=" + }, + { + "name": "dummy-blue.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/dummy-blue.png", + "relative_path": "../resources/assets/aj_booth/textures/blueprint/dummy-blue.png", + "folder": "", + "namespace": "", + "id": "2", + "group": "", + "scope": 0, + "width": 32, + "height": 32, + "uv_width": 32, + "uv_height": 32, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "de6a4a8d-9572-aa66-83d6-97dd13d04b15", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC90lEQVR4AbyUS2hTQRSGT68IQhE0omZhohRUJItYulA0iFBXplXEBy4E94obKehCSleCUARBEVc+Fio+qEXrRguiQRSF2lUEoWgrJSAGNxFBJOYbMuMwmeRO2mDJ1/vf/z8zczJzc6OXE4VqCD/f3alW56cV6JAx1EjMXxSTq7g0My1P3pTl/sOCAo2nwto/tI9aFPsJaoBZkj1ZscHrBEENsLC7mM9za0LugxoImWihNUENcL7uAj7PrQm5D2qAiVjQBq8TBDXAeQ9sT8jhgzkFGo8GaArtg4yaVgQ10GoCFm6Wk/EuAN4dvveIaoBOfeiJ516PyYVrz2Rk+JICjadz31g8nVM79ui93L5yS4HGI1cNIOLYtHalKbG1MWPE0mSP2Ohy0wDbZaML9JXBmWyfAFr7+mqPRWufq69ee6oBdwCDbE8X42tsz67Vuc/TmX2N7LOyAzQZoH2QgS/DIwO0DzK1A77Q5/0uzQj4soV6QQ2wnZDacUAADaGLUuuD8REBQnP86RbRjBYH5czHo+Z+aCKty8zVHW+CmiCDmjSfXflcl+bIqZNdsTuwe2tCwMzQYRHbQIfXa5gutoEXH8oCDSM7ZEScq83qakUqzwuKz5NTcnNv0TCan1XPw/X5nQL288FzwzxuX8eupgUOnf4usGbzeBXSA7NViDK9KTMGDd17cgImcAQ7Atr+86UioO991w39vca2tTqCb13dAqaiLpZt/DeobrW8sGPNCpg/P7RPAK3rVAP6JuTKEdlwXL8+TcmKt48lWf7aMMWS9d3KY4cmx+cE0JhkbTdgd4/mqNipH9sGpZRYx7xt0XYDbc1eL+ab+iD+Lw2wUDNUA/pM3aJk45vXLQm658x9MDjioUAAGiimKTwX20fHPYTMxRzuEeCRRf37U5KpvQsAPXI2JcA9RS68jGweXFwlcPlGVs4Nu9Ui7CK/Ehpdfu+uABqPTB2BPexVUQRsbzGaL8JvH/rOnxBAA1lDA4tZzDcWj7emD7K/AAAA//9P7heUAAAABklEQVQDABc076K58GTjAAAAAElFTkSuQmCC" + }, + { + "name": "dummy-green.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/dummy-green.png", + "relative_path": "../resources/assets/aj_booth/textures/blueprint/dummy-green.png", + "folder": "", + "namespace": "", + "id": "3", + "group": "", + "scope": 0, + "width": 32, + "height": 32, + "uv_width": 32, + "uv_height": 32, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "c4620ba1-f183-e58d-473c-9249d0f9fabc", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC+klEQVR4AbyVTUiUQRjHH1+IwrbIELJoYfEgkYFRlxLrUIR9GBHRx706hV2kU1DZIYjyUBFRUIeCPoiwgxGytxAL+gAhIjqIuH142MpiWQxht/0NzjCMs76z66L4c/7zf5555tmZd1+jVy+GiiHk3z4qFr+PKNAha8iRmJ8oJq7CE6MjMvDmlzx9NqRA46lg6Q/aRykU+xvUAFWamtvEBq8WBDXAxu5mPs/NCZkHNRBSqNqcoAa4X3cDn+fmhMyDGqAQG9rg1YKgBrjvri0r5fChDgUajwZoCu2DGDlzEdTAXAXYuFycGO8C4N3he4+oBujUhy6cGe6Xy7fTcuHcNQUaT8d9a/F0nNz+5+/k4c37CjQecdUAIo6WVQ0mxdbGjBGLmprFRqebBjguG52gRxa3tm0WQGtfj/ZatPYZffnaUw24C1hkezoZX2N7dq6O+zwds8fIvis7gCYGaB/EwBfDIwZoH8TUCfiCPm96YlTAF6vWC2qA44Rk+0EBNIRuSq4P1kcEEJorheOiuTV1SR6krpv5+U9HdZoZ3fUmUBLEoCTN7/Z9HXWaI92n6mJP4FhXn/xONZoCtRaxDdR6Q7debAOPB3qkYSzrrqvZPOJebXKfcxKlvyqWZyblTHTX0Lv+iXoeMnsnBezng+eGOm5nvd+2CfQNdgocOL20CDvv1BUhmt6dMmvQUNi1VsAEHMGpgLbzP74I6Llv/JtcYWxbqytIrEsImIwZkduQn1FhAydWLpP6P09uFEDrPNWAnoSMXJEN15X4WC/Zl0tkLFOYVaJ+dYvyOKHFr4cF0JjEKm7A7h7NVXFSjXumJJWsuJxUvoLWK4RP6oMyC9IAG5VDNaDv1E0q/FnjWlXNuXMfFIt4KBCABpJpCs/F9tFxDyG1qOFeAR6x6N/WduG7D+jW/d0CzEly4WVk09M5KHDjRFrO7rjqpgunyLeERsfvjQug8YipK7BXfci+F7C9+Wg+CN99WHZxkwAaiM1qYD6b+dbi8b/EB7H/AAAA///FshSiAAAABklEQVQDANe2/eIjJHRIAAAAAElFTkSuQmCC" + }, + { + "name": "dummy-orange.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/dummy-orange.png", + "relative_path": "../resources/assets/aj_booth/textures/blueprint/dummy-orange.png", + "folder": "", + "namespace": "", + "id": "4", + "group": "", + "scope": 0, + "width": 32, + "height": 32, + "uv_width": 32, + "uv_height": 32, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "6ef76b9a-a646-8fd1-5257-c5e819302f92", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADAUlEQVR4AbyVT0hUQRzHfz4IBe2PQv45GCkRRKGHDkVsewkPsaFE1KHORVCdo4Lq0p89dAiKkE51MCjCiKSDdBGRoCBWojqECy2kbWAGGUrF9j7DzjSMs75ZXRI/vu/7fn8z89uZt89obGS8FMLPVw9Kpc85BTpkDDWS8BMl5CqemcrJs5ez8ujxuAKNp8L4D9pHHCX+BjXALO3dvWKDVwuCGmBhdzGf59aE3Ac1EDLRSmuCGuB83QV8nlsTch/UABOxoA1eLQhqgPM+sLtFDh9KKdB4NEBTaB9k1CxHUAPLTcDClXIy3gXAu8P3HlEN0KkPPXFhYliyg6Ny+eJNBRpP576xeDqndvjJaxm6fV+BxiNXDSCS2NrWbEpsbcwEsaa9W2x0uWmA7bLRBfrK4O29OwXQ2tdXeyxa+1x99dpTDbgDGGR7uhhfY3t2rc59ns7sa2SflR2gyQDtgwx8GR4ZoH2QqR3whT7v18yUgC9bqRfUANsJnXsOCqAhdFFqfTA+IkBotjy9Kpq1Lx5K6u2IuZ+/e0GXmas73gSxIINYmt90JlWnOXLmVF3iDnQc3S+tG7+bCWotEhuo9YLufIkNTA89l+LX9e64mt1HnKtN7su8jL6vUxRnm+Rj/3lD4/Er6nnY2/RGwH4+eG6Yx+2sc/CSQD57TeBeOlOCfP++EkR9O36bMWjFtpL0xZjAEewKaHtxelFA3/uurS0/jG1rdQS9bY0CpqIs0hsWyirswo5VqmT+Y+k5AbSuUw3om5ArR2TDcY3NNcitfFEmv31aMkV9R73y2KHCZIMAGpOs6gbs7tEcVTreqdNdrdLTvIl5q6LqBqqavVzMJ/VB/F8aYKFKqAb0mbpFH6J/3xA3q+aeM/fBHBEPBQLQQDFN4bnYPjrpIWQu5nCPAI8s6uxZEPXdj98H6M2ZbgE8ilx4Gdl0nT0nMHD9juw6cdItF3aRbwmN3pgoCKDxyNQR2KP+FN4J2N5qNB+E7z5kB9YJoIFsSQOrWcw3Fo//JT7I/gIAAP//Oumm7wAAAAZJREFUAwD/z/ySVJzgOwAAAABJRU5ErkJggg==" + }, + { + "name": "dummy-purple.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/dummy-purple.png", + "relative_path": "../resources/assets/aj_booth/textures/blueprint/dummy-purple.png", + "folder": "", + "namespace": "", + "id": "5", + "group": "", + "scope": 0, + "width": 32, + "height": 32, + "uv_width": 32, + "uv_height": 32, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "1fc4185b-fc53-76fe-b361-520e3cab1bd1", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADAElEQVR4AbyVQUiUQRTHnx9le6hAyZIgDwZaGRnVIWQL6RQVRkh7FCkIITp07RDSqU4RVFREiIc8SBlLRRB0iEWkPGgUaJAHBZEMg4La1nDb3+hMwzjrN61L4s/5z/u/efN25tvP6PWzTD6EH2/78vnpUQU6ZA05EvMTxfjKnpkYladDc9L/KKNAE1Nm4Q/aR8GK/Q1qgCq19c1iQ6wcBDXAxu5mvpibEzIPaiCkUKk5QQ1wv+4GvpibEzIPaoBCbGhDrBwENcB9nzhYLafbkwo0MRqgKbQPPHJWIqiBlQqwcTEfj3cB8O7wvUdUA3TqQxeeGhyQa3dfSvflGwo0Me371hLTPrkDT4bl4a1eBZoYvmoAEUfDliqTYmsTjBFra+vFRqebBjguG52gRxY3Ne8XQOu4Hu21aB1n9OXrmGrAXcAiO6aTiWvsmJ2rfV9Me/YY2XdlG2g8QPvAA59HDA/QPvDUCfhMX2x+ZkLA55UaC2qA44RtLacE0BC6Kbk+WB9hIDTpFxtF05fZKW8+HjLz6705nWZGd70xCgIPCtL8Hj6erNCkLpyviD2BziPrZG9ijSlQbhHbQLk3dOvFNtDz6peMZH+768o2j7hXm0+fv8jzyYxiPDsmbUe/GS52VKrnoTpXI2A/H+nCs0Mdt7Ob/esFuu69E9h18nYeUp0jeYja62rNGjQcq0sKGMMRnAro8OT3BQE9942NiR0mbGt1Bds3bxIwGUtid1XLkgobxgsnViyT+pcaWgXQOk81oCchI1dkw3W9/zoowx8eSHZ6bFmJug2LW3BC6dmcAJpEvEWXWSB292iuipM60HRGElv/HnNgOfnnBkIL23l8Uh/k/JcG2KgYqgF9p27S/M85N1TSnDv3QbGIhwIBaCCZpoi52HF03ENILWq4V0AML2qrqRS++4A+uy8hwJwkF15GNnfO7RHo6U7J1Y5GN104Rb4lNPp46L4AmhieugJ71ezUgoAdW43mg/DdhyutXQJowFvWwGo2860lxv8SH3h/AAAA//8RcHB7AAAABklEQVQDAMoJAoUPp0uuAAAAAElFTkSuQmCC" + }, + { + "name": "dummy-yellow.png", + "path": "/var/mnt/ssd2/repos/snavesutit/aj-booth-smithed-summit-2026/resources/assets/aj_booth/textures/blueprint/dummy-yellow.png", + "relative_path": "../resources/assets/aj_booth/textures/blueprint/dummy-yellow.png", + "folder": "", + "namespace": "", + "id": "6", + "group": "", + "scope": 0, + "width": 32, + "height": 32, + "uv_width": 32, + "uv_height": 32, + "particle": false, + "use_as_default": false, + "layers_enabled": false, + "sync_to_project": "", + "file_format": "png", + "render_mode": "default", + "render_sides": "auto", + "wrap_mode": "limited", + "pbr_channel": "color", + "fps": 7, + "frame_time": 1, + "frame_order_type": "loop", + "frame_order": "", + "frame_interpolate": false, + "visible": true, + "internal": true, + "saved": true, + "uuid": "faec7662-9c97-b15a-ff48-ae547e303a65", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADAElEQVR4AbyUzUtVQRjGX08Zln3QByRBREaCFPdiRUVIK7HourGPG0EuahfhP1AUrYKWLQqiRZBgZYUtFAJbhUQfEuhGMDIiCFdBWWKY3eY3hzlNc+d65l4vib97nvO87zvznpk5J3o+OFwIYebNvULh86gGHVJDjqT8RSlxHZ6aHJWBl1/k4eNhDRpPB9UP2ocKpf4HNcAoDY1ZscGrBkENMLE7mc9zc0LugxoIGajSnKAG2F93Ap/n5oTcBzXAQExog1cNghpgvzv2r5MTx1o1aDwaoCm0D2LkLERQAwsNwMSl4sT4FgDfDt93RDdApz7MwJ9e9Mu1W0Ny5fJ1DRrPxH21eCZObv+TEem9cVeDxiOuG0Ck0bRxbZJi68RMEbUNjWJj0pMGWC4bk2CuFO/I7hZAG99c7Vq08bn68o2nG3ALKLI9k4xvsD0718R9nonZ18jeKzuAJgZoH8TAF8MjBmgfxPQK+II+b25qUsAXq9QLaoDlhM0HOgXQEDopuT6ojwggDJnmnBjaT12U9tyF5D6zr8OkJVe3PgkoQQyUTP4P5lprDPnu8zWpK1C3tUsgGaHKIrWBKs9XNFxqA7MfegSKKqtkROyrjayukYmn9TF9K2RsfPAvrwb0edh75L7AP+eDs+M5Iy3LDgnUfcwLvL65qQDTQ/UFiOrWn06eBQ1Nh38IJAFHsCJg7CXvfwmYe9+1KT+T2LaOt+BbQQSSlFg0b/8ai8DfCbViJVPV+JlzRwXsueIGSlZ5AmqL2CYD2zX+bo30PFglI29/FxXMb1uqPVZo7tkdATQmsfIbUE9CsUZptoqV6jo5LXt2lT9c+RV65vJ+eFIfjPJfGmCiUsQNmH11suZbah2nslv23AejRRwKBKCBZH3IMF1o1nhKpx1CPZbKd7dAWfrVjWrbzgjvPqBXtn0X4J4klzH1MbKZ3dInsLPzkWzIXnLThVXkLaHR3qvLBdB4xOItsMp+SreAZS1K8iC8+3D29nEBNBAramBRs3mKsfhq+iD2BwAA///YlcY2AAAABklEQVQDAJJV2AyLC60mAAAAAElFTkSuQmCC" + } + ], + "variants": { + "default": { + "name": "default", + "display_name": "Default", + "uuid": "cfddab63-2784-9d8d-28a0-db5a92e5e79c", + "texture_map": {}, + "excluded_nodes": [], + "is_default": true + }, + "list": [ + { + "name": "color1", + "display_name": "color1", + "uuid": "2e4a7a35-f54e-4169-2bd7-1608fec713da", + "texture_map": { + "9230eadb-794f-c7ee-226c-9057fa3dbfc0": "56a7cab8-b8c2-7236-1e43-6d205a231cf9" + }, + "excluded_nodes": [] + }, + { + "name": "color2", + "display_name": "color2", + "uuid": "f7ac442b-a23c-a1a6-9ed9-4e3ffe60e45d", + "texture_map": { + "9230eadb-794f-c7ee-226c-9057fa3dbfc0": "6ef76b9a-a646-8fd1-5257-c5e819302f92" + }, + "excluded_nodes": [] + }, + { + "name": "color3", + "display_name": "color3", + "uuid": "6809af79-bf39-d65f-35d9-c392fe0c8898", + "texture_map": { + "9230eadb-794f-c7ee-226c-9057fa3dbfc0": "faec7662-9c97-b15a-ff48-ae547e303a65" + }, + "excluded_nodes": [] + }, + { + "name": "color4", + "display_name": "color4", + "uuid": "03e6b8ad-767f-4e6d-4beb-bd412523668e", + "texture_map": { + "9230eadb-794f-c7ee-226c-9057fa3dbfc0": "c4620ba1-f183-e58d-473c-9249d0f9fabc" + }, + "excluded_nodes": [] + }, + { + "name": "color5", + "display_name": "color5", + "uuid": "b72bc719-deb3-841f-ebb7-6a1870bd3572", + "texture_map": { + "9230eadb-794f-c7ee-226c-9057fa3dbfc0": "de6a4a8d-9572-aa66-83d6-97dd13d04b15" + }, + "excluded_nodes": [] + }, + { + "name": "color6", + "display_name": "color6", + "uuid": "baabfb65-de97-367f-b00c-df166be3ad99", + "texture_map": { + "9230eadb-794f-c7ee-226c-9057fa3dbfc0": "1fc4185b-fc53-76fe-b361-520e3cab1bd1" + }, + "excluded_nodes": [] + } + ] + }, + "animations": [ + { + "uuid": "5282c207-27fc-6d15-9ecb-2ab888e773b6", + "name": "floss", + "loop": "loop", + "override": false, + "length": 3, + "snapping": 20, + "selected": true, + "saved": true, + "path": "", + "scope": 0, + "anim_time_update": "", + "blend_weight": "", + "start_delay": "", + "loop_delay": "0", + "excluded_nodes": [], + "animators": { + "94423fd0-c142-7a22-b7e0-a0923dc09001": { + "name": "root", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "e2925fd0-0e3a-a24e-6d46-78a88e0152cd": { + "name": "hip", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "541fe9f0-73c8-eb6a-9a04-cab1b4a35436": { + "name": "body", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "3", + "y": "v.freq = -2;\nv.mag = 6;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;", + "z": "v.freq = 2;\nv.mag = 12.25;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;" + } + ], + "uuid": "670f8a61-c2ec-183e-6cb9-66a4c02c50d2", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "v.freq = 2;\nv.mag = -1;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;", + "y": "v.freq = 4;\nv.mag = 0.25;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;", + "z": "0" + } + ], + "uuid": "9e7cfb37-99a6-fb3d-9c55-f28f1d8cf02a", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "7e88cca3-a783-43c2-bca9-d209d23c8267": { + "name": "head", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "-6", + "y": "0", + "z": "v.freq = 2;\nv.mag = -12.25;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;" + } + ], + "uuid": "85507e34-a7a3-5010-6709-a6c6a7607972", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "c62aea43-e02d-1e4b-194d-290157b28f75": { + "name": "right_arm", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "v.freq = 1;\nv.mag = 45;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = -0.25;\n\nv.v = math.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;\n\nv.a = 0;\nv.b = v.v;\nv.k = 22.5;\n\nv.h = math.clamp(0.5 + (0.5 * (v.a - v.b) / v.k), 0, 1);\nv.v = math.lerp(v.a, v.b, v.h) - (v.k * v.h * (1 - v.h));\nv.v = v.v;\n\nreturn 22.5 + (v.v * (q.life_time > 1 && q.life_time < 3));\n", + "y": "0", + "z": "v.freq = 2;\nv.mag = 45;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;" + } + ], + "uuid": "7301f9ba-4985-7f5d-384a-709614e0ec69", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "v.freq = 2;\nv.mag = 1.25;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;", + "y": "0", + "z": "v.freq = 1;\nv.mag = 4;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = -0.25;\n\nv.v = math.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;\n\nv.a = 0;\nv.b = v.v;\nv.k = 4;\n\nv.h = math.clamp(0.5 + (0.5 * (v.a - v.b) / v.k), 0, 1);\nv.v = math.lerp(v.a, v.b, v.h) - (v.k * v.h * (1 - v.h));\nv.v = -v.v;\n\nreturn -2 + ((math.mod(q.life_time, 3) > 0.75 && math.mod(q.life_time, 2) < 2.5) ? v.v);" + } + ], + "uuid": "5af6f3cf-3bf7-1ecc-2eec-6dc3db6cf298", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "f7687416-3ab6-ac7e-db96-736a4aa7bbda": { + "name": "right_leg_up", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "de264961-27eb-a7ac-b42a-cf40a8d52d1e": { + "name": "right_leg_down", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "-3", + "y": "0", + "z": "v.freq = 2;\nv.mag = -10;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset + 4;" + } + ], + "uuid": "c5147b25-61bc-2d04-2232-4305ee589eb2", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "1", + "y": "0", + "z": "0" + } + ], + "uuid": "a8eba5b1-58d4-7d66-f89e-e7b26580179f", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "fd36d7de-e6a9-1b56-bcd4-e7c969415d2b": { + "name": "left_leg_up", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false + }, + "b1f5db33-1d58-996b-5840-30cac02aed11": { + "name": "left_leg_down", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "-3", + "y": "0", + "z": "v.freq = 2;\nv.mag = -10;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset - 4;" + } + ], + "uuid": "0a2abe49-5a80-af0f-d335-49505c8e8ee2", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "-1", + "y": "0", + "z": "0" + } + ], + "uuid": "80fb9727-fbed-1043-b4d2-114ff6905262", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + }, + "ebba3cac-918d-1185-86aa-d7ce83935ef4": { + "name": "left_arm", + "type": "bone", + "rotation_global": false, + "quaternion_interpolation": false, + "keyframes": [ + { + "channel": "rotation", + "data_points": [ + { + "x": "v.freq = 1;\nv.mag = 45;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = 1.25;\n\nv.time = q.life_time > 2 ? q.life_time + 1 : q.life_time;\n\nv.v = math.atan(v.balloon * math.sin((v.time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;\n\nv.a = 0;\nv.b = v.v;\nv.k = 22.5;\n\nv.h = math.clamp(0.5 + (0.5 * (v.a - v.b) / v.k), 0, 1);\nv.v = math.lerp(v.a, v.b, v.h) - (v.k * v.h * (1 - v.h));\nv.v = v.v;\n\nreturn 22.5 + v.v * (q.life_time < 1 || q.life_time > 2);\n", + "y": "0", + "z": "v.freq = 2;\nv.mag = 45;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;" + } + ], + "uuid": "a0e2fc0e-a522-923a-3674-3cb1c9b9ad0c", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + }, + { + "channel": "position", + "data_points": [ + { + "x": "v.freq = 2;\nv.mag = 1;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;", + "y": "0", + "z": "v.freq = 1;\nv.mag = 4;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = 1.25;\n\nv.time = q.life_time > 2 ? q.life_time + 1 : q.life_time;\n\nv.v = math.atan(v.balloon * math.sin((v.time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;\n\nv.a = 0;\nv.b = v.v;\nv.k = 4;\n\nv.h = math.clamp(0.5 + (0.5 * (v.a - v.b) / v.k), 0, 1);\nv.v = math.lerp(v.a, v.b, v.h) - (v.k * v.h * (1 - v.h));\nv.v = -v.v;\n\nreturn -2 + (v.v * (q.life_time < 1.25 || q.life_time > 2.25));" + } + ], + "uuid": "a296e4cb-3147-2a7f-a98d-392a5f3077a1", + "time": 0, + "color": -1, + "interpolation": "linear", + "easing": "linear", + "easingArgs": [] + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/test_blueprints/amy-stand.png b/test_blueprints/amy-stand.png new file mode 100644 index 0000000000000000000000000000000000000000..54a7002de5d4448d7d77d4a7d99afaa12eeb54f2 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jPK-BC>eK@{Ea{HEjtmSN z`?>!lvI6-E$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD52-+ z;uvCaI(f~BGk?xAu*OZCXrR`-cCGH5vnPO{f!V+?fJ4J9L8PZC&_R`f!N7@yZT>!C QOQ22$Pgg&ebxsLQ0Cu`BwEzGB literal 0 HcmV?d00001 diff --git a/test_blueprints/amy_stand.bbmodel b/test_blueprints/amy_stand.bbmodel new file mode 100644 index 00000000..1e54aa28 --- /dev/null +++ b/test_blueprints/amy_stand.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"5.0","model_format":"free","box_uv":false},"name":"amy_stand","model_identifier":"","visible_box":[1,1,0],"variable_placeholders":"","multi_file_ruleset":"","variable_placeholder_buttons":[],"timeline_setups":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"body_top","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-5,20,-1.5],"to":[5,23,1.5],"autouv":0,"color":2,"inflate":-0.25,"origin":[0,21.5,0],"faces":{"north":{"uv":[4,1,5,2],"texture":0},"east":{"uv":[1,1,2,2],"texture":0},"south":{"uv":[4,1,5,2],"texture":0},"west":{"uv":[1,1,2,2],"texture":0},"up":{"uv":[1,1,2,2],"texture":0},"down":{"uv":[1,1,2,2],"texture":0}},"type":"cube","uuid":"4566ad55-020b-987f-89b1-5ed910073398"},{"name":"left_body","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-3,13,-1],"to":[-1,20,1],"autouv":0,"color":2,"inflate":-0.25,"origin":[-2,16.5,0],"faces":{"north":{"uv":[4,1,5,2],"texture":0},"east":{"uv":[2,1,1,2],"texture":0},"south":{"uv":[4,1,5,2],"texture":0},"west":{"uv":[1,1,2,2],"texture":0},"up":{"uv":[1,1,2,2],"texture":0},"down":{"uv":[1,1,2,2],"texture":0}},"type":"cube","uuid":"00b30e55-f715-4bdd-9a7f-762bccc11869"},{"name":"waist","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-4,11,-1],"to":[4,13,1],"autouv":0,"color":2,"inflate":-0.25,"origin":[0,12,0],"faces":{"north":{"uv":[4,1,5,2],"texture":0},"east":{"uv":[2,1,1,2],"texture":0},"south":{"uv":[4,1,5,2],"texture":0},"west":{"uv":[1,1,2,2],"texture":0},"up":{"uv":[1,1,2,2],"texture":0},"down":{"uv":[1,1,2,2],"texture":0}},"type":"cube","uuid":"82895f3a-e029-6aba-13b5-aa5fb87d7af6"},{"name":"head","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-1,23,-1],"to":[1,29,1],"autouv":0,"color":2,"inflate":-0.25,"origin":[0,25.5,0],"faces":{"north":{"uv":[4,1,5,2],"texture":0},"east":{"uv":[1,1,2,2],"texture":0},"south":{"uv":[4,1,5,2],"texture":0},"west":{"uv":[1,1,2,2],"texture":0},"up":{"uv":[1,1,2,2],"texture":0},"down":{"uv":[1,1,2,2],"texture":0}},"type":"cube","uuid":"d5cd5bb3-f5a0-3426-b2c2-9b5718d154aa"},{"name":"left_arm","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-7,11,-1],"to":[-5,23,1],"autouv":0,"color":2,"inflate":-0.25,"origin":[-6,17,0],"faces":{"north":{"uv":[4,1,5,2],"texture":0},"east":{"uv":[1,1,2,2],"texture":0},"south":{"uv":[4,1,5,2],"texture":0},"west":{"uv":[1,1,2,2],"texture":0},"up":{"uv":[1,1,2,2],"texture":0},"down":{"uv":[1,1,2,2],"texture":0}},"type":"cube","uuid":"2c4ada70-9f6b-6fdb-d09f-78a841058598"},{"name":"right_leg","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[1,0,-1],"to":[3,11,1],"autouv":0,"color":2,"inflate":-0.25,"origin":[2,5.5,0],"faces":{"north":{"uv":[4,1,5,2],"texture":0},"east":{"uv":[2,1,1,2],"texture":0},"south":{"uv":[4,1,5,2],"texture":0},"west":{"uv":[1,1,2,2],"texture":0},"up":{"uv":[1,1,2,2],"texture":0},"down":{"uv":[1,1,2,2],"texture":0}},"type":"cube","uuid":"36492cd8-ab91-866f-fb9c-47671f5edc21"},{"name":"left_leg","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-3,0,-1],"to":[-1,11,1],"autouv":0,"color":2,"inflate":-0.25,"origin":[-2,5.5,0],"faces":{"north":{"uv":[4,1,5,2],"texture":0},"east":{"uv":[2,1,1,2],"texture":0},"south":{"uv":[4,1,5,2],"texture":0},"west":{"uv":[1,1,2,2],"texture":0},"up":{"uv":[1,1,2,2],"texture":0},"down":{"uv":[1,1,2,2],"texture":0}},"type":"cube","uuid":"d2687e3a-a2c9-9baf-acef-c69a8f36f754"},{"name":"left_leg_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-1,11,1],"to":[-3,0,-1],"autouv":0,"color":2,"inflate":-0.125,"origin":[-2,5.5,0],"faces":{"north":{"uv":[7,2,8,1],"texture":0},"east":{"uv":[7,2,8,1],"texture":0},"south":{"uv":[7,2,8,1],"texture":0},"west":{"uv":[7,2,8,1],"texture":0},"up":{"uv":[7,2,8,1],"texture":0},"down":{"uv":[7,2,8,1],"texture":0}},"type":"cube","uuid":"310a8ac2-0391-75e1-b707-4107be669f92"},{"name":"waist_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[4,13,1],"to":[-4,11,-1],"autouv":0,"color":2,"inflate":-0.125,"origin":[0,12,0],"faces":{"north":{"uv":[8,1,7,2],"texture":0},"east":{"uv":[8,1,7,2],"texture":0},"south":{"uv":[8,1,7,2],"texture":0},"west":{"uv":[8,1,7,2],"texture":0},"up":{"uv":[8,1,7,2],"texture":0},"down":{"uv":[8,1,7,2],"texture":0}},"type":"cube","uuid":"cbbccd65-8d48-2e7e-325e-40718f1b5d10"},{"name":"right_leg_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[3,11,1],"to":[1,0,-1],"autouv":0,"color":2,"inflate":-0.125,"origin":[2,5.5,0],"faces":{"north":{"uv":[7,2,8,1],"texture":0},"east":{"uv":[7,2,8,1],"texture":0},"south":{"uv":[7,2,8,1],"texture":0},"west":{"uv":[7,2,8,1],"texture":0},"up":{"uv":[7,2,8,1],"texture":0},"down":{"uv":[7,2,8,1],"texture":0}},"type":"cube","uuid":"1555fa54-9792-b3bb-5d76-70c96803b871"},{"name":"right_body_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-1,20,1],"to":[-3,13,-1],"autouv":0,"color":2,"inflate":-0.125,"origin":[-2,16.5,0],"faces":{"north":{"uv":[7,2,8,1],"texture":0},"east":{"uv":[7,2,8,1],"texture":0},"south":{"uv":[7,2,8,1],"texture":0},"west":{"uv":[7,2,8,1],"texture":0},"up":{"uv":[7,2,8,1],"texture":0},"down":{"uv":[7,2,8,1],"texture":0}},"type":"cube","uuid":"d4d2c040-9ede-9d25-5244-dc8e9653a584"},{"name":"left_body_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[3,20,1],"to":[1,13,-1],"autouv":0,"color":2,"inflate":-0.125,"origin":[2,16.5,0],"faces":{"north":{"uv":[8,2,7,1],"texture":0},"east":{"uv":[8,2,7,1],"texture":0},"south":{"uv":[8,2,7,1],"texture":0},"west":{"uv":[8,2,7,1],"texture":0},"up":{"uv":[8,2,7,1],"texture":0},"down":{"uv":[8,2,7,1],"texture":0}},"type":"cube","uuid":"c9cf565c-a57d-64ba-118e-35e8a1888aa7"},{"name":"right_body","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[1,13,-1],"to":[3,20,1],"autouv":0,"color":2,"inflate":-0.25,"origin":[2,16.5,0],"faces":{"north":{"uv":[5,1,4,2],"texture":0},"east":{"uv":[2,1,1,2],"texture":0},"south":{"uv":[5,1,4,2],"texture":0},"west":{"uv":[1,1,2,2],"texture":0},"up":{"uv":[2,1,1,2],"texture":0},"down":{"uv":[2,1,1,2],"texture":0}},"type":"cube","uuid":"c1a1ff4c-44ab-d092-95a8-07206936345b"},{"name":"left_arm_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-5,23,1],"to":[-7,11,-1],"autouv":0,"color":2,"inflate":-0.125,"origin":[-6,17,0],"faces":{"north":{"uv":[7,2,8,1],"texture":0},"east":{"uv":[7,2,8,1],"texture":0},"south":{"uv":[7,2,8,1],"texture":0},"west":{"uv":[7,2,8,1],"texture":0},"up":{"uv":[7,2,8,1],"texture":0},"down":{"uv":[7,2,8,1],"texture":0}},"type":"cube","uuid":"2309b0da-b8b5-f7f0-a172-2c9e95d6c54a"},{"name":"body_bottom_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[5,23,1.5],"to":[-5,20,-1.5],"autouv":0,"color":2,"inflate":-0.125,"origin":[0,21.5,0],"faces":{"north":{"uv":[7,2,8,1],"texture":0},"east":{"uv":[7,2,8,1],"texture":0},"south":{"uv":[7,2,8,1],"texture":0},"west":{"uv":[7,2,8,1],"texture":0},"up":{"uv":[7,2,8,1],"texture":0},"down":{"uv":[7,2,8,1],"texture":0}},"type":"cube","uuid":"f600d9cc-5306-3145-cccf-37f45bb7dc63"},{"name":"right_arm","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[5,11,-1],"to":[7,23,1],"autouv":0,"color":2,"inflate":-0.25,"origin":[6,17,0],"faces":{"north":{"uv":[5,1,4,2],"texture":0},"east":{"uv":[2,1,1,2],"texture":0},"south":{"uv":[5,1,4,2],"texture":0},"west":{"uv":[2,1,1,2],"texture":0},"up":{"uv":[2,1,1,2],"texture":0},"down":{"uv":[2,1,1,2],"texture":0}},"type":"cube","uuid":"b7389450-9f87-a117-b711-e42645ebf292"},{"name":"right_arm_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[7,23,1],"to":[5,11,-1],"autouv":0,"color":2,"inflate":-0.125,"origin":[6,17,0],"faces":{"north":{"uv":[8,2,7,1],"texture":0},"east":{"uv":[8,2,7,1],"texture":0},"south":{"uv":[8,2,7,1],"texture":0},"west":{"uv":[8,2,7,1],"texture":0},"up":{"uv":[8,2,7,1],"texture":0},"down":{"uv":[8,2,7,1],"texture":0}},"type":"cube","uuid":"3646d1de-68e6-fe50-2ae8-6392747b54ce"},{"name":"head_inverted","box_uv":false,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[1,29,1],"to":[-1,23,-1],"autouv":0,"color":2,"inflate":-0.125,"origin":[0,25.5,0],"faces":{"north":{"uv":[7,2,8,1],"texture":0},"east":{"uv":[7,2,8,1],"texture":0},"south":{"uv":[7,2,8,1],"texture":0},"west":{"uv":[7,2,8,1],"texture":0},"up":{"uv":[7,2,8,1],"texture":0},"down":{"uv":[7,2,8,1],"texture":0}},"type":"cube","uuid":"0946130f-bf6c-2a32-115b-86ae1a6790b1"}],"groups":[{"name":"root","uuid":"5138d87b-0694-3a62-b4a5-3dc844c0d856","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[0,0,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"on_apply_function":"say Entityless bone on-summon","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":false,"glowing":false,"override_glow_color":false,"glow_color":"#ffffff","invisible":false,"shadow_radius":0,"shadow_strength":1},"variants":{}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"waist_pivot","uuid":"bbc60e6a-9c61-3483-c3c6-c7f54facb659","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[0,11,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"billboard":"fixed","enchanted":false,"glowing":false,"override_glow_color":true,"glow_color":"#ffffff","inherit_settings":true,"invisible":false,"nbt":"{}","shadow_radius":0,"shadow_strength":1,"use_nbt":false,"sky_brightness":0,"block_brightness":0},"variants":{"5417306e-2c69-3f36-1e3c-edd904034a36":{}}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"body_waist_pivot","uuid":"3eed169e-c5af-d8b1-b004-4bc0d2f55f70","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[0,11,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"billboard":"fixed","enchanted":false,"glowing":false,"override_glow_color":true,"glow_color":"#ffffff","inherit_settings":true,"invisible":false,"nbt":"{}","shadow_radius":0,"shadow_strength":1,"use_nbt":false,"sky_brightness":0,"block_brightness":0},"variants":{"5417306e-2c69-3f36-1e3c-edd904034a36":{}}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"body","uuid":"25b8c0a1-9fa5-65c4-545e-8a32dff442d8","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[0,23,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":false,"glowing":false,"override_glow_color":true,"glow_color":"#ffffff","invisible":false,"shadow_radius":0,"shadow_strength":1},"variants":{"5417306e-2c69-3f36-1e3c-edd904034a36":{"billboard":"fixed","override_brightness":false,"enchanted":false,"glowing":false,"override_glow_color":false,"glow_color":"#ffffff","inherit_settings":true,"invisible":false,"nbt":"{}","shadow_radius":0,"shadow_strength":1,"use_nbt":false,"sky_brightness":0,"block_brightness":0},"49521f4b-b970-e4bd-b594-2e05d2d46027":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":true,"glowing":true,"override_glow_color":true,"glow_color":"#00ff06","invisible":false,"shadow_radius":0,"shadow_strength":1}}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"head","uuid":"1a8834ef-205f-cc3a-c551-3c51d5470cfb","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[0,22,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":false,"glowing":false,"override_glow_color":true,"glow_color":"#ffffff","invisible":false,"shadow_radius":0,"shadow_strength":1},"variants":{"49521f4b-b970-e4bd-b594-2e05d2d46027":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":true,"glowing":true,"override_glow_color":true,"glow_color":"#c400ff","invisible":false,"shadow_radius":0,"shadow_strength":1}}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"left_arm","uuid":"da4deb3c-16d7-6ea7-9337-24f8fc024a90","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[-6,22,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":false,"glowing":false,"override_glow_color":true,"glow_color":"#ffffff","invisible":false,"shadow_radius":0,"shadow_strength":1},"variants":{"49521f4b-b970-e4bd-b594-2e05d2d46027":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":true,"glowing":true,"override_glow_color":true,"glow_color":"#00ff9f","invisible":false,"shadow_radius":0,"shadow_strength":1}}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"right_arm","uuid":"1094a9b8-c198-b0d9-1c5f-df299a804853","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[6,22,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":false,"glowing":false,"override_glow_color":true,"glow_color":"#ffffff","invisible":false,"shadow_radius":0,"shadow_strength":1},"variants":{"49521f4b-b970-e4bd-b594-2e05d2d46027":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":true,"glowing":true,"override_glow_color":true,"glow_color":"#ff0000","invisible":false,"shadow_radius":0,"shadow_strength":1}}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"right_leg","uuid":"b3cf189a-1115-d9e7-62ab-74264f0c3de5","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[2,11,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":false,"glowing":false,"override_glow_color":false,"glow_color":"#ffffff","invisible":false,"shadow_radius":0,"shadow_strength":1},"variants":{"49521f4b-b970-e4bd-b594-2e05d2d46027":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":true,"glowing":true,"override_glow_color":true,"glow_color":"#ffee00","invisible":false,"shadow_radius":0,"shadow_strength":1}}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"left_leg","uuid":"c8c98301-ffa1-4f7c-0263-545f51d8acd5","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[-2,11,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"configs":{"default":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":false,"glowing":false,"override_glow_color":false,"glow_color":"#ffffff","invisible":false,"shadow_radius":0,"shadow_strength":1},"variants":{"49521f4b-b970-e4bd-b594-2e05d2d46027":{"on_apply_function":"","billboard":"fixed","override_brightness":false,"sky_brightness":0,"block_brightness":0,"enchanted":true,"glowing":true,"override_glow_color":true,"glow_color":"#6e00ff","invisible":false,"shadow_radius":0,"shadow_strength":1}}},"itemModelProperties":{"tints":[]},"primary_selected":false},{"name":"right_leg_down","uuid":"5c7ea6fe-6f58-30aa-e290-2086fc2396e7","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[2,0,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"name":"left_leg_down","uuid":"0d0a0429-76b1-3074-c050-d255bae55fb9","export":true,"locked":false,"scope":0,"selected":false,"_static":{"properties":{},"temp_data":{}},"origin":[-2,0,0],"rotation":[0,0,0],"color":0,"children":[],"reset":false,"shade":true,"mirror_uv":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false}],"outliner":[{"uuid":"5138d87b-0694-3a62-b4a5-3dc844c0d856","isOpen":true,"children":[{"uuid":"bbc60e6a-9c61-3483-c3c6-c7f54facb659","isOpen":true,"children":[{"uuid":"3eed169e-c5af-d8b1-b004-4bc0d2f55f70","isOpen":true,"children":[{"uuid":"25b8c0a1-9fa5-65c4-545e-8a32dff442d8","isOpen":true,"children":["4566ad55-020b-987f-89b1-5ed910073398","f600d9cc-5306-3145-cccf-37f45bb7dc63","00b30e55-f715-4bdd-9a7f-762bccc11869","d4d2c040-9ede-9d25-5244-dc8e9653a584","c9cf565c-a57d-64ba-118e-35e8a1888aa7","c1a1ff4c-44ab-d092-95a8-07206936345b","82895f3a-e029-6aba-13b5-aa5fb87d7af6","cbbccd65-8d48-2e7e-325e-40718f1b5d10",{"uuid":"1a8834ef-205f-cc3a-c551-3c51d5470cfb","isOpen":true,"children":["d5cd5bb3-f5a0-3426-b2c2-9b5718d154aa","0946130f-bf6c-2a32-115b-86ae1a6790b1"]},{"uuid":"da4deb3c-16d7-6ea7-9337-24f8fc024a90","isOpen":true,"children":["2c4ada70-9f6b-6fdb-d09f-78a841058598","2309b0da-b8b5-f7f0-a172-2c9e95d6c54a"]},{"uuid":"1094a9b8-c198-b0d9-1c5f-df299a804853","isOpen":true,"children":["b7389450-9f87-a117-b711-e42645ebf292","3646d1de-68e6-fe50-2ae8-6392747b54ce"]}]}]},{"uuid":"b3cf189a-1115-d9e7-62ab-74264f0c3de5","isOpen":true,"children":[{"uuid":"5c7ea6fe-6f58-30aa-e290-2086fc2396e7","isOpen":true,"children":["36492cd8-ab91-866f-fb9c-47671f5edc21","1555fa54-9792-b3bb-5d76-70c96803b871"]}]},{"uuid":"c8c98301-ffa1-4f7c-0263-545f51d8acd5","isOpen":true,"children":[{"uuid":"0d0a0429-76b1-3074-c050-d255bae55fb9","isOpen":true,"children":["d2687e3a-a2c9-9baf-acef-c69a8f36f754","310a8ac2-0391-75e1-b707-4107be669f92"]}]}]}]}],"textures":[{"name":"amy-stand.png","relative_path":"amy-stand.png","folder":"block","namespace":"","id":"0","group":"","scope":0,"width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"use_as_default":false,"layers_enabled":false,"sync_to_project":"e30e304e-bef4-5d57-cd05-5cd70f18c64a","file_format":"png","render_mode":"emissive","render_sides":"auto","wrap_mode":"limited","pbr_channel":"color","fps":7,"frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"71bb3ecd-1a19-c655-1f64-d2eb34bcd8ce","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAASklEQVR4AeyQsQkAMAgE1cHcxw0yQjZwHxczlWAlgk0KH656eI6nI+KBmXngKVCEiq5VzQeuKgbMjAGmVCpzg2q9060BwH7wwwcPAAD//xvCAPAAAAAGSURBVAMAV5AkIaAqFX0AAAAASUVORK5CYII="}],"animations":[{"uuid":"fdc5f2e4-4d44-575a-c560-78fb60728ddb","name":"floss","loop":"loop","override":false,"length":3,"snapping":20,"selected":false,"group_name":"","scope":0,"anim_time_update":"","blend_weight":"","start_delay":"","loop_delay":"0","animators":{"e2925fd0-0e3a-a24e-6d46-78a88e0152cd":{"name":"hip","type":"bone","rotation_global":false,"quaternion_interpolation":false},"f7687416-3ab6-ac7e-db96-736a4aa7bbda":{"name":"right_leg_up","type":"bone","rotation_global":false,"quaternion_interpolation":false},"fd36d7de-e6a9-1b56-bcd4-e7c969415d2b":{"name":"left_leg_up","type":"bone","rotation_global":false,"quaternion_interpolation":false},"92dcf713-d635-a9d6-2fa1-1a2e7dd14456":{"name":"armor_stand_root","type":"bone","rotation_global":false,"quaternion_interpolation":false},"9fcde70a-f243-a5b1-3c09-fe373e13adc6":{"name":"body_waist_pivot_base","type":"bone","rotation_global":false,"quaternion_interpolation":false},"effects":{"name":"Effects","type":"effect"},"5138d87b-0694-3a62-b4a5-3dc844c0d856":{"name":"root","type":"bone","rotation_global":false,"quaternion_interpolation":false},"bbc60e6a-9c61-3483-c3c6-c7f54facb659":{"name":"waist_pivot","type":"bone","rotation_global":false,"quaternion_interpolation":false},"3eed169e-c5af-d8b1-b004-4bc0d2f55f70":{"name":"body_waist_pivot","type":"bone","rotation_global":false,"quaternion_interpolation":false},"25b8c0a1-9fa5-65c4-545e-8a32dff442d8":{"name":"body","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"3","y":"v.freq = -2;\nv.mag = 6;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;","z":"v.freq = 2;\nv.mag = 12.25;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;"}],"uuid":"670f8a61-c2ec-183e-6cb9-66a4c02c50d2","time":0,"color":-1,"interpolation":"linear"},{"channel":"position","data_points":[{"x":"v.freq = 2;\nv.mag = -10 / 16;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;","y":"v.freq = 4;\nv.mag = 2.5 / 16;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;","z":"0"}],"uuid":"9e7cfb37-99a6-fb3d-9c55-f28f1d8cf02a","time":0,"color":-1,"interpolation":"linear"}]},"1a8834ef-205f-cc3a-c551-3c51d5470cfb":{"name":"head","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"-6","y":"0","z":"v.freq = 2;\nv.mag = -12.25;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;"}],"uuid":"85507e34-a7a3-5010-6709-a6c6a7607972","time":0,"color":-1,"interpolation":"linear"}]},"da4deb3c-16d7-6ea7-9337-24f8fc024a90":{"name":"left_arm","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"v.freq = 1;\nv.mag = 45;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = 1.25;\n\nv.time = q.life_time > 2 ? q.life_time + 1 : q.life_time;\n\nv.v = math.atan(v.balloon * math.sin((v.time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;\n\nv.a = 0;\nv.b = v.v;\nv.k = 22.5;\n\nv.h = math.clamp(0.5 + (0.5 * (v.a - v.b) / v.k), 0, 1);\nv.v = math.lerp(v.a, v.b, v.h) - (v.k * v.h * (1 - v.h));\nv.v = v.v;\n\nreturn 22.5 + v.v * (q.life_time < 1 || q.life_time > 2);\n","y":"0","z":"v.freq = 2;\nv.mag = 45;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;"}],"uuid":"a0e2fc0e-a522-923a-3674-3cb1c9b9ad0c","time":0,"color":-1,"interpolation":"linear"},{"channel":"position","data_points":[{"x":"v.freq = 2;\nv.mag = 1;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;","y":"0","z":"v.freq = 1;\nv.mag = 40 / 16;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = 1.25;\n\nv.time = q.life_time > 2 ? q.life_time + 1 : q.life_time;\n\nv.v = math.atan(v.balloon * math.sin((v.time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;\n\nv.a = 0;\nv.b = v.v;\nv.k = 4;\n\nv.h = math.clamp(0.5 + (0.5 * (v.a - v.b) / v.k), 0, 1);\nv.v = math.lerp(v.a, v.b, v.h) - (v.k * v.h * (1 - v.h));\nv.v = -v.v;\n\nreturn -20 / 16 + (v.v * (q.life_time < 1.25 || q.life_time > 2.25));"}],"uuid":"a296e4cb-3147-2a7f-a98d-392a5f3077a1","time":0,"color":-1,"interpolation":"linear"}]},"1094a9b8-c198-b0d9-1c5f-df299a804853":{"name":"right_arm","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"v.freq = 1;\nv.mag = 45;\nv.balloon = 1;\nv.offset = 0;\nv.time_offset = -0.25;\n\nv.v = math.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;\n\nv.a = 0;\nv.b = v.v;\nv.k = 22.5;\n\nv.h = math.clamp(0.5 + (0.5 * (v.a - v.b) / v.k), 0, 1);\nv.v = math.lerp(v.a, v.b, v.h) - (v.k * v.h * (1 - v.h));\nv.v = v.v;\n\nreturn 22.5 + (v.v * (q.life_time > 1 && q.life_time < 3));\n","y":"0","z":"v.freq = 2;\nv.mag = 45;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;"}],"uuid":"7301f9ba-4985-7f5d-384a-709614e0ec69","time":0,"color":-1,"interpolation":"linear"},{"channel":"position","data_points":[{"x":"v.freq = 2;\nv.mag = 1.25;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;","y":"0","z":"v.freq = 1;\nv.mag = 40 / 16;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = -0.25;\n\nv.v = math.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset;\n\nv.a = 0;\nv.b = v.v;\nv.k = 4;\n\nv.h = math.clamp(0.5 + (0.5 * (v.a - v.b) / v.k), 0, 1);\nv.v = math.lerp(v.a, v.b, v.h) - (v.k * v.h * (1 - v.h));\nv.v = -v.v;\n\nreturn -20 / 16 + ((math.mod(q.life_time, 3) > 0.75 && math.mod(q.life_time, 2) < 2.5) ? v.v);"}],"uuid":"5af6f3cf-3bf7-1ecc-2eec-6dc3db6cf298","time":0,"color":-1,"interpolation":"linear"}]},"b3cf189a-1115-d9e7-62ab-74264f0c3de5":{"name":"right_leg","type":"bone","rotation_global":false,"quaternion_interpolation":false},"c8c98301-ffa1-4f7c-0263-545f51d8acd5":{"name":"left_leg","type":"bone","rotation_global":false,"quaternion_interpolation":false},"0d0a0429-76b1-3074-c050-d255bae55fb9":{"name":"left_leg_down","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"-3","y":"0","z":"v.freq = 2;\nv.mag = -10;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset - 4;"}],"uuid":"55affe95-843e-aaee-e08b-4475db84e874","time":0,"color":-1,"interpolation":"linear"},{"channel":"position","data_points":[{"x":"-10 / 16","y":"0","z":"0"}],"uuid":"ad24d3c1-3d6b-c5b9-ef35-85c6a1c8396b","time":0,"color":-1,"interpolation":"linear"}]},"5c7ea6fe-6f58-30aa-e290-2086fc2396e7":{"name":"right_leg_down","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"-3","y":"0","z":"v.freq = 2;\nv.mag = -10;\nv.balloon = 2;\nv.offset = 0;\nv.time_offset = 0.5;\n\nmath.atan(v.balloon * math.sin((q.anim_time + v.time_offset) * 180 * v.freq)) / math.atan(v.balloon) * v.mag + v.offset + 4;"}],"uuid":"23fae470-4c2d-f7e9-119d-b07ba66ee213","time":0,"color":-1,"interpolation":"linear"},{"channel":"position","data_points":[{"x":"10 / 16","y":"0","z":"0"}],"uuid":"d4d6a93c-3133-f4c7-3365-d753e9ab7e2a","time":0,"color":-1,"interpolation":"linear"}]}}},{"uuid":"eeb3ad95-491e-e81c-0770-a6371e4104cc","name":"idle","loop":"loop","override":false,"length":4,"snapping":20,"selected":true,"group_name":"","scope":0,"anim_time_update":"","blend_weight":"","start_delay":"","loop_delay":"0","animators":{"effects":{"name":"Effects","type":"effect"},"92dcf713-d635-a9d6-2fa1-1a2e7dd14456":{"name":"armor_stand_root","type":"bone","rotation_global":false,"quaternion_interpolation":false},"9fcde70a-f243-a5b1-3c09-fe373e13adc6":{"name":"body_waist_pivot_base","type":"bone","rotation_global":false,"quaternion_interpolation":false},"5138d87b-0694-3a62-b4a5-3dc844c0d856":{"name":"root","type":"bone","rotation_global":false,"quaternion_interpolation":false},"bbc60e6a-9c61-3483-c3c6-c7f54facb659":{"name":"waist_pivot","type":"bone","rotation_global":false,"quaternion_interpolation":false},"3eed169e-c5af-d8b1-b004-4bc0d2f55f70":{"name":"body_waist_pivot","type":"bone","rotation_global":false,"quaternion_interpolation":false},"25b8c0a1-9fa5-65c4-545e-8a32dff442d8":{"name":"body","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"-2.560618951","y":"-12.4879106328","z":"-6.945956461 - math.cos(q.life_time * 90) * 1"}],"uuid":"9d5cd751-9085-73f0-021f-cac42d06da6c","time":0,"color":-1,"interpolation":"linear"},{"channel":"position","data_points":[{"x":"(22 + math.cos(q.life_time * 90) * 3) / 16","y":"0","z":"-8 / 16"}],"uuid":"45fa3711-2d03-fac1-b68a-05d990b083bb","time":0,"color":-1,"interpolation":"linear"}]},"1a8834ef-205f-cc3a-c551-3c51d5470cfb":{"name":"head","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"2.5191570088","y":"7.4952107227","z":"0.2196979085 - math.sin(q.life_time * 90) * 1"}],"uuid":"741801b0-e2e1-f6aa-78a3-51f0c3e972d7","time":0,"color":-1,"interpolation":"linear"}]},"da4deb3c-16d7-6ea7-9337-24f8fc024a90":{"name":"left_arm","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"0","y":"-10","z":"-161 + math.sin(q.life_time * 90) * 22.5"}],"uuid":"58a880e4-0f34-d8a9-2c31-7b0f06ed3858","time":0,"color":-1,"interpolation":"linear"}]},"1094a9b8-c198-b0d9-1c5f-df299a804853":{"name":"right_arm","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"-7.4365576814","y":"0.9762004016","z":"19.9365576815 - math.sin(q.life_time * 90 + 15) * 4"}],"uuid":"2ec466a7-765a-2de8-5c5e-a4e9f2ca927c","time":0,"color":-1,"interpolation":"linear"}]},"b3cf189a-1115-d9e7-62ab-74264f0c3de5":{"name":"right_leg","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"2.5215446767","y":"-7.4928206685","z":"4.6709767995"}],"uuid":"90d16b1f-61af-e83f-275e-096dd9b7fd68","time":0,"color":-1,"interpolation":"linear"}]},"c8c98301-ffa1-4f7c-0263-545f51d8acd5":{"name":"left_leg","type":"bone","rotation_global":false,"quaternion_interpolation":false,"keyframes":[{"channel":"rotation","data_points":[{"x":"-5.0767330166","y":"9.9615580981","z":"-10.8804470158"}],"uuid":"2ab7a965-c385-86a4-e789-b333a43da565","time":0,"color":-1,"interpolation":"linear"}]},"5c7ea6fe-6f58-30aa-e290-2086fc2396e7":{"name":"right_leg_down","type":"bone","rotation_global":false,"quaternion_interpolation":false},"0d0a0429-76b1-3074-c050-d255bae55fb9":{"name":"left_leg_down","type":"bone","rotation_global":false,"quaternion_interpolation":false}}}]} \ No newline at end of file diff --git a/test_blueprints/armor_stand.ajblueprint b/test_blueprints/armor_stand.ajblueprint index 4e20978e..de9b5561 100644 --- a/test_blueprints/armor_stand.ajblueprint +++ b/test_blueprints/armor_stand.ajblueprint @@ -1,17 +1,17 @@ { "meta": { "format": "animated-java:format/blueprint", - "format_version": "1.9.0-beta.3", + "format_version": "1.10.0-beta.6", "uuid": "167b27cd-b559-3f13-a97c-0841fe21f1d1", "save_location": "/var/mnt/ssd2/repos/animated-java/animated-java/test_blueprints/armor_stand.ajblueprint", - "last_used_export_namespace": "armor_stand" + "last_used_blueprint_id": "aj:undefined" }, "resolution": { "width": 64, "height": 64 }, "blueprint_settings": { - "export_namespace": "armor_stand", + "blueprint_id": "aj:armor_stand", "render_box": [95, 32], "target_minecraft_version": "1.21.5", "resource_pack": "C:\\Users\\SnaveSutit\\AppData\\Roaming\\ModrinthApp\\profiles\\Animated Java Dev\\resourcepacks\\resourcepack", @@ -1012,13 +1012,16 @@ }, "variants": {} }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, "mirror_uv": false, "visibility": true, "autouv": 0, - "isOpen": true, + "isOpen": false, "primary_selected": false }, { @@ -1052,6 +1055,9 @@ }, "variants": {} }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1092,6 +1098,9 @@ }, "variants": {} }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1133,6 +1142,9 @@ }, "variants": {} }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1176,6 +1188,9 @@ "5417306e-2c69-3f36-1e3c-edd904034a36": {} } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1219,6 +1234,9 @@ "5417306e-2c69-3f36-1e3c-edd904034a36": {} } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1291,6 +1309,9 @@ } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1349,6 +1370,9 @@ } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1407,6 +1431,9 @@ } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1465,6 +1492,9 @@ } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1521,6 +1551,9 @@ } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1577,6 +1610,9 @@ } } }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1604,6 +1640,9 @@ "configs": { "variants": {} }, + "itemModelProperties": { + "tints": [] + }, "children": [], "reset": false, "shade": true, @@ -1617,7 +1656,7 @@ "outliner": [ { "uuid": "98795982-9c43-6e3e-eed9-2c776a957938", - "isOpen": true, + "isOpen": false, "children": [ { "uuid": "102db36a-eeda-0e6f-d5cc-c186ecda8165", @@ -1883,7 +1922,7 @@ "override": false, "length": 2, "snapping": 20, - "selected": true, + "selected": false, "saved": true, "path": "", "scope": 0, @@ -1903,8 +1942,8 @@ "channel": "rotation", "data_points": [ { - "x": "90\n- math.sin(q.life_time * 360) * 30", - "y": "22.5\n- math.cos(q.life_time * 360) * 30", + "x": "-90\n+ math.sin(q.life_time * 360) * 30", + "y": "-22.5\n+ math.cos(q.life_time * 360) * 30", "z": "0" } ], @@ -1927,8 +1966,8 @@ "channel": "rotation", "data_points": [ { - "x": "90\n- math.sin(q.life_time * 360) * 30", - "y": "-22.5\n+ math.cos(q.life_time * 360) * 30", + "x": "-90\n+ math.sin(q.life_time * 360) * 30", + "y": "22.5\n- math.cos(q.life_time * 360) * 30", "z": "0" } ], @@ -2007,7 +2046,7 @@ "channel": "position", "data_points": [ { - "x": "-16 + math.cos(q.life_time * 180) * 16", + "x": "16 - math.cos(q.life_time * 180) * 16", "y": "16 + math.sin(q.life_time * 360) * 8", "z": "-32" } @@ -2156,7 +2195,7 @@ "channel": "rotation", "data_points": [ { - "x": "-90", + "x": "90", "y": "0", "z": "0" } @@ -2196,7 +2235,7 @@ "channel": "rotation", "data_points": [ { - "x": "-math.cos(q.life_time * 360) * 22.5", + "x": "math.cos(q.life_time * 360) * 22.5", "y": "0", "z": "0" } @@ -2236,7 +2275,7 @@ "channel": "rotation", "data_points": [ { - "x": "6\n- math.sin(q.life_time * 360) * 22.5", + "x": "-6\n+ math.sin(q.life_time * 360) * 22.5", "y": "0", "z": "0" } @@ -2260,7 +2299,7 @@ "channel": "rotation", "data_points": [ { - "x": "math.cos(q.life_time * 360) * 22.5", + "x": "-math.cos(q.life_time * 360) * 22.5", "y": "0", "z": "0" } @@ -2284,7 +2323,7 @@ "channel": "rotation", "data_points": [ { - "x": "math.cos(q.life_time * 360) * 12.25", + "x": "-math.cos(q.life_time * 360) * 12.25", "y": "0", "z": "0" } @@ -2308,7 +2347,7 @@ "channel": "rotation", "data_points": [ { - "x": "math.cos(q.life_time * 360) * 12.25", + "x": "-math.cos(q.life_time * 360) * 12.25", "y": "0", "z": "0" } @@ -2332,7 +2371,7 @@ "channel": "rotation", "data_points": [ { - "x": "math.sin(q.life_time * 360) * 22.5", + "x": "-math.sin(q.life_time * 360) * 22.5", "y": "0", "z": "0" } @@ -2356,7 +2395,7 @@ "channel": "rotation", "data_points": [ { - "x": "math.sin(q.life_time * 360) * 22.5", + "x": "-math.sin(q.life_time * 360) * 22.5", "y": "0", "z": "0" } @@ -2429,7 +2468,7 @@ "data_points": [ { "x": "0", - "y": "-1 + math.sin(q.life_time * v.walk_speed + 90) * 12.25\n", + "y": "1 - math.sin(q.life_time * v.walk_speed + 90) * 12.25\n", "z": "0" } ], @@ -2469,7 +2508,7 @@ "data_points": [ { "x": "0", - "y": "-1 - math.sin(q.life_time * v.walk_speed + 90) * 12.25", + "y": "1 + math.sin(q.life_time * v.walk_speed + 90) * 12.25", "z": "0" } ], @@ -2492,7 +2531,7 @@ "channel": "rotation", "data_points": [ { - "x": "-math.sin(q.life_time * v.walk_speed) * 8", + "x": "math.sin(q.life_time * v.walk_speed) * 8", "y": "0", "z": "22.5" } @@ -2508,7 +2547,7 @@ "channel": "position", "data_points": [ { - "x": "-2", + "x": "2", "y": "0", "z": "-math.sin(q.life_time * v.walk_speed) * 2" } @@ -2532,8 +2571,8 @@ "channel": "rotation", "data_points": [ { - "x": "-math.sin(q.life_time * v.walk_speed) * 22.5", - "y": "-math.sin(q.life_time * v.walk_speed) * 12.25", + "x": "math.sin(q.life_time * v.walk_speed) * 22.5", + "y": "math.sin(q.life_time * v.walk_speed) * 12.25", "z": "math.cos(q.life_time * v.walk_speed * 2) * 6 + 6" } ], @@ -2556,7 +2595,7 @@ "channel": "rotation", "data_points": [ { - "x": "math.sin(q.life_time * v.walk_speed) * 22.5", + "x": "-math.sin(q.life_time * v.walk_speed) * 22.5", "y": "0", "z": "0" } @@ -2596,7 +2635,7 @@ "channel": "rotation", "data_points": [ { - "x": "-math.sin(q.life_time * v.walk_speed) * 22.5", + "x": "math.sin(q.life_time * v.walk_speed) * 22.5", "y": "0", "z": "0" } @@ -2724,8 +2763,8 @@ "channel": "rotation", "data_points": [ { - "x": "-lopsided_wave(q.life_time * v.run_speed, 10) * 45 - 22.5", - "y": "-3", + "x": "lopsided_wave(q.life_time * v.run_speed, 10) * 45 + 22.5", + "y": "3", "z": "0" } ], @@ -2764,8 +2803,8 @@ "channel": "rotation", "data_points": [ { - "x": "-12.25", - "y": "-math.sin(q.life_time * v.run_speed) * 12.25", + "x": "12.25", + "y": "math.sin(q.life_time * v.run_speed) * 12.25", "z": "-math.sin(q.life_time * v.run_speed) * 2" } ], @@ -2804,8 +2843,8 @@ "channel": "rotation", "data_points": [ { - "x": "6", - "y": "math.sin(q.life_time * v.run_speed) * 12.25", + "x": "-6", + "y": "-math.sin(q.life_time * v.run_speed) * 12.25", "z": "math.sin(q.life_time * v.run_speed) * 2" } ], @@ -2828,8 +2867,8 @@ "channel": "rotation", "data_points": [ { - "x": "-lopsided_wave(q.life_time * v.run_speed + 180, 20) * 45 + 12.25", - "y": "-6", + "x": "lopsided_wave(q.life_time * v.run_speed + 180, 20) * 45 - 12.25", + "y": "6", "z": "-12.25" } ], @@ -2852,8 +2891,8 @@ "channel": "rotation", "data_points": [ { - "x": "-lopsided_wave(q.life_time * v.run_speed, 20) * 45 + 12.25", - "y": "6", + "x": "lopsided_wave(q.life_time * v.run_speed, 20) * 45 - 12.25", + "y": "-6", "z": "12.25" } ], @@ -2876,8 +2915,8 @@ "channel": "rotation", "data_points": [ { - "x": "-lopsided_wave(q.life_time * v.run_speed + 180, 10) * 45 - 22.5", - "y": "-3", + "x": "lopsided_wave(q.life_time * v.run_speed + 180, 10) * 45 + 22.5", + "y": "3", "z": "0" } ], @@ -2959,7 +2998,7 @@ "channel": "rotation", "data_points": [ { - "x": "-math.clamp(-math.cos(q.life_time * 360 * 2 - 45) * 1, -2, 0) * -2", + "x": "math.clamp(-math.cos(q.life_time * 360 * 2 - 45) * 1, -2, 0) * -2", "y": "0", "z": "0" } @@ -2999,7 +3038,7 @@ "channel": "rotation", "data_points": [ { - "x": "-math.clamp(-math.cos(q.life_time * 360 * 2 - 90) * 1, -2, 0) * -5", + "x": "math.clamp(-math.cos(q.life_time * 360 * 2 - 90) * 1, -2, 0) * -5", "y": "0", "z": "0" } @@ -3072,7 +3111,7 @@ "data_points": [ { "x": "0", - "y": "v.progress = math.cos(q.life_time * 360 - 22.5) * 0.5 + 0.5;\nv.ease = v.progress < 0.5\n ? 4 * v.progress * v.progress * v.progress\n : 1 - math.pow(-2 * v.progress + 2, 3) / 2;\n\nreturn -math.lerp(10, 22.5, v.ease)", + "y": "v.progress = math.cos(q.life_time * 360 - 22.5) * 0.5 + 0.5;\nv.ease = v.progress < 0.5\n ? 4 * v.progress * v.progress * v.progress\n : 1 - math.pow(-2 * v.progress + 2, 3) / 2;\n\nreturn math.lerp(10, 22.5, v.ease)", "z": "v.progress = math.cos(q.life_time * 360 - 22.5) * 0.5 + 0.5;\nv.ease = v.progress < 0.5\n ? 4 * v.progress * v.progress * v.progress\n : 1 - math.pow(-2 * v.progress + 2, 3) / 2;\n\nreturn math.lerp(0, 12.25, v.ease)" } ], @@ -3087,7 +3126,7 @@ "channel": "position", "data_points": [ { - "x": "v.progress = math.cos(q.life_time * 360 - 22.5) * 0.5 + 0.5;\nv.ease = v.progress < 0.5\n ? 4 * v.progress * v.progress * v.progress\n : 1 - math.pow(-2 * v.progress + 2, 3) / 2;\n\nreturn -math.lerp(0, -0.5, v.ease)", + "x": "v.progress = math.cos(q.life_time * 360 - 22.5) * 0.5 + 0.5;\nv.ease = v.progress < 0.5\n ? 4 * v.progress * v.progress * v.progress\n : 1 - math.pow(-2 * v.progress + 2, 3) / 2;\n\nreturn math.lerp(0, -0.5, v.ease)", "y": "0", "z": "0" } @@ -3127,7 +3166,7 @@ "channel": "position", "data_points": [ { - "x": "v.progress = math.cos(q.life_time * 360 - 22.5) * 0.5 + 0.5;\nv.ease = v.progress < 0.5\n ? 4 * v.progress * v.progress * v.progress\n : 1 - math.pow(-2 * v.progress + 2, 3) / 2;\n\nreturn -math.lerp(0, 0.5, v.ease)", + "x": "v.progress = math.cos(q.life_time * 360 - 22.5) * 0.5 + 0.5;\nv.ease = v.progress < 0.5\n ? 4 * v.progress * v.progress * v.progress\n : 1 - math.pow(-2 * v.progress + 2, 3) / 2;\n\nreturn math.lerp(0, 0.5, v.ease)", "y": "0", "z": "0" } @@ -3170,7 +3209,7 @@ "channel": "rotation", "data_points": [ { - "x": "10", + "x": "-10", "y": "0", "z": "0" } @@ -3210,7 +3249,7 @@ "channel": "rotation", "data_points": [ { - "x": "-22.5", + "x": "22.5", "y": "0", "z": "0" } @@ -3250,7 +3289,7 @@ "channel": "rotation", "data_points": [ { - "x": "5", + "x": "-5", "y": "0", "z": "0" } @@ -3274,8 +3313,8 @@ "channel": "rotation", "data_points": [ { - "x": "-v.value = q.life_time * 360;\nv.lopside_mag = +30;\n\n14.6772\n- (math.sin(v.value + math.cos(v.value) * v.lopside_mag)) * 6;", - "y": "-24.92619", + "x": "v.value = q.life_time * 360;\nv.lopside_mag = -30;\n\n14.6772\n+ (math.sin(v.value + math.cos(v.value) * v.lopside_mag)) * 6;", + "y": "24.92619", "z": "166.58275" } ], @@ -3314,8 +3353,8 @@ "channel": "rotation", "data_points": [ { - "x": "\n-v.value = q.life_time * 90;\nv.lopside_mag = +30;\n\n+67.1224\n- (math.sin(v.value + math.cos(v.value) * v.lopside_mag)) * 2;\n", - "y": "66.97934", + "x": "\nv.value = q.life_time * 90;\nv.lopside_mag = -30;\n\n-67.1224\n+ (math.sin(v.value + math.cos(v.value) * v.lopside_mag)) * 2;\n", + "y": "-66.97934", "z": "-11.88242" } ], @@ -3330,7 +3369,7 @@ "channel": "position", "data_points": [ { - "x": "1", + "x": "-1", "y": "-1", "z": "-1" } @@ -3354,7 +3393,7 @@ "channel": "rotation", "data_points": [ { - "x": "-90", + "x": "90", "y": "0", "z": "0" } @@ -3509,8 +3548,8 @@ "channel": "rotation", "data_points": [ { - "x": "22.01816", - "y": "-4.75113", + "x": "-22.01816", + "y": "4.75113", "z": "11.57518" } ], @@ -3533,8 +3572,8 @@ "channel": "rotation", "data_points": [ { - "x": "22.01816", - "y": "4.75113", + "x": "-22.01816", + "y": "-4.75113", "z": "-11.57518" } ], @@ -3557,8 +3596,8 @@ "channel": "rotation", "data_points": [ { - "x": "90", - "y": "-22.5", + "x": "-90", + "y": "22.5", "z": "0" } ], @@ -3581,8 +3620,8 @@ "channel": "rotation", "data_points": [ { - "x": "90", - "y": "22.5", + "x": "-90", + "y": "-22.5", "z": "0" } ], @@ -3624,7 +3663,7 @@ "channel": "position", "data_points": [ { - "x": "-math.sin(q.life_time * v.stickbug_speed) * 3", + "x": "math.sin(q.life_time * v.stickbug_speed) * 3", "y": "math.cos(q.life_time * v.stickbug_speed * 2)", "z": "0" } @@ -3648,7 +3687,7 @@ "channel": "rotation", "data_points": [ { - "x": "-90", + "x": "90", "y": "0", "z": "0" } @@ -3689,7 +3728,7 @@ "data_points": [ { "x": "0", - "y": "math.sin(q.life_time * v.stickbug_speed) * 12.25", + "y": "-math.sin(q.life_time * v.stickbug_speed) * 12.25", "z": "0" } ], @@ -3712,7 +3751,7 @@ "channel": "rotation", "data_points": [ { - "x": "67.5", + "x": "-67.5", "y": "0", "z": "0" } @@ -3736,8 +3775,8 @@ "channel": "rotation", "data_points": [ { - "x": "112.5\n", - "y": "12.25\n- math.sin(q.life_time * v.stickbug_speed) * 33\n", + "x": "-112.5\n", + "y": "-12.25\n+ math.sin(q.life_time * v.stickbug_speed) * 33\n", "z": "0" } ], @@ -3752,7 +3791,7 @@ "channel": "position", "data_points": [ { - "x": "-1 - math.sin(q.life_time * v.stickbug_speed) * 1", + "x": "1 + math.sin(q.life_time * v.stickbug_speed) * 1", "y": "0", "z": "-math.sin(q.life_time * v.stickbug_speed) * 1\n- math.cos(q.life_time * v.stickbug_speed * 2) * 1" } @@ -3776,8 +3815,8 @@ "channel": "rotation", "data_points": [ { - "x": "112.5\n", - "y": "-12.25\n- math.sin(q.life_time * v.stickbug_speed) * 33\n", + "x": "-112.5\n", + "y": "12.25\n+ math.sin(q.life_time * v.stickbug_speed) * 33\n", "z": "0" } ], @@ -3792,7 +3831,7 @@ "channel": "position", "data_points": [ { - "x": "1 - math.sin(q.life_time * v.stickbug_speed) * 1", + "x": "-1 + math.sin(q.life_time * v.stickbug_speed) * 1", "y": "0", "z": "math.sin(q.life_time * v.stickbug_speed) * 1\n- math.cos(q.life_time * v.stickbug_speed * 2) * 1" } @@ -3816,8 +3855,8 @@ "channel": "rotation", "data_points": [ { - "x": "72\n", - "y": "-12.25\n- math.sin(q.life_time * v.stickbug_speed) * 22.5\n", + "x": "-72\n", + "y": "12.25\n+ math.sin(q.life_time * v.stickbug_speed) * 22.5\n", "z": "0" } ], @@ -3832,7 +3871,7 @@ "channel": "position", "data_points": [ { - "x": "1 - math.sin(q.life_time * v.stickbug_speed) * 0.25", + "x": "-1 + math.sin(q.life_time * v.stickbug_speed) * 0.25", "y": "0", "z": "-math.sin(q.life_time * v.stickbug_speed) * 0.5\n- math.cos(q.life_time * v.stickbug_speed * 2) * 0.75" } @@ -3856,8 +3895,8 @@ "channel": "rotation", "data_points": [ { - "x": "72\n", - "y": "12.25\n- math.sin(q.life_time * v.stickbug_speed) * 22.5\n", + "x": "-72\n", + "y": "-12.25\n+ math.sin(q.life_time * v.stickbug_speed) * 22.5\n", "z": "0" } ], @@ -3872,7 +3911,7 @@ "channel": "position", "data_points": [ { - "x": "-1 - math.sin(q.life_time * v.stickbug_speed) * 0.25", + "x": "1 + math.sin(q.life_time * v.stickbug_speed) * 0.25", "y": "0", "z": "math.sin(q.life_time * v.stickbug_speed) * 0.5\n- math.cos(q.life_time * v.stickbug_speed * 2) * 0.75" } @@ -3888,7 +3927,7 @@ "channel": "position", "data_points": [ { - "x": "-easeinoutquart(\n linear_wave(q.life_time * v.stickbug_speed + 90 + 45)\n)", + "x": "easeinoutquart(\n linear_wave(q.life_time * v.stickbug_speed + 90 + 45)\n)", "y": "0", "z": "0" } @@ -3904,7 +3943,7 @@ "channel": "position", "data_points": [ { - "x": "1 - easeinoutquart(\n linear_wave(q.life_time * v.stickbug_speed + 90 + 45)\n)", + "x": "-1 + easeinoutquart(\n linear_wave(q.life_time * v.stickbug_speed + 90 + 45)\n)", "y": "0", "z": "0" } From 8e479a094ab5061de9b2d213528e4900415d4f88 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Mon, 17 Aug 2026 12:53:44 -0400 Subject: [PATCH 09/85] =?UTF-8?q?=E2=9C=A8=20Add=20a=20link=20icon=20for?= =?UTF-8?q?=20textures=20indicating=20resource=20pack=20linking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mods/textureLinkIcon.ts | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/mods/textureLinkIcon.ts diff --git a/src/mods/textureLinkIcon.ts b/src/mods/textureLinkIcon.ts new file mode 100644 index 00000000..0e541950 --- /dev/null +++ b/src/mods/textureLinkIcon.ts @@ -0,0 +1,47 @@ +import { registerProjectPatch } from 'blockbench-patch-manager' +import { BLUEPRINT_FORMAT_ID } from '../formats/blueprint' +import { isResourcePackPath } from '../util/minecraftUtil' + +export function updateTextureIcon(texture: Texture) { + const saveIcon = document.querySelector(`li[texid="${texture.uuid}"] .texture_save_icon`) + if (!saveIcon) return + + if (texture.path && isResourcePackPath(texture.path)) { + saveIcon.innerHTML = 'link' + saveIcon.setAttribute('title', 'Linked to resource pack') + } else { + saveIcon.setAttribute('title', '') + } +} + +registerProjectPatch({ + id: `animated_java:texture-link-icon`, + + condition({ project }) { + return project.format.id === BLUEPRINT_FORMAT_ID + }, + + apply() { + requestAnimationFrame(() => { + for (const texture of Texture.all) { + console.log('texture', texture) + updateTextureIcon(texture) + } + }) + + const onTextureChange = ({ texture }: BlockbenchEventMap['change_texture_path']) => + updateTextureIcon(texture) + + Blockbench.on('change_texture_path', onTextureChange) + Blockbench.on('add_texture', onTextureChange) + Blockbench.on('select_texture', onTextureChange) + + return { onTextureChange } + }, + + revert({ onTextureChange }) { + Blockbench.removeListener('change_texture_path', onTextureChange) + Blockbench.removeListener('add_texture', onTextureChange) + Blockbench.removeListener('select_texture', onTextureChange) + }, +}) From 90359e1175a74404ee134169ca48d9f5c739b981 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Sun, 30 Aug 2026 08:15:53 -0400 Subject: [PATCH 10/85] =?UTF-8?q?=F0=9F=90=9B=20Fix=20constant=20log=20spa?= =?UTF-8?q?m=20when=20unjank=20is=20installed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/systems/datapackCompiler/26.2/global.mcb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systems/datapackCompiler/26.2/global.mcb b/src/systems/datapackCompiler/26.2/global.mcb index d70b7d51..106ddbe9 100644 --- a/src/systems/datapackCompiler/26.2/global.mcb +++ b/src/systems/datapackCompiler/26.2/global.mcb @@ -245,7 +245,7 @@ dir global { block { with storage <%temp_storage%> args $data modify storage <%temp_storage%> args.uuid set from storage <%data_storage%> "$(id)".uuid scoreboard players set #success <%OBJECTIVES.I()%> 0 - block { with storage <%temp_storage%> args + execute if data storage <%temp_storage%> args.uuid run { with storage <%temp_storage%> args $execute store success score #success <%OBJECTIVES.I()%> if score $(uuid) <%OBJECTIVES.ID()%> matches 1.. $execute if score #success <%OBJECTIVES.I()%> matches 0 run data remove storage <%data_storage%> "$(id)" } From 3c7e73f5439b0fafa1fea1dcc6533a8809ef7f0d Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Sun, 30 Aug 2026 08:16:29 -0400 Subject: [PATCH 11/85] =?UTF-8?q?=E2=9C=82=EF=B8=8F=20Reduce=20entity=20na?= =?UTF-8?q?mes=20to=20empty=20strings=20to=20improve=20performance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/systems/datapackCompiler/entityNames.ts | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/systems/datapackCompiler/entityNames.ts b/src/systems/datapackCompiler/entityNames.ts index 9ead9db7..adf4a5de 100644 --- a/src/systems/datapackCompiler/entityNames.ts +++ b/src/systems/datapackCompiler/entityNames.ts @@ -1,24 +1,7 @@ -import { TextComponent } from 'book-and-quill' -import { makeTagSafe } from './tags' - namespace ENTITY_NAMES { - export const ROOT = (exportNamespace: string) => - new TextComponent([ - '', - { text: makeTagSafe(exportNamespace), color: '#00aced' }, - '.', - { text: 'root', color: 'light_purple' }, - ]).toString(true) + export const ROOT = (exportNamespace: string) => '""' - export const NODE = (exportNamespace: string, type: string, name: string) => - new TextComponent([ - '', - { text: makeTagSafe(exportNamespace), color: '#00aced' }, - '.', - { text: type, color: 'light_purple' }, - '.', - { text: name, color: 'gold' }, - ]).toString(true) + export const NODE = (exportNamespace: string, type: string, name: string) => '""' } export default ENTITY_NAMES From 7583baaab15c2fd5b4ed25481ea15421533129fb Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Sun, 30 Aug 2026 08:17:58 -0400 Subject: [PATCH 12/85] =?UTF-8?q?=F0=9F=90=9B=20Fix=20#470?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/systems/resourcepackCompiler/1.20.4.ts | 7 +++++-- src/systems/resourcepackCompiler/1.21.2.ts | 7 +++++-- src/systems/resourcepackCompiler/1.21.4.ts | 7 +++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/systems/resourcepackCompiler/1.20.4.ts b/src/systems/resourcepackCompiler/1.20.4.ts index 57e7647b..4d868d47 100644 --- a/src/systems/resourcepackCompiler/1.20.4.ts +++ b/src/systems/resourcepackCompiler/1.20.4.ts @@ -213,8 +213,11 @@ const compileResourcePack: ResourcePackCompiler = async ({ } // Texture atlas - const blockAtlasPath = PathModule.join(resourcePackPath, 'assets/minecraft/atlases/blocks.json') - const blockAtlas: ITextureAtlas = await readFile(blockAtlasPath, 'utf-8') + const blockAtlasPath = 'assets/minecraft/atlases/blocks.json' + const blockAtlas: ITextureAtlas = await readFile( + PathModule.join(resourcePackPath, blockAtlasPath), + 'utf-8' + ) .catch(() => { console.log('Creating new block atlas...') return '{ "sources": [] }' diff --git a/src/systems/resourcepackCompiler/1.21.2.ts b/src/systems/resourcepackCompiler/1.21.2.ts index c401d1b1..0e9efa87 100644 --- a/src/systems/resourcepackCompiler/1.21.2.ts +++ b/src/systems/resourcepackCompiler/1.21.2.ts @@ -29,8 +29,11 @@ const compileResourcePack: ResourcePackCompiler = async ({ const { readFile } = promises // Texture atlas - const blockAtlasPath = PathModule.join(resourcePackPath, 'assets/minecraft/atlases/blocks.json') - const blockAtlas: ITextureAtlas = await readFile(blockAtlasPath, 'utf-8') + const blockAtlasPath = 'assets/minecraft/atlases/blocks.json' + const blockAtlas: ITextureAtlas = await readFile( + PathModule.join(resourcePackPath, blockAtlasPath), + 'utf-8' + ) .catch(() => { console.log('Creating new block atlas...') return JSON.stringify({ sources: [] }) diff --git a/src/systems/resourcepackCompiler/1.21.4.ts b/src/systems/resourcepackCompiler/1.21.4.ts index 91e00fe3..edb81c32 100644 --- a/src/systems/resourcepackCompiler/1.21.4.ts +++ b/src/systems/resourcepackCompiler/1.21.4.ts @@ -41,8 +41,11 @@ const compileResourcePack: ResourcePackCompiler = async ({ const { readFile } = promises // Texture atlas - const blockAtlasPath = PathModule.join(resourcePackPath, 'assets/minecraft/atlases/blocks.json') - const blockAtlas: ITextureAtlas = await readFile(blockAtlasPath, 'utf-8') + const blockAtlasPath = 'assets/minecraft/atlases/blocks.json' + const blockAtlas: ITextureAtlas = await readFile( + PathModule.join(resourcePackPath, blockAtlasPath), + 'utf-8' + ) .catch(() => { console.log('Creating new block atlas...') return '{ "sources": [] }' From 6720da19f7d99c6cf52a343bea6494a4d9932b8c Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Sun, 30 Aug 2026 09:38:48 -0400 Subject: [PATCH 13/85] =?UTF-8?q?=E2=9C=A8=20Switch=20to=20the=20`block-mo?= =?UTF-8?q?del-renderer`=20library=20for=20item=20and=20block=20model=20re?= =?UTF-8?q?ndering?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .scripts/esbuild.ts | 8 +- .scripts/plugins/assetOverridePlugin.ts | 48 -- TEXTURE_PALLETS.md | 0 bun.lock | 6 +- package.json | 1 + .../animated_java/textures/steve.png | Bin 1153 -> 0 bytes src/assets/vanillaAssetOverrides/index.json | 1 - .../minecraft/blockstates/black_bed.json | 7 - .../blockstates/black_shulker_box.json | 7 - .../minecraft/blockstates/blue_bed.json | 7 - .../blockstates/blue_shulker_box.json | 7 - .../minecraft/blockstates/brown_bed.json | 7 - .../blockstates/brown_shulker_box.json | 7 - .../minecraft/blockstates/chest.json | 7 - .../minecraft/blockstates/conduit.json | 7 - .../minecraft/blockstates/cyan_bed.json | 7 - .../blockstates/cyan_shulker_box.json | 7 - .../minecraft/blockstates/ender_chest.json | 7 - .../minecraft/blockstates/gray_bed.json | 7 - .../blockstates/gray_shulker_box.json | 7 - .../minecraft/blockstates/green_bed.json | 7 - .../blockstates/green_shulker_box.json | 7 - .../minecraft/blockstates/light_blue_bed.json | 7 - .../blockstates/light_blue_shulker_box.json | 7 - .../minecraft/blockstates/light_gray_bed.json | 7 - .../blockstates/light_gray_shulker_box.json | 7 - .../minecraft/blockstates/lime_bed.json | 7 - .../blockstates/lime_shulker_box.json | 7 - .../minecraft/blockstates/magenta_bed.json | 7 - .../blockstates/magenta_shulker_box.json | 7 - .../minecraft/blockstates/orange_bed.json | 7 - .../blockstates/orange_shulker_box.json | 7 - .../minecraft/blockstates/pink_bed.json | 7 - .../blockstates/pink_shulker_box.json | 7 - .../minecraft/blockstates/purple_bed.json | 7 - .../blockstates/purple_shulker_box.json | 7 - .../minecraft/blockstates/red_bed.json | 7 - .../blockstates/red_shulker_box.json | 7 - .../minecraft/blockstates/shulker_box.json | 7 - .../minecraft/blockstates/white_bed.json | 7 - .../blockstates/white_shulker_box.json | 7 - .../minecraft/blockstates/yellow_bed.json | 7 - .../blockstates/yellow_shulker_box.json | 7 - .../minecraft/models/block/bed.json | 122 ---- .../minecraft/models/block/black_bed.json | 6 - .../models/block/black_shulker_box.json | 6 - .../minecraft/models/block/blue_bed.json | 6 - .../models/block/blue_shulker_box.json | 6 - .../minecraft/models/block/brown_bed.json | 6 - .../models/block/brown_shulker_box.json | 6 - .../minecraft/models/block/chest.json | 47 -- .../minecraft/models/block/conduit.json | 23 - .../minecraft/models/block/cyan_bed.json | 6 - .../models/block/cyan_shulker_box.json | 6 - .../minecraft/models/block/ender_chest.json | 46 -- .../minecraft/models/block/gray_bed.json | 6 - .../models/block/gray_shulker_box.json | 6 - .../minecraft/models/block/green_bed.json | 6 - .../models/block/green_shulker_box.json | 6 - .../models/block/light_blue_bed.json | 6 - .../models/block/light_blue_shulker_box.json | 6 - .../models/block/light_gray_bed.json | 6 - .../models/block/light_gray_shulker_box.json | 6 - .../minecraft/models/block/lime_bed.json | 6 - .../models/block/lime_shulker_box.json | 6 - .../minecraft/models/block/magenta_bed.json | 6 - .../models/block/magenta_shulker_box.json | 6 - .../minecraft/models/block/orange_bed.json | 6 - .../models/block/orange_shulker_box.json | 6 - .../minecraft/models/block/pink_bed.json | 6 - .../models/block/pink_shulker_box.json | 6 - .../minecraft/models/block/purple_bed.json | 6 - .../models/block/purple_shulker_box.json | 6 - .../minecraft/models/block/red_bed.json | 6 - .../models/block/red_shulker_box.json | 6 - .../minecraft/models/block/shulker_box.json | 31 - .../minecraft/models/block/white_bed.json | 6 - .../models/block/white_shulker_box.json | 6 - .../minecraft/models/block/yellow_bed.json | 6 - .../models/block/yellow_shulker_box.json | 6 - .../minecraft/models/item/black_banner.json | 3 - .../models/item/black_shulker_box.json | 35 - .../minecraft/models/item/blue_banner.json | 3 - .../models/item/blue_shulker_box.json | 35 - .../minecraft/models/item/brown_banner.json | 3 - .../models/item/brown_shulker_box.json | 35 - .../minecraft/models/item/conduit.json | 38 -- .../minecraft/models/item/creeper_head.json | 23 - .../minecraft/models/item/cyan_banner.json | 3 - .../models/item/cyan_shulker_box.json | 35 - .../minecraft/models/item/decorated_pot.json | 46 -- .../minecraft/models/item/dragon_head.json | 128 ---- .../minecraft/models/item/ender_chest.json | 3 - .../minecraft/models/item/gray_banner.json | 3 - .../models/item/gray_shulker_box.json | 35 - .../minecraft/models/item/green_banner.json | 3 - .../models/item/green_shulker_box.json | 35 - .../models/item/light_blue_banner.json | 3 - .../models/item/light_blue_shulker_box.json | 35 - .../models/item/light_gray_banner.json | 3 - .../models/item/light_gray_shulker_box.json | 35 - .../minecraft/models/item/lime_banner.json | 3 - .../models/item/lime_shulker_box.json | 35 - .../minecraft/models/item/magenta_banner.json | 3 - .../models/item/magenta_shulker_box.json | 35 - .../minecraft/models/item/mob_skull.json | 18 - .../minecraft/models/item/orange_banner.json | 3 - .../models/item/orange_shulker_box.json | 35 - .../minecraft/models/item/piglin_head.json | 93 --- .../minecraft/models/item/pink_banner.json | 3 - .../models/item/pink_shulker_box.json | 35 - .../minecraft/models/item/player_head.json | 37 -- .../minecraft/models/item/purple_banner.json | 3 - .../models/item/purple_shulker_box.json | 35 - .../minecraft/models/item/red_banner.json | 3 - .../models/item/red_shulker_box.json | 35 - .../minecraft/models/item/shield.json | 45 -- .../minecraft/models/item/shulker_box.json | 35 - .../minecraft/models/item/skeleton_skull.json | 37 -- .../models/item/template_banner.json | 98 --- .../minecraft/models/item/template_chest.json | 47 -- .../minecraft/models/item/trident.json | 61 -- .../minecraft/models/item/white_banner.json | 3 - .../models/item/white_shulker_box.json | 35 - .../models/item/wither_skeleton_skull.json | 37 -- .../minecraft/models/item/yellow_banner.json | 3 - .../models/item/yellow_shulker_box.json | 35 - .../minecraft/models/item/zombie_head.json | 37 -- src/global.d.ts | 93 +++ src/systems/animationRenderer.ts | 6 +- src/systems/exporter.ts | 5 +- src/systems/minecraft/assetManager.ts | 36 +- src/systems/minecraft/blockModelManager.ts | 625 ++---------------- src/systems/minecraft/bmrModelRenderer.ts | 125 ++++ src/systems/minecraft/itemModelManager.ts | 439 ++---------- src/systems/minecraft/model.d.ts | 115 ---- src/systems/minecraft/textureShaders.ts | 109 --- .../blueprints/armor_stand_latest.ajblueprint | 174 ++++- 138 files changed, 537 insertions(+), 3358 deletions(-) delete mode 100644 .scripts/plugins/assetOverridePlugin.ts create mode 100644 TEXTURE_PALLETS.md delete mode 100644 src/assets/vanillaAssetOverrides/animated_java/textures/steve.png delete mode 100644 src/assets/vanillaAssetOverrides/index.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/black_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/black_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/blue_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/blue_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/brown_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/brown_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/chest.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/conduit.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/cyan_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/cyan_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/ender_chest.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/gray_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/gray_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/green_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/green_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/light_blue_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/light_blue_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/light_gray_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/light_gray_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/lime_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/lime_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/magenta_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/magenta_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/orange_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/orange_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/pink_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/pink_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/purple_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/purple_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/red_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/red_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/white_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/white_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/yellow_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/blockstates/yellow_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/black_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/black_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/blue_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/blue_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/brown_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/brown_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/chest.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/conduit.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/cyan_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/cyan_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/ender_chest.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/gray_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/gray_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/green_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/green_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/light_blue_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/light_blue_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/light_gray_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/light_gray_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/lime_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/lime_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/magenta_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/magenta_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/orange_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/orange_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/pink_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/pink_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/purple_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/purple_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/red_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/red_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/white_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/white_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/yellow_bed.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/block/yellow_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/black_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/black_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/blue_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/blue_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/brown_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/brown_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/conduit.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/creeper_head.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/cyan_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/cyan_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/decorated_pot.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/dragon_head.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/ender_chest.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/gray_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/gray_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/green_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/green_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/light_blue_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/light_blue_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/light_gray_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/light_gray_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/lime_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/lime_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/magenta_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/magenta_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/mob_skull.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/orange_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/orange_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/piglin_head.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/pink_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/pink_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/player_head.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/purple_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/purple_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/red_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/red_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/shield.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/skeleton_skull.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/template_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/template_chest.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/trident.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/white_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/white_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/wither_skeleton_skull.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/yellow_banner.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/yellow_shulker_box.json delete mode 100644 src/assets/vanillaAssetOverrides/minecraft/models/item/zombie_head.json create mode 100644 src/systems/minecraft/bmrModelRenderer.ts delete mode 100644 src/systems/minecraft/model.d.ts delete mode 100644 src/systems/minecraft/textureShaders.ts diff --git a/.scripts/esbuild.ts b/.scripts/esbuild.ts index aa04c20c..3f23ce20 100644 --- a/.scripts/esbuild.ts +++ b/.scripts/esbuild.ts @@ -20,7 +20,6 @@ import { esbuildPluginSvelte, } from 'svelte-patching-tools/esbuildPlugin' import { TextDecoder } from 'util' -import assetOverridePlugin from './plugins/assetOverridePlugin' import bufferPatchPlugin from './plugins/bufferPatchFunction.js' import langPlugin from './plugins/lang' import mcbCompressionPlugin from './plugins/mcbCompressionPlugin' @@ -193,7 +192,7 @@ const COMMON_CONFIG: esbuild.BuildOptions = { bundle: true, platform: 'browser', external: ['node:*'], - loader: { '.svg': 'dataurl', '.ttf': 'binary', '.css': 'text' }, + loader: { '.svg': 'dataurl', '.ttf': 'binary', '.css': 'text', '.zip': 'dataurl' }, target: 'es2020', plugins: [ langPlugin({ @@ -226,7 +225,6 @@ const COMMON_CONFIG: esbuild.BuildOptions = { }) ), packagerPlugin(), - assetOverridePlugin(), mcbCompressionPlugin(), DEPENDENCY_QUARKS, ], @@ -235,6 +233,10 @@ const COMMON_CONFIG: esbuild.BuildOptions = { module: './.scripts/fakeModule.js', 'node:module': './.scripts/fakeModule.js', 'node:fs': './src/constants.ts', + // block-model-renderer's assets.zip isn't in its package exports; inlined it as a data URL instead. + 'block-model-renderer/assets.zip': path.resolve( + 'node_modules/block-model-renderer/assets.zip' + ), }, format: 'iife', define: DEFINES, diff --git a/.scripts/plugins/assetOverridePlugin.ts b/.scripts/plugins/assetOverridePlugin.ts deleted file mode 100644 index a0e9916d..00000000 --- a/.scripts/plugins/assetOverridePlugin.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { Plugin } from 'esbuild' -import * as fs from 'fs/promises' -import * as pathjs from 'node:path' - -const ASSET_OVERRIDES_PATH = 'src/assets/vanillaAssetOverrides/' - -function plugin(): Plugin { - return { - name: 'assetOverridePlugin', - setup(build) { - build.onLoad({ filter: /index\.json$/ }, async () => { - const contents: any = {} - - const recurse = async (dir: string) => { - for (const path of await fs.readdir(dir)) { - if ((await fs.stat(pathjs.join(dir, path))).isDirectory()) { - await recurse(pathjs.join(dir, path)) - } - - if (path.endsWith('.json') || path.endsWith('.png')) { - const key = pathjs - .join('assets', dir, path) - .replaceAll(pathjs.sep, '/') - .replace(ASSET_OVERRIDES_PATH, '') - if (path.endsWith('.json')) { - contents[key] = await fs.readFile(pathjs.join(dir, path), 'utf-8') - } else if (path.endsWith('.png')) { - contents[key] = ( - await fs.readFile(pathjs.join(dir, path)) - ).toString('base64') - } else { - throw new Error(`Unsupported asset type: '${path}'`) - } - } - } - } - - await recurse(ASSET_OVERRIDES_PATH) - - return { - contents: `export default ${JSON.stringify(contents)}`, - } - }) - }, - } -} - -export default plugin diff --git a/TEXTURE_PALLETS.md b/TEXTURE_PALLETS.md new file mode 100644 index 00000000..e69de29b diff --git a/bun.lock b/bun.lock index 64a7d06e..01648df9 100644 --- a/bun.lock +++ b/bun.lock @@ -5,7 +5,7 @@ "": { "name": "animated_java", "dependencies": { - "block-model-renderer": "^2.1.0", + "block-model-renderer": "^2.15.2", "deepslate": "^0.19.2", "fflate": "^0.8.2", "generic-stream": "^3.0.1", @@ -572,7 +572,7 @@ "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], - "block-model-renderer": ["block-model-renderer@2.1.0", "", { "dependencies": { "gl": "^8.1.6", "headless-three": "^1.8.0", "sharp": "^0.34.5", "skia-canvas": "^3.0.8" }, "peerDependencies": { "three": ">=0.152.0" }, "optionalPeers": ["three"] }, "sha512-XCE6vj9e3VG3k7r6i+38sJhkzFP8bD4aleKsXV65bhUu/w7c5P1GCQPCn9N4lQGO597om9raBF4DTJ45u1C8jg=="], + "block-model-renderer": ["block-model-renderer@2.15.2", "", { "dependencies": { "gl": "^8.1.6", "headless-three": "^1.8.1", "sharp": "^0.34.5", "skia-canvas": "^3.0.8" }, "peerDependencies": { "three": ">=0.152.0" }, "optionalPeers": ["three"] }, "sha512-xE2LcLsKh9GX9injZ4dButM/l0zE8ds3IBOcW4QYm/JXz8g/tt1UZMtcvuRDIoxK35/w5ys1R01LVUfndtO2bg=="], "blockbench-patch-manager": ["blockbench-patch-manager@1.1.0", "", { "dependencies": { "blockbench-types": "^5.1.0-beta.1", "simple-subpub": "^1.2.0", "svelte": "^5.46.3", "svelte-observable-store": "^1.0.1", "svelte-preprocess": "^6.0.3", "svelte-preprocess-esbuild": "^3.0.1" }, "peerDependencies": { "typescript": "^5" } }, "sha512-68FXezYJ3HdkVcam90r/MY8W2gS8jZeitfUz3XXnC/XyDkHJZlLr8dpFJmJrrUqUSBVRG7wweOhbs/tn+znotQ=="], @@ -854,7 +854,7 @@ "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], - "headless-three": ["headless-three@1.8.0", "", { "dependencies": { "gl": "^8.1.6", "sharp": "^0.34.5", "three": "0.162.0" } }, "sha512-xI9UOW4F0HVRIeWxVmqTdNMUyxjsotrlJjCdHNisX1E/OTAPZCCYfvDsXqfKPcaBzbWmIEXrzaeifCRVHR/EWQ=="], + "headless-three": ["headless-three@1.9.0", "", { "dependencies": { "gl": "^8.1.6", "sharp": "^0.34.5", "three": "0.162.0" } }, "sha512-4QuRO2VPE2Dlt7dhwkUU29oETHLjKNbZmd7vOks/GfDZnQG3WogF37QlUtrUr/uS7IHuzHodVr0uAg2uYszguA=="], "http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="], diff --git a/package.json b/package.json index 9c117905..7f7f5a3d 100644 --- a/package.json +++ b/package.json @@ -123,6 +123,7 @@ "vitest": "^3.2.4" }, "dependencies": { + "block-model-renderer": "^2.15.2", "deepslate": "^0.19.2", "fflate": "^0.8.2", "generic-stream": "^3.0.1", diff --git a/src/assets/vanillaAssetOverrides/animated_java/textures/steve.png b/src/assets/vanillaAssetOverrides/animated_java/textures/steve.png deleted file mode 100644 index 784d21cfdeadbd3739991e6c207b467c36bf3852..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1153 zcmV-{1b+L8P)SDjf|bAzME`KWl4ihgCb4Z(ArR zC;(t!R!Phz8VUf+%r74gIx&eP7zijE3IJPM0000{F(m+=o+%s*EFKPqQ#30c4S`cR z9}o*B7z-#G4JR85EgcRmAP|~kL^C82MIsKIXGkL#2_zT_CK?PV8w)5L3o9NDEFKXr zA`vnp5J4dfIw%xkLoZT2iF8OWicCF(QZa{EI*3|1idj3HV?~^4Or2^^qH0I9gl)Tt za{vGTFCYy<9SSrh5l+fNi&ea<++VzKCqSi*mh=a=ngp#+HDsppQoY0004WQchC< zK<3zH00093NklXM3VR5XU1+*+ul=?hu3v%~;cWzx3pK@4bEh&v3K5ZlV|i z#<%_-A9pD8V`iC$nW?F+45JFa>P)e#sZnKA9R~o_qRw;+faBO4@Bs9DbU@XiIXDIf z+$sXYww-YR%zqq!?S%FW1;lzB-{viZHpnnWevO`IH^Yr~`%&VoRPDrQw>QG3?Rlau z@&N28OlFfLnSJ&&TA5A4$fkg9U1S2Hx*e`AFNVp_KmUIJ{qiJSTwV?BdL-&1JAy_l z@|w}Qd?tVYe13eq9yPtF)$l}JTCPT z!H2Iubp6-q>jPzft=^!U$m=3|54_g)NhdD8d%wB2H}|$yj5{aWEiV#vkqL<7PCTz1 z?!J7n`FL*b&8ywRPxBw=J5WosE{bukTDT9o3lhf_UQ3mGU5WF!Qo;JPKAjEV--H1` z1vD-IgTFpj3IhO1DoF(pEOd1>P4h`mJFV4%0BkM57$bx+w-H+r=n7Ek0~9n>)i4gg zA0e<+Oz#E&m>R+;px09XsSm(zL^vSe3AT#3Fask7y&2%Est?x#0)N~l2onx~pl*l& z3>T#OzE22sBLqyJdBd@yD5eZD!JunDz;z3BFDL+fRKg!h0Hz{#fH}aDWyQP>(7Oi| z00CeIfIXnz05LhhVgSqP0Z7uoTMz(^ZQ><>KA8f{{s;s>x&k2Pg^1WND)8d~B?Ty# z1)yBM1JYDYBZLOP0bsLjP&hzVXe5wI4}d$06;dftV8I0dEi%`|gt!F`uw)iV27pBb z1R~0tz#n}w_*rH;f{7-YXrfW(1w5=P=N>pfV*&86!D5sYasztj1()^-5Pai?X zP`Ye10W=A%+v@WJq*8CE!UJu66u`A}!B9YIUKlzT3yl@E+EiEq~l>!A=9ANg% z1=#?eipc=1E1NkZkWv7J1I(O&^t_;SbEl&XO(h4QzumJZTjKyAcgtd<&9#94=saBY TqTu-%00000NkvXXu0mjf)AY-i diff --git a/src/assets/vanillaAssetOverrides/index.json b/src/assets/vanillaAssetOverrides/index.json deleted file mode 100644 index 0967ef42..00000000 --- a/src/assets/vanillaAssetOverrides/index.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/black_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/black_bed.json deleted file mode 100644 index 462eb463..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/black_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/black_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/black_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/black_shulker_box.json deleted file mode 100644 index 4ac7e959..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/black_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/black_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/blue_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/blue_bed.json deleted file mode 100644 index 9fd7a60e..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/blue_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/blue_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/blue_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/blue_shulker_box.json deleted file mode 100644 index 9fbb5eb4..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/blue_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/blue_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/brown_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/brown_bed.json deleted file mode 100644 index c6ae2896..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/brown_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/brown_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/brown_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/brown_shulker_box.json deleted file mode 100644 index 50c0e4bd..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/brown_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/brown_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/chest.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/chest.json deleted file mode 100644 index 9889d2bd..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/chest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/chest" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/conduit.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/conduit.json deleted file mode 100644 index 509c7e8e..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/conduit.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/conduit" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/cyan_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/cyan_bed.json deleted file mode 100644 index 28f99dcf..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/cyan_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/cyan_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/cyan_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/cyan_shulker_box.json deleted file mode 100644 index 1e0167f9..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/cyan_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/cyan_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/ender_chest.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/ender_chest.json deleted file mode 100644 index 045830a0..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/ender_chest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/ender_chest" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/gray_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/gray_bed.json deleted file mode 100644 index 3cb3af71..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/gray_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/gray_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/gray_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/gray_shulker_box.json deleted file mode 100644 index 214ca7c4..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/gray_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/gray_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/green_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/green_bed.json deleted file mode 100644 index d4c9dc4c..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/green_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/green_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/green_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/green_shulker_box.json deleted file mode 100644 index 7623bc3e..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/green_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/green_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_blue_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_blue_bed.json deleted file mode 100644 index 0c2dbdbd..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_blue_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/light_blue_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_blue_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_blue_shulker_box.json deleted file mode 100644 index c40ecde7..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_blue_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/light_blue_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_gray_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_gray_bed.json deleted file mode 100644 index ce874ca9..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_gray_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/light_gray_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_gray_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_gray_shulker_box.json deleted file mode 100644 index 11b479b5..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/light_gray_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/light_gray_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/lime_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/lime_bed.json deleted file mode 100644 index f8980092..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/lime_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/lime_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/lime_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/lime_shulker_box.json deleted file mode 100644 index 743f5a78..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/lime_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/lime_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/magenta_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/magenta_bed.json deleted file mode 100644 index ccafa9d4..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/magenta_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/magenta_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/magenta_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/magenta_shulker_box.json deleted file mode 100644 index 3cee5dfd..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/magenta_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/magenta_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/orange_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/orange_bed.json deleted file mode 100644 index 08f1c48b..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/orange_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/orange_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/orange_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/orange_shulker_box.json deleted file mode 100644 index bc22a74b..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/orange_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/orange_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/pink_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/pink_bed.json deleted file mode 100644 index af614849..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/pink_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/pink_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/pink_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/pink_shulker_box.json deleted file mode 100644 index a2adcbe3..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/pink_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/pink_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/purple_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/purple_bed.json deleted file mode 100644 index d35c2246..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/purple_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/purple_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/purple_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/purple_shulker_box.json deleted file mode 100644 index 0c1e0711..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/purple_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/purple_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/red_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/red_bed.json deleted file mode 100644 index 281d5a44..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/red_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/red_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/red_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/red_shulker_box.json deleted file mode 100644 index d580b1b3..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/red_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/red_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/shulker_box.json deleted file mode 100644 index 9efe89ad..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/white_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/white_bed.json deleted file mode 100644 index 0c1244f2..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/white_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/white_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/white_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/white_shulker_box.json deleted file mode 100644 index 4524b795..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/white_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/white_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/yellow_bed.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/yellow_bed.json deleted file mode 100644 index dec2d725..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/yellow_bed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/yellow_bed" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/blockstates/yellow_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/blockstates/yellow_shulker_box.json deleted file mode 100644 index bd67c758..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/blockstates/yellow_shulker_box.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "minecraft:block/yellow_shulker_box" - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/bed.json deleted file mode 100644 index 0f4a12a3..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/bed.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 64], - "elements": [ - { - "name": "bed", - "from": [0, 3, 0], - "to": [16, 9, 16], - "rotation": {"angle": 0, "axis": "x", "origin": [8, 0, 0]}, - "faces": { - "north": {"uv": [9.5, 0, 5.5, 1.5], "rotation": 180, "texture": "#0"}, - "east": {"uv": [0, 1.5, 1.5, 5.5], "rotation": 270, "texture": "#0"}, - "south": {"uv": [5.5, 1.5, 1.5, 0], "texture": "#0"}, - "west": {"uv": [5.5, 1.5, 7, 5.5], "rotation": 90, "texture": "#0"}, - "up": {"uv": [1.5, 1.5, 5.5, 5.5], "rotation": 180, "texture": "#0"}, - "down": {"uv": [7, 1.5, 11, 5.5], "texture": "#0"} - } - }, - { - "name": "bed", - "from": [0, 3, -16], - "to": [16, 9, 0], - "rotation": {"angle": 0, "axis": "x", "origin": [8, 0, 0]}, - "faces": { - "north": {"uv": [9.5, 5.5, 5.5, 7], "rotation": 180, "texture": "#0"}, - "east": {"uv": [0, 7, 1.5, 11], "rotation": 270, "texture": "#0"}, - "south": {"uv": [5.5, 7, 1.5, 5.5], "texture": "#0"}, - "west": {"uv": [5.5, 7, 7, 11], "rotation": 90, "texture": "#0"}, - "up": {"uv": [1.5, 7, 5.5, 11], "rotation": 180, "texture": "#0"}, - "down": {"uv": [7, 7, 11, 11], "texture": "#0"} - } - }, - { - "name": "leg0", - "from": [13, 0, -16], - "to": [16, 3, -13], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 0]}, - "faces": { - "north": {"uv": [13.25, 0.75, 14, 1.5], "texture": "#0"}, - "east": {"uv": [12.5, 0.75, 13.25, 1.5], "texture": "#0"}, - "south": {"uv": [14.75, 0.75, 15.5, 1.5], "texture": "#0"}, - "west": {"uv": [14, 0.75, 14.75, 1.5], "texture": "#0"}, - "up": {"uv": [14, 0.75, 13.25, 0], "texture": "#0"}, - "down": {"uv": [14.75, 0, 14, 0.75], "texture": "#0"} - } - }, - { - "name": "leg1", - "from": [13, 0, 13], - "to": [16, 3, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 0]}, - "faces": { - "north": {"uv": [13.25, 2.25, 14, 3], "texture": "#0"}, - "east": {"uv": [12.5, 2.25, 13.25, 3], "texture": "#0"}, - "south": {"uv": [14.75, 2.25, 15.5, 3], "texture": "#0"}, - "west": {"uv": [14, 2.25, 14.75, 3], "texture": "#0"}, - "up": {"uv": [14, 2.25, 13.25, 1.5], "texture": "#0"}, - "down": {"uv": [14.75, 1.5, 14, 2.25], "texture": "#0"} - } - }, - { - "name": "leg2", - "from": [0, 0, -16], - "to": [3, 3, -13], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 0]}, - "faces": { - "north": {"uv": [13.25, 3.75, 14, 4.5], "texture": "#0"}, - "east": {"uv": [12.5, 3.75, 13.25, 4.5], "texture": "#0"}, - "south": {"uv": [14.75, 3.75, 15.5, 4.5], "texture": "#0"}, - "west": {"uv": [14, 3.75, 14.75, 4.5], "texture": "#0"}, - "up": {"uv": [14, 3.75, 13.25, 3], "texture": "#0"}, - "down": {"uv": [14.75, 3, 14, 3.75], "texture": "#0"} - } - }, - { - "name": "leg3", - "from": [0, 0, 13], - "to": [3, 3, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 0]}, - "faces": { - "north": {"uv": [13.25, 5.25, 14, 6], "texture": "#0"}, - "east": {"uv": [12.5, 5.25, 13.25, 6], "texture": "#0"}, - "south": {"uv": [14.75, 5.25, 15.5, 6], "texture": "#0"}, - "west": {"uv": [14, 5.25, 14.75, 6], "texture": "#0"}, - "up": {"uv": [14, 5.25, 13.25, 4.5], "texture": "#0"}, - "down": {"uv": [14.75, 4.5, 14, 5.25], "texture": "#0"} - } - } - ], - "groups": [ - { - "name": "bed", - "origin": [8, 0, 8], - "color": 0, - "children": [0, 1] - }, - { - "name": "leg0", - "origin": [14.5, 1.5, -6.5], - "color": 0, - "children": [2] - }, - { - "name": "leg1", - "origin": [14.5, 1.5, 22.5], - "color": 0, - "children": [3] - }, - { - "name": "leg2", - "origin": [1.5, 1.5, -6.5], - "color": 0, - "children": [4] - }, - { - "name": "leg3", - "origin": [1.5, 1.5, 22.5], - "color": 0, - "children": [5] - } - ] -} \ No newline at end of file diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/black_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/black_bed.json deleted file mode 100644 index 57c82022..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/black_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/black" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/black_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/black_shulker_box.json deleted file mode 100644 index eb269330..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/black_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_black" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/blue_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/blue_bed.json deleted file mode 100644 index fdaf6806..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/blue_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/blue" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/blue_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/blue_shulker_box.json deleted file mode 100644 index 472d1f7a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/blue_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_blue" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/brown_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/brown_bed.json deleted file mode 100644 index 2b88c6a6..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/brown_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/brown" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/brown_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/brown_shulker_box.json deleted file mode 100644 index 606900fd..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/brown_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_brown" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/chest.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/chest.json deleted file mode 100644 index 73a8d454..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/chest.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "parent": "block/block", - "textures": { - "0": "entity/chest/normal" - }, - "elements": [ - { - "from": [1, 9, 1], - "to": [15, 14, 15], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 11.5, 8] }, - "faces": { - "north": { "uv": [7, 3.5, 3.5, 4.75], "rotation": 180, "texture": "#0" }, - "east": { "uv": [3.5, 3.5, 0, 4.75], "rotation": 180, "texture": "#0" }, - "south": { "uv": [14, 3.5, 10.5, 4.75], "rotation": 180, "texture": "#0" }, - "west": { "uv": [10.5, 3.5, 7, 4.75], "rotation": 180, "texture": "#0" }, - "up": { "uv": [7, 3.5, 10.5, 0], "texture": "#0" }, - "down": { "uv": [3.5, 3.5, 7, 0], "texture": "#0" } - } - }, - { - "from": [7, 8, 15], - "to": [9, 12, 16], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 10, 15.5] }, - "faces": { - "north": { "uv": [1, 1.25, 0.5, 0.25], "texture": "#0" }, - "east": { "uv": [0.5, 1.25, 0.25, 0.25], "texture": "#0" }, - "south": { "uv": [1, 1.25, 0.5, 0.25], "texture": "#0" }, - "west": { "uv": [1.25, 1.25, 1, 0.25], "texture": "#0" }, - "up": { "uv": [0.5, 0.25, 1, 0], "texture": "#0" }, - "down": { "uv": [0.5, 0.25, 1, 0], "texture": "#0" } - } - }, - { - "from": [1, 0, 1], - "to": [15, 10, 15], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 5, 8] }, - "faces": { - "north": { "uv": [7, 8.25, 3.5, 10.75], "rotation": 180, "texture": "#0" }, - "east": { "uv": [10.5, 8.25, 7, 10.75], "rotation": 180, "texture": "#0" }, - "south": { "uv": [14, 8.25, 10.5, 10.75], "rotation": 180, "texture": "#0" }, - "west": { "uv": [3.5, 8.25, 0, 10.75], "rotation": 180, "texture": "#0" }, - "up": { "uv": [7, 8.25, 10.5, 4.75], "texture": "#0" }, - "down": { "uv": [3.5, 8.25, 7, 4.75], "rotation": 180, "texture": "#0" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/conduit.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/conduit.json deleted file mode 100644 index f0e4447e..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/conduit.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [32, 16], - "textures": { - "0": "minecraft:entity/conduit/base", - "particle": "minecraft:entity/conduit/base" - }, - "elements": [ - { - "from": [5, 5, 5], - "to": [11, 11, 11], - "rotation": { "angle": 0, "axis": "y", "origin": [5, 5, 5] }, - "faces": { - "north": { "uv": [3, 6, 6, 12], "texture": "#0" }, - "east": { "uv": [0, 6, 3, 12], "texture": "#0" }, - "south": { "uv": [9, 6, 12, 12], "texture": "#0" }, - "west": { "uv": [6, 6, 9, 12], "texture": "#0" }, - "up": { "uv": [6, 6, 3, 0], "texture": "#0" }, - "down": { "uv": [9, 0, 6, 6], "texture": "#0" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/cyan_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/cyan_bed.json deleted file mode 100644 index 9fccd84a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/cyan_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/cyan" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/cyan_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/cyan_shulker_box.json deleted file mode 100644 index 42e269ab..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/cyan_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_cyan" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/ender_chest.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/ender_chest.json deleted file mode 100644 index 25ddd45b..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/ender_chest.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "textures": { - "0": "entity/chest/ender" - }, - "elements": [ - { - "from": [1, 9, 1], - "to": [15, 14, 15], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 11.5, 8] }, - "faces": { - "north": { "uv": [10.5, 3.5, 14, 4.75], "rotation": 180, "texture": "#0" }, - "east": { "uv": [0, 3.5, 3.5, 4.75], "rotation": 180, "texture": "#0" }, - "south": { "uv": [3.5, 3.5, 7, 4.75], "rotation": 180, "texture": "#0" }, - "west": { "uv": [7, 3.5, 10.5, 4.75], "rotation": 180, "texture": "#0" }, - "up": { "uv": [7, 0, 10.5, 3.5], "texture": "#0" }, - "down": { "uv": [3.5, 0, 7, 3.5], "texture": "#0" } - } - }, - { - "from": [7, 8, 0], - "to": [9, 12, 1], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 10, 0.5] }, - "faces": { - "north": { "uv": [0.5, 1.25, 1, 0.25], "texture": "#0" }, - "east": { "uv": [0.25, 1.25, 0.5, 0.25], "texture": "#0" }, - "south": { "uv": [0.5, 1.25, 1, 0.25], "texture": "#0" }, - "west": { "uv": [1, 1.25, 1.25, 0.25], "texture": "#0" }, - "up": { "uv": [0.5, 0, 1, 0.25], "texture": "#0" }, - "down": { "uv": [0.5, 0, 1, 0.25], "texture": "#0" } - } - }, - { - "from": [1, 0, 1], - "to": [15, 10, 15], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 5, 8] }, - "faces": { - "north": { "uv": [10.5, 8.25, 14, 10.75], "rotation": 180, "texture": "#0" }, - "east": { "uv": [7, 8.25, 10.5, 10.75], "rotation": 180, "texture": "#0" }, - "south": { "uv": [3.5, 8.25, 7, 10.75], "rotation": 180, "texture": "#0" }, - "west": { "uv": [0, 8.25, 3.5, 10.75], "rotation": 180, "texture": "#0" }, - "up": { "uv": [7, 4.75, 10.5, 8.25], "texture": "#0" }, - "down": { "uv": [3.5, 4.75, 7, 8.25], "rotation": 180, "texture": "#0" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/gray_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/gray_bed.json deleted file mode 100644 index fd3d5140..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/gray_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/gray" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/gray_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/gray_shulker_box.json deleted file mode 100644 index 3b33366d..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/gray_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_gray" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/green_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/green_bed.json deleted file mode 100644 index 405c6d60..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/green_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/green" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/green_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/green_shulker_box.json deleted file mode 100644 index 50c46318..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/green_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_green" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/light_blue_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/light_blue_bed.json deleted file mode 100644 index f58cbc75..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/light_blue_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/light_blue" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/light_blue_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/light_blue_shulker_box.json deleted file mode 100644 index 83266db8..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/light_blue_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_light_blue" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/light_gray_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/light_gray_bed.json deleted file mode 100644 index d7ce483c..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/light_gray_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/light_gray" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/light_gray_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/light_gray_shulker_box.json deleted file mode 100644 index 65c79552..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/light_gray_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_light_gray" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/lime_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/lime_bed.json deleted file mode 100644 index d99d5162..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/lime_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/lime" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/lime_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/lime_shulker_box.json deleted file mode 100644 index ae717b4e..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/lime_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_lime" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/magenta_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/magenta_bed.json deleted file mode 100644 index 6ff52613..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/magenta_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/magenta" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/magenta_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/magenta_shulker_box.json deleted file mode 100644 index 917a4600..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/magenta_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_magenta" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/orange_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/orange_bed.json deleted file mode 100644 index 868a5c5b..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/orange_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/orange" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/orange_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/orange_shulker_box.json deleted file mode 100644 index 34c7214d..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/orange_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_orange" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/pink_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/pink_bed.json deleted file mode 100644 index 32b11d80..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/pink_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/pink" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/pink_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/pink_shulker_box.json deleted file mode 100644 index 072c5abb..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/pink_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_pink" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/purple_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/purple_bed.json deleted file mode 100644 index 1edecbdf..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/purple_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/purple" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/purple_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/purple_shulker_box.json deleted file mode 100644 index 10798664..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/purple_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_purple" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/red_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/red_bed.json deleted file mode 100644 index f39725ac..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/red_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/red" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/red_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/red_shulker_box.json deleted file mode 100644 index f2a185f3..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/red_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_red" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/shulker_box.json deleted file mode 100644 index d4890e6d..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/shulker_box.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "credit": "Made with Blockbench", - "textures": { - "0": "entity/shulker/shulker", - "particle": "entity/shulker/shulker" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 16, 16], - "faces": { - "north": { "uv": [0, 9, 4, 13], "texture": "#0" }, - "east": { "uv": [0, 9, 4, 13], "texture": "#0" }, - "south": { "uv": [0, 9, 4, 13], "texture": "#0" }, - "west": { "uv": [0, 9, 4, 13], "texture": "#0" }, - "down": { "uv": [8, 7, 12, 11], "texture": "#0" } - } - }, - { - "from": [0, 0, 0], - "to": [16, 16, 16], - "faces": { - "north": { "uv": [0, 4, 4, 8], "texture": "#0" }, - "east": { "uv": [0, 4, 4, 8], "texture": "#0" }, - "south": { "uv": [0, 4, 4, 8], "texture": "#0" }, - "west": { "uv": [0, 4, 4, 8], "texture": "#0" }, - "up": { "uv": [4, 0, 8, 4], "texture": "#0" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/white_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/white_bed.json deleted file mode 100644 index e889fa63..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/white_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/white" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/white_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/white_shulker_box.json deleted file mode 100644 index f41d2b06..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/white_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_white" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/yellow_bed.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/yellow_bed.json deleted file mode 100644 index 200a1d46..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/yellow_bed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/bed", - "textures": { - "0": "entity/bed/yellow" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/block/yellow_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/block/yellow_shulker_box.json deleted file mode 100644 index 3e184271..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/block/yellow_shulker_box.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/shulker_box", - "textures": { - "0": "entity/shulker/shulker_yellow" - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/black_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/black_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/black_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/black_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/black_shulker_box.json deleted file mode 100644 index a9ba4851..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/black_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/black_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/blue_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/blue_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/blue_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/blue_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/blue_shulker_box.json deleted file mode 100644 index e5f42972..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/blue_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/blue_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/brown_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/brown_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/brown_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/brown_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/brown_shulker_box.json deleted file mode 100644 index 57a3a34f..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/brown_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/brown_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/conduit.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/conduit.json deleted file mode 100644 index ecce55d6..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/conduit.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "parent": "block/conduit", - "textures": { - "particle": "block/conduit" - }, - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [1.0, 1.0, 1.0] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.5, 0.5, 0.5] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.5, 0.5, 0.5] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.8, 0.8, 0.8] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/creeper_head.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/creeper_head.json deleted file mode 100644 index 627544a8..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/creeper_head.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 32], - "textures": { - "0": "entity/creeper/creeper" - }, - "elements": [ - { - "name": "Head", - "from": [4, -8, 4], - "to": [12, 0, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -4, 8]}, - "faces": { - "north": {"uv": [2, 4, 4, 8], "texture": "#0"}, - "east": {"uv": [0, 4, 2, 8], "texture": "#0"}, - "south": {"uv": [6, 4, 8, 8], "texture": "#0"}, - "west": {"uv": [4, 4, 6, 8], "texture": "#0"}, - "up": {"uv": [4, 4, 2, 0], "texture": "#0"}, - "down": {"uv": [6, 0, 4, 4], "texture": "#0"} - } - } - ] -} \ No newline at end of file diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/cyan_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/cyan_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/cyan_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/cyan_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/cyan_shulker_box.json deleted file mode 100644 index 7374e97a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/cyan_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/cyan_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/decorated_pot.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/decorated_pot.json deleted file mode 100644 index f2679f4c..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/decorated_pot.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "credit": "Made with Blockbench", - "textures": { - "0": "entity/decorated_pot/decorated_pot_side", - "1": "entity/decorated_pot/decorated_pot_base", - "particle": "entity/decorated_pot/decorated_pot_side" - }, - "elements": [ - { - "from": [1, 0, 1], - "to": [15, 16, 15], - "faces": { - "north": { "uv": [1, 0, 15, 16], "texture": "#0" }, - "east": { "uv": [1, 0, 15, 16], "texture": "#0" }, - "south": { "uv": [1, 0, 15, 16], "texture": "#0" }, - "west": { "uv": [1, 0, 15, 16], "texture": "#0" }, - "up": { "uv": [7, 6.5, 14, 13.5], "texture": "#1" }, - "down": { "uv": [0, 6.5, 7, 13.5], "texture": "#1" } - } - }, - { - "from": [4.75, 16, 4.75], - "to": [11.25, 20, 11.25], - "rotation": { "angle": 0, "axis": "y", "origin": [6, 16, 6] }, - "faces": { - "north": { "uv": [0, 4, 4, 6], "texture": "#1" }, - "east": { "uv": [0, 4, 4, 6], "texture": "#1" }, - "south": { "uv": [0, 4, 4, 6], "texture": "#1" }, - "west": { "uv": [0, 4, 4, 6], "texture": "#1" } - } - }, - { - "from": [4, 17, 4], - "to": [12, 20, 12], - "rotation": { "angle": 0, "axis": "y", "origin": [6, 17, 6] }, - "faces": { - "north": { "uv": [12, 4, 16, 5.5], "texture": "#1" }, - "east": { "uv": [12, 4, 16, 5.5], "texture": "#1" }, - "south": { "uv": [12, 4, 16, 5.5], "texture": "#1" }, - "west": { "uv": [12, 4, 16, 5.5], "texture": "#1" }, - "up": { "uv": [4, 0, 8, 4], "texture": "#1" }, - "down": { "uv": [8, 0, 12, 4], "texture": "#1" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/dragon_head.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/dragon_head.json deleted file mode 100644 index 715432d9..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/dragon_head.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [256, 256], - "textures": { - "0": "enderdragon" - }, - "elements": [ - { - "name": "head", - "from": [2, -6, -16], - "to": [14, -1, 0], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -9, 8]}, - "faces": { - "north": {"uv": [12, 3.75, 12.75, 4.0625], "texture": "#0"}, - "east": {"uv": [11, 3.75, 12, 4.0625], "texture": "#0"}, - "south": {"uv": [13.75, 3.75, 14.5, 4.0625], "texture": "#0"}, - "west": {"uv": [12.75, 3.75, 13.75, 4.0625], "texture": "#0"}, - "up": {"uv": [12.75, 3.75, 12, 2.75], "texture": "#0"}, - "down": {"uv": [13.5, 2.75, 12.75, 3.75], "texture": "#0"} - } - }, - { - "name": "head", - "from": [0, -10, 0], - "to": [16, 6, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -9, 24]}, - "faces": { - "north": {"uv": [8, 2.875, 9, 3.875], "texture": "#0"}, - "east": {"uv": [7, 2.875, 8, 3.875], "texture": "#0"}, - "south": {"uv": [10, 2.875, 11, 3.875], "texture": "#0"}, - "west": {"uv": [9, 2.875, 10, 3.875], "texture": "#0"}, - "up": {"uv": [9, 2.875, 8, 1.875], "texture": "#0"}, - "down": {"uv": [10, 1.875, 9, 2.875], "texture": "#0"} - } - }, - { - "name": "head", - "from": [11, 6, 6], - "to": [13, 10, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -9, 30]}, - "faces": { - "north": {"uv": [0.5, 0.375, 0.375, 0.625], "texture": "#0"}, - "east": {"uv": [0.875, 0.375, 0.5, 0.625], "texture": "#0"}, - "south": {"uv": [1, 0.375, 0.875, 0.625], "texture": "#0"}, - "west": {"uv": [0.375, 0.375, 0, 0.625], "texture": "#0"}, - "up": {"uv": [0.375, 0.375, 0.5, 0], "texture": "#0"}, - "down": {"uv": [0.5, 0, 0.625, 0.375], "texture": "#0"} - } - }, - { - "name": "head", - "from": [11, -1, -16], - "to": [13, 1, -12], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -9, 8]}, - "faces": { - "north": {"uv": [7.375, 0.25, 7.25, 0.375], "texture": "#0"}, - "east": {"uv": [7.625, 0.25, 7.375, 0.375], "texture": "#0"}, - "south": {"uv": [7.75, 0.25, 7.625, 0.375], "texture": "#0"}, - "west": {"uv": [7.25, 0.25, 7, 0.375], "texture": "#0"}, - "up": {"uv": [7.25, 0.25, 7.375, 0], "texture": "#0"}, - "down": {"uv": [7.375, 0, 7.5, 0.25], "texture": "#0"} - } - }, - { - "name": "head", - "from": [3, 6, 6], - "to": [5, 10, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -9, 30]}, - "faces": { - "north": {"uv": [0.375, 0.375, 0.5, 0.625], "texture": "#0"}, - "east": {"uv": [0, 0.375, 0.375, 0.625], "texture": "#0"}, - "south": {"uv": [0.875, 0.375, 1, 0.625], "texture": "#0"}, - "west": {"uv": [0.5, 0.375, 0.875, 0.625], "texture": "#0"}, - "up": {"uv": [0.5, 0.375, 0.375, 0], "texture": "#0"}, - "down": {"uv": [0.625, 0, 0.5, 0.375], "texture": "#0"} - } - }, - { - "name": "head", - "from": [3, -1, -16], - "to": [5, 1, -12], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -9, 8]}, - "faces": { - "north": {"uv": [7.25, 0.25, 7.375, 0.375], "texture": "#0"}, - "east": {"uv": [7, 0.25, 7.25, 0.375], "texture": "#0"}, - "south": {"uv": [7.625, 0.25, 7.75, 0.375], "texture": "#0"}, - "west": {"uv": [7.375, 0.25, 7.625, 0.375], "texture": "#0"}, - "up": {"uv": [7.375, 0.25, 7.25, 0], "texture": "#0"}, - "down": {"uv": [7.5, 0, 7.375, 0.25], "texture": "#0"} - } - }, - { - "name": "jaw", - "from": [2, -10, -16], - "to": [14, -6, 0], - "rotation": {"angle": -22.5, "axis": "x", "origin": [8, -6, 0]}, - "faces": { - "north": {"uv": [12, 5.0625, 12.75, 5.3125], "texture": "#0"}, - "east": {"uv": [11, 5.0625, 12, 5.3125], "texture": "#0"}, - "south": {"uv": [13.75, 5.0625, 14.5, 5.3125], "texture": "#0"}, - "west": {"uv": [12.75, 5.0625, 13.75, 5.3125], "texture": "#0"}, - "up": {"uv": [12.75, 5.0625, 12, 4.0625], "texture": "#0"}, - "down": {"uv": [13.5, 4.0625, 12.75, 5.0625], "texture": "#0"} - } - } - ], - "groups": [ - { - "name": "head", - "origin": [8, 7, -50], - "color": 0, - "children": [ - 0, - 1, - 2, - 3, - 4, - 5, - { - "name": "jaw", - "origin": [8, 3, -63], - "color": 0, - "children": [6] - } - ] - } - ] -} \ No newline at end of file diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/ender_chest.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/ender_chest.json deleted file mode 100644 index 3620ea87..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/ender_chest.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "minecraft:block/ender_chest" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/gray_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/gray_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/gray_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/gray_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/gray_shulker_box.json deleted file mode 100644 index 84577af2..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/gray_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/gray_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/green_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/green_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/green_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/green_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/green_shulker_box.json deleted file mode 100644 index 3ab83019..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/green_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/green_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/light_blue_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/light_blue_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/light_blue_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/light_blue_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/light_blue_shulker_box.json deleted file mode 100644 index 645965d6..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/light_blue_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/light_blue_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/light_gray_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/light_gray_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/light_gray_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/light_gray_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/light_gray_shulker_box.json deleted file mode 100644 index 2ad2c558..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/light_gray_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/light_gray_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/lime_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/lime_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/lime_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/lime_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/lime_shulker_box.json deleted file mode 100644 index 2e01765d..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/lime_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/lime_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/magenta_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/magenta_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/magenta_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/magenta_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/magenta_shulker_box.json deleted file mode 100644 index 91fa9d1a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/magenta_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/magenta_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/mob_skull.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/mob_skull.json deleted file mode 100644 index e8041a1b..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/mob_skull.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "elements": [ - { - "name": "head", - "from": [4, 0, 4], - "to": [12, 8, 12], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 0, 8] }, - "faces": { - "north": { "uv": [2, 4, 4, 8], "texture": "#skull" }, - "east": { "uv": [0, 4, 2, 8], "texture": "#skull" }, - "south": { "uv": [6, 4, 8, 8], "texture": "#skull" }, - "west": { "uv": [4, 4, 6, 8], "texture": "#skull" }, - "up": { "uv": [4, 4, 2, 0], "texture": "#skull" }, - "down": { "uv": [6, 0, 4, 4], "texture": "#skull" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/orange_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/orange_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/orange_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/orange_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/orange_shulker_box.json deleted file mode 100644 index f2c1dc2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/orange_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/orange_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/piglin_head.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/piglin_head.json deleted file mode 100644 index 6bd42612..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/piglin_head.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 64], - "textures": { - "0": "entity/piglin/piglin" - }, - "elements": [ - { - "name": "rightear", - "from": [12.5, -7, 6], - "to": [13.5, -2, 10], - "rotation": {"angle": 45, "axis": "z", "origin": [13, -2, 8]}, - "faces": { - "north": {"uv": [10.75, 2.5, 11, 3.75], "texture": "#0"}, - "east": {"uv": [9.75, 2.5, 10.75, 3.75], "texture": "#0"}, - "south": {"uv": [12, 2.5, 12.25, 3.75], "texture": "#0"}, - "west": {"uv": [11, 2.5, 12, 3.75], "texture": "#0"}, - "up": {"uv": [11, 2.5, 10.75, 1.5], "texture": "#0"}, - "down": {"uv": [11.25, 1.5, 11, 2.5], "texture": "#0"} - } - }, - { - "name": "leftear", - "from": [2.5, -7, 6], - "to": [3.5, -2, 10], - "rotation": {"angle": -45, "axis": "z", "origin": [3, -2, 8]}, - "faces": { - "north": {"uv": [13.75, 2.5, 14, 3.75], "texture": "#0"}, - "east": {"uv": [12.75, 2.5, 13.75, 3.75], "texture": "#0"}, - "south": {"uv": [15, 2.5, 15.25, 3.75], "texture": "#0"}, - "west": {"uv": [14, 2.5, 15, 3.75], "texture": "#0"}, - "up": {"uv": [14, 2.5, 13.75, 1.5], "texture": "#0"}, - "down": {"uv": [14.25, 1.5, 14, 2.5], "texture": "#0"} - } - }, - { - "name": "head", - "from": [10, -8, 3], - "to": [11, -6, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -32, 8]}, - "faces": { - "north": {"uv": [0.75, 0.25, 1, 0.75], "texture": "#0"}, - "east": {"uv": [0.5, 0.25, 0.75, 0.75], "texture": "#0"}, - "south": {"uv": [1.25, 0.25, 1.5, 0.75], "texture": "#0"}, - "west": {"uv": [1, 0.25, 1.25, 0.75], "texture": "#0"}, - "up": {"uv": [1, 0.25, 0.75, 0], "texture": "#0"}, - "down": {"uv": [1.25, 0, 1, 0.25], "texture": "#0"} - } - }, - { - "name": "head", - "from": [5, -8, 3], - "to": [6, -6, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -32, 8]}, - "faces": { - "north": {"uv": [0.75, 1.25, 1, 1.75], "texture": "#0"}, - "east": {"uv": [0.5, 1.25, 0.75, 1.75], "texture": "#0"}, - "south": {"uv": [1.25, 1.25, 1.5, 1.75], "texture": "#0"}, - "west": {"uv": [1, 1.25, 1.25, 1.75], "texture": "#0"}, - "up": {"uv": [1, 1.25, 0.75, 1], "texture": "#0"}, - "down": {"uv": [1.25, 1, 1, 1.25], "texture": "#0"} - } - }, - { - "name": "head", - "from": [6, -8, 3], - "to": [10, -4, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -32, 8]}, - "faces": { - "north": {"uv": [8, 0.5, 9, 1.5], "texture": "#0"}, - "east": {"uv": [7.75, 0.5, 8, 1.5], "texture": "#0"}, - "south": {"uv": [9.25, 0.5, 10.25, 1.5], "texture": "#0"}, - "west": {"uv": [9, 0.5, 9.25, 1.5], "texture": "#0"}, - "up": {"uv": [9, 0.5, 8, 0.25], "texture": "#0"}, - "down": {"uv": [10, 0.25, 9, 0.5], "texture": "#0"} - } - }, - { - "name": "head", - "from": [3.02, -7.98, 4.02], - "to": [12.98, -0.02, 11.98], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -32, 8]}, - "faces": { - "north": {"uv": [2, 2, 4.5, 4], "texture": "#0"}, - "east": {"uv": [0, 2, 2, 4], "texture": "#0"}, - "south": {"uv": [6.5, 2, 9, 4], "texture": "#0"}, - "west": {"uv": [4.5, 2, 6.5, 4], "texture": "#0"}, - "up": {"uv": [4.5, 2, 2, 0], "texture": "#0"}, - "down": {"uv": [7, 0, 4.5, 2], "texture": "#0"} - } - } - ] -} \ No newline at end of file diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/pink_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/pink_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/pink_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/pink_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/pink_shulker_box.json deleted file mode 100644 index a9bdc762..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/pink_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/pink_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/player_head.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/player_head.json deleted file mode 100644 index 189ab21e..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/player_head.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 64], - "textures": { - "0": "animated_java:steve" - }, - "elements": [ - { - "name": "Hat Layer", - "from": [3.5, -8.5, 3.5], - "to": [12.5, 0.5, 12.5], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -31.5, 8]}, - "faces": { - "north": {"uv": [10, 2, 12, 4], "texture": "#0"}, - "east": {"uv": [8, 2, 10, 4], "texture": "#0"}, - "south": {"uv": [14, 2, 16, 4], "texture": "#0"}, - "west": {"uv": [12, 2, 14, 4], "texture": "#0"}, - "up": {"uv": [12, 2, 10, 0], "texture": "#0"}, - "down": {"uv": [14, 0, 12, 2], "texture": "#0"} - } - }, - { - "name": "Head", - "from": [4, -8, 4], - "to": [12, 0, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -32, 8]}, - "faces": { - "north": {"uv": [2, 2, 4, 4], "texture": "#0"}, - "east": {"uv": [0, 2, 2, 4], "texture": "#0"}, - "south": {"uv": [6, 2, 8, 4], "texture": "#0"}, - "west": {"uv": [4, 2, 6, 4], "texture": "#0"}, - "up": {"uv": [4, 2, 2, 0], "texture": "#0"}, - "down": {"uv": [6, 0, 4, 2], "texture": "#0"} - } - } - ] -} \ No newline at end of file diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/purple_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/purple_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/purple_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/purple_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/purple_shulker_box.json deleted file mode 100644 index 5cfadf62..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/purple_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/purple_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/red_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/red_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/red_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/red_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/red_shulker_box.json deleted file mode 100644 index 45a5e0d9..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/red_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/red_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/shield.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/shield.json deleted file mode 100644 index f8dc8aed..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/shield.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 64], - "textures": { - "0": "entity/shield_base" - }, - "elements": [ - { - "name": "shield", - "from": [16, -11, 13], - "to": [18, -5, 19], - "rotation": {"angle": 0, "axis": "y", "origin": [18, -36, 13]}, - "faces": { - "north": {"uv": [8, 1.5, 8.5, 3], "texture": "#0"}, - "east": {"uv": [6.5, 1.5, 8, 3], "texture": "#0"}, - "south": {"uv": [10, 1.5, 10.5, 3], "texture": "#0"}, - "west": {"uv": [8.5, 1.5, 10, 3], "texture": "#0"}, - "up": {"uv": [8.5, 1.5, 8, 0], "texture": "#0"}, - "down": {"uv": [9, 0, 8.5, 1.5], "texture": "#0"} - } - }, - { - "name": "shield", - "from": [11, -19, 12], - "to": [23, 3, 13], - "rotation": {"angle": 0, "axis": "y", "origin": [18, -29, 13]}, - "faces": { - "north": {"uv": [0.25, 0.25, 3.25, 5.75], "texture": "#0"}, - "east": {"uv": [0, 0.25, 0.25, 5.75], "texture": "#0"}, - "south": {"uv": [3.5, 0.25, 6.5, 5.75], "texture": "#0"}, - "west": {"uv": [3.25, 0.25, 3.5, 5.75], "texture": "#0"}, - "up": {"uv": [3.25, 0.25, 0.25, 0], "texture": "#0"}, - "down": {"uv": [6.25, 0, 3.25, 0.25], "texture": "#0"} - } - } - ], - "groups": [ - { - "name": "shield", - "origin": [7, 15.5, 11], - "color": 0, - "children": [0, 1] - } - ] -} \ No newline at end of file diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/shulker_box.json deleted file mode 100644 index 5bf34410..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/skeleton_skull.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/skeleton_skull.json deleted file mode 100644 index 1672d386..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/skeleton_skull.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 32], - "textures": { - "0": "minecraft:entity/skeleton/skeleton" - }, - "elements": [ - { - "name": "Hat Layer", - "from": [3.5, -8.5, 3.5], - "to": [12.5, 0.5, 12.5], - "rotation": { "angle": 0, "axis": "y", "origin": [8, -31.5, 8] }, - "faces": { - "north": { "uv": [10, 4, 12, 8], "texture": "#0" }, - "east": { "uv": [8, 4, 10, 8], "texture": "#0" }, - "south": { "uv": [14, 4, 16, 8], "texture": "#0" }, - "west": { "uv": [12, 4, 14, 8], "texture": "#0" }, - "up": { "uv": [12, 4, 10, 0], "texture": "#0" }, - "down": { "uv": [14, 0, 12, 4], "texture": "#0" } - } - }, - { - "name": "Head", - "from": [4, -8, 4], - "to": [12, 0, 12], - "rotation": { "angle": 0, "axis": "y", "origin": [8, -32, 8] }, - "faces": { - "north": { "uv": [2, 4, 4, 8], "texture": "#0" }, - "east": { "uv": [0, 4, 2, 8], "texture": "#0" }, - "south": { "uv": [6, 4, 8, 8], "texture": "#0" }, - "west": { "uv": [4, 4, 6, 8], "texture": "#0" }, - "up": { "uv": [4, 4, 2, 0], "texture": "#0" }, - "down": { "uv": [6, 0, 4, 4], "texture": "#0" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/template_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/template_banner.json deleted file mode 100644 index 657b3caf..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/template_banner.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 64], - "textures": { - "0": "entity/banner/base", - "tint": "entity/banner/base" - }, - "elements": [ - { - "name": "stand", - "from": [-2, 30, 7], - "to": [18, 32, 9], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 0, 7] }, - "faces": { - "north": { "uv": [0.5, 11, 5.5, 11.5], "texture": "#0" }, - "east": { "uv": [0, 11, 0.5, 11.5], "texture": "#0" }, - "south": { "uv": [6, 11, 11, 11.5], "texture": "#0" }, - "west": { "uv": [5.5, 11, 6, 11.5], "texture": "#0" }, - "up": { "uv": [5.5, 11, 0.5, 10.5], "texture": "#0" }, - "down": { "uv": [10.5, 10.5, 5.5, 11], "texture": "#0" } - } - }, - { - "name": "stand", - "from": [7, -12, 7], - "to": [9, 30, 9], - "rotation": { "angle": 0, "axis": "y", "origin": [8, -2, 7] }, - "faces": { - "north": { "uv": [11.5, 0.5, 12, 11], "texture": "#0" }, - "east": { "uv": [11, 0.5, 11.5, 11], "texture": "#0" }, - "south": { "uv": [12.5, 0.5, 13, 11], "texture": "#0" }, - "west": { "uv": [12, 0.5, 12.5, 11], "texture": "#0" }, - "up": { "uv": [12, 0.5, 11.5, 0], "texture": "#0" }, - "down": { "uv": [12.5, 0, 12, 0.5], "texture": "#0" } - } - }, - { - "name": "banner", - "from": [-2, -8, 6], - "to": [18, 32, 7], - "rotation": { "angle": 0.5, "axis": "x", "origin": [8, 32, 7] }, - "faces": { - "north": { "uv": [0.25, 0.25, 5.25, 10.25], "texture": "#tint" }, - "east": { "uv": [0, 0.25, 0.25, 10.25], "texture": "#tint" }, - "south": { "uv": [5.5, 0.25, 10.5, 10.25], "texture": "#tint" }, - "west": { "uv": [5.25, 0.25, 5.5, 10.25], "texture": "#tint" }, - "up": { "uv": [5.25, 0.25, 0.25, 0], "texture": "#tint" }, - "down": { "uv": [10.25, 0, 5.25, 0.25], "texture": "#tint" } - } - } - ], - "display": { - "thirdperson_righthand": { - "rotation": [0, 90, 0], - "translation": [0, 2, 0.5], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 90, 0], - "scale": [0.375, 0.375, 0.375] - }, - "ground": { - "translation": [0, 1, 0], - "scale": [0.25, 0.25, 0.25] - }, - "gui": { - "rotation": [30, 20, 0], - "translation": [0, -3.25, 0], - "scale": [0.5325, 0.5325, 0.5325] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 16, 7], - "scale": [1.5, 1.5, 1.5] - }, - "fixed": { - "rotation": [0, 180, 0], - "scale": [0.5, 0.5, 0.5] - } - }, - "groups": [ - { - "name": "stand", - "origin": [8, 0, 8], - "color": 0, - "children": [ - 0, - 1, - { - "name": "banner", - "origin": [8, 44, 8], - "color": 0, - "children": [2] - } - ] - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/template_chest.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/template_chest.json deleted file mode 100644 index 70769b4c..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/template_chest.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "parent": "block/block", - "textures": { - "0": "entity/chest/normal" - }, - "elements": [ - { - "from": [1, 9, 1], - "to": [15, 14, 15], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 11.5, 8] }, - "faces": { - "north": { "uv": [10.5, 3.5, 14, 4.75], "rotation": 180, "texture": "#0" }, - "east": { "uv": [0, 3.5, 3.5, 4.75], "rotation": 180, "texture": "#0" }, - "south": { "uv": [3.5, 3.5, 7, 4.75], "rotation": 180, "texture": "#0" }, - "west": { "uv": [7, 3.5, 10.5, 4.75], "rotation": 180, "texture": "#0" }, - "up": { "uv": [7, 0, 10.5, 3.5], "texture": "#0" }, - "down": { "uv": [3.5, 0, 7, 3.5], "texture": "#0" } - } - }, - { - "from": [7, 8, 0], - "to": [9, 12, 1], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 10, 0.5] }, - "faces": { - "north": { "uv": [0.5, 1.25, 1, 0.25], "texture": "#0" }, - "east": { "uv": [0.25, 1.25, 0.5, 0.25], "texture": "#0" }, - "south": { "uv": [0.5, 1.25, 1, 0.25], "texture": "#0" }, - "west": { "uv": [1, 1.25, 1.25, 0.25], "texture": "#0" }, - "up": { "uv": [0.5, 0, 1, 0.25], "texture": "#0" }, - "down": { "uv": [0.5, 0, 1, 0.25], "texture": "#0" } - } - }, - { - "from": [1, 0, 1], - "to": [15, 10, 15], - "rotation": { "angle": 0, "axis": "y", "origin": [8, 5, 8] }, - "faces": { - "north": { "uv": [10.5, 8.25, 14, 10.75], "rotation": 180, "texture": "#0" }, - "east": { "uv": [7, 8.25, 10.5, 10.75], "rotation": 180, "texture": "#0" }, - "south": { "uv": [3.5, 8.25, 7, 10.75], "rotation": 180, "texture": "#0" }, - "west": { "uv": [0, 8.25, 3.5, 10.75], "rotation": 180, "texture": "#0" }, - "up": { "uv": [7, 4.75, 10.5, 8.25], "texture": "#0" }, - "down": { "uv": [3.5, 4.75, 7, 8.25], "rotation": 180, "texture": "#0" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/trident.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/trident.json deleted file mode 100644 index 2f48b5e5..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/trident.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "credit": "Made with Blockbench", - "textures": { - "0": "entity/trident", - "particle": "entity/trident" - }, - "elements": [ - { - "from": [15, -34, 15], - "to": [16, -3, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [15, -18, 15]}, - "faces": { - "north": {"uv": [1.5, 0.5, 2, 16], "texture": "#0"}, - "east": {"uv": [1, 0.5, 1.5, 16], "texture": "#0"}, - "south": {"uv": [0.5, 0.5, 1, 16], "texture": "#0"}, - "west": {"uv": [0, 0.5, 0.5, 16], "texture": "#0"}, - "up": {"uv": [0.5, 0, 1, 0.5], "texture": "#0"}, - "down": {"uv": [1, 0, 1.5, 0.5], "texture": "#0"} - } - }, - { - "from": [14, -9, 15], - "to": [17, -7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [14, -18, 15]}, - "faces": { - "north": {"uv": [2.5, 0.5, 4, 1.5], "texture": "#0"}, - "east": {"uv": [2, 0.5, 2.5, 1.5], "texture": "#0"}, - "south": {"uv": [2.5, 0.5, 4, 1.5], "texture": "#0"}, - "west": {"uv": [3, 0.5, 3.5, 1.5], "texture": "#0"}, - "up": {"uv": [2.5, 0, 4, 0.5], "texture": "#0"}, - "down": {"uv": [4, 0, 5.5, 0.5], "texture": "#0"} - } - }, - { - "from": [13, -8, 15], - "to": [14, -4, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [13, -17, 15]}, - "faces": { - "north": {"uv": [2.5, 2, 3, 4], "texture": "#0"}, - "east": {"uv": [2, 2, 2.5, 4], "texture": "#0"}, - "south": {"uv": [3.5, 2, 4, 4], "texture": "#0"}, - "west": {"uv": [3, 2, 3.5, 4], "texture": "#0"}, - "up": {"uv": [2.5, 1.5, 3, 2], "texture": "#0"}, - "down": {"uv": [3, 1.5, 3.5, 2], "texture": "#0"} - } - }, - { - "from": [17, -8, 15], - "to": [18, -4, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, -17, 15]}, - "faces": { - "north": {"uv": [2.5, 2, 3, 4], "texture": "#0"}, - "east": {"uv": [2, 2, 2.5, 4], "texture": "#0"}, - "south": {"uv": [3.5, 2, 4, 4], "texture": "#0"}, - "west": {"uv": [3, 2, 3.5, 4], "texture": "#0"}, - "up": {"uv": [2.5, 1.5, 3, 2], "texture": "#0"}, - "down": {"uv": [3, 1.5, 3.5, 2], "texture": "#0"} - } - } - ] -} \ No newline at end of file diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/white_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/white_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/white_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/white_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/white_shulker_box.json deleted file mode 100644 index 4c1417c1..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/white_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/white_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/wither_skeleton_skull.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/wither_skeleton_skull.json deleted file mode 100644 index cacd60f5..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/wither_skeleton_skull.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 32], - "textures": { - "0": "entity/skeleton/wither_skeleton" - }, - "elements": [ - { - "name": "Hat Layer", - "from": [3.5, -1, 3.5], - "to": [12.5, 8, 12.5], - "rotation": { "angle": 0, "axis": "y", "origin": [8, -24, 8] }, - "faces": { - "north": { "uv": [10, 4, 12, 8], "texture": "#0" }, - "east": { "uv": [8, 4, 10, 8], "texture": "#0" }, - "south": { "uv": [14, 4, 16, 8], "texture": "#0" }, - "west": { "uv": [12, 4, 14, 8], "texture": "#0" }, - "up": { "uv": [12, 4, 10, 0], "texture": "#0" }, - "down": { "uv": [14, 0, 12, 4], "texture": "#0" } - } - }, - { - "name": "Head", - "from": [4, 0, 4], - "to": [12, 8, 12], - "rotation": { "angle": 0, "axis": "y", "origin": [8, -24, 8] }, - "faces": { - "north": { "uv": [2, 4, 4, 8], "texture": "#0" }, - "east": { "uv": [0, 4, 2, 8], "texture": "#0" }, - "south": { "uv": [6, 4, 8, 8], "texture": "#0" }, - "west": { "uv": [4, 4, 6, 8], "texture": "#0" }, - "up": { "uv": [4, 4, 2, 0], "texture": "#0" }, - "down": { "uv": [6, 0, 4, 4], "texture": "#0" } - } - } - ] -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/yellow_banner.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/yellow_banner.json deleted file mode 100644 index 47720f2a..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/yellow_banner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "item/template_banner" -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/yellow_shulker_box.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/yellow_shulker_box.json deleted file mode 100644 index f1ef0550..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/yellow_shulker_box.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "block/yellow_shulker_box", - "display": { - "gui": { - "rotation": [30, 45, 0], - "translation": [0, 0, 0], - "scale": [0.625, 0.625, 0.625] - }, - "ground": { - "rotation": [0, 0, 0], - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "head": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 0, 0], - "scale": [0.5, 0.5, 0.5] - }, - "thirdperson_righthand": { - "rotation": [75, 315, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 315, 0], - "translation": [0, 0, 0], - "scale": [0.4, 0.4, 0.4] - } - } -} diff --git a/src/assets/vanillaAssetOverrides/minecraft/models/item/zombie_head.json b/src/assets/vanillaAssetOverrides/minecraft/models/item/zombie_head.json deleted file mode 100644 index d6a8b8e1..00000000 --- a/src/assets/vanillaAssetOverrides/minecraft/models/item/zombie_head.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [64, 64], - "textures": { - "0": "entity/zombie/zombie" - }, - "elements": [ - { - "name": "Hat Layer", - "from": [3.5, -8.5, 3.5], - "to": [12.5, 0.5, 12.5], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -31.5, 8]}, - "faces": { - "north": {"uv": [10, 2, 12, 4], "texture": "#0"}, - "east": {"uv": [8, 2, 10, 4], "texture": "#0"}, - "south": {"uv": [14, 2, 16, 4], "texture": "#0"}, - "west": {"uv": [12, 2, 14, 4], "texture": "#0"}, - "up": {"uv": [12, 2, 10, 0], "texture": "#0"}, - "down": {"uv": [14, 0, 12, 2], "texture": "#0"} - } - }, - { - "name": "Head", - "from": [4, -8, 4], - "to": [12, 0, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -32, 8]}, - "faces": { - "north": {"uv": [2, 2, 4, 4], "texture": "#0"}, - "east": {"uv": [0, 2, 2, 4], "texture": "#0"}, - "south": {"uv": [6, 2, 8, 4], "texture": "#0"}, - "west": {"uv": [4, 2, 6, 4], "texture": "#0"}, - "up": {"uv": [4, 2, 2, 0], "texture": "#0"}, - "down": {"uv": [6, 0, 4, 2], "texture": "#0"} - } - } - ] -} \ No newline at end of file diff --git a/src/global.d.ts b/src/global.d.ts index 09430aee..3b69a081 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -63,6 +63,99 @@ declare module 'deepslate/lib/nbt' { export * from 'deepslate/nbt' } +declare module 'block-model-renderer/assets.zip' { + const url: string + export default url +} + +declare module 'block-model-renderer' { + interface AssetHandler { + read( + path: string + ): Uint8Array | string | null | undefined | Promise + list(dir: string): string[] | Promise + filter?: unknown[] + } + + /** Opaque, normalized asset bundle returned by {@link prepareAssets}. */ + type PreparedAssets = unknown[] & { readonly __prepared: unique symbol } + + /** A single model reference / inline model, as passed between the low level scene functions. */ + type ModelReference = Record + + type DisplayTransform = + | string + | { + type?: 'fallback' + display?: string + rotation?: [number, number, number] + translation?: [number, number, number] + scale?: [number, number, number] + } + + export function configure(opts: { THREE?: unknown; three?: unknown; assetsUrl?: string }): void + + export function getThree(): Promise + + export function prepareAssets( + sources: Array, + options?: { + cache?: boolean + version?: string + translucency?: { min: number; max: number } + } + ): Promise + + export function disposeCache(assets: PreparedAssets): void + + export function parseBlockstate( + assets: PreparedAssets, + id: string, + args?: { + data?: Record + seed?: number + ignoreAtlases?: boolean + version?: string + } + ): Promise + + export function parseItemDefinition( + assets: PreparedAssets, + id: string, + args?: { + data?: Record + display?: string + ignoreAtlases?: boolean + version?: string + } + ): Promise + + export function resolveModelData( + assets: PreparedAssets, + model: ModelReference | string + ): Promise + + export function loadModel( + scene: THREE.Scene | null, + assets: PreparedAssets, + model: ModelReference, + args?: { + display?: DisplayTransform + lighting?: 'item' | 'world' | 'scene' | 'off' + version?: string + animate?: boolean + cull?: Set | Record + } + ): Promise + + export function makeModelScene(): Promise<{ + scene: THREE.Scene + camera: THREE.Camera + }> + + export function isCrossModel(models: ModelReference | ModelReference[]): boolean +} + /** * Import this folder's contents recursively. * If a local index is found in a folder, it is imported and the rest of that folder is ignored. diff --git a/src/systems/animationRenderer.ts b/src/systems/animationRenderer.ts index 3fb2ba39..b67c48fc 100644 --- a/src/systems/animationRenderer.ts +++ b/src/systems/animationRenderer.ts @@ -60,7 +60,7 @@ function threeAxisRotationToTwoAxisRotation(rot: THREE.Quaternion): ArrayVector2 export interface INodeTransform { matrix: THREE.Matrix4 - decomposed: { + decomposed?: { translation: THREE.Vector3 left_rotation: THREE.Quaternion scale: THREE.Vector3 @@ -238,7 +238,9 @@ export function getFrame( const rot = new THREE.Quaternion() const scale = new THREE.Vector3() transform.matrix.decompose(pos, rot, scale) - transform.decomposed = getDecomposedTransformation(transform.matrix) + if (Project.animated_java.enable_plugin_mode) { + transform.decomposed = getDecomposedTransformation(transform.matrix) + } if (node.type === 'locator' || node.type === 'camera' || node.type === 'interaction') { node.max_distance = Math.max(node.max_distance, pos.length()) diff --git a/src/systems/exporter.ts b/src/systems/exporter.ts index 57bc39fb..60c23da7 100644 --- a/src/systems/exporter.ts +++ b/src/systems/exporter.ts @@ -4,7 +4,7 @@ import { openExportProgressDialog, } from '../dialogs/exportProgress/exportProgress' import { openUnexpectedErrorDialog } from '../dialogs/unexpectedError/unexpectedError' -import { projectTargetVersionIsAtLeast, saveBlueprint } from '../formats/blueprint' +import { projectTargetVersionIsAtLeast } from '../formats/blueprint' import { validateThisProjectsBlueprintSettings } from '../formats/blueprint/settings' import { resolvePath } from '../util/fileUtil' import { localize as translate } from '../util/lang' @@ -58,12 +58,10 @@ export function getExportPaths() { } interface ExportProjectOptions { - forceSave?: boolean debugMode?: boolean } async function actuallyExportProject({ - forceSave = true, debugMode = false, }: ExportProjectOptions = {}): Promise { const aj = Project!.animated_java @@ -160,7 +158,6 @@ async function actuallyExportProject({ Project!.last_used_blueprint_id = aj.blueprint_id - if (forceSave) saveBlueprint() Blockbench.showQuickMessage('Project exported successfully!', 2000) return true diff --git a/src/systems/minecraft/assetManager.ts b/src/systems/minecraft/assetManager.ts index 7e0925cc..fcd9efe7 100644 --- a/src/systems/minecraft/assetManager.ts +++ b/src/systems/minecraft/assetManager.ts @@ -1,7 +1,6 @@ import type { Unzipped } from 'fflate' import ky from 'ky' import { dirname, join } from 'node:path' -import index from '../../assets/vanillaAssetOverrides/index.json' import { getFsModule } from '../../constants' import { unzip } from '../util' import { getVersionById, getVersionDownloadUrl } from './versionManager' @@ -12,8 +11,6 @@ const ASSETS_CACHE = new Map() const FOLDER_CACHE = new Map>() const ACTIVE_DOWNLOAD_PROMISES = new Map>() -const ASSET_OVERRIDES = index as unknown as Record - async function downloadFile(url: string, savePath: string) { const response = await ky(url, { method: 'GET', @@ -76,6 +73,29 @@ export async function getAssets(versionId: string) { return loadedAssets } +/** A `block-model-renderer` virtual asset handler over a version's client jar. */ +export const getAssetHandler = async (versionId: string) => { + const assets = await getAssets(versionId) + const paths = Object.keys(assets) + return { + read(filePath: string): Uint8Array | null { + return assets[filePath] ?? null + }, + list(dir: string): string[] { + const prefix = dir.endsWith('/') ? dir : dir + '/' + const children = new Set() + for (const path of paths) { + if (!path.startsWith(prefix)) continue + const rest = path.slice(prefix.length) + const slash = rest.indexOf('/') + children.add(slash === -1 ? rest : rest.slice(0, slash)) + } + return [...children] + }, + filter: [] as unknown[], + } +} + export async function hasAsset(versionId: string, assetPath: string) { const assets = await getAssets(versionId) return assetPath in assets @@ -84,10 +104,6 @@ export async function hasAsset(versionId: string, assetPath: string) { export async function getRawAsset(versionId: string, assetPath: string) { const assets = await getAssets(versionId) - if (ASSET_OVERRIDES[assetPath]) { - return Buffer.from(ASSET_OVERRIDES[assetPath]) - } - const asset = assets[assetPath] if (!asset) { @@ -125,11 +141,7 @@ export async function getFolder(versionId: string, folderPath: string) { const folderAssets: Record = {} for (const assetPath in assets) { if (assetPath.startsWith(folderPath)) { - if (ASSET_OVERRIDES[assetPath]) { - folderAssets[assetPath] = Buffer.from(ASSET_OVERRIDES[assetPath]) - } else { - folderAssets[assetPath] = Buffer.from(assets[assetPath]) - } + folderAssets[assetPath] = Buffer.from(assets[assetPath]) } } diff --git a/src/systems/minecraft/blockModelManager.ts b/src/systems/minecraft/blockModelManager.ts index 6ecebf09..54335dd9 100644 --- a/src/systems/minecraft/blockModelManager.ts +++ b/src/systems/minecraft/blockModelManager.ts @@ -1,417 +1,85 @@ -import { type ItemDisplayMode } from '../../outliner/vanillaItemDisplay' -import { mergeGeometries } from '../../util/bufferGeometryUtils' -import { localize as translate } from '../../util/lang' +import { type IParsedBlock, parseBlock } from '../../util/minecraftUtil' import { - type IParsedBlock, - getPathFromResourceLocation, - parseBlock, - resolveBlockstateValueType, -} from '../../util/minecraftUtil' -import { getJSONAsset, getPngAsset, hasAsset } from './assetManager' -import type { BlockStateValue } from './blockstateManager' -import { applyModelDisplayTransform } from './itemModelManager' -import type { - IBlockModel, - IBlockState, - IBlockStateMultipartCase, - IBlockStateMultipartCaseCondition, - IBlockStateVariant, -} from './model' -import { TEXTURE_FRAG_SHADER, TEXTURE_VERT_SHADER } from './textureShaders' + bmr, + cloneRenderedModel, + convertBmrGroup, + ensureConfigured, + getPreparedAssets, +} from './bmrModelRenderer' export interface BlockModelMesh { - mesh: THREE.Mesh + mesh: THREE.Object3D outline: THREE.LineSegments boundingBox: THREE.BufferGeometry isBlock: true } -const LOADER = new THREE.TextureLoader() const BLOCK_MODEL_CACHE = new Map() - -const BLACKLISTED_BLOCKS = new Map([ - ['water', translate('block_model_manager.fluid_warning')], - ['lava', translate('block_model_manager.fluid_warning')], - - ['player_head', translate('block_model_manager.mob_head_warning')], - ['player_wall_head', translate('block_model_manager.mob_head_warning')], - ['skeleton_skull', translate('block_model_manager.mob_head_warning')], - ['skeleton_wall_skull', translate('block_model_manager.mob_head_warning')], - ['wither_skeleton_skull', translate('block_model_manager.mob_head_warning')], - ['wither_skeleton_wall_skull', translate('block_model_manager.mob_head_warning')], - ['creeper_head', translate('block_model_manager.mob_head_warning')], - ['creeper_wall_head', translate('block_model_manager.mob_head_warning')], - ['zombie_head', translate('block_model_manager.mob_head_warning')], - ['zombie_wall_head', translate('block_model_manager.mob_head_warning')], - ['dragon_head', translate('block_model_manager.mob_head_warning')], - ['dragon_wall_head', translate('block_model_manager.mob_head_warning')], - ['piglin_head', translate('block_model_manager.mob_head_warning')], - ['piglin_wall_head', translate('block_model_manager.mob_head_warning')], -]) +const BLOCK_MODEL_PENDING = new Map>() export async function getBlockModel( block: string, minecraftVersion = Project.animated_java.target_minecraft_version ): Promise { - const key = minecraftVersion + '|' + block - let result = BLOCK_MODEL_CACHE.get(key) - if (!result) { + const cacheKey = `${minecraftVersion}|${block}` + + let template = BLOCK_MODEL_CACHE.get(cacheKey) + if (!template) { const parsed = await parseBlock(block) if (!parsed) return undefined - if (BLACKLISTED_BLOCKS.has(block)) { - throw new Error(BLACKLISTED_BLOCKS.get(block)) - } - result = await parseBlockState(parsed) - BLOCK_MODEL_CACHE.set(key, result) - } - if (!result) return undefined - result = { - mesh: result.mesh.clone(true), - outline: result.outline.clone(true), - boundingBox: result.boundingBox.clone(), - isBlock: true, - } - for (const child of result.mesh.children as THREE.Mesh[]) { - child.geometry = child.geometry.clone() - } - result.mesh.geometry = result.mesh.geometry.clone() - result.mesh.name = block - result.mesh.isVanillaBlockModel = true - return result -} - -export async function parseBlockModel( - variant: IBlockStateVariant, - childModel?: IBlockModel, - itemDisplay: ItemDisplayMode = 'none' -): Promise { - const modelPath = getPathFromResourceLocation(variant.model, 'models') - const model = (await getJSONAsset( - Project.animated_java.target_minecraft_version, - modelPath + '.json' - )) as IBlockModel - if (childModel) { - if (childModel.textures !== undefined) { - model.textures ??= {} - Object.assign(model.textures, childModel.textures) + let pending = BLOCK_MODEL_PENDING.get(cacheKey) + if (!pending) { + pending = buildBlockModel(parsed, minecraftVersion) + BLOCK_MODEL_PENDING.set(cacheKey, pending) + void pending.catch(() => undefined).finally(() => BLOCK_MODEL_PENDING.delete(cacheKey)) } - // Interesting that elements aren't merged in vanilla... - if (childModel.elements !== undefined) model.elements = childModel.elements - if (childModel.display !== undefined) - model.display = Object.assign(model.display ?? {}, childModel.display) - if (childModel.ambientocclusion !== undefined) - model.ambientocclusion = childModel.ambientocclusion + template = await pending + BLOCK_MODEL_CACHE.set(cacheKey, template) } - if (model.parent) { - const parentVariant = { ...variant, model: model.parent } - return await parseBlockModel(parentVariant, model, itemDisplay) - } - - const mesh = await generateModelMesh(variant, model) - applyModelDisplayTransform(mesh, model, itemDisplay) - return mesh + return cloneRenderedModel(template, block) as BlockModelMesh } -async function generateModelMesh( - variant: IBlockStateVariant, - model: IBlockModel +async function buildBlockModel( + block: IParsedBlock, + minecraftVersion: string ): Promise { - console.log( - `Generating block mesh for '${variant.model}':`, - '\n - Variant', - variant, - '\n - Model', - model - ) - - if (!model.elements) { - throw new Error(`No elements defined in block model '${variant.model}'`) - } - if (!model.textures) { - throw new Error(`No textures defined in block model '${variant.model}'`) - } - - const mesh: THREE.Mesh = new THREE.Mesh() - const boundingBoxes: THREE.BufferGeometry[] = [] - const outlineGeos: THREE.BufferGeometry[] = [] - - for (const element of model.elements) { - const size: ArrayVector3 = [ - element.to[0] - element.from[0], - element.to[1] - element.from[1], - element.to[2] - element.from[2], - ] - const position: ArrayVector3 = [ - element.from[0] + (element.to[0] - element.from[0]) / 2, - element.from[1] + (element.to[1] - element.from[1]) / 2, - element.from[2] + (element.to[2] - element.from[2]) / 2, - ] - if (size[0] === 0) { - size[0] += 0.01 - position[0] -= 0.005 - } - if (size[1] === 0) { - size[1] += 0.01 - position[1] -= 0.005 - } - if (size[2] === 0) { - size[2] += 0.01 - position[2] -= 0.005 - } - - const geometry = new THREE.BoxGeometry(...size) - geometry.translate(...position) - - if (element.rotation) { - let factor: number | undefined - if (element.rotation.rescale) { - factor = getRescalingFactor(element.rotation.angle) - } - - const origin = element.rotation.origin - if (origin) { - geometry.translate(...(origin.map(v => -v) as ArrayVector3)) - } - - switch (element.rotation.axis) { - case 'x': - geometry.rotateX(Math.degToRad(element.rotation.angle)) - if (factor !== undefined) geometry.scale(1, factor, factor) - break - case 'y': - geometry.rotateY(Math.degToRad(element.rotation.angle)) - if (factor !== undefined) geometry.scale(factor, 1, factor) - break - case 'z': - geometry.rotateZ(Math.degToRad(element.rotation.angle)) - if (factor !== undefined) geometry.scale(factor, factor, 1) - break - } - - if (origin) { - geometry.translate(...origin) - } - } - - geometry.translate(-8, -8, -8) - geometry.rotateY(Math.degToRad(180)) // Blockbench's rotation is mirrored compared to MC - if (variant.x) geometry.rotateX(Math.degToRad(variant.x)) - if (variant.y) geometry.rotateY(-Math.degToRad(variant.y)) - geometry.rotateY(Math.degToRad(-180)) // Rotate back after mirroring - if (!variant.isItemModel) { - geometry.translate(8, 8, 8) - } - - const indices = [] - for (let i = 0; i < 6; i++) { - indices.push(0 + i * 4, 2 + i * 4, 1 + i * 4, 2 + i * 4, 3 + i * 4, 1 + i * 4) - geometry.addGroup(i * 6, 6, i) - } - geometry.setIndex(indices) - geometry.setAttribute( - 'highlight', - new THREE.BufferAttribute(new Uint8Array(geometry.attributes.position.count), 1) - ) - - if (!element.faces) { - throw new Error(`No faces defined in element for block model '${variant.model}'`) - } - - const uvs: number[] = [] - const materials: THREE.Material[] = [] - for (const faceKey of Canvas.face_order) { - const face = element.faces[faceKey] - if (!face) { - materials.push(Canvas.transparentMaterial) - uvs.push(0, 0, 0, 0, 0, 0, 0, 0) - continue - } - const texture = (await loadTexture(model.textures, face.texture)).clone() - const material = new THREE.ShaderMaterial({ - uniforms: { - map: new THREE.Uniform(texture), - // @ts-expect-error Uniforms types are wrong - SHADE: { type: 'bool', value: settings.shading.value }, - LIGHTCOLOR: { - // @ts-expect-error Uniforms types are wrong - type: 'vec3', - value: new THREE.Color() - .copy(Canvas.global_light_color) - .multiplyScalar((settings.brightness.value as number) / 50), - }, - // @ts-expect-error Uniforms types are wrong - LIGHTSIDE: { type: 'int', value: Canvas.global_light_side }, - // @ts-expect-error Uniforms types are wrong - EMISSIVE: { type: 'bool', value: false }, - }, - vertexShader: TEXTURE_VERT_SHADER, - fragmentShader: TEXTURE_FRAG_SHADER, - blending: THREE.NormalBlending, - side: Canvas.getRenderSide(), - transparent: true, - }) - // @ts-expect-error Uniforms types are wrong - material.map = texture - material.name = variant.model - materials.push(material) - - // UVs are always based on 16x16 texture width, not the actual texture size - const tw = 16 - const th = 16 - // const tw = texture.image.width - // const th = texture.image.height - if (face.uv) { - const [x, y, w, h] = face.uv - // The THREE face UV has a strange order. - // upper-left, upper-right, lower-left, lower-right - // The MC input UV is only upper-left, and lower-right coords. - // prettier-ignore - const uv = [ - [x / tw, y / th], - [w / tw, y / th], - [x / tw, h / th], - [w / tw, h / th], - ] - if (face.rotation) { - let rot = face.rotation + 0 - while (rot > 0) { - const a = uv[0] - uv[0] = uv[2] - uv[2] = uv[3] - uv[3] = uv[1] - uv[1] = a - rot -= 90 - } - } - texture.flipY = false - - uvs.push(...uv.flat()) - } else { - // Create uvs based on the element's position and size - const [x, y, z] = element.from - const [w, h, d] = size - switch (faceKey) { - // Up and down faces are flipped on both axes - case 'down': - // prettier-ignore - uvs.push( - x / tw, z / th, - (x + w) / tw, z / th, - x / tw, (z + d) / th, - (x + w) / tw, (z + d) / th, - ) - break - case 'up': - // prettier-ignore - uvs.push( - x / tw, z / th, - (x + w) / tw, z / th, - x / tw, (z + d) / th, - (x + w) / tw, (z + d) / th, - ) - break - case 'north': - // prettier-ignore - uvs.push( - (x + w) / tw, (y + h) / th, - x / tw, (y + h) / th, - (x + w) / tw, y / th, - x / tw, y / th, - ) - break - case 'south': - // prettier-ignore - uvs.push( - (x + w) / tw, (y + h) / th, - x / tw, (y + h) / th, - (x + w) / tw, y / th, - x / tw, y / th, - ) - break - case 'west': - // prettier-ignore - uvs.push( - (z + d) / tw, (y + h) / th, - z / tw, (y + h) / th, - (z + d) / tw, y / th, - z / tw, y / th, - ) - break - case 'east': - // prettier-ignore - uvs.push( - (z + d) / tw, (y + h) / th, - z / tw, (y + h) / th, - (z + d) / tw, y / th, - z / tw, y / th, - ) - break - } - } - texture.needsUpdate = true - } - - geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2)) - geometry.attributes.uv.needsUpdate = true - - boundingBoxes.push(geometry.clone()) - const outlineGeo = new THREE.EdgesGeometry(geometry) - outlineGeos.push(outlineGeo) - const elementMesh = new THREE.Mesh(geometry, materials) - mesh.add(elementMesh) - } - - const outlineGeo = mergeGeometries(outlineGeos)! - const outline = new THREE.LineSegments(outlineGeo, Canvas.outlineMaterial) - const boundingBox = mergeGeometries(boundingBoxes)! - - outline.no_export = true - outline.renderOrder = 2 - outline.frustumCulled = false - - return { mesh, outline, boundingBox, isBlock: true } -} - -const TEXTURE_CACHE = new Map() -async function loadTexture(textures: IBlockModel['textures'], key: string): Promise { - if (key.at(0) === '#') key = key.slice(1) - const resourceLocation = textures[key] - if (resourceLocation?.at(0) === '#') { - return await loadTexture(textures, resourceLocation.slice(1)) - } - const texturePath = getPathFromResourceLocation(resourceLocation, 'textures') + '.png' - if (TEXTURE_CACHE.has(texturePath)) { - return TEXTURE_CACHE.get(texturePath)! - } - let texture: THREE.Texture - if (await hasAsset(Project.animated_java.target_minecraft_version, texturePath + '.mcmeta')) { - const img = new Image() - img.src = await getPngAsset(Project.animated_java.target_minecraft_version, texturePath) - const canvas = document.createElement('canvas') - const ctx = canvas.getContext('2d')! - await new Promise(resolve => { - img.onload = () => { - canvas.width = img.width - canvas.height = img.width - ctx.drawImage(img, 0, 0) - resolve() - } + ensureConfigured() + const assets = await getPreparedAssets(minecraftVersion) + + const data: Record = {} + for (const [key, value] of Object.entries(block.states)) { + data[key] = String(value) + } + + const models = await bmr.parseBlockstate(assets, block.resourceLocation, { + data, + version: minecraftVersion, + }) + if (!models.length) { + throw new Error(`The selected block state for '${block.resourceLocation}' has no model!`) + } + + const root = new THREE.Group() + for (const model of models) { + const resolved = await bmr.resolveModelData(assets, model) + // Skip vanilla's empty block-entity stubs; bmr's overlay carries the geometry. + const elements = (resolved as { elements?: unknown[] }).elements + if ((!elements || elements.length === 0) && !(resolved as { fluid?: unknown }).fluid) { + continue + } + const group = await bmr.loadModel(null, assets, resolved, { + lighting: 'world', + version: minecraftVersion, + animate: false, // the auto-animator can't survive the per-element clone }) - texture = new THREE.CanvasTexture(canvas) - } else { - texture = await LOADER.loadAsync( - await getPngAsset(Project.animated_java.target_minecraft_version, texturePath) - ) + root.add(group) } - texture.magFilter = THREE.NearestFilter - texture.minFilter = THREE.NearestFilter - - TEXTURE_CACHE.set(texturePath, texture) - - return texture + // Block displays pivot at the block's (0,0,0) corner in game. + const converted = convertBmrGroup(root, { pivot: 'corner', isBlock: true }) + return { ...converted, isBlock: true } } export function validateBlockState(block: IParsedBlock) { @@ -438,184 +106,3 @@ export function validateBlockState(block: IParsedBlock) { } return '' } - -export async function parseBlockState(block: IParsedBlock): Promise { - const path = getPathFromResourceLocation(block.resourceLocation, 'blockstates') - const blockstate = (await getJSONAsset( - Project.animated_java.target_minecraft_version, - path + '.json' - )) as IBlockState - if (!block.blockStateRegistryEntry) { - throw new Error(`Block state registry entry not found for '${block.resource.name}'`) - } - // Make sure the block has all the default states - block.states = Object.assign({}, block.blockStateRegistryEntry.defaultStates, block.states) - console.log( - 'Block states for', - block.resourceLocation, - '\n - States', - block.states, - '\n - Registry entry', - block.blockStateRegistryEntry - ) - - for (const [k, v] of Object.entries(block.states)) { - if (!block.blockStateRegistryEntry.stateValues[k]) { - throw new Error( - `Invalid block state '${k}' for '${block.resource.name}'` + - ` Expected one of: ${Object.keys( - block.blockStateRegistryEntry.stateValues - ).join(', ')}` - ) - } else if (!block.blockStateRegistryEntry.stateValues[k].includes(v)) { - throw new Error( - `Invalid block state value '${v.toString()}' for '${k}'.` + - ` Expected one of: ${block.blockStateRegistryEntry.stateValues[k].join(', ')}` - ) - } - } - - if (blockstate.variants) { - const singleVariant = blockstate.variants[''] - if (singleVariant) { - if (Array.isArray(singleVariant)) { - console.warn( - `Multiple weighted variants found for '${block.resourceLocation}' default variant. Using the first one.` - ) - return await parseBlockModel(singleVariant[0]) - } else { - return await parseBlockModel(singleVariant) - } - } - - for (const [name, variant] of Object.entries(blockstate.variants)) { - const variantStates: Record> = {} - const args = name.split(',') - for (const arg of args) { - const [key, value] = arg.trim().split('=') - const parsedValue = resolveBlockstateValueType(value, false) - variantStates[key] = parsedValue - } - - const matchesState = Object.entries(variantStates).allAre(([k, v]) => - checkIfBlockStateMatches(block, k, v, false) - ) - - if (!matchesState) { - continue - } - - let model: BlockModelMesh - if (Array.isArray(variant)) { - console.warn( - `Multiple weighted variants found for '${block.resourceLocation}' variant '${name}'. Using the first one.` - ) - model = await parseBlockModel(variant[0]) - } else { - model = await parseBlockModel(variant) - } - return model - } - } else if (blockstate.multipart) { - // throw new Error(`Multipart block states are not supported yet`) - const mesh = new THREE.Mesh() - const boundingBoxes: THREE.BufferGeometry[] = [] - const outlines: THREE.BufferGeometry[] = [] - for (const c of blockstate.multipart) { - const result = await parseMultipartCase(block, c) - if (!result) continue - for (const child of result.mesh.children as THREE.Mesh[]) { - const newChild = child.clone() - newChild.geometry = newChild.geometry.clone() - newChild.rotateY(result.mesh.rotation.y) - newChild.rotateX(result.mesh.rotation.x) - mesh.add(newChild) - const boundingBox = result.boundingBox.clone() - boundingBox.rotateY(result.mesh.rotation.y) - boundingBox.rotateX(result.mesh.rotation.x) - boundingBoxes.push(boundingBox) - } - const outlineGeo = result.outline.geometry.clone() - outlineGeo.rotateY(result.mesh.rotation.y) - outlineGeo.rotateX(result.mesh.rotation.x) - outlines.push(outlineGeo) - } - - if (outlines.length === 0) { - throw new Error( - `The selected block state for '${block.resourceLocation}' has no model!` - ) - } - - const outlineGeo = mergeGeometries(outlines)! - const outline = new THREE.LineSegments(outlineGeo, Canvas.outlineMaterial) - const boundingBox = mergeGeometries(boundingBoxes)! - - outline.no_export = true - outline.renderOrder = 2 - outline.frustumCulled = false - - return { mesh, outline, boundingBox, isBlock: true } - } - - throw new Error(`Unsupported block state '${block.resourceLocation}'`) -} - -async function parseMultipartCase( - block: IParsedBlock, - mpCase: IBlockStateMultipartCase -): Promise { - if (mpCase.when) { - const recurse = (c: IBlockStateMultipartCaseCondition): boolean => { - if (c.OR && c.AND) { - throw new Error(`Cannot have both OR and AND in a multipart case condition`) - } else if (c.OR) { - return c.OR.some(v => recurse(v)) - } else if (c.AND) { - return c.AND.every(v => recurse(v)) - } - - let matchesState = true - for (const [k, v] of Object.entries(c) as Array<[string, string]>) { - const parsedValue = resolveBlockstateValueType(v, true) - matchesState = checkIfBlockStateMatches(block, k, parsedValue, true) - if (!matchesState) break - } - return matchesState - } - const result = recurse(mpCase.when) - if (!result) return - } - if (Array.isArray(mpCase.apply)) { - return await parseBlockModel(mpCase.apply[0]) - } else { - return await parseBlockModel(mpCase.apply) - } -} - -function checkIfBlockStateMatches( - block: IParsedBlock, - key: string, - value: BlockStateValue, - allowArray: boolean -) { - if (typeof value === 'string' && value.includes('|')) { - if (!allowArray) - throw new Error(`Unsupported OR condition in block state '${key}': '${value}'`) - value = value.split('|') - } - - if (typeof value === 'boolean') { - return block.states[key] === value - } else if (typeof value === 'string') { - return block.states[key] === value - } else if (typeof value === 'number') { - return value === 0 - ? block.states[key] === value || block.states[key] === undefined - : block.states[key] === value - } else if (allowArray) { - return value.includes(block.states[key] as string | number | boolean) - } else { - throw new Error(`Unsupported variant state type '${typeof value}'`) - } -} diff --git a/src/systems/minecraft/bmrModelRenderer.ts b/src/systems/minecraft/bmrModelRenderer.ts new file mode 100644 index 00000000..e040f0a5 --- /dev/null +++ b/src/systems/minecraft/bmrModelRenderer.ts @@ -0,0 +1,125 @@ +import * as bmr from 'block-model-renderer' +import ASSETS_ZIP_URL from 'block-model-renderer/assets.zip' +import { mergeGeometries } from '../../util/bufferGeometryUtils' +import { getAssetHandler } from './assetManager' + +/** The editor-preview mesh for a vanilla item or block model. */ +export interface RenderedModelMesh { + mesh: THREE.Object3D + outline: THREE.LineSegments + boundingBox: THREE.BufferGeometry + isBlock?: boolean +} + +let configured = false +/** Point `block-model-renderer` at Blockbench's `THREE` and the inlined asset pack. */ +export function ensureConfigured() { + if (configured) return + bmr.configure({ THREE, assetsUrl: ASSETS_ZIP_URL }) + configured = true +} + +type PreparedAssets = Awaited> + +const PREPARED_ASSETS_CACHE = new Map>() + +/** A cached bmr asset bundle over the client jar for the given version. */ +export async function getPreparedAssets(versionId: string): Promise { + let prepared = PREPARED_ASSETS_CACHE.get(versionId) + if (!prepared) { + prepared = (async () => { + const handler = await getAssetHandler(versionId) + // `version` must be pinned here: the { cache: true } cache isn't version-aware. + return bmr.prepareAssets([handler], { cache: true, version: versionId }) + })() + PREPARED_ASSETS_CACHE.set(versionId, prepared) + } + return prepared +} + +function toPositionOnlyWorldGeometry( + geometry: THREE.BufferGeometry, + matrixWorld: THREE.Matrix4 +): THREE.BufferGeometry { + const source = geometry.index ? geometry.toNonIndexed() : geometry + const out = new THREE.BufferGeometry() + out.setAttribute('position', (source.getAttribute('position') as THREE.BufferAttribute).clone()) + out.applyMatrix4(matrixWorld) + return out +} + +/** + * Converts a bmr model group into the outliner's expected structure. bmr builds + * in Minecraft space (origin-centered, 16u/block); Blockbench's is that rotated + * 180° around Y. `pivot` picks the block (corner) or item (center) origin. + */ +export function convertBmrGroup( + root: THREE.Object3D, + options: { pivot: 'center' | 'corner'; isBlock?: boolean } +): RenderedModelMesh { + const wrapper = new THREE.Group() + wrapper.rotation.y = Math.PI + if (options.pivot === 'corner') wrapper.position.set(8, 8, 8) + wrapper.add(root) + wrapper.updateMatrixWorld(true) + + const edgeGeometries: THREE.BufferGeometry[] = [] + const boxGeometries: THREE.BufferGeometry[] = [] + + wrapper.traverse(object => { + const mesh = object as THREE.Mesh + if (!mesh.isMesh || !mesh.geometry) return + + // The enchantment glint overlay reads `material.map`; bmr keeps it on a uniform. + const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material] + for (const mat of materials as Array) { + if (mat && !mat.map && mat.uniforms?.map?.value) { + mat.map = mat.uniforms.map.value as THREE.Texture + } + } + + const worldGeometry = toPositionOnlyWorldGeometry(mesh.geometry, mesh.matrixWorld) + boxGeometries.push(worldGeometry) + edgeGeometries.push(new THREE.EdgesGeometry(worldGeometry)) + }) + + const boundingBox = boxGeometries.length + ? mergeGeometries(boxGeometries)! + : new THREE.BufferGeometry() + + const outlineGeometry = edgeGeometries.length + ? mergeGeometries(edgeGeometries)! + : new THREE.BufferGeometry() + const outline = new THREE.LineSegments(outlineGeometry, Canvas.outlineMaterial) + outline.no_export = true + outline.renderOrder = 2 + outline.frustumCulled = false + + return { + mesh: wrapper, + outline, + boundingBox, + isBlock: options.isBlock ? true : undefined, + } +} + +/** A per-element copy of a cached template; geometry and materials are shared. */ +export function cloneRenderedModel(template: RenderedModelMesh, name: string): RenderedModelMesh { + const mesh = template.mesh.clone(true) + mesh.name = name + + const flag = template.isBlock ? 'isVanillaBlockModel' : 'isVanillaItemModel' + mesh[flag] = true + mesh.traverse(object => { + if ((object as THREE.Mesh).isMesh) object[flag] = true + }) + + return { + mesh, + outline: template.outline.clone(), + boundingBox: template.boundingBox.clone(), + isBlock: template.isBlock, + } +} + +export { bmr } diff --git a/src/systems/minecraft/itemModelManager.ts b/src/systems/minecraft/itemModelManager.ts index 3c6e4167..2344fd0b 100644 --- a/src/systems/minecraft/itemModelManager.ts +++ b/src/systems/minecraft/itemModelManager.ts @@ -1,397 +1,76 @@ import { type ItemDisplayMode } from '../../outliner/vanillaItemDisplay' -import { mergeGeometries } from '../../util/bufferGeometryUtils' -import { getPathFromResourceLocation, parseResourceLocation } from '../../util/minecraftUtil' -import { getJSONAsset, getPngAsset } from './assetManager' -import { parseBlockModel } from './blockModelManager' -import type { IItemModel } from './model' -import { TEXTURE_FRAG_SHADER, TEXTURE_VERT_SHADER } from './textureShaders' - -interface ItemMesh { - mesh: THREE.Mesh - outline: THREE.LineSegments - boundingBox: THREE.BufferGeometry - isBlock?: boolean -} - -const LOADER = new THREE.TextureLoader() -const ITEM_MODEL_CACHE = new Map() +import { + bmr, + cloneRenderedModel, + convertBmrGroup, + ensureConfigured, + getPreparedAssets, + type RenderedModelMesh, +} from './bmrModelRenderer' + +const ITEM_MODEL_CACHE = new Map() +const ITEM_MODEL_PENDING = new Map>() export async function getItemModel( item: string, itemDisplay: ItemDisplayMode, minecraftVersion = Project.animated_java.target_minecraft_version -): Promise { - const cacheKey = minecraftVersion + '|' + item + '|' + itemDisplay - let result = ITEM_MODEL_CACHE.get(cacheKey) - if (!result) { - result = await parseItemModel(getItemResourceLocation(item), itemDisplay) - ITEM_MODEL_CACHE.set(cacheKey, result) - } - if (!result) { - console.warn(`Failed to load item model for ${item} with display mode ${itemDisplay}`) - return undefined - } - result = { - mesh: result.mesh.clone(true), - outline: result.outline.clone(true), - boundingBox: result.boundingBox.clone(), - isBlock: result.isBlock, - } - - result.mesh.geometry = result.mesh.geometry.clone() - result.outline.geometry = result.outline.geometry.clone() - result.mesh.name = item - if (result.isBlock) { - result.mesh.isVanillaBlockModel = true - } else { - result.mesh.isVanillaItemModel = true - } - - return result -} - -function getItemResourceLocation(item: string) { - const resource = parseResourceLocation(item) - return resource.namespace + ':' + 'item/' + resource.path -} - -const GENERATED_ITEM_DISPLAY_SETTINGS: NonNullable = { - thirdperson_righthand: { translation: [0, 3, 1], scale: [0.55, 0.55, 0.55] }, - thirdperson_lefthand: { translation: [0, 3, 1], scale: [0.55, 0.55, 0.55] }, - firstperson_righthand: { - rotation: [0, -90, 25], - translation: [1.13, 3.2, 1.13], - scale: [0.68, 0.68, 0.68], - }, - firstperson_lefthand: { - rotation: [0, -90, 25], - translation: [1.13, 3.2, 1.13], - scale: [0.68, 0.68, 0.68], - }, - ground: { translation: [0, 2, 0], scale: [0.5, 0.5, 0.5] }, - head: { rotation: [0, -180, 0], translation: [0, 13, 7] }, - fixed: { rotation: [0, -180, 0] }, -} - -export function applyModelDisplayTransform( - itemModel: ItemMesh, - model: IItemModel, - itemDisplay: ItemDisplayMode -) { - if (itemDisplay === 'none' || !model.display) return - - // default to right hand if left hand display is not defined - if (!model.display.thirdperson_lefthand && model.display.thirdperson_righthand) { - model.display.thirdperson_lefthand = structuredClone(model.display.thirdperson_righthand) - } - if (!model.display.firstperson_lefthand && model.display.firstperson_righthand) { - model.display.firstperson_lefthand = structuredClone(model.display.thirdperson_righthand) - } - - const display = model.display[itemDisplay] - if (!display) return - - const matrix = new THREE.Matrix4() - if (display.rotation) { - const rot = display.rotation.map((n: number) => (n * Math.PI) / 180) - matrix.makeRotationFromEuler(Reusable.euler1.set(-rot[0], -rot[1], rot[2])) - } - if (display.scale) { - matrix.scale(Reusable.vec2.set(...display.scale)) - } - if (display.translation) { - matrix.setPosition( - Reusable.vec1.set( - display.translation[0], - display.translation[1], - -display.translation[2] - ) - ) +): Promise { + const cacheKey = `${minecraftVersion}|${item}|${itemDisplay}` + + let template = ITEM_MODEL_CACHE.get(cacheKey) + if (!template) { + let pending = ITEM_MODEL_PENDING.get(cacheKey) + if (!pending) { + pending = buildItemModel(item, itemDisplay, minecraftVersion) + ITEM_MODEL_PENDING.set(cacheKey, pending) + void pending.catch(() => undefined).finally(() => ITEM_MODEL_PENDING.delete(cacheKey)) + } + template = await pending + ITEM_MODEL_CACHE.set(cacheKey, template) } - itemModel.boundingBox.applyMatrix4(matrix) - itemModel.outline.geometry.applyMatrix4(matrix) - itemModel.mesh.applyMatrix4(matrix) + return cloneRenderedModel(template, item) } -async function parseItemModel( - location: string, +async function buildItemModel( + item: string, itemDisplay: ItemDisplayMode, - childModel?: IItemModel -): Promise { - const modelPath = getPathFromResourceLocation(location, 'models') - let model: IItemModel - try { - model = await getJSONAsset( - Project.animated_java.target_minecraft_version, - modelPath + '.json' - ) - } catch { - // Fallback to block model if item model doesn't exist - model = await getJSONAsset( - Project.animated_java.target_minecraft_version, - modelPath.replace('item/', 'block/') + '.json' - ) + minecraftVersion: string +): Promise { + ensureConfigured() + const assets = await getPreparedAssets(minecraftVersion) + + const displayContext = itemDisplay === 'none' ? undefined : itemDisplay + const models = await bmr.parseItemDefinition(assets, item, { + version: minecraftVersion, + display: displayContext, + }) + if (!models.length) { + throw new Error(`No model found for item '${item}'.`) } - if (childModel) { - // if (childModel.ambientocclusion !== undefined) - // model.ambientocclusion = childModel.ambientocclusion - if (childModel.textures !== undefined) { - model.textures ??= {} - Object.assign(model.textures, childModel.textures) - } - // Interesting that elements aren't merged in vanilla... - if (childModel.elements !== undefined) model.elements = childModel.elements - if (childModel.display !== undefined) - Object.assign(model.display as any, childModel.display) - if (childModel.gui_light !== undefined) model.gui_light = childModel.gui_light - if (childModel.overrides !== undefined) model.overrides = childModel.overrides - } - - if (model.parent) { - const resource = parseResourceLocation(model.parent) - if (resource.type === 'block') { - return await parseBlockModel( - { model: model.parent, isItemModel: true }, - model, - itemDisplay - ) - } else if (resource.path === 'item/generated') { - const itemMesh = await generateItemMesh(location, model) - model.display ??= GENERATED_ITEM_DISPLAY_SETTINGS - applyModelDisplayTransform(itemMesh, model, itemDisplay) - return itemMesh - } else { - return await parseItemModel(model.parent, itemDisplay, model) - } - } else { - // The block model parser handles custom item models made from elements just fine, so we can use it here - return await parseBlockModel({ model: location, isItemModel: true }, model, itemDisplay) - } -} - -async function generateItemMesh(location: string, model: IItemModel): Promise { - const masterMesh = new THREE.Mesh() - const boundingBoxes: THREE.BufferGeometry[] = [] - const outlineGeos: THREE.BufferGeometry[] = [] - - for (const textureResourceLoc of Object.values(model.textures)) { - const texturePath = getPathFromResourceLocation(textureResourceLoc, 'textures') + '.png' - const textureUrl = await getPngAsset( - Project.animated_java.target_minecraft_version, - texturePath - ) - const texture = await LOADER.loadAsync(textureUrl) - texture.magFilter = THREE.NearestFilter - texture.minFilter = THREE.NearestFilter - - const mat = new THREE.ShaderMaterial({ - uniforms: { - // @ts-expect-error Uniforms types are wrong - map: { type: 't', value: texture }, - // @ts-expect-error Uniforms types are wrong - SHADE: { type: 'bool', value: settings.shading.value }, - LIGHTCOLOR: { - // @ts-expect-error Uniforms types are wrong - type: 'vec3', - value: new THREE.Color() - .copy(Canvas.global_light_color) - .multiplyScalar((settings.brightness.value as number) / 50), - }, - // @ts-expect-error Uniforms types are wrong - LIGHTSIDE: { type: 'int', value: Canvas.global_light_side }, - // @ts-expect-error Uniforms types are wrong - EMISSIVE: { type: 'bool', value: false }, - }, - vertexShader: TEXTURE_VERT_SHADER, - fragmentShader: TEXTURE_FRAG_SHADER, - blending: THREE.NormalBlending, - side: Canvas.getRenderSide(), - transparent: true, + // 'none' = no transform; any other mode uses the model's transform for that context. + const display = + itemDisplay === 'none' + ? { rotation: [0, 0, 0] as [number, number, number] } + : { type: 'fallback' as const, display: itemDisplay } + + let isBlock = false + const root = new THREE.Group() + for (const model of models) { + const resolved = await bmr.resolveModelData(assets, model) + const modelIsBlock = resolved.type === 'block' + isBlock ||= modelIsBlock + const group = await bmr.loadModel(null, assets, resolved, { + display, + lighting: modelIsBlock ? 'world' : 'item', + version: minecraftVersion, + animate: false, // the auto-animator can't survive the per-element clone }) - // @ts-expect-error Uniforms types are wrong - mat.map = texture - mat.name = location - - const mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), mat) - - const positionArray: number[] = [] - const indices: number[] = [] - const uvs: number[] = [] - const normals: number[] = [] - const colors: number[] = [] - const addNormal = (x: number, y: number, z: number) => { - normals.push(x, y, z, x, y, z, x, y, z, x, y, z) - } - - if (texture?.image.width) { - const canvas = document.createElement('canvas') - const ctx = canvas.getContext('2d')! - canvas.width = texture.image.width - canvas.height = texture.image.height - ctx.drawImage(texture.image as HTMLImageElement, 0, 0) - - const addFace = (x: number, z: number, w: number, h: number, dir: number) => { - const s = positionArray.length / 3 - const y = dir === 1 ? -1 : 0 - // prettier-ignore - positionArray.push( - -x, y, z, - -x, y, z + 1, - -x - w, y, z + h, - -x - w, y, z + h - 1 - ) - - if (dir === 1) { - indices.push(s + 0, s + 1, s + 2, s + 0, s + 2, s + 3) - } else if (dir === -1) { - indices.push(s + 0, s + 2, s + 1, s + 0, s + 3, s + 2) - } - - addNormal(dir, 0, 0) - uvs.push( - (x + w) / canvas.width, - 1 - z / canvas.height, - (x + w) / canvas.width, - 1 - (z + h) / canvas.height, - x / canvas.width, - 1 - (z + h) / canvas.height, - x / canvas.width, - 1 - z / canvas.height - ) - colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) - } - - const addEdge = ( - startX: number, - startY: number, - endX: number, - endY: number, - dir: number - ) => { - const s = positionArray.length / 3 - // prettier-ignore - positionArray.push( - -startX, 0, startY, - -startX, -1, startY, - -endX , -1, endY, - -endX , 0, endY - ) - - if (dir === 1) { - indices.push(s + 0, s + 1, s + 2, s + 0, s + 2, s + 3) - } else if (dir === -1) { - indices.push(s + 0, s + 2, s + 1, s + 0, s + 3, s + 2) - } - - if (startX == endX) { - startX += 0.1 * -dir - endX += 0.4 * -dir - startY += 0.1 - endY -= 0.1 - addNormal(-dir, 0, 0) - } - if (startY == endY) { - startY += 0.1 * dir - endY += 0.4 * dir - startX += 0.1 - endX -= 0.1 - addNormal(0, 0, -dir) - } - // prettier-ignore - uvs.push( - endX / canvas.width, 1 - startY / canvas.height, - endX / canvas.width, 1 - endY / canvas.height, - startX / canvas.width, 1 - endY / canvas.height, - startX / canvas.width, 1 - startY / canvas.height - ) - colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) - } - - const result = ctx.getImageData(0, 0, canvas.width, canvas.height) - - const matrix1 = [] - for (let i = 0; i < result.data.length; i += 4) { - matrix1.push(result.data[i + 3] > 140 ? 1 : 0) - } - const matrix2 = matrix1.slice() - - let pixel = 0 - for (let y = 0; y < canvas.height; y++) { - for (let x = 0; x < canvas.width; x++) { - pixel = matrix1[y * canvas.width + x] - if (pixel) { - addFace(x, y, 1, 1, 1) - addFace(x, y, 1, 1, -1) - } - } - } - - for (let y = 0; y < canvas.height; y++) { - for (let x = 0; x <= canvas.width; x++) { - const px0 = x == 0 ? 0 : matrix1[y * canvas.width + x - 1] - const px1 = x == canvas.width ? 0 : matrix1[y * canvas.width + x] - if (!px0 !== !px1) { - addEdge(x, y, x, y + 1, px0 ? 1 : -1) - } - } - } - - for (let x = 0; x < canvas.width; x++) { - for (let y = 0; y <= canvas.height; y++) { - const px0 = y == 0 ? 0 : matrix2[(y - 1) * canvas.width + x] - const px1 = y == canvas.height ? 0 : matrix2[y * canvas.width + x] - if (!px0 !== !px1) { - addEdge(x, y, x + 1, y, px0 ? -1 : 1) - } - } - } - } - - positionArray.forEach((n, i) => { - positionArray[i] = n + [8, 0.5, -8][i % 3] - }) - - mesh.geometry.setAttribute( - 'position', - new THREE.BufferAttribute(new Float32Array(positionArray), 3) - ) - mesh.geometry.setAttribute( - 'highlight', - new THREE.BufferAttribute(new Uint8Array(mesh.geometry.attributes.position.count), 1) - ) - mesh.geometry.setIndex(indices) - mesh.geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2)) - mesh.geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3)) - mesh.geometry.setAttribute( - 'normal', - new THREE.BufferAttribute(new Float32Array(normals), 3) - ) - mesh.geometry.attributes.color.needsUpdate = true - mesh.geometry.attributes.normal.needsUpdate = true - - mesh.geometry.rotateX(Math.PI / 2) - - const outlineGeo = mesh.geometry.clone() - // Remove the front and back face planes - const outlineVerts = Array.from(outlineGeo.attributes.position.array) - outlineVerts.splice(0, 24) - outlineGeo.setAttribute( - 'position', - new THREE.BufferAttribute(new Float32Array(outlineVerts), 3) - ) - outlineGeos.push(outlineGeo) - boundingBoxes.push(mesh.geometry.clone()) - masterMesh.add(mesh) + root.add(group) } - const outlineGeo = mergeGeometries(outlineGeos) - const boundingBox = mergeGeometries(boundingBoxes)! - const outline = new THREE.LineSegments( - new THREE.EdgesGeometry(outlineGeo!), - Canvas.outlineMaterial - ) - - return { mesh: masterMesh, outline, boundingBox } + // Item displays always pivot at the model's center, even for block items. + return convertBmrGroup(root, { pivot: 'center', isBlock }) } diff --git a/src/systems/minecraft/model.d.ts b/src/systems/minecraft/model.d.ts deleted file mode 100644 index 39ce37bc..00000000 --- a/src/systems/minecraft/model.d.ts +++ /dev/null @@ -1,115 +0,0 @@ -export type ModelDisplaySlot = - | 'thirdperson_righthand' - | 'thirdperson_lefthand' - | 'firstperson_righthand' - | 'firstperson_lefthand' - | 'gui' - | 'head' - | 'ground' - | 'fixed' - -export type ItemModelFaceDirection = 'up' | 'down' | 'north' | 'south' | 'west' | 'east' - -type ItemModelPredicateTypes = - | 'angle' - | 'blocking' - | 'broken' - | 'cast' - | 'cooldown' - | 'damage' - | 'damaged' - | 'lefthanded' - | 'pull' - | 'pulling' - | 'charged' - | 'firework' - | 'throwing' - | 'time' - | 'custom_model_data' - | 'level' - | 'filled' - | 'tooting' - | 'trim_type' - | 'brushing' - -export interface IItemModelElementFace { - uv: [number, number, number, number] - texture: string - cullface?: ItemModelFaceDirection - rotation?: 0 | 90 | 180 | 270 - tintindex?: number -} - -export interface IModelELement { - from: ArrayVector3 - to: ArrayVector3 - rotation?: { - origin: ArrayVector3 - axis: 'x' | 'y' | 'z' - angle: number - rescale: boolean - } - shade?: boolean - faces?: Record -} - -export interface IItemModel { - parent?: string - textures: Record & Record<`layer${number}`, string> & { particle?: string } - display?: Partial< - Record< - ModelDisplaySlot, - { - rotation?: ArrayVector3 - translation?: ArrayVector3 - scale?: ArrayVector3 - } - > - > - gui_light?: 'front' | 'side' - elements?: IModelELement[] - overrides?: { - predicate: Record - model: string - } -} - -export interface IBlockModel { - parent?: string - textures: Record & Record<`layer${number}`, string> & { particle?: string } - display?: Partial< - Record< - ModelDisplaySlot, - { - rotation?: ArrayVector3 - translation?: ArrayVector3 - scale?: ArrayVector3 - } - > - > - ambientocclusion?: boolean - elements?: IModelELement[] -} - -export interface IBlockStateVariant { - model: string - uvlock?: boolean - x?: number - y?: number - isItemModel?: boolean // Internal use only -} - -export type IBlockStateMultipartCaseCondition = { - OR: IBlockStateMultipartCaseCondition[] - AND: IBlockStateMultipartCaseCondition[] -} & Record - -export interface IBlockStateMultipartCase { - when?: IBlockStateMultipartCaseCondition - apply: IBlockStateVariant | Array -} - -export interface IBlockState { - variants?: Record> - multipart?: IBlockStateMultipartCase[] -} diff --git a/src/systems/minecraft/textureShaders.ts b/src/systems/minecraft/textureShaders.ts deleted file mode 100644 index 81996429..00000000 --- a/src/systems/minecraft/textureShaders.ts +++ /dev/null @@ -1,109 +0,0 @@ -export const TEXTURE_VERT_SHADER = ` - attribute float highlight; - - uniform bool SHADE; - uniform int LIGHTSIDE; - - varying vec2 vUv; - varying float light; - varying float lift; - - float AMBIENT = 0.5; - float XFAC = -0.15; - float ZFAC = 0.05; - - void main() - { - - if (SHADE) { - - vec3 N = normalize( vec3( modelMatrix * vec4(normal, 0.0) ) ); - - if (LIGHTSIDE == 1) { - float temp = N.y; - N.y = N.z * -1.0; - N.z = temp; - } - if (LIGHTSIDE == 2) { - float temp = N.y; - N.y = N.x; - N.x = temp; - } - if (LIGHTSIDE == 3) { - N.y = N.y * -1.0; - } - if (LIGHTSIDE == 4) { - float temp = N.y; - N.y = N.z; - N.z = temp; - } - if (LIGHTSIDE == 5) { - float temp = N.y; - N.y = N.x * -1.0; - N.x = temp; - } - - float yLight = (1.0+N.y) * 0.5; - light = yLight * (1.0-AMBIENT) + N.x*N.x * XFAC + N.z*N.z * ZFAC + AMBIENT; - - } else { - - light = 1.0; - - } - - if (highlight == 2.0) { - lift = 0.22; - } else if (highlight == 1.0) { - lift = 0.1; - } else { - lift = 0.0; - } - - vUv = uv; - vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); - gl_Position = projectionMatrix * mvPosition; - }` - -export const TEXTURE_FRAG_SHADER = ` - #ifdef GL_ES - precision highp float; - #endif - - uniform sampler2D map; - - uniform bool SHADE; - uniform bool EMISSIVE; - uniform vec3 LIGHTCOLOR; - - varying vec2 vUv; - varying float light; - varying float lift; - - void main(void) - { - vec4 color = texture2D(map, vUv); - - if (color.a < 0.01) discard; - - if (EMISSIVE == false) { - - gl_FragColor = vec4(lift + color.rgb * light, color.a); - gl_FragColor.r = gl_FragColor.r * LIGHTCOLOR.r; - gl_FragColor.g = gl_FragColor.g * LIGHTCOLOR.g; - gl_FragColor.b = gl_FragColor.b * LIGHTCOLOR.b; - - } else { - - float light_r = (light * LIGHTCOLOR.r) + (1.0 - light * LIGHTCOLOR.r) * (1.0 - color.a); - float light_g = (light * LIGHTCOLOR.g) + (1.0 - light * LIGHTCOLOR.g) * (1.0 - color.a); - float light_b = (light * LIGHTCOLOR.b) + (1.0 - light * LIGHTCOLOR.b) * (1.0 - color.a); - gl_FragColor = vec4(lift + color.r * light_r, lift + color.g * light_g, lift + color.b * light_b, 1.0); - - } - - if (lift > 0.2) { - gl_FragColor.r = gl_FragColor.r * 0.6; - gl_FragColor.g = gl_FragColor.g * 0.7; - } - }` diff --git a/test-packs/latest/blueprints/armor_stand_latest.ajblueprint b/test-packs/latest/blueprints/armor_stand_latest.ajblueprint index 9de67690..172f9eba 100644 --- a/test-packs/latest/blueprints/armor_stand_latest.ajblueprint +++ b/test-packs/latest/blueprints/armor_stand_latest.ajblueprint @@ -1163,7 +1163,7 @@ "visibility": true, "locked": false, "export": true, - "block": "minecraft:stone", + "block": "minecraft:oak_stairs[facing=north,shape=inner_right]", "onSummonFunction": "", "configs": { "default": { @@ -1196,7 +1196,7 @@ "visibility": true, "locked": false, "export": true, - "block": "minecraft:grass_block", + "block": "minecraft:command_block", "onSummonFunction": "", "configs": { "default": { @@ -1229,7 +1229,7 @@ "visibility": true, "locked": false, "export": true, - "block": "minecraft:oak_log", + "block": "minecraft:enchanting_table", "onSummonFunction": "", "configs": { "default": { @@ -1272,7 +1272,7 @@ "override_brightness": false, "sky_brightness": 0, "block_brightness": 0, - "enchanted": false, + "enchanted": true, "glowing": false, "override_glow_color": false, "glow_color": "#ffffff", @@ -1296,7 +1296,7 @@ "visibility": true, "locked": false, "export": true, - "item": "minecraft:orange_dye", + "item": "minecraft:gold_ingot", "itemDisplay": "ground", "onSummonFunction": "", "configs": { @@ -1330,7 +1330,7 @@ "visibility": true, "locked": false, "export": true, - "item": "minecraft:orange_dye", + "item": "minecraft:stone_sword", "itemDisplay": "ground", "onSummonFunction": "", "configs": { @@ -1353,6 +1353,159 @@ "scope": 0, "uuid": "01475b0a-1cfb-55fc-f1f5-70dda0fc8d71", "type": "animated_java:vanilla_item_display" + }, + { + "name": "block_display6", + "position": [56, 0, -8], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1.0625, 1], + "color": 9, + "visibility": true, + "locked": false, + "export": true, + "block": "minecraft:chest[facing=south]", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "de661450-24fc-70c7-7927-1f0e5524f216", + "type": "animated_java:vanilla_block_display" + }, + { + "name": "block_display8", + "position": [72, 0, -8], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1.0625, 1], + "color": 9, + "visibility": true, + "locked": false, + "export": true, + "block": "minecraft:oak_slab[waterlogged=true]", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "c6ac5d8b-0da4-b065-c8ca-1ab06a21aaee", + "type": "animated_java:vanilla_block_display" + }, + { + "name": "item_display2", + "position": [32, 25, 0], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1, 1], + "color": 6, + "visibility": true, + "locked": false, + "export": true, + "item": "minecraft:player_head", + "itemDisplay": "none", + "onSummonFunction": "", + "configs": { + "default": {}, + "variants": {} + }, + "scope": 0, + "uuid": "98c410fa-8f40-26b4-28f6-e6972180d138", + "type": "animated_java:vanilla_item_display" + }, + { + "name": "block_display10", + "position": [88, 0, -8], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1.0625, 1], + "color": 9, + "visibility": true, + "locked": false, + "export": true, + "block": "minecraft:water", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "07e1c24e-d4e4-9284-6c7e-6628ac996110", + "type": "animated_java:vanilla_block_display" + }, + { + "name": "block_display12", + "position": [104, 0, -8], + "rotation": [0, 0, 0], + "pivotOffset": [0, 0, 0], + "scale": [1, 1.0625, 1], + "color": 9, + "visibility": true, + "locked": false, + "export": true, + "block": "minecraft:lava", + "onSummonFunction": "", + "configs": { + "default": { + "on_apply_function": "", + "billboard": "fixed", + "override_brightness": false, + "sky_brightness": 0, + "block_brightness": 0, + "enchanted": true, + "glowing": false, + "override_glow_color": false, + "glow_color": "#ffffff", + "invisible": false, + "shadow_radius": 0, + "shadow_strength": 1 + }, + "variants": {} + }, + "scope": 0, + "uuid": "f3872b69-65b3-2812-3827-518ece3e20e8", + "type": "animated_java:vanilla_block_display" } ], "groups": [ @@ -1739,7 +1892,7 @@ "override_brightness": false, "sky_brightness": 0, "block_brightness": 0, - "enchanted": false, + "enchanted": true, "glowing": false, "override_glow_color": true, "glow_color": "#ffffff", @@ -2098,9 +2251,14 @@ "857172ba-7e40-f659-9b57-c9e9030d5ebd", "10960a14-0305-4213-fc7b-d9cb56e30a49", "e1de5b7c-4e08-e515-6697-f24326e769c1", + "de661450-24fc-70c7-7927-1f0e5524f216", + "c6ac5d8b-0da4-b065-c8ca-1ab06a21aaee", + "07e1c24e-d4e4-9284-6c7e-6628ac996110", + "f3872b69-65b3-2812-3827-518ece3e20e8", "446c95f8-f3ba-c843-c9b9-7c06fbd62da7", "0a0e0205-c124-0e26-3a2f-1d35f08b8790", - "01475b0a-1cfb-55fc-f1f5-70dda0fc8d71" + "01475b0a-1cfb-55fc-f1f5-70dda0fc8d71", + "98c410fa-8f40-26b4-28f6-e6972180d138" ], "textures": [ { From 8b41cb8d1ef6de82e50144c823b03a4b9f4fe21b Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 19:43:15 -0400 Subject: [PATCH 14/85] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Move=20auto-update?= =?UTF-8?q?=20rig=20orientation=20toggle=20to=20the=20Rig=20settings=20pag?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - it configures rig behaviour, not data pack output - still shown only when a data pack is being exported --- src/dialogs/blueprintSettings/pages/datapack.svelte | 9 --------- src/dialogs/blueprintSettings/pages/rig.svelte | 11 +++++++++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/dialogs/blueprintSettings/pages/datapack.svelte b/src/dialogs/blueprintSettings/pages/datapack.svelte index 6427bf52..8ec1efed 100644 --- a/src/dialogs/blueprintSettings/pages/datapack.svelte +++ b/src/dialogs/blueprintSettings/pages/datapack.svelte @@ -2,7 +2,6 @@ import { onDestroy } from 'svelte' import { validateDataPackFolder, validateZipPath } from '../../../formats/blueprint/settings' import BoxSelect from '../../../svelteComponents/sidebarDialogItems/boxSelect.svelte' - import Checkbox from '../../../svelteComponents/sidebarDialogItems/checkbox.svelte' import SelectFile from '../../../svelteComponents/sidebarDialogItems/selectFile.svelte' import SelectFolder from '../../../svelteComponents/sidebarDialogItems/selectFolder.svelte' import { createScopedTranslator } from '../../../util/lang' @@ -14,13 +13,11 @@ let animationSystem = $state( Project.animated_java.use_storage_for_animation ? 'storage' : 'functions' ) - let autoUpdateRigOrientation = $state(Project.animated_java.auto_update_rig_orientation) onDestroy(() => { Project.animated_java.data_pack_export_mode = dataPackExportFormat Project.animated_java.data_pack = dataPackLocation Project.animated_java.use_storage_for_animation = animationSystem === 'storage' - Project.animated_java.auto_update_rig_orientation = autoUpdateRigOrientation }) @@ -66,12 +63,6 @@ {/if} {#if dataPackExportFormat !== 'none'} - - { Project.animated_java.custom_rig_entity_tags = customRigEntityTags Project.animated_java.interpolation_duration = interpolationDuration Project.animated_java.teleportation_duration = teleportationDuration + Project.animated_java.auto_update_rig_orientation = autoUpdateRigOrientation Project.animated_java.use_entity_stacking = useEntityStacking }) @@ -44,6 +47,14 @@ max={2147483647} /> +{#if dataPackExportFormat !== 'none'} + +{/if} + Date: Tue, 1 Sep 2026 19:43:39 -0400 Subject: [PATCH 15/85] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Rework=20text-displa?= =?UTF-8?q?y=20font=20pipeline,=20make=20asset=20loading=20resource-pack?= =?UTF-8?q?=20aware?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - delegate JSON-text wrapping to book-and-quill 1.1.0, drop the local port (src/systems/jsonText/wrapping.ts) - split THREE.js text-mesh generation out of fontManager into a dedicated fontRenderer with geometry/colour/layout caches, so option-only edits skip re-parsing and re-wrapping - assetManager now reads stacked resource-pack layers and exposes a preview-pack cache-busting key, so fonts can merge providers across packs --- bun.lock | 4 +- package.json | 2 +- src/index.ts | 1 + src/outliner/textDisplay.ts | 86 ++-- src/systems/jsonText/wrapping.ts | 372 ----------------- src/systems/minecraft/assetManager.ts | 172 +++++++- src/systems/minecraft/fontManager.ts | 515 +++++------------------ src/systems/minecraft/fontRenderer.ts | 568 ++++++++++++++++++++++++++ vitest.config.ts | 8 + 9 files changed, 892 insertions(+), 836 deletions(-) delete mode 100644 src/systems/jsonText/wrapping.ts create mode 100644 src/systems/minecraft/fontRenderer.ts diff --git a/bun.lock b/bun.lock index 01648df9..46e7da9e 100644 --- a/bun.lock +++ b/bun.lock @@ -26,7 +26,7 @@ "@typescript-eslint/eslint-plugin": "^5.54.0", "@typescript-eslint/parser": "^5.54.0", "blockbench-patch-manager": "^1.1.0", - "book-and-quill": "^1.0.10", + "book-and-quill": "^1.1.0", "esbuild": "^0.21.5", "esbuild-plugin-import-folder": "^1.0.1", "esbuild-plugin-import-glob": "^0.1.1", @@ -578,7 +578,7 @@ "blockbench-types": ["blockbench-types@5.1.0", "", { "dependencies": { "@babel/types": "^7.20.7", "@types/dompurify": "^3.0.5", "@types/jquery": "^3.5.32", "@types/prismjs": "^1.26.0", "@types/three": "^0.129.2", "@types/tinycolor2": "^1.4.6", "dompurify": "^3.0.1", "electron": "^40.8.0", "prismjs": "^1.29.0", "tinycolor2": "^1.6.0", "typescript": "^5.8.3", "vue": "2.7.14", "wintersky": "^1.3.0" } }, "sha512-JLMHJZ+2J7aFQwSacfW4N/rvd56JRqvaBsHNH2R6sjyxkwKPuNPKYIeav/WtRXnq3dmlsEoH3rtg09s7yhe3sg=="], - "book-and-quill": ["book-and-quill@1.0.10", "", { "dependencies": { "@types/node": "^25.3.3", "tinycolor2": "^1.6.0" }, "peerDependencies": { "typescript": "^5" } }, "sha512-9NaTEOmnJM8GPJVsdvl8Th9peju97KgvAtWPhya3v+IGI4hAafpdpuVoIlCK7TjHkHjIqKJ2HLYmcJX2qd4kEQ=="], + "book-and-quill": ["book-and-quill@1.1.0", "", { "dependencies": { "@types/node": "^25.3.3", "tinycolor2": "^1.6.0" }, "peerDependencies": { "typescript": "^5" } }, "sha512-xYHwKKunplZRHyrwX7BnYCrufVxeMR2VgLT+aTOsHoLSUNT34RkxyY26FwIDlqCejkEH81kMsAtuvOecEcba6A=="], "boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="], diff --git a/package.json b/package.json index 7f7f5a3d..a5ecb15a 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "@typescript-eslint/eslint-plugin": "^5.54.0", "@typescript-eslint/parser": "^5.54.0", "blockbench-patch-manager": "^1.1.0", - "book-and-quill": "^1.0.10", + "book-and-quill": "^1.1.0", "esbuild": "^0.21.5", "esbuild-plugin-import-folder": "^1.0.1", "esbuild-plugin-import-glob": "^0.1.1", diff --git a/src/index.ts b/src/index.ts index b1fd3380..374a1b1d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,6 +21,7 @@ import datapackCompiler from './systems/datapackCompiler' import './systems/minecraft/assetManager' import './systems/minecraft/blockstateManager' import './systems/minecraft/fontManager' +import './systems/minecraft/fontRenderer' import './systems/minecraft/registryManager' import './systems/minecraft/versionManager' // Shaders diff --git a/src/outliner/textDisplay.ts b/src/outliner/textDisplay.ts index 5a1b6e5a..2b270d98 100644 --- a/src/outliner/textDisplay.ts +++ b/src/outliner/textDisplay.ts @@ -3,7 +3,7 @@ import { TextComponent, TextComponentParser, type TextElement } from 'book-and-q import { observable } from 'svelte-observable-store' import { PACKAGE } from '../constants' import { activeProjectIsBlueprintFormat } from '../formats/blueprint' -import { MinecraftFont } from '../systems/minecraft/fontManager' +import { generateTextDisplayMesh, type TextDisplayMesh } from '../systems/minecraft/fontRenderer' import { type IDisplayEntityConfigs } from '../systems/rigRenderer' import EVENTS from '../util/events' import { localize as translate } from '../util/lang' @@ -48,7 +48,11 @@ export class TextDisplay extends ResizableOutlinerElement { needsMeshUpdate = false - private __pendingMeshUpdate?: ReturnType + private __pendingMeshUpdate?: Promise + /** Cached parse of `this.text`, keyed by `text \0 minecraftVersion`, so + * option-only mesh rebuilds don't re-parse an unchanged (and possibly huge) + * component. `component` is undefined when the text failed to parse. */ + private __parsed?: { key: string; component?: TextComponent; error?: string } private __text = observable('Hello World!') private __lineWidth = TextDisplay.properties.lineWidth.default as number private __backgroundColor = TextDisplay.properties.backgroundColor.default as string @@ -73,6 +77,7 @@ export class TextDisplay extends ResizableOutlinerElement { static forceUpdateAll() { for (const textDisplay of TextDisplay.all) { + textDisplay.needsMeshUpdate = true textDisplay.preview_controller.updateAll(textDisplay) } } @@ -212,49 +217,52 @@ export class TextDisplay extends ResizableOutlinerElement { } updateTextMesh() { - let result: TextComponent | undefined - try { - const parser = new TextComponentParser({ - minecraftVersion: Project!.animated_java.target_minecraft_version, - }) - parser.enabledFeatures &= ~( - TextComponentParser.FEATURES.CLICK_EVENTS | - TextComponentParser.FEATURES.HOVER_EVENTS - ) - result = new TextComponent(parser.parse(this.text)) - this.textError.set('') - } catch (e: any) { - console.error(e) - if (e.name === 'SyntaxPointerError') { - this.textError.set(e.getOriginErrorMessage()) - } else { - this.textError.set(e.message as string) + const parseKey = this.text + '\0' + Project!.animated_java.target_minecraft_version + if (this.__parsed?.key !== parseKey) { + this.__parsed = { key: parseKey } + try { + const parser = new TextComponentParser({ + minecraftVersion: Project!.animated_java.target_minecraft_version, + }) + parser.enabledFeatures &= ~( + TextComponentParser.FEATURES.CLICK_EVENTS | + TextComponentParser.FEATURES.HOVER_EVENTS + ) + this.__parsed.component = new TextComponent(parser.parse(this.text)) + } catch (e: any) { + console.error(e) + this.__parsed.error = + e.name === 'SyntaxPointerError' + ? e.getOriginErrorMessage() + : (e.message as string) } } - result ??= new TextComponent({ text: 'Invalid JSON Text!', color: 'red' }) - void this.renderTextMesh(result).then(({ mesh, hitbox, outline }) => { + this.textError.set(this.__parsed.error ?? '') + + const jsonText = + this.__parsed.component ?? + new TextComponent({ text: 'Invalid JSON Text!', color: 'red' }) + const cacheKey = this.__parsed.component ? this.text : '\0invalid' + void this.renderTextMesh(jsonText, cacheKey).then(({ mesh, hitbox, outline }) => { this.applyTextMesh(mesh, hitbox, outline) }) } - private renderTextMesh(jsonText: TextComponent) { - const promise = MinecraftFont.getById('minecraft:default') - .then(font => { - return font.generateTextDisplayMesh({ - jsonText, - maxLineWidth: this.lineWidth, - backgroundColor: tinycolor(this.backgroundColor), - shadow: this.shadow, - alignment: this.align, - }) - }) - .then(result => { - if (this.__pendingMeshUpdate === promise) { - this.__pendingMeshUpdate = undefined - return result - } - return this.__pendingMeshUpdate - }) as ReturnType + private renderTextMesh(jsonText: TextComponent, cacheKey: string) { + const promise = generateTextDisplayMesh({ + jsonText, + cacheKey, + maxLineWidth: this.lineWidth, + backgroundColor: tinycolor(this.backgroundColor), + shadow: this.shadow, + alignment: this.align, + }).then(result => { + if (this.__pendingMeshUpdate === promise) { + this.__pendingMeshUpdate = undefined + return result + } + return this.__pendingMeshUpdate + }) as Promise this.__pendingMeshUpdate = promise return promise diff --git a/src/systems/jsonText/wrapping.ts b/src/systems/jsonText/wrapping.ts deleted file mode 100644 index 5588e943..00000000 --- a/src/systems/jsonText/wrapping.ts +++ /dev/null @@ -1,372 +0,0 @@ -import { - TextComponent, - UnicodeString, - type TextComponentStyle, - type TextElement, - type TextObject, -} from 'book-and-quill' -import { Stopwatch } from '../../util/stopwatch' -import { MinecraftFont } from '../minecraft/fontManager' - -// Jumpstarted by @IanSSenne (FetchBot) and refactored by @SnaveSutit to do line wrapping on JSON Text Components. -// THANK U IAN <3 - SnaveSutit - -const KEYBIND_KEY_MAP: Record = { - 'key.advancements': 'L', - 'key.attack': 'key.mouse.left', - 'key.back': 'S', - 'key.chat': 'T', - 'key.command': '/', - 'key.drop': 'Q', - 'key.forward': 'W', - 'key.fullscreen': 'F11', - 'key.hotbar.1': '1', - 'key.hotbar.2': '2', - 'key.hotbar.3': '3', - 'key.hotbar.4': '4', - 'key.hotbar.5': '5', - 'key.hotbar.6': '6', - 'key.hotbar.7': '7', - 'key.hotbar.8': '8', - 'key.hotbar.9': '9', - 'key.inventory': 'E', - 'key.jump': 'Space', - 'key.left': 'A', - 'key.loadToolbarActivator': 'X', - 'key.pickItem': 'key.mouse.middle', - 'key.playerlist': 'Tab', - 'key.quickActions': 'Quick Actions', - 'key.right': 'D', - 'key.saveToolbarActivator': 'G', - 'key.screenshot': 'F2', - 'key.smoothCamera': 'Toggle Cinematic Camera', - 'key.sneak': 'Left Shift', - 'key.socialInteractions': 'P', - 'key.spectatorHotbar': 'key.keyboard.unknown', - 'key.spectatorOutlines': 'key.keyboard.unknown', - 'key.sprint': 'Left Control', - 'key.swapOffhand': 'F', - 'key.toggleGui': 'F1', - 'key.togglePerspective': 'F5', - 'key.toggleSpectatorShaderEffects': 'F4', - 'key.use': 'key.mouse.right', -} - -async function getLangTranslation(key: string): Promise { - const lang = await AnimatedJava.assetManager.getJSONAsset( - Project.animated_java.target_minecraft_version, - 'assets/minecraft/lang/en_us.json' - ) - return lang[key] ?? key -} - -async function getKeybindTranslation(keybind: string): Promise { - const mappedKeybind = KEYBIND_KEY_MAP[keybind] ?? keybind - return getLangTranslation(mappedKeybind) -} - -async function getRawText(element: string | TextObject): Promise { - if (typeof element === 'string') { - return new UnicodeString(element) - } - - switch (true) { - case element.text !== undefined: - return new UnicodeString(element.text) - - case element.translate !== undefined: - const translation = await getLangTranslation(element.translate) - return new UnicodeString( - translation === element.translate ? `{${element.translate}}` : translation - ) - - case element.selector !== undefined: - return new UnicodeString(`{${element.selector}}`) - - case element.score !== undefined: - return new UnicodeString(`{${element.score.name}:${element.score.objective}}`) - - case element.keybind !== undefined: - const keybindTranslation = await getKeybindTranslation(element.keybind) - return new UnicodeString( - element.keybind === keybindTranslation ? `{${element.keybind}}` : keybindTranslation - ) - - case element.nbt !== undefined: - switch (true) { - case element.block !== undefined: - return new UnicodeString(`{${element.block}:${element.nbt}}`) - - case element.entity !== undefined: - return new UnicodeString(`{${element.entity}:${element.nbt}}`) - - case element.storage !== undefined: - return new UnicodeString(`{${element.storage}:${element.nbt}}`) - - default: - return new UnicodeString(`{${element.nbt}}`) - } - - case element.sprite !== undefined: - return new UnicodeString(`{sprite:${element.sprite}}`) - - case element.player !== undefined: - return new UnicodeString(`{player:${element.player}}`) - - default: - console.warn('Unknown JSON Text element:', element) - return new UnicodeString('{Unknown Element}') - } -} - -export interface StyleSpan { - style: TextComponentStyle - start: number - end: number -} - -export interface Word { - styles: StyleSpan[] - text: UnicodeString - /** - * The width of the word in pixels. - */ - width: number - forceWrap?: boolean -} - -interface Line { - words: Word[] - width: number -} - -/** - * Gets the words from a JSON Text Element, keeping track of the styles applied to each word. - * - * WARNING: Word width is ***not calculated*** by this function. - */ -export async function parseWords(inputElement: TextElement) { - const stopwatch = new Stopwatch('Parse Words').start() - const optimized = new TextComponent(inputElement).optimized(true) - if (!optimized.length) return [] - const words: Word[] = [] - - let word: Word | undefined - let element = optimized.shift() - if (Array.isArray(element)) { - throw new Error('Unexpected array element in optimized JSON Text') - } - if (element === undefined) return words - - let componentText = await getRawText(element) - let span: StyleSpan = { - style: TextComponent.getComponentStyle(element), - start: 0, - end: 0, - } - - while (element !== undefined) { - for (const char of componentText) { - if (char === ' ') { - // A group of multiple spaces is treated as a word. - if (word && !(word.text.at(-1) === ' ')) { - span.end++ - if (Object.keys(span.style).length) { - word.styles.push({ ...span }) - span.start = 0 - span.end = 0 - } - words.push(word) - word = undefined - } - } else if (char === '\n') { - if (word) { - if (Object.keys(span.style).length) { - if (span.start < span.end) { - word.styles.push({ ...span }) - } - span.start = 0 - span.end = 0 - } - words.push(word) - } - words.push({ - styles: [], - text: new UnicodeString(''), - width: 0, - forceWrap: true, - }) - word = undefined - continue - } else if (char !== ' ' && word?.text.at(-1) === ' ') { - span.end++ - if (Object.keys(span.style).length) { - word.styles.push({ ...span }) - span.start = 0 - span.end = 0 - } - words.push(word) - word = undefined - } - - word ??= { styles: [], text: new UnicodeString(''), width: 0 } - word.text.append(char) - span.end++ - } - - element = optimized.shift() - if (Array.isArray(element)) { - throw new Error('Unexpected array element in optimized JSON Text') - } - - if (element !== undefined) { - componentText = await getRawText(element) - if (word) { - word.styles.push(span) - span = { - style: TextComponent.getComponentStyle(element), - start: span.end, - end: span.end, - } - } else { - span = { - style: TextComponent.getComponentStyle(element), - start: 0, - end: 0, - } - } - } - } - - if (word) { - if (Object.keys(span.style).length) { - word.styles.push(span) - } - words.push(word) - } - - stopwatch.debug() - return words -} - -export async function wrapJsonText(jsonText: TextComponent, maxLineWidth = 200) { - const stopwatch = new Stopwatch('Wrap Json Text').start() - - const words = await parseWords(jsonText.toJSON()) - const lines: Line[] = [] - // The `getWordWidth` function handles getting the width of words with different / custom fonts - const font = (await MinecraftFont.getById('minecraft:default'))! - - let backgroundWidth = 0 - let currentLine: Line = { words: [], width: 0 } - for (const word of words) { - const wordWidth = await font.getWordWidth(word) - const wordStyles = [...word.styles] - - // If the word is longer than than the max line width, split it into multiple lines - if (wordWidth - 1 > maxLineWidth) { - if (currentLine.words.length) { - lines.push(currentLine) - backgroundWidth = Math.max(backgroundWidth, currentLine.width) - } - currentLine = { words: [], width: 0 } - - let part = new UnicodeString('') - let partWidth = 0 - let partStartIndex = 0 - let style: StyleSpan | undefined = wordStyles.shift() - if (!style) throw new Error(`No active style found for word '${word.text.toString()}'`) - - for (let i = 0; i < word.text.length; i++) { - const char = word.text.at(i)! - if (wordStyles.length > 1 && i >= style.end) { - style = wordStyles.shift()! - } - - const charWidth = await font.getTextWidth(new UnicodeString(char), style) - if (part.length > 0 && partWidth + (charWidth - 1) > maxLineWidth) { - // Find all styles that apply to this part - // FIXME: Attempt to avoid filtering and maping the styles for each character - const partStyles = word.styles - .filter( - span => - span.start < partStartIndex + part.length && - span.end >= partStartIndex - ) - .map(span => ({ - ...span, - start: Math.max(span.start - partStartIndex, 0), - end: Math.min(span.end - partStartIndex, part.length), - })) - lines.push({ - words: [{ text: part, styles: partStyles, width: wordWidth }], - width: partWidth, - }) - backgroundWidth = Math.max(backgroundWidth, partWidth) - partStartIndex += part.length - part = new UnicodeString('') - partWidth = 0 - } - part.append(char) - partWidth += charWidth - } - if (part) { - // Find all styles that apply to this part - // FIXME: Attempt to avoid filtering and maping the styles for each character - const partStyles = word.styles - .filter( - span => - span.start < partStartIndex + part.length && span.end >= partStartIndex - ) - .map(span => ({ - ...span, - start: Math.max(span.start - partStartIndex, 0), - end: Math.min(span.end - partStartIndex, part.length), - })) - backgroundWidth = Math.max(backgroundWidth, partWidth) - currentLine = { - words: [{ text: part, styles: partStyles, width: wordWidth }], - width: partWidth, - } - } - continue - // If the word is a newline character, force a line break - } else if (word.forceWrap) { - if (currentLine.words.length) { - lines.push(currentLine) - backgroundWidth = Math.max(backgroundWidth, currentLine.width) - } - currentLine = { words: [], width: 0 } - // If the current line has words and adding the current word would exceed the max line width, start a new line - } else if (currentLine.words.length && currentLine.width + (wordWidth - 1) > maxLineWidth) { - const lastWord = currentLine.words.at(-1) - // This will only effect space "words" - if (lastWord?.text.at(-1) === ' ') { - currentLine.words.pop() - currentLine.width -= lastWord.width - } - if (word.text.at(0) === ' ') { - // If the word starts with a space, remove it. - word.text = word.text.slice(1) - word.styles.forEach(span => { - span.start = Math.max(0, span.start - 1) - span.end = Math.max(0, span.end - 1) - }) - // word.width = await font.getWordWidth(word) - } - lines.push(currentLine) - backgroundWidth = Math.max(backgroundWidth, currentLine.width) - currentLine = { words: [], width: 0 } - } - word.width = wordWidth - currentLine.words.push(word) - currentLine.width += wordWidth - } - if (currentLine.words.length) { - lines.push(currentLine) - backgroundWidth = Math.max(backgroundWidth, currentLine.width) - } - - stopwatch.debug() - return { lines, backgroundWidth } -} diff --git a/src/systems/minecraft/assetManager.ts b/src/systems/minecraft/assetManager.ts index fcd9efe7..231ffc26 100644 --- a/src/systems/minecraft/assetManager.ts +++ b/src/systems/minecraft/assetManager.ts @@ -1,7 +1,9 @@ import type { Unzipped } from 'fflate' import ky from 'ky' +import { createHash } from 'node:crypto' import { dirname, join } from 'node:path' import { getFsModule } from '../../constants' +import { resolvePath } from '../../util/fileUtil' import { unzip } from '../util' import { getVersionById, getVersionDownloadUrl } from './versionManager' @@ -11,6 +13,150 @@ const ASSETS_CACHE = new Map() const FOLDER_CACHE = new Map>() const ACTIVE_DOWNLOAD_PROMISES = new Map>() +// region Preview Resource Pack +/** + * A merged in-memory overlay of the `assets/` trees of one or more user-provided + * resource packs. When present, its files take precedence over the vanilla client + * jar for every asset lookup, letting the editor preview custom fonts, models, + * and textures without exporting. + */ +let previewPack: Map | undefined +/** + * The individual preview pack overlays, highest priority first. Kept alongside the + * flattened {@link previewPack} for assets that stack rather than replace (fonts). + */ +let previewPackLayers: Array> = [] +/** + * A cache-busting token that changes whenever the preview resource pack overlay + * changes. Downstream caches (bmr asset bundles, model/font caches) mix this into + * their keys so a swapped pack keeps no stale renders. + */ +let previewPackKey = '' + +export function getPreviewResourcePackKey(): string { + return previewPackKey +} + +export function isPreviewResourcePackLoaded(): boolean { + return previewPack !== undefined +} + +async function walkPreviewFolder( + root: string, + relativeDir: string, + into: Map, + signature: string[] +) { + const { promises } = getFsModule() + const entries = await promises.readdir(join(root, relativeDir), { withFileTypes: true }) + for (const entry of entries) { + const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name + const absolutePath = join(root, relativePath) + if (entry.isDirectory()) { + await walkPreviewFolder(root, relativePath, into, signature) + } else if (entry.isFile()) { + const [data, stat] = await Promise.all([ + promises.readFile(absolutePath), + promises.stat(absolutePath), + ]) + const key = relativePath.replace(/\\/g, '/') + into.set(key, new Uint8Array(data)) + signature.push(`${key}:${stat.size}:${stat.mtimeMs}`) + } + } +} + +/** Loads one resource pack (folder or `.zip`) into its own `assets/`-only overlay. */ +async function loadOnePreviewPack( + path: string +): Promise<{ entries: Map; signature: string }> { + const { existsSync, promises } = getFsModule() + const resolved = resolvePath(path) + + if (!existsSync(resolved)) { + throw new Error(`Preview resource pack does not exist at '${resolved}'`) + } + + const entries = new Map() + + // A `.zip` path is a zipped pack; anything else is treated as a pack folder. + if (/\.zip$/i.test(resolved)) { + const bytes = new Uint8Array(await promises.readFile(resolved)) + const unzipped = await unzip(bytes, { + filter: v => v.name.startsWith('assets/'), + }) + for (const [name, data] of Object.entries(unzipped)) { + entries.set(name, data) + } + const digest = createHash('sha1').update(bytes).digest('hex') + return { entries, signature: `zip:${resolved}:${digest}` } + } + + const parts: string[] = [] + if (existsSync(join(resolved, 'assets'))) { + await walkPreviewFolder(resolved, 'assets', entries, parts) + } + parts.sort() + const digest = createHash('sha1').update(parts.join('|')).digest('hex') + return { entries, signature: `dir:${resolved}:${digest}` } +} + +/** + * Loads (or, given an empty list, clears) the preview resource pack overlay. + * Packs are listed highest priority first: earlier entries override later ones, + * and all of them override the vanilla client jar. + */ +export async function setPreviewResourcePacks(paths: string[]): Promise { + const cleaned = paths.map(p => p.trim()).filter(Boolean) + + if (cleaned.length === 0) { + previewPack = undefined + previewPackLayers = [] + previewPackKey = '' + return + } + + const loaded = await Promise.all(cleaned.map(loadOnePreviewPack)) + + previewPackLayers = loaded.map(l => l.entries) + + // Merge lowest priority first so higher-priority packs (earlier in the list) win. + const overlay = new Map() + for (const { entries } of [...loaded].reverse()) { + for (const [key, data] of entries) overlay.set(key, data) + } + + previewPack = overlay + previewPackKey = loaded.map(l => l.signature).join('\n') +} + +function readPreviewAsset(assetPath: string): Uint8Array | undefined { + return previewPack?.get(assetPath) +} + +/** + * Every layer's copy of an asset, highest priority first: each preview pack that + * has it, then the vanilla client jar. Used for assets that stack instead of + * replace (font definitions merge their `providers` across packs). + */ +export async function getAllRawAssets(versionId: string, assetPath: string): Promise { + const results: Buffer[] = [] + for (const layer of previewPackLayers) { + const data = layer.get(assetPath) + if (data) results.push(Buffer.from(data)) + } + const jarAsset = (await getAssets(versionId))[assetPath] + if (jarAsset) results.push(Buffer.from(jarAsset)) + return results +} + +/** {@link getAllRawAssets}, parsed as JSON. */ +export async function getAllJSONAssets(versionId: string, assetPath: string): Promise { + const buffers = await getAllRawAssets(versionId, assetPath) + return buffers.map(buffer => JSON.parse(buffer.toString('utf-8'))) +} +// endregion + async function downloadFile(url: string, savePath: string) { const response = await ky(url, { method: 'GET', @@ -76,10 +222,13 @@ export async function getAssets(versionId: string) { /** A `block-model-renderer` virtual asset handler over a version's client jar. */ export const getAssetHandler = async (versionId: string) => { const assets = await getAssets(versionId) - const paths = Object.keys(assets) + const paths = new Set(Object.keys(assets)) + if (previewPack) { + for (const key of previewPack.keys()) paths.add(key) + } return { read(filePath: string): Uint8Array | null { - return assets[filePath] ?? null + return readPreviewAsset(filePath) ?? assets[filePath] ?? null }, list(dir: string): string[] { const prefix = dir.endsWith('/') ? dir : dir + '/' @@ -97,11 +246,15 @@ export const getAssetHandler = async (versionId: string) => { } export async function hasAsset(versionId: string, assetPath: string) { + if (previewPack?.has(assetPath)) return true const assets = await getAssets(versionId) return assetPath in assets } export async function getRawAsset(versionId: string, assetPath: string) { + const previewAsset = readPreviewAsset(assetPath) + if (previewAsset) return Buffer.from(previewAsset) + const assets = await getAssets(versionId) const asset = assets[assetPath] @@ -132,7 +285,7 @@ export async function getJSONAsset(versionId: string, assetPath: string) { } export async function getFolder(versionId: string, folderPath: string) { - const cacheKey = `${versionId}:${folderPath}` + const cacheKey = `${versionId}:${previewPackKey}:${folderPath}` if (FOLDER_CACHE.has(cacheKey)) { return FOLDER_CACHE.get(cacheKey)! } @@ -144,6 +297,13 @@ export async function getFolder(versionId: string, folderPath: string) { folderAssets[assetPath] = Buffer.from(assets[assetPath]) } } + if (previewPack) { + for (const [assetPath, data] of previewPack) { + if (assetPath.startsWith(folderPath)) { + folderAssets[assetPath] = Buffer.from(data) + } + } + } FOLDER_CACHE.set(cacheKey, folderAssets) return folderAssets @@ -151,5 +311,9 @@ export async function getFolder(versionId: string, folderPath: string) { export async function filterAssets(versionId: string, predicate: (assetPath: string) => boolean) { const assets = await getAssets(versionId) - return Object.keys(assets).filter(predicate) + const keys = new Set(Object.keys(assets)) + if (previewPack) { + for (const key of previewPack.keys()) keys.add(key) + } + return [...keys].filter(predicate) } diff --git a/src/systems/minecraft/fontManager.ts b/src/systems/minecraft/fontManager.ts index 17128527..eb0b19f8 100644 --- a/src/systems/minecraft/fontManager.ts +++ b/src/systems/minecraft/fontManager.ts @@ -1,12 +1,7 @@ -import { COLORS, TextComponent, UnicodeString, type TextComponentStyle } from 'book-and-quill' -import { createHash } from 'node:crypto' +import { UnicodeString, type StyledSegment, type TextComponentStyle } from 'book-and-quill' import MissingCharacter from '../../assets/missing_character.png' -import { TextDisplay, type Alignment } from '../../outliner/textDisplay' -import { mergeGeometries } from '../../util/bufferGeometryUtils' import { getPathFromResourceLocation } from '../../util/minecraftUtil' -import { Stopwatch } from '../../util/stopwatch' -import { wrapJsonText, type StyleSpan, type Word } from '../jsonText/wrapping' -import { getJSONAsset, getPngAsset, hasAsset } from './assetManager' +import { getAllJSONAssets, getJSONAsset, getPngAsset } from './assetManager' namespace MinecraftJson { export interface FontProviderBitmap { @@ -41,6 +36,8 @@ interface CachedBitmapChar { type: 'bitmap' ascent: number width: number + /** Factor from atlas pixels to rendered pixels (`height` field / native cell height). */ + scale: number atlas: THREE.Texture bitmapUV: { x: number @@ -55,19 +52,18 @@ interface CachedSpaceChar { width: number } -type CachedChar = CachedBitmapChar | CachedSpaceChar - -interface CachedCharGeo { - geo?: THREE.BufferGeometry - width: number -} +export type CachedChar = CachedBitmapChar | CachedSpaceChar const MISSING_CHARACTER_TEXTURE = new THREE.TextureLoader().load(MissingCharacter) +MISSING_CHARACTER_TEXTURE.magFilter = THREE.NearestFilter +MISSING_CHARACTER_TEXTURE.minFilter = THREE.NearestFilter +MISSING_CHARACTER_TEXTURE.generateMipmaps = false function createMissingCharacter(): CachedBitmapChar { return { type: 'bitmap', ascent: 7, width: 6, + scale: 1, atlas: MISSING_CHARACTER_TEXTURE, bitmapUV: { x: 0, y: 0, width: 8, height: 8 }, } @@ -157,8 +153,11 @@ class SpaceFontProvider extends FontProvider { class BitmapFontProvider extends FontProvider { bitmapPath: string + /** Native cell height in atlas pixels (set once the atlas loads). */ charHeight: number charWidth: number + /** Target render height in pixels (Minecraft's `height` field, default 8). */ + renderHeight: number ascent: number chars: UnicodeString[] = [] @@ -174,7 +173,8 @@ class BitmapFontProvider extends FontProvider { this.providerJSON = providerJSON this.type = providerJSON.type this.bitmapPath = getPathFromResourceLocation(providerJSON.file, 'textures') - this.charHeight = providerJSON.height ?? 8 + this.renderHeight = providerJSON.height ?? 8 + this.charHeight = this.renderHeight this.charWidth = 8 this.ascent = providerJSON.ascent for (const row of providerJSON.chars) { @@ -191,6 +191,15 @@ class BitmapFontProvider extends FontProvider { this.bitmapPath ) const texture = await new THREE.TextureLoader().loadAsync(dataUrl) + // Sample the atlas as crisp pixels, and keep colours (emoji fonts) accurate. + texture.magFilter = THREE.NearestFilter + texture.minFilter = THREE.NearestFilter + texture.generateMipmaps = false + if ('colorSpace' in texture) { + ;(texture as any).colorSpace = (THREE as any).SRGBColorSpace + } else if ('encoding' in texture) { + ;(texture as any).encoding = (THREE as any).sRGBEncoding + } this.atlas = texture this.charHeight = texture.image.height / this.chars.length @@ -256,10 +265,15 @@ class BitmapFontProvider extends FontProvider { return createMissingCharacter() } + // Glyphs are scaled from their native atlas cell to the provider's `height`. + const scale = this.renderHeight / this.charHeight + this.charCache.set(char, { type: 'bitmap', ascent: this.ascent, - width: width + 1, // Add 1 pixel of spacing between characters + // Advance is the scaled glyph width plus 1px of inter-character spacing. + width: Math.round(width * scale) + 1, + scale, atlas: this.atlas, bitmapUV: { x: startX, @@ -281,10 +295,9 @@ export class MinecraftFont { fallback: MinecraftFont | undefined private loaded = false + private loadPromise: Promise | undefined private assetPath: string private charCache = new Map() - private geoCache = new Map() - private materialCache = new Map() constructor(id: string, assetPath: string, fallback?: MinecraftFont) { this.id = id @@ -312,27 +325,41 @@ export class MinecraftFont { return font } - async load() { - if (this.loaded) return this + load(): Promise { + if (this.loaded) return Promise.resolve(this) + // Guard against concurrent callers (many text displays refresh at once) + // re-entering and pushing the provider list twice. + this.loadPromise ??= this.doLoad().catch(error => { + this.loadPromise = undefined + throw error + }) + return this.loadPromise + } - if (!(await hasAsset(Project.animated_java.target_minecraft_version, this.assetPath))) { - throw new Error(`Font ${this.id} does not exist at ${this.assetPath}`) - } + private async doLoad() { + if (this.loaded) return this - let fontJSON: MinecraftJson.Font + // Fonts stack: a resource pack's font definition prepends its providers to + // the ones below it (and to vanilla) rather than replacing them. Read the + // definition from every layer and concatenate, highest priority first. + let fontJSONs: MinecraftJson.Font[] try { - fontJSON = (await getJSONAsset( + fontJSONs = (await getAllJSONAssets( Project.animated_java.target_minecraft_version, this.assetPath - )) as MinecraftJson.Font + )) as MinecraftJson.Font[] } catch (error) { console.error(`Failed to load font JSON from ${this.assetPath}:`, error) throw error } - // console.log(this.assetPath, fontJSON) + if (fontJSONs.length === 0) { + throw new Error(`Font ${this.id} does not exist at ${this.assetPath}`) + } + + const providerJSONs = fontJSONs.flatMap(fontJSON => fontJSON.providers ?? []) - for (const providerJSON of fontJSON.providers) { + for (const providerJSON of providerJSONs) { switch (providerJSON.type) { case 'bitmap': this.providers.push(new BitmapFontProvider(providerJSON)) @@ -344,13 +371,25 @@ export class MinecraftFont { this.providers.push(new SpaceFontProvider(providerJSON)) break default: - throw new Error( - `Unsupported font provider type: ${(providerJSON as any).type as string}` + console.warn( + `Skipping unsupported font provider type '${ + (providerJSON as any).type as string + }' in font '${this.id}'` ) } } - await Promise.all(this.providers.map(provider => provider.load())) + // One broken provider (e.g. an unsupported nested type) shouldn't take down + // the whole font - drop the failures and keep what loaded. + const results = await Promise.allSettled(this.providers.map(provider => provider.load())) + this.providers = this.providers.filter((provider, i) => { + if (results[i].status === 'fulfilled') return true + console.warn( + `Font provider (${provider.type}) failed to load in font '${this.id}':`, + (results[i] as PromiseRejectedResult).reason + ) + return false + }) this.loaded = true return this @@ -371,399 +410,39 @@ export class MinecraftFont { return createMissingCharacter() } - async getTextWidth(text: UnicodeString, span?: StyleSpan) { - let width = 0 - const boldExtra = span?.style.bold ? 1 : 0 - let font: MinecraftFont = this - - if (span?.style.font && span.style.font !== this.id) { - const newFont = await MinecraftFont.getById(span.style.font) - if (newFont) font = newFont - } - - for (const char of text) { - if (char === '\n') break - const charData = font.getChar(char) - if (!charData) { - console.warn('Encountered unknown character while getting text width:', char) - continue - } - - width += charData.width + boldExtra - } - - return Math.max(width, 0) - } - - async getWordWidth(word: Word) { - let width = 0 - let font: MinecraftFont = this - - for (const span of word.styles) { - if (span.style.font && span.style.font !== this.id) { - const newFont = await MinecraftFont.getById(span.style.font) - if (newFont) font = newFont - } - const text = word.text.slice(span.start, span.end) - const textWidth = await font.getTextWidth(text, span) - width += textWidth - } - - return Math.max(width, 0) + /** Advance of one code point, matching Minecraft's `StringSplitter` width + * provider (glyph advance + bold pixel). `style.font` must already be loaded + * (see {@link preloadReferencedFonts}). */ + getCodePointWidth(codePoint: string, style: TextComponentStyle): number { + const font = this.resolveFont(style.font) + return font.getChar(codePoint).width + (style.bold ? 1 : 0) } - getColorMaterial( - color: tinycolor.Instance, - minecraftVersion = Project.animated_java.target_minecraft_version - ): THREE.Material { - const cacheKey = color.toHex8String() + ';' + minecraftVersion - let material = this.materialCache.get(cacheKey) - if (!material) { - const alpha = color.getAlpha() - if (alpha < 1) { - material = new THREE.MeshBasicMaterial({ - color: color.toHexString(), - transparent: true, - opacity: alpha, - }) - } else { - material = new THREE.MeshBasicMaterial({ color: color.toHexString() }) - } - this.materialCache.set(cacheKey, material) - } - return material - } - - // TODO - Add support for rendering object text components - async generateTextDisplayMesh({ - jsonText, - maxLineWidth = TextDisplay.properties.maxLineWidth.default, - backgroundColor = tinycolor(TextDisplay.properties.backgroundColor.default), - shadow = TextDisplay.properties.shadow.default, - alignment = TextDisplay.properties.align.default, - }: { - jsonText: TextComponent - maxLineWidth?: number - backgroundColor?: tinycolor.Instance - /** Whether or not to render any text shadow */ - shadow?: boolean - alignment?: Alignment - }) { - const stopwatch = new Stopwatch('Generate Text Display Mesh').start() - - const { lines, backgroundWidth } = await wrapJsonText(jsonText, maxLineWidth) - const width = backgroundWidth + 1 - const height = (lines.length || 1) * 10 + 1 - - const spanGeos: THREE.BufferGeometry[] = [] - const spanMaterials: THREE.Material[] = [] - const cursor = { x: 0, y: height - 9 } - for (const line of lines) { - switch (alignment) { - case 'center': - cursor.x = -width / 2 + Math.ceil((width - line.width) / 2) - break - case 'right': - cursor.x = -width / 2 + width - line.width - break - default: - cursor.x = -width / 2 + 1 - } - - for (const word of line.words) { - for (const span of word.styles) { - const charGeos: THREE.BufferGeometry[] = [] - const shadowGeos: THREE.BufferGeometry[] = [] - - const text = word.text.slice(span.start, span.end) - for (const char of text) { - const charGeo = await this.getCharGeo(char, span.style) - - if (!charGeo) { - console.error('Failed to get character geometry:', char) - continue - } - - if (charGeo.geo) { - const clone = charGeo.geo.clone() - clone.translate(cursor.x, cursor.y, 0) - charGeos.push(clone) - if (shadow) { - const shadowGeo = charGeo.geo.clone() - shadowGeo.translate(cursor.x + 1, cursor.y - 1, -0.01) - shadowGeos.push(shadowGeo) - } - } - - cursor.x += charGeo.width - } - - if (charGeos.length > 0) { - spanGeos.push(mergeGeometries(charGeos)!) - - const color = TextComponent.getColor(span.style.color ?? COLORS.white) - spanMaterials.push(this.getColorMaterial(color)) - - if (shadow && shadowGeos.length > 0) { - spanGeos.push(mergeGeometries(shadowGeos)!) - - if (span.style.shadow_color) { - spanMaterials.push( - this.getColorMaterial( - TextComponent.getColor(span.style.shadow_color) - ) - ) - } else { - // Default shadow color is 25% the brightness of the main color - spanMaterials.push( - this.getColorMaterial( - // This version of tinycolor doesn't have a multiply method... - tinycolor( - new THREE.Color(color.toHexString()) - .multiplyScalar(0.25) - .getHexString() - ) - ) - ) - } - } - } - } - } - - cursor.y -= 10 - } - - const mesh = new THREE.Mesh() - - // Transforms a geometry to emulate how Minecraft renders text in the world - const transform = (geo: THREE.BufferGeometry) => { - geo.scale(0.4, 0.4, 0.4) - geo.rotateY(Math.PI) - geo.translate(1 / 5, 0, 0) - return geo - } - - if (spanGeos.length > 0) { - const charGeo = transform(mergeGeometries(spanGeos, true)!) - const textMesh = new THREE.Mesh(charGeo, spanMaterials) - textMesh.name = 'text' - mesh.add(textMesh) + /** The already-loaded font `fontId` refers to, or this font if it isn't set + * or isn't loaded. */ + resolveFont(fontId: string | undefined): MinecraftFont { + if (fontId && fontId !== this.id) { + return MinecraftFont.all.get(fontId) ?? this } - - const backgroundGeo = transform( - // Align bottom-middle of the background with origin, and move it slightly backwards to avoid z-fighting with text. - // Minecraft applies the same backwards offset to prevent z-fighting. - new THREE.PlaneBufferGeometry(width, height).translate(0, height / 2, -0.05) - ) - const backgroundMesh = new THREE.Mesh( - backgroundGeo, - new THREE.MeshBasicMaterial({ - color: backgroundColor.toHexString(), - opacity: backgroundColor.getAlpha(), - transparent: true, - }) - ) - backgroundMesh.name = 'background' - mesh.add(backgroundMesh) - - const outline = new THREE.LineSegments( - new THREE.EdgesGeometry(backgroundGeo), - Canvas.outlineMaterial - ) - outline.no_export = true - outline.renderOrder = 2 - outline.frustumCulled = false - - stopwatch.debug({ mesh, hitbox: backgroundGeo, outline }) - return { mesh, hitbox: backgroundGeo, outline } + return this } +} - async getCharGeo( - char: string, - style: TextComponentStyle, - minecraftVersion = Project.animated_java.target_minecraft_version - ): Promise { - let font: MinecraftFont = this - if (style.font) { - const newFont = await MinecraftFont.getById(style.font) - if (newFont) font = newFont - } - - const hash = createHash('sha256') - hash.update(char) - hash.update(';' + minecraftVersion) - hash.update(';' + font.id) - if (style.bold) hash.update(';bold') - if (style.italic) hash.update(';italic') - if (style.underlined) hash.update(';underlined') - if (style.strikethrough) hash.update(';strikethrough') - const digest = hash.digest('hex') - - const charData = font.getChar(char) - const boldExtra = style.bold ? 1 : 0 - - let charGeo = this.geoCache.get(digest) - - if (charGeo === undefined) { - const canvas = document.createElement('canvas') - if (charData.type === 'space') { - canvas.width = charData.width - canvas.height = 7 - } else { - canvas.width = charData.bitmapUV.width - canvas.height = charData.bitmapUV.height - } - - const ctx = canvas.getContext('2d', { willReadFrequently: true })! - ctx.imageSmoothingEnabled = false - ctx.clearRect(0, 0, canvas.width, canvas.height) - - if (charData.type !== 'space') { - ctx.drawImage( - charData.atlas.image, - charData.bitmapUV.x, - charData.bitmapUV.y, - charData.bitmapUV.width, - charData.bitmapUV.height, - 0, - 0, - canvas.width, - canvas.height - ) - } - - const data = ctx.getImageData(0, 0, canvas.width, canvas.height) - - const geo = new THREE.BufferGeometry() - - const geoData = { - vertices: [] as number[], - indices: [] as number[], - uvs: [] as number[], - } - - const createQuad = (x: number, y: number, w: number, h: number) => { - const vertIndex = geoData.vertices.length / 3 - // prettier-ignore - geoData.vertices.push( - x, y, 0, - x + w, y, 0, - x + w, y + h, 0, - x, y + h, 0 - ) - geoData.indices.push( - vertIndex, - vertIndex + 1, - vertIndex + 2, - vertIndex, - vertIndex + 2, - vertIndex + 3 - ) - } - - if (charData.type !== 'space') { - // Generate a quad for each pixel in the character - // This also attempts to make a single quad for each horizontal line of connected pixels - for (let y = 0; y < canvas.height; y++) { - const ascent = -y + charData.ascent - let width = 0 - for (let x = 0; x < canvas.width; x++) { - const i = (y * canvas.width + x) * 4 - const alpha = data.data[i + 3] - if (alpha === 0) { - if (width > 0) { - createQuad(x - width, ascent, width + boldExtra, 1) - width = 0 - } - continue - } else { - width++ - } - } - if (width > 0) { - createQuad(canvas.width - width, ascent, width + boldExtra, 1) - } - } - } - - geo.setIndex(geoData.indices) - geo.setAttribute( - 'position', - new THREE.BufferAttribute(new Float32Array(geoData.vertices), 3) - ) - if (style.italic) { - geo.applyMatrix4(new THREE.Matrix4().makeShear(0, 0, 0.2, 0, 0, 0)) - geo.translate(-1, 0, 0) - } - - geoData.vertices = Array.from(geo.getAttribute('position').array) - geoData.indices = Array.from(geo.getIndex()!.array) - - if (style.underlined) { - createQuad(-1, -1, canvas.width + 2, 1) - } - - if (charData.type === 'space') { - if (style.strikethrough) { - const ascent = 7 / 2 - createQuad(-1, ascent, canvas.width + 2, 1) - } - } else { - if (style.strikethrough) { - const ascent = charData.ascent / 2 - createQuad(-1, ascent, canvas.width + 2, 1) - } - } - - geo.setIndex(geoData.indices) - geo.setAttribute( - 'position', - new THREE.BufferAttribute(new Float32Array(geoData.vertices), 3) - ) - - geo.attributes.position.needsUpdate = true - charGeo = { - geo, - width: charData.width + boldExtra, - } +/** + * Drops every loaded font (and its cached atlases/glyph metrics). Call when the + * preview resource pack changes so custom fonts are re-read from the overlay. + * Pair with `fontRenderer`'s `clearGlyphGeometryCache()`. + */ +export function clearFontCache() { + MinecraftFont.all.clear() +} - this.geoCache.set(digest, charGeo) - } - return charGeo +/** Loads every `style.font` in `segments` up front, so the synchronous width + * provider `wrapText` uses can resolve them. Must finish before wrapping. */ +export async function preloadReferencedFonts(segments: StyledSegment[]) { + const ids = new Set() + for (const { style } of segments) { + if (style.font) ids.add(style.font) } + await Promise.all([...ids].map(id => MinecraftFont.getById(id))) } - -// let vanillaFont: MinecraftFont -// let illagerFont: MinecraftFont -// let standardGalacticAlphabetFont: MinecraftFont -// async function loadMinecraftFonts() { -// console.log('Loading Minecraft fonts...') - -// vanillaFont = new MinecraftFont('minecraft:default', 'assets/minecraft/font/default.json') -// illagerFont = new MinecraftFont( -// 'minecraft:illageralt', -// 'assets/minecraft/font/illageralt.json', -// vanillaFont -// ) -// standardGalacticAlphabetFont = new MinecraftFont( -// 'minecraft:alt', -// 'assets/minecraft/font/alt.json', -// vanillaFont -// ) - -// await Promise.all([ -// vanillaFont.load(), -// illagerFont.load(), -// standardGalacticAlphabetFont.load(), -// ]).then(() => { -// console.log('Minecraft fonts loaded!') -// }) -// } - -// export async function getVanillaFont() { -// if (!vanillaFont) { -// await loadMinecraftFonts() -// } -// return vanillaFont.load() -// } diff --git a/src/systems/minecraft/fontRenderer.ts b/src/systems/minecraft/fontRenderer.ts new file mode 100644 index 00000000..74d2f7c6 --- /dev/null +++ b/src/systems/minecraft/fontRenderer.ts @@ -0,0 +1,568 @@ +import { + COLORS, + resolveComponent, + TextComponent, + wrapText, + type Color, + type ShadowColor, + type TextComponentStyle, +} from 'book-and-quill' +import type { Alignment } from '../../outliner/textDisplay' +import { Stopwatch } from '../../util/stopwatch' +import { getJSONAsset, getPreviewResourcePackKey } from './assetManager' +import { MinecraftFont, preloadReferencedFonts, type CachedChar } from './fontManager' + +// Turns a text component into THREE.js geometry. +// +// The whole thing is cache-heavy because `updateTextMesh` runs on every property +// change (typing, dragging a colour picker, toggling shadow): glyph geometry, +// resolved colours and language data survive across renders, and a component's +// full wrapped layout is cached so option-only changes skip resolve + wrap. + +const DEFAULT_MAX_LINE_WIDTH = 200 +const DEFAULT_BACKGROUND_COLOR = '#00000040' +const DEFAULT_ALIGNMENT: Alignment = 'center' + +// Style flags packed into a nibble; keys every place a glyph's look depends on style. +const BOLD = 1 +const ITALIC = 2 +const UNDERLINED = 4 +const STRIKETHROUGH = 8 +function styleFlags(style: TextComponentStyle): number { + return ( + (style.bold ? BOLD : 0) | + (style.italic ? ITALIC : 0) | + (style.underlined ? UNDERLINED : 0) | + (style.strikethrough ? STRIKETHROUGH : 0) + ) +} + +// --------------------------------------------------------------------------- +// Caches (all cleared together by clearGlyphGeometryCache) +// --------------------------------------------------------------------------- + +/** + * A glyph in glyph-local pixel space, pre-expanded to triangles so layout is + * offset-and-copy. `tris`/`trisUV` are absent for whitespace; `decoTris` holds + * 0-2 underline/strikethrough bars. + */ +interface GlyphGeo { + tris?: Float32Array + trisUV?: Float32Array + atlas?: THREE.Texture + decoTris: Float32Array[] + /** Advance width in pixels (glyph advance + bold pixel). */ + width: number +} + +// version -> fontId -> char -> [styleFlags 0..15] +const GLYPH_GEO_CACHE = new Map>>>() +// raw colour value -> resolved THREE colour + alpha, kept across renders +const COLOR_CACHE = new Map() +// version + previewPackKey -> parsed language map +const LANG_CACHE = new Map>() +// version + text + maxLineWidth -> wrapped, laid-out glyph list (alignment/shadow independent) +const LAYOUT_CACHE = new Map() +const LAYOUT_CACHE_LIMIT = 48 + +/** Drops cached glyph geometry, colours, language data and layouts. Pair with + * `fontManager`'s `clearFontCache()`. */ +export function clearGlyphGeometryCache() { + GLYPH_GEO_CACHE.clear() + COLOR_CACHE.clear() + LANG_CACHE.clear() + LAYOUT_CACHE.clear() +} + +interface ColorInfo { + color: THREE.Color + opacity: number +} + +function colorKey(value: Color | ShadowColor): string { + return typeof value === 'string' ? value : JSON.stringify(value) +} + +/** Resolved THREE colour + alpha for an explicit colour value. Memoised across + * renders - these come straight from an 8-bit hex so there's no rounding drift. */ +function colorInfo(value: Color | ShadowColor): ColorInfo { + let info = COLOR_CACHE.get(colorKey(value)) + if (!info) { + const tc = TextComponent.getColor(value) + info = { color: new THREE.Color(tc.toHexString()), opacity: tc.getAlpha() } + COLOR_CACHE.set(colorKey(value), info) + } + return info +} + +/** `getHexString();opacity` - the per-colour part of a batch key, as the + * pre-merge renderer formed it. */ +const infoKey = (i: ColorInfo) => i.color.getHexString() + ';' + i.opacity.toFixed(3) + +async function getLangMap(version: string): Promise> { + const cacheKey = version + '\0' + getPreviewResourcePackKey() + let map = LANG_CACHE.get(cacheKey) + if (!map) { + map = (await getJSONAsset(version, 'assets/minecraft/lang/en_us.json')) as Record< + string, + string + > + LANG_CACHE.set(cacheKey, map) + } + return map +} + +// A quad's 4 corners are BL, BR, TR, TL; expand to two triangles (BL,BR,TR then BL,TR,TL). +function quadTris(x: number, y: number, w: number, h: number): number[] { + const x1 = x + w + const y1 = y + h + // prettier-ignore + return [x, y, 0, x1, y, 0, x1, y1, 0, x, y, 0, x1, y1, 0, x, y1, 0] +} + +/** Italic shear, matching Minecraft: x' = x + 0.2 * y - 1. Mutates in place. */ +function shearInPlace(tris: Float32Array): void { + for (let i = 0; i < tris.length; i += 3) { + tris[i] = tris[i] + 0.2 * tris[i + 1] - 1 + } +} + +function buildGlyphGeo(font: MinecraftFont, char: string, flags: number): GlyphGeo { + const charData: CachedChar = font.getChar(char) + const boldExtra = flags & BOLD ? 1 : 0 + const geo: GlyphGeo = { decoTris: [], width: charData.width + boldExtra } + + if (charData.type === 'bitmap') { + const image = charData.atlas.image as { width: number; height: number } | undefined + const { x: px, y: py, width: pw, height: ph } = charData.bitmapUV + const atlasW = image && image.width > 0 ? image.width : px + pw + const atlasH = image && image.height > 0 ? image.height : py + ph + + const glyphW = pw * charData.scale + boldExtra + const glyphH = ph * charData.scale + const top = charData.ascent + 1 + const tris = new Float32Array(quadTris(0, top - glyphH, glyphW, glyphH)) + if (flags & ITALIC) shearInPlace(tris) + geo.tris = tris + + const u0 = px / atlasW + const u1 = (px + pw) / atlasW + // The atlas keeps flipY (loader default), so v = 1 - imageY / atlasH. + const vTop = 1 - py / atlasH + const vBot = 1 - (py + ph) / atlasH + // Triangle order matching `tris`: BL, BR, TR, BL, TR, TL. + // prettier-ignore + geo.trisUV = new Float32Array([u0, vBot, u1, vBot, u1, vTop, u0, vBot, u1, vTop, u0, vTop]) + geo.atlas = charData.atlas + } + + const decoWidth = + (charData.type === 'space' ? charData.width : charData.bitmapUV.width * charData.scale) + 2 + if (flags & UNDERLINED) { + geo.decoTris.push(new Float32Array(quadTris(-1, -1, decoWidth, 1))) + } + if (flags & STRIKETHROUGH) { + const y = (charData.type === 'space' ? 7 : charData.ascent) / 2 + geo.decoTris.push(new Float32Array(quadTris(-1, y, decoWidth, 1))) + } + + return geo +} + +function getGlyphGeo(version: string, font: MinecraftFont, char: string, flags: number): GlyphGeo { + let byFont = GLYPH_GEO_CACHE.get(version) + if (!byFont) GLYPH_GEO_CACHE.set(version, (byFont = new Map())) + let byChar = byFont.get(font.id) + if (!byChar) byFont.set(font.id, (byChar = new Map())) + let byFlags = byChar.get(char) + if (!byFlags) byChar.set(char, (byFlags = [])) + return byFlags[flags] ?? (byFlags[flags] = buildGlyphGeo(font, char, flags)) +} + +// --------------------------------------------------------------------------- +// Layout (wrap + place), cached per (version, text, maxLineWidth) +// --------------------------------------------------------------------------- + +interface GlyphPlacement { + geo: GlyphGeo + /** x offset from the line's start (alignment-independent). */ + relX: number + /** `style.color ?? white` - looked up through {@link colorInfo} per render. */ + mainColor: Color | ShadowColor + /** explicit `style.shadow_color`, or undefined for the derived default shadow. */ + shadowColor: ShadowColor | undefined +} + +interface LineLayout { + /** Minecraft's `Font.width(line)` - what alignment offsets are measured against. */ + width: number + /** baseline y for this line in pixel space. */ + y: number + glyphs: GlyphPlacement[] +} + +interface TextLayout { + /** raw `wrapText` width (widest line), before the `max(_, 1)` clamp. */ + layoutWidth: number + /** background height in pixels: lineCount * 10 + 1. */ + height: number + lines: LineLayout[] +} + +function buildLayout( + version: string, + baseFont: MinecraftFont, + segments: ReturnType, + maxLineWidth: number +): TextLayout { + const { lines, width: layoutWidth } = wrapText(segments, maxLineWidth, (codePoint, style) => + baseFont.getCodePointWidth(codePoint, style) + ) + + const lineCount = lines.length || 1 + const height = lineCount * 10 + 1 + + const outLines: LineLayout[] = [] + let y = height - 9 + for (const line of lines) { + const glyphs: GlyphPlacement[] = [] + let relX = 0 + for (const segment of line.segments) { + const style = segment.style + const styledFont = baseFont.resolveFont(style.font) + const flags = styleFlags(style) + const mainColor = style.color ?? (COLORS.white as Color) + const shadowColor = style.shadow_color + for (const char of segment.text) { + const geo = getGlyphGeo(version, styledFont, char, flags) + if (geo.tris || geo.decoTris.length > 0) { + glyphs.push({ geo, relX, mainColor, shadowColor }) + } + relX += geo.width + } + } + outLines.push({ width: line.width, y, glyphs }) + y -= 10 + } + + return { layoutWidth, height, lines: outLines } +} + +// --------------------------------------------------------------------------- +// Mesh generation +// --------------------------------------------------------------------------- + +export interface TextDisplayMesh { + mesh: THREE.Mesh + hitbox: THREE.BufferGeometry + outline: THREE.LineSegments +} + +export interface TextDisplayMeshOptions { + jsonText: TextComponent + /** Stable identifier for `jsonText` (e.g. its raw source string). Enables the + * layout cache - option-only changes then skip resolve + wrap. */ + cacheKey?: string + maxLineWidth?: number + backgroundColor?: tinycolor.Instance + /** Whether or not to render any text shadow */ + shadow?: boolean + alignment?: Alignment +} + +// Minecraft's world transform for text: scale 0.4, flip 180deg, nudge +0.2px x. +// Applied as three passes (not one combined matrix) so the vertex data is +// bit-for-bit what the pre-merge renderer produced. +function transformed(geo: THREE.BufferGeometry): THREE.BufferGeometry { + geo.scale(0.4, 0.4, 0.4) + geo.rotateY(Math.PI) + geo.translate(1 / 5, 0, 0) + return geo +} + +// One textured draw for every glyph sharing an atlas, coloured per vertex (RGBA) +// so many text colours collapse into a single mesh / draw call. +interface TexBatch { + atlas: THREE.Texture + quads: number + pos: Float32Array + uv: Float32Array + col: Float32Array + pw: number + uw: number + cw: number +} +/** A solid batch: decoration quads of one colour. */ +interface SolidBatch { + color: THREE.Color + opacity: number + quads: number + pos: Float32Array + pw: number +} + +function writeQuadPos( + pos: Float32Array, + at: number, + tris: Float32Array, + dx: number, + dy: number, + dz: number +): void { + for (let k = 0; k < 18; k += 3) { + pos[at] = tris[k] + dx + pos[at + 1] = tris[k + 1] + dy + pos[at + 2] = tris[k + 2] + dz + at += 3 + } +} + +function writeTexQuad( + b: TexBatch, + tris: Float32Array, + uv: Float32Array, + dx: number, + dy: number, + dz: number, + c: ColorInfo +): void { + writeQuadPos(b.pos, b.pw, tris, dx, dy, dz) + b.pw += 18 + b.uv.set(uv, b.uw) + b.uw += 12 + const { r, g, b: bl } = c.color + const a = c.opacity + let w = b.cw + for (let v = 0; v < 6; v++) { + b.col[w] = r + b.col[w + 1] = g + b.col[w + 2] = bl + b.col[w + 3] = a + w += 4 + } + b.cw = w +} + +// TODO - Add support for rendering object text components +export async function generateTextDisplayMesh({ + jsonText, + cacheKey, + maxLineWidth = DEFAULT_MAX_LINE_WIDTH, + backgroundColor = tinycolor(DEFAULT_BACKGROUND_COLOR), + shadow = false, + alignment = DEFAULT_ALIGNMENT, +}: TextDisplayMeshOptions): Promise { + const stopwatch = new Stopwatch('Generate Text Display Mesh').start() + + const version = Project.animated_java.target_minecraft_version + const font = await MinecraftFont.getById('minecraft:default') + if (!font) throw new Error('Could not load the default Minecraft font') + + // --- Wrap + place (cached per component) ------------------------------ + const layoutKey = + cacheKey === undefined ? undefined : version + '\0' + maxLineWidth + '\0' + cacheKey + let layout = layoutKey === undefined ? undefined : LAYOUT_CACHE.get(layoutKey) + if (!layout) { + const lang = await getLangMap(version) + const segments = resolveComponent(jsonText, { translate: key => lang[key] }) + await preloadReferencedFonts(segments) + layout = buildLayout(version, font, segments, maxLineWidth) + if (layoutKey !== undefined) { + if (LAYOUT_CACHE.size >= LAYOUT_CACHE_LIMIT) LAYOUT_CACHE.clear() + LAYOUT_CACHE.set(layoutKey, layout) + } + } + + // --- Layout metrics -------------------------------------------------- + const layoutW = Math.max(layout.layoutWidth, 1) + const width = layoutW + 1 + const height = layout.height + const lineStartX = (lineWidth: number) => + alignment === 'center' + ? 1 - lineWidth / 2 + : alignment === 'right' + ? 1 + layoutW / 2 - lineWidth + : 1 - layoutW / 2 + + // The derived default shadow is 25% of the main colour. Memoised per main + // value so it is computed once per distinct colour, not once per glyph. + const shadowRaw = new Map() + const rawShadow = (mainValue: Color | ShadowColor): ColorInfo => { + let info = shadowRaw.get(colorKey(mainValue)) + if (!info) { + const main = colorInfo(mainValue) + info = { color: main.color.clone().multiplyScalar(0.25), opacity: main.opacity } + shadowRaw.set(colorKey(mainValue), info) + } + return info + } + + // --- Batches: one textured mesh per atlas for glyphs and for shadows, --- + // coloured per vertex; decorations stay per-colour (rare, keeps their key). + const mainGlyphs = new Map() + const shadowGlyphs = new Map() + const solids = new Map() + + const glyphBatchFor = (map: Map, atlas: THREE.Texture) => { + let b = map.get(atlas) + if (!b) { + map.set( + atlas, + (b = { atlas, quads: 0, pos: null!, uv: null!, col: null!, pw: 0, uw: 0, cw: 0 }) + ) + } + return b + } + const mainGlyphFor = (atlas: THREE.Texture) => glyphBatchFor(mainGlyphs, atlas) + const shadowGlyphFor = (atlas: THREE.Texture) => glyphBatchFor(shadowGlyphs, atlas) + const solidFor = (info: ColorInfo) => { + const key = infoKey(info) + let b = solids.get(key) + if (!b) + solids.set( + key, + (b = { color: info.color, opacity: info.opacity, quads: 0, pos: null!, pw: 0 }) + ) + return b + } + const shadowInfoOf = (g: GlyphPlacement) => + g.shadowColor ? colorInfo(g.shadowColor) : rawShadow(g.mainColor) + + // --- Pass 1: count quads per batch (establishes solids' first-wins) --- + for (const line of layout.lines) { + for (const g of line.glyphs) { + const geo = g.geo + if (geo.tris) { + mainGlyphFor(geo.atlas!).quads++ + if (shadow) shadowGlyphFor(geo.atlas!).quads++ + } + if (geo.decoTris.length > 0) { + solidFor(colorInfo(g.mainColor)).quads += geo.decoTris.length + if (shadow) solidFor(shadowInfoOf(g)).quads += geo.decoTris.length + } + } + } + + // --- Allocate ------------------------------------------------------ + for (const b of mainGlyphs.values()) { + b.pos = new Float32Array(b.quads * 18) + b.uv = new Float32Array(b.quads * 12) + b.col = new Float32Array(b.quads * 24) + } + for (const b of shadowGlyphs.values()) { + b.pos = new Float32Array(b.quads * 18) + b.uv = new Float32Array(b.quads * 12) + b.col = new Float32Array(b.quads * 24) + } + for (const b of solids.values()) b.pos = new Float32Array(b.quads * 18) + + // --- Pass 2: write vertices -------------------------------------- + for (const line of layout.lines) { + const startX = lineStartX(line.width) + const y = line.y + for (const g of line.glyphs) { + const geo = g.geo + const x = startX + g.relX + const mainInfo = colorInfo(g.mainColor) + if (geo.tris) { + const atlas = geo.atlas! + writeTexQuad(mainGlyphFor(atlas), geo.tris, geo.trisUV!, x, y, 0, mainInfo) + if (shadow) { + writeTexQuad( + shadowGlyphFor(atlas), + geo.tris, + geo.trisUV!, + x + 1, + y - 1, + -0.01, + shadowInfoOf(g) + ) + } + } + if (geo.decoTris.length > 0) { + const dm = solidFor(mainInfo) + const sm = shadow ? solidFor(shadowInfoOf(g)) : undefined + for (const deco of geo.decoTris) { + writeQuadPos(dm.pos, dm.pw, deco, x, y, 0) + dm.pw += 18 + if (sm) { + writeQuadPos(sm.pos, sm.pw, deco, x + 1, y - 1, -0.01) + sm.pw += 18 + } + } + } + } + } + + // --- Build THREE meshes ----------------------------------------- + const mesh = new THREE.Mesh() + + const addTexBatch = (b: TexBatch) => { + if (b.quads === 0) return + const g = new THREE.BufferGeometry() + g.setAttribute('position', new THREE.BufferAttribute(b.pos, 3)) + g.setAttribute('uv', new THREE.BufferAttribute(b.uv, 2)) + g.setAttribute('color', new THREE.BufferAttribute(b.col, 4)) + transformed(g) + const child = new THREE.Mesh( + g, + new THREE.MeshBasicMaterial({ + map: b.atlas, + vertexColors: true, + transparent: true, + alphaTest: 0.01, + // Minecraft text displays only draw their front face. + side: THREE.FrontSide, + }) + ) + child.name = 'text' + mesh.add(child) + } + for (const b of mainGlyphs.values()) addTexBatch(b) + for (const b of shadowGlyphs.values()) addTexBatch(b) + + for (const b of solids.values()) { + if (b.quads === 0) continue + const g = new THREE.BufferGeometry() + g.setAttribute('position', new THREE.BufferAttribute(b.pos, 3)) + transformed(g) + const child = new THREE.Mesh( + g, + new THREE.MeshBasicMaterial({ + color: b.color, + transparent: b.opacity < 1, + opacity: b.opacity, + side: THREE.FrontSide, + }) + ) + child.name = 'text' + mesh.add(child) + } + + const backgroundGeo = transformed( + // Plane spanning y in [0, height], so its top edge sits 1px above the + // first line's glyphs. -z avoids z-fighting with the text (Minecraft too). + new THREE.PlaneBufferGeometry(width, height).translate(0.5, height / 2, -0.05) + ) + const backgroundMesh = new THREE.Mesh( + backgroundGeo, + new THREE.MeshBasicMaterial({ + color: backgroundColor.toHexString(), + opacity: backgroundColor.getAlpha(), + transparent: true, + }) + ) + backgroundMesh.name = 'background' + mesh.add(backgroundMesh) + + const outline = new THREE.LineSegments( + new THREE.EdgesGeometry(backgroundGeo), + Canvas.outlineMaterial + ) + outline.no_export = true + outline.renderOrder = 2 + outline.frustumCulled = false + + stopwatch.debug({ mesh, hitbox: backgroundGeo, outline }) + return { mesh, hitbox: backgroundGeo, outline } +} diff --git a/vitest.config.ts b/vitest.config.ts index ba83ee18..3f0b2fbd 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -3,5 +3,13 @@ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { dir: 'src/tests', + server: { + deps: { + // `book-and-quill` and its `generic-stream` dep ship extensionless + // ESM imports that Node's native resolver rejects; inlining lets + // Vite/esbuild transform them the way the plugin build does. + inline: ['book-and-quill', 'generic-stream'], + }, + }, }, }) From c080f471c9fd26b5d1e51dc99f35445c79156d06 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 19:43:56 -0400 Subject: [PATCH 16/85] =?UTF-8?q?=E2=9C=A8=20Add=20editor=20preview=20reso?= =?UTF-8?q?urce=20pack=20overlay?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - new Blueprint Settings "Preview" page overlays resource pack folders or .zip archives on vanilla assets, in the editor only - never exported; separate from the blueprint's own resource pack - packs stack by priority; changing them invalidates the asset caches and refreshes affected displays --- .../blueprintSettings/blueprintSettings.ts | 6 + .../blueprintSettings/pages/preview.svelte | 277 ++++++++++++++++++ src/formats/blueprint/settings.ts | 90 ++++++ src/index.ts | 1 + src/lang/en.yml | 26 ++ src/systems/minecraft/blockModelManager.ts | 6 + src/systems/minecraft/bmrModelRenderer.ts | 23 +- src/systems/minecraft/itemModelManager.ts | 6 + src/systems/minecraft/previewResourcePack.ts | 95 ++++++ 9 files changed, 524 insertions(+), 6 deletions(-) create mode 100644 src/dialogs/blueprintSettings/pages/preview.svelte create mode 100644 src/systems/minecraft/previewResourcePack.ts diff --git a/src/dialogs/blueprintSettings/blueprintSettings.ts b/src/dialogs/blueprintSettings/blueprintSettings.ts index 7f6b6023..4f7d4a6b 100644 --- a/src/dialogs/blueprintSettings/blueprintSettings.ts +++ b/src/dialogs/blueprintSettings/blueprintSettings.ts @@ -18,6 +18,7 @@ import EventFunctionsComponent from './pages/eventFunctions.svelte' import GeneralComponent from './pages/general.svelte' import MiscComponent from './pages/misc.svelte' import PluginComponent from './pages/plugin.svelte' +import PreviewComponent from './pages/preview.svelte' import ResourcepackComponent from './pages/resourcepack.svelte' import RigComponent from './pages/rig.svelte' @@ -65,6 +66,11 @@ export function openBlueprintSettings() { label: localize('pages.plugin.title'), icon: 'fa-paper-plane', }, + preview: { + component: PreviewComponent, + label: localize('pages.preview.title'), + icon: 'visibility', + }, misc: { component: MiscComponent, label: localize('pages.misc.title'), diff --git a/src/dialogs/blueprintSettings/pages/preview.svelte b/src/dialogs/blueprintSettings/pages/preview.svelte new file mode 100644 index 00000000..fb8df392 --- /dev/null +++ b/src/dialogs/blueprintSettings/pages/preview.svelte @@ -0,0 +1,277 @@ + + +
+
+ {translate('preview.list.title')} + +
+
{@html translate('preview.list.hint')}
+ + {#if packs.length === 0} +

{translate('preview.list.empty')}

+ {:else} +
+ {#each packs as _, index (index)} +
+
+ {index + 1} +
+ + browseZip(index)} + > + browseFolder(index)} + > +
+
+ movePack(index, -1)} + > + movePack(index, 1)} + > + removePack(index)} + > +
+
+ {#if checks[index]} +
+ {@html checks[index]?.message} +
+ {/if} +
+ {/each} +
+ {/if} + + {#if packs.some(p => p.trim() !== '')} + + {/if} +
+ + diff --git a/src/formats/blueprint/settings.ts b/src/formats/blueprint/settings.ts index 4cdd5f52..c232a63f 100644 --- a/src/formats/blueprint/settings.ts +++ b/src/formats/blueprint/settings.ts @@ -26,6 +26,9 @@ export interface BlueprintSettings { custom_model_data_offset: number enable_advanced_resource_pack_settings: boolean resource_pack: string + // Preview Settings + /** Editor-only resource pack overlays, highest priority first. */ + preview_resource_packs: string[] // Data Pack Settings enable_advanced_data_pack_settings: boolean data_pack: string @@ -63,6 +66,9 @@ export const defaultValues: BlueprintSettings = { enable_advanced_resource_pack_settings: false, resource_pack: '', + // Preview Settings + preview_resource_packs: [], + // Data Pack Settings enable_advanced_data_pack_settings: false, data_pack: '', @@ -237,6 +243,66 @@ export function validateResourcePackFolder(value: string): ValueCheckResult { } } +/** + * Validates the optional preview resource pack path. An empty value is fine (the + * feature is simply off). A `.zip` path is treated as a zipped pack; anything + * else is treated as an unzipped pack folder. + */ +export function validatePreviewResourcePack(value: string): ValueCheckResult { + if (value === '') return + + let path: string + try { + path = resolvePath(value) + } catch (error: any) { + console.error(error) + return { + type: 'error', + message: localize('resource_pack.folder.error.invalid_path', error.message), + } + } + + const { existsSync, statSync } = getFsModule() + + if (!existsSync(path)) { + return { + type: 'error', + message: localize('resource_pack.folder.error.does_not_exist'), + } + } + + if (/\.zip$/i.test(path)) { + if (statSync(path).isDirectory()) { + return { + type: 'error', + message: localize('preview.error.zip_is_a_dir'), + } + } + return + } + + if (!statSync(path).isDirectory()) { + return { + type: 'error', + message: localize('resource_pack.folder.error.not_a_dir'), + } + } + + if (!existsSync(join(path, 'pack.mcmeta'))) { + return { + type: 'error', + message: localize('resource_pack.folder.error.no_pack_mcmeta'), + } + } + + if (!existsSync(join(path, 'assets'))) { + return { + type: 'warning', + message: localize('resource_pack.folder.warning.no_assets'), + } + } +} + export function validateDataPackFolder(value: string): ValueCheckResult { if (value === '') { return { @@ -338,5 +404,29 @@ export async function validateThisProjectsBlueprintSettings(): Promise< Project.animated_java.data_pack_export_mode === 'zip' ? validateZipPath(Project.animated_java.data_pack) : undefined, + preview_resource_packs: validatePreviewResourcePacks( + Project.animated_java.preview_resource_packs + ), + } +} + +/** Reports the first error (or, failing that, warning) among the preview pack overlays. */ +export function validatePreviewResourcePacks(values: string[]): ValueCheckResult { + let firstWarning: ValueCheckResult | undefined + for (const [index, value] of values.entries()) { + const result = validatePreviewResourcePack(value) + if (result?.type === 'error') { + return { + type: 'error', + message: localize('preview.list.error.entry', String(index + 1), result.message), + } + } + if (result?.type === 'warning') { + firstWarning ??= { + type: 'warning', + message: localize('preview.list.warning.entry', String(index + 1), result.message), + } + } } + return firstWarning } diff --git a/src/index.ts b/src/index.ts index 374a1b1d..8dab4e00 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,6 +22,7 @@ import './systems/minecraft/assetManager' import './systems/minecraft/blockstateManager' import './systems/minecraft/fontManager' import './systems/minecraft/fontRenderer' +import './systems/minecraft/previewResourcePack' import './systems/minecraft/registryManager' import './systems/minecraft/versionManager' // Shaders diff --git a/src/lang/en.yml b/src/lang/en.yml index a38b5f87..82c37868 100644 --- a/src/lang/en.yml +++ b/src/lang/en.yml @@ -151,6 +151,7 @@ animated_java: rig.title: Rig event_functions.title: Event Functions plugin.title: Plugin + preview.title: Preview misc.title: Misc project_settings: @@ -289,6 +290,31 @@ animated_java: does_not_exist: Selected path does not exist. not_a_dir: Selected path is not a directory. no_pack_mcmeta: Selected folder does not contain a pack.mcmeta file. + preview: + list: + title: Preview Resource Packs + hint: |- + [Markdown] + Load custom Resource Packs to preview custom fonts, models, and textures directly in the editor. + + This only affects the editor preview - it is never exported, and does not replace your Blueprint's own Resource Pack. + + Each entry is a Resource Pack folder (containing a `pack.mcmeta` file) or a `.zip` archive. Packs higher in the list override packs below them. + add: Add Pack + empty: No preview Resource Packs. + placeholder: Path to a Resource Pack folder or .zip + browse_folder: Select a folder + browse_zip: Select a .zip file + move_up: Move up + move_down: Move down + remove: Remove + error: + entry: 'Pack %s: %s' + warning: + entry: 'Pack %s: %s' + error: + zip_is_a_dir: Path ends with `.zip` but is a folder. + reload: Reload Preview data_pack_settings: title: Data Pack data_pack: diff --git a/src/systems/minecraft/blockModelManager.ts b/src/systems/minecraft/blockModelManager.ts index 54335dd9..88d712a9 100644 --- a/src/systems/minecraft/blockModelManager.ts +++ b/src/systems/minecraft/blockModelManager.ts @@ -82,6 +82,12 @@ async function buildBlockModel( return { ...converted, isBlock: true } } +/** Drops every cached block model. Call when the preview resource pack changes. */ +export function clearBlockModelCache() { + BLOCK_MODEL_CACHE.clear() + BLOCK_MODEL_PENDING.clear() +} + export function validateBlockState(block: IParsedBlock) { if (!block.blockStateRegistryEntry) { if (Object.keys(block.states).length > 0) { diff --git a/src/systems/minecraft/bmrModelRenderer.ts b/src/systems/minecraft/bmrModelRenderer.ts index e040f0a5..7152165e 100644 --- a/src/systems/minecraft/bmrModelRenderer.ts +++ b/src/systems/minecraft/bmrModelRenderer.ts @@ -1,7 +1,7 @@ import * as bmr from 'block-model-renderer' import ASSETS_ZIP_URL from 'block-model-renderer/assets.zip' import { mergeGeometries } from '../../util/bufferGeometryUtils' -import { getAssetHandler } from './assetManager' +import { getAssetHandler, getPreviewResourcePackKey } from './assetManager' /** The editor-preview mesh for a vanilla item or block model. */ export interface RenderedModelMesh { @@ -23,20 +23,31 @@ type PreparedAssets = Awaited> const PREPARED_ASSETS_CACHE = new Map>() -/** A cached bmr asset bundle over the client jar for the given version. */ +/** A cached bmr asset bundle over the client jar (plus preview pack) for the given version. */ export async function getPreparedAssets(versionId: string): Promise { - let prepared = PREPARED_ASSETS_CACHE.get(versionId) + // The preview resource pack overlays the client jar, so its token is part of + // our cache key or a swapped pack keeps serving the old bundle. + const previewKey = getPreviewResourcePackKey() + const cacheKey = previewKey ? `${versionId}::${previewKey}` : versionId + let prepared = PREPARED_ASSETS_CACHE.get(cacheKey) if (!prepared) { prepared = (async () => { const handler = await getAssetHandler(versionId) - // `version` must be pinned here: the { cache: true } cache isn't version-aware. - return bmr.prepareAssets([handler], { cache: true, version: versionId }) + // bmr's { cache: true } store isn't version-aware, so `version` must be + // pinned to `versionId` (renders pass that same value). It also can't tell + // preview-pack overlays apart, so bypass it entirely while one is active. + return bmr.prepareAssets([handler], { cache: !previewKey, version: versionId }) })() - PREPARED_ASSETS_CACHE.set(versionId, prepared) + PREPARED_ASSETS_CACHE.set(cacheKey, prepared) } return prepared } +/** Drops every cached bmr asset bundle. Call when the preview resource pack changes. */ +export function clearPreparedAssetsCache() { + PREPARED_ASSETS_CACHE.clear() +} + function toPositionOnlyWorldGeometry( geometry: THREE.BufferGeometry, matrixWorld: THREE.Matrix4 diff --git a/src/systems/minecraft/itemModelManager.ts b/src/systems/minecraft/itemModelManager.ts index 2344fd0b..fd1fdba1 100644 --- a/src/systems/minecraft/itemModelManager.ts +++ b/src/systems/minecraft/itemModelManager.ts @@ -33,6 +33,12 @@ export async function getItemModel( return cloneRenderedModel(template, item) } +/** Drops every cached item model. Call when the preview resource pack changes. */ +export function clearItemModelCache() { + ITEM_MODEL_CACHE.clear() + ITEM_MODEL_PENDING.clear() +} + async function buildItemModel( item: string, itemDisplay: ItemDisplayMode, diff --git a/src/systems/minecraft/previewResourcePack.ts b/src/systems/minecraft/previewResourcePack.ts new file mode 100644 index 00000000..b5f03783 --- /dev/null +++ b/src/systems/minecraft/previewResourcePack.ts @@ -0,0 +1,95 @@ +import { TextDisplay } from '../../outliner/textDisplay' +import { VanillaBlockDisplay } from '../../outliner/vanillaBlockDisplay' +import { VanillaItemDisplay } from '../../outliner/vanillaItemDisplay' +import EVENTS from '../../util/events' +import { getPreviewResourcePackKey, setPreviewResourcePacks } from './assetManager' +import { clearBlockModelCache } from './blockModelManager' +import { clearPreparedAssetsCache } from './bmrModelRenderer' +import { clearFontCache } from './fontManager' +import { clearGlyphGeometryCache } from './fontRenderer' +import { clearItemModelCache } from './itemModelManager' + +/** The preview resource pack paths configured on the current project, highest priority first. */ +function getConfiguredPreviewResourcePacks(): string[] { + return Project?.animated_java?.preview_resource_packs ?? [] +} + +function invalidateCaches() { + clearPreparedAssetsCache() + clearItemModelCache() + clearBlockModelCache() + clearFontCache() + clearGlyphGeometryCache() +} + +function refreshDisplays() { + VanillaItemDisplay.forceUpdateAll() + VanillaBlockDisplay.forceUpdateAll() + TextDisplay.forceUpdateAll() + Canvas.updateAll() +} + +/** + * Loads the preview resource packs configured on the current project (or clears + * any previously loaded overlay), then rebuilds every affected preview so custom + * fonts, models, and textures show up in the editor. + */ +export async function applyPreviewResourcePack() { + const paths = getConfiguredPreviewResourcePacks() + const previousKey = getPreviewResourcePackKey() + + try { + await setPreviewResourcePacks(paths) + } catch (error) { + console.error('Failed to load preview resource packs:', error) + Blockbench.showQuickMessage( + 'Failed to load preview resource packs. See console for details.' + ) + await setPreviewResourcePacks([]) + } + + // Nothing changed, so there's no need to churn every cache and preview. + if (getPreviewResourcePackKey() === previousKey) return + + invalidateCaches() + refreshDisplays() +} + +EVENTS.SELECT_AJ_PROJECT.subscribe(() => { + requestAnimationFrame(() => { + if (!Project?.animated_java) return + void applyPreviewResourcePack() + }) +}) + +// Free the overlay's memory when its project closes; the next AJ project select +// reloads whatever that project configured. +EVENTS.CLOSE_PROJECT.subscribe(() => { + if (!getPreviewResourcePackKey()) return + void setPreviewResourcePacks([]).then(() => { + invalidateCaches() + }) +}) + +/** + * Force-reloads the current project's preview resource packs from disk, rebuilding + * every preview even if the paths are unchanged (their contents may have been + * edited on disk). + */ +export async function reloadPreviewResourcePack() { + const paths = getConfiguredPreviewResourcePacks() + + try { + await setPreviewResourcePacks([]) + await setPreviewResourcePacks(paths) + } catch (error) { + console.error('Failed to reload preview resource packs:', error) + Blockbench.showQuickMessage( + 'Failed to load preview resource packs. See console for details.' + ) + await setPreviewResourcePacks([]) + } + + invalidateCaches() + refreshDisplays() +} From e1c43b3e629092ad8540f300d8ba716ed141a919 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 20:33:35 -0400 Subject: [PATCH 17/85] =?UTF-8?q?=E2=9C=85=20Migrate=20test=20suite=20from?= =?UTF-8?q?=20vitest=20to=20jestbench?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - vitest can't run code that only works inside Blockbench; jestbench drives the built plugin in a real headless Blockbench - swap in jest + @swc/jest, add config files, update CI (xvfb + envbench cache) - drop the empty vitest stub test --- .github/workflows/build.yml | 14 +- blockbench.config.mjs | 9 + bun.lock | 1080 +++++++++++++++++++++++++++++------ eslint.config.ts | 4 + jest.config.mjs | 24 + package.json | 12 +- src/tests/pass.test.ts | 3 - tsconfig.json | 8 +- vitest.config.ts | 15 - 9 files changed, 971 insertions(+), 198 deletions(-) create mode 100644 blockbench.config.mjs create mode 100644 jest.config.mjs delete mode 100644 src/tests/pass.test.ts delete mode 100644 vitest.config.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8f790875..223c7f1a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,5 +25,17 @@ jobs: - name: Build run: bun run prod + # jestbench drives a real, headless Blockbench (via xvfb-run) and downloads + # it plus the target Minecraft client jar on the first run. Both live under + # ~/.envbench, so caching that folder keeps later runs offline-fast. + - name: Cache Blockbench test environment + uses: actions/cache@v4 + with: + path: ~/.envbench + key: envbench-${{ runner.os }}-animated-java-tests + + - name: Install xvfb + run: sudo apt-get update && sudo apt-get install -y xvfb + - name: Run tests - run: bun test + run: bun run test:only diff --git a/blockbench.config.mjs b/blockbench.config.mjs new file mode 100644 index 00000000..6e0084c1 --- /dev/null +++ b/blockbench.config.mjs @@ -0,0 +1,9 @@ +import { defineConfig } from '@snavesutit/jestbench' + +export default defineConfig({ + blockbenchVersion: 'latest', + environment: 'animated-java-tests', + // Built by `yarn prod` (the `test` script runs it first). The file name must + // stay in sync with `BBPlugin.register(PACKAGE.name)` in src/plugin.ts. + plugins: ['./dist/animated_java.js'], +}) diff --git a/bun.lock b/bun.lock index 46e7da9e..9d61b625 100644 --- a/bun.lock +++ b/bun.lock @@ -17,7 +17,11 @@ "svelte-dnd-action": "^0.9.38", }, "devDependencies": { + "@jest/globals": "^30.5.1", "@novacbn/svelte-codejar": "^0.1.2", + "@snavesutit/jestbench": "^0.2.0", + "@swc/core": "^1.16.1", + "@swc/jest": "^0.2.39", "@types/download": "^8.0.5", "@types/eslint": "^8.21.1", "@types/js-yaml": "^4.0.5", @@ -36,6 +40,7 @@ "eslint": "^9.37.0", "eslint-plugin-svelte": "^3.12.4", "firebase": "^9.19.0", + "jest": "^30", "jiti": "^2.6.1", "js-yaml": "^4.1.0", "mc-build": "^4.1.3", @@ -53,25 +58,92 @@ "svelte-preprocess-esbuild": "^3.0.1", "typescript": "^6.0.2", "typescript-eslint": "^8.45.0", - "vitest": "^3.2.4", }, }, }, "packages": { "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], + "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], + + "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], + + "@babel/core": ["@babel/core@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-module-transforms": "^7.29.7", "@babel/helpers": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA=="], + + "@babel/generator": ["@babel/generator@7.29.8", "", { "dependencies": { "@babel/parser": "^7.29.8", "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg=="], + + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.29.7", "", { "dependencies": { "@babel/compat-data": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g=="], + + "@babel/helper-globals": ["@babel/helper-globals@7.29.7", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="], + + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="], + + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.29.7", "", {}, "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw=="], + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.24.1", "", {}, "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ=="], "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.24.5", "", {}, "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA=="], - "@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.29.7", "", {}, "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw=="], + + "@babel/helpers": ["@babel/helpers@7.29.7", "", { "dependencies": { "@babel/template": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg=="], + + "@babel/parser": ["@babel/parser@7.29.8", "", { "dependencies": { "@babel/types": "^7.29.8" }, "bin": "./bin/babel-parser.js" }, "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA=="], + + "@babel/plugin-syntax-async-generators": ["@babel/plugin-syntax-async-generators@7.8.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw=="], + + "@babel/plugin-syntax-bigint": ["@babel/plugin-syntax-bigint@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg=="], + + "@babel/plugin-syntax-class-properties": ["@babel/plugin-syntax-class-properties@7.12.13", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA=="], + + "@babel/plugin-syntax-class-static-block": ["@babel/plugin-syntax-class-static-block@7.14.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw=="], + + "@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg=="], + + "@babel/plugin-syntax-import-meta": ["@babel/plugin-syntax-import-meta@7.10.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g=="], + + "@babel/plugin-syntax-json-strings": ["@babel/plugin-syntax-json-strings@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA=="], + + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A=="], + + "@babel/plugin-syntax-logical-assignment-operators": ["@babel/plugin-syntax-logical-assignment-operators@7.10.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig=="], + + "@babel/plugin-syntax-nullish-coalescing-operator": ["@babel/plugin-syntax-nullish-coalescing-operator@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ=="], + + "@babel/plugin-syntax-numeric-separator": ["@babel/plugin-syntax-numeric-separator@7.10.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug=="], + + "@babel/plugin-syntax-object-rest-spread": ["@babel/plugin-syntax-object-rest-spread@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA=="], + + "@babel/plugin-syntax-optional-catch-binding": ["@babel/plugin-syntax-optional-catch-binding@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q=="], + + "@babel/plugin-syntax-optional-chaining": ["@babel/plugin-syntax-optional-chaining@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg=="], + + "@babel/plugin-syntax-private-property-in-object": ["@babel/plugin-syntax-private-property-in-object@7.14.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg=="], + + "@babel/plugin-syntax-top-level-await": ["@babel/plugin-syntax-top-level-await@7.14.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw=="], + + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA=="], + + "@babel/template": ["@babel/template@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg=="], + + "@babel/traverse": ["@babel/traverse@7.29.8", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.8", "@babel/helper-globals": "^7.29.7", "@babel/parser": "^7.29.8", "@babel/template": "^7.29.7", "@babel/types": "^7.29.8", "debug": "^4.3.1" } }, "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg=="], "@babel/types": ["@babel/types@7.24.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.24.1", "@babel/helper-validator-identifier": "^7.24.5", "to-fast-properties": "^2.0.0" } }, "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ=="], + "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], + + "@cronvel/get-pixels": ["@cronvel/get-pixels@3.4.1", "", { "dependencies": { "jpeg-js": "^0.4.4", "ndarray": "^1.0.19", "ndarray-pack": "^1.1.1", "node-bitmap": "0.0.1", "omggif": "^1.0.10", "pngjs": "^6.0.0" } }, "sha512-gB5C5nDIacLUdsMuW8YsM9SzK3vaFANe4J11CVXpovpy7bZUGrcJKmc6m/0gWG789pKr6XSZY2aEetjFvSRw5g=="], + "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], + "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], + "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], @@ -294,6 +366,52 @@ "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], + "@istanbuljs/load-nyc-config": ["@istanbuljs/load-nyc-config@1.1.0", "", { "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" } }, "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ=="], + + "@istanbuljs/schema": ["@istanbuljs/schema@0.1.6", "", {}, "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw=="], + + "@jest/console": ["@jest/console@30.5.1", "", { "dependencies": { "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "jest-message-util": "30.5.1", "jest-util": "30.5.1", "slash": "^3.0.0" } }, "sha512-u5Ncuc+gXVUwjNMFQOnphHo2Qx2DxyC8Dvpmf4HCx4y0kvSkRRNiQYRixrvOP4V7y52JcSuNxqochCt0PpdHVg=="], + + "@jest/core": ["@jest/core@30.5.1", "", { "dependencies": { "@jest/console": "30.5.1", "@jest/pattern": "30.5.0", "@jest/reporters": "30.5.1", "@jest/test-result": "30.5.1", "@jest/transform": "30.5.1", "@jest/types": "30.5.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "exit-x": "^0.2.2", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", "jest-changed-files": "30.5.1", "jest-config": "30.5.1", "jest-haste-map": "30.5.1", "jest-message-util": "30.5.1", "jest-regex-util": "30.5.0", "jest-resolve": "30.5.1", "jest-resolve-dependencies": "30.5.1", "jest-runner": "30.5.1", "jest-runtime": "30.5.1", "jest-snapshot": "30.5.1", "jest-util": "30.5.1", "jest-validate": "30.5.1", "jest-watcher": "30.5.1", "pretty-format": "30.5.1", "slash": "^3.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"] }, "sha512-BL9g6CJUUhIbdoAflz/Va658erSSXUIvU8XUYiWNTbZljJjZ5yaC9EJ9/dQ19rpbYV3ZOK4sBACqhPaTyhoUIA=="], + + "@jest/create-cache-key-function": ["@jest/create-cache-key-function@30.5.1", "", { "dependencies": { "@jest/types": "30.5.1" } }, "sha512-5qkif//qhlbt54255O/M2JtUZNlnefOzE12bi7FlApOIYO4pqrZcAwhNCfP4jOGFubez8uoLgY9czWFjYY57ow=="], + + "@jest/diff-sequences": ["@jest/diff-sequences@30.5.0", "", {}, "sha512-OsqBjHXCn8cadasoAZBP6nWYvMsRhpMzGXTpxJ5aO04NlbdhIz+FVe3q49l0AwVhsz/cEmIpBes6gAFl1/dWQg=="], + + "@jest/environment": ["@jest/environment@30.5.1", "", { "dependencies": { "@jest/fake-timers": "30.5.1", "@jest/types": "30.5.1", "@types/node": "*", "jest-mock": "30.5.1" } }, "sha512-eYJAkOsrpwDXPcoLNEG6lN9Zo3Cy35pxnVQD74vyIfsi/Q8wB/lZFsEjU4wrecOgT4ZviQDZaX/cFIJyMdMxTw=="], + + "@jest/expect": ["@jest/expect@30.5.1", "", { "dependencies": { "expect": "30.5.1", "jest-snapshot": "30.5.1" } }, "sha512-uOGd40P/COyUp9xHf5jeGiGJC2/ANg+2+Tk9/xN5/LxmlY/r/gxsPrx3DTEtaRZsLAX4wgNSLEDELZ5bmVs2bA=="], + + "@jest/expect-utils": ["@jest/expect-utils@30.5.1", "", { "dependencies": { "@jest/get-type": "30.5.0" } }, "sha512-WcRWhHQdTMRDpyWKZ/6MINBmovI7zeD+bL8wFjCncRV3NQOwKy1X45IfyblfHR4k/XciIlNEdFL9QjFO+HNKOg=="], + + "@jest/fake-timers": ["@jest/fake-timers@30.5.1", "", { "dependencies": { "@jest/types": "30.5.1", "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", "jest-message-util": "30.5.1", "jest-mock": "30.5.1", "jest-util": "30.5.1" } }, "sha512-rEkV6YzpBXo/L9cnj2ibyuYZuyGiNWaPUsyCu3HYJbqCV4jnEiKmf7hId20z8eKjZ0JQ9jtIYKxRSmYB/OYSsA=="], + + "@jest/get-type": ["@jest/get-type@30.5.0", "", {}, "sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q=="], + + "@jest/globals": ["@jest/globals@30.5.1", "", { "dependencies": { "@jest/environment": "30.5.1", "@jest/expect": "30.5.1", "@jest/types": "30.5.1", "jest-mock": "30.5.1" } }, "sha512-VhqvQ251XIC7pk46YymI3HCeBLOdvriDw9zibekodAHEwoVvbVVgpU5H13GvmyOAzxtZCfsm1uvzqkaqJf2I+g=="], + + "@jest/pattern": ["@jest/pattern@30.5.0", "", { "dependencies": { "@types/node": "*", "jest-regex-util": "30.5.0" } }, "sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w=="], + + "@jest/react-is-18": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + + "@jest/react-is-19": ["react-is@19.2.8", "", {}, "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ=="], + + "@jest/reporters": ["@jest/reporters@30.5.1", "", { "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "30.5.1", "@jest/test-result": "30.5.1", "@jest/transform": "30.5.1", "@jest/types": "30.5.1", "@jridgewell/trace-mapping": "^0.3.31", "@types/node": "*", "chalk": "^4.1.2", "collect-v8-coverage": "^1.0.2", "exit-x": "^0.2.2", "glob": "^13.0.6", "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", "jest-message-util": "30.5.1", "jest-util": "30.5.1", "jest-worker": "30.5.1", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"] }, "sha512-RbUXIfv85KxitJn4l3MpAoMilkvXe2QCO5lXxHWftywo/VdZ5vkEoHRDgphcxP6qmoIkUaN8/UZj6NhdkIFdJg=="], + + "@jest/schemas": ["@jest/schemas@30.5.0", "", { "dependencies": { "@sinclair/typebox": "^0.34.0" } }, "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg=="], + + "@jest/snapshot-utils": ["@jest/snapshot-utils@30.5.1", "", { "dependencies": { "@jest/types": "30.5.1", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" } }, "sha512-V3wnxNtiVmw5PPVg433Cn3VdXnsOeu/ofLw3KC04Bn2y1wIlU5kozXQn48rhrgj/02LrCVtntTEF1yBha0XSUw=="], + + "@jest/source-map": ["@jest/source-map@30.5.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "callsites": "^3.1.0", "convert-source-map": "^2.0.0", "graceful-fs": "^4.2.11" } }, "sha512-xWpTJP9D0bDFGbPGT8XuWSwwha/iHADyyKzUnMx4UbdgnHugxrDaQFO4RZ8x4ZsFzRP6pNii8uvlgKCDxCIuDg=="], + + "@jest/test-result": ["@jest/test-result@30.5.1", "", { "dependencies": { "@jest/console": "30.5.1", "@jest/types": "30.5.1", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" } }, "sha512-A/1S6ZBdpic50E0pxLgvaB9XNPL4k7AksmG69OO2oiotxciWZwHkbOec+qbIi+uUtIIByOVlXJUl97oZUsz+Jw=="], + + "@jest/test-sequencer": ["@jest/test-sequencer@30.5.1", "", { "dependencies": { "@jest/test-result": "30.5.1", "graceful-fs": "^4.2.11", "jest-haste-map": "30.5.1", "slash": "^3.0.0" } }, "sha512-SHcPnrjdVRYJv6y6l4JUTy4Jccu7zmO6BmiOfOA34UiVBto22s19WiDC0A/2qfM7MWB/qdcoqfSIRMitpjTT4A=="], + + "@jest/transform": ["@jest/transform@30.5.1", "", { "dependencies": { "@babel/core": "^7.27.4", "@jest/types": "30.5.1", "@jridgewell/trace-mapping": "^0.3.31", "babel-plugin-istanbul": "^8.0.0", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", "jest-haste-map": "30.5.1", "jest-regex-util": "30.5.0", "jest-util": "30.5.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" } }, "sha512-EDnDhn0jleU9ZhpVoA4gvqw+Ev0iw/r5upNT2b79RiwiaTiYAMMhvNJP3lmocjIe5J2ZkoNr0B3K/J6O5GIm4Q=="], + + "@jest/types": ["@jest/types@30.5.1", "", { "dependencies": { "@jest/pattern": "30.5.0", "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", "@types/yargs": "^17.0.33", "chalk": "^4.1.2" } }, "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g=="], + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], @@ -306,6 +424,8 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" } }, "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q=="], + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], @@ -368,8 +488,36 @@ "@octokit/webhooks-methods": ["@octokit/webhooks-methods@6.0.0", "", {}, "sha512-MFlzzoDJVw/GcbfzVC1RLR36QqkTLUf79vLVO3D+xn7r0QgxnFoLZgtrzxiQErAjFUOdH6fas2KeQJ1yr/qaXQ=="], + "@parcel/watcher": ["@parcel/watcher@2.6.0", "", { "dependencies": { "detect-libc": "^2.0.3", "is-glob": "^4.0.3", "node-addon-api": "^7.0.0", "picomatch": "^4.0.4" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.6.0", "@parcel/watcher-darwin-arm64": "2.6.0", "@parcel/watcher-darwin-x64": "2.6.0", "@parcel/watcher-freebsd-x64": "2.6.0", "@parcel/watcher-linux-arm-glibc": "2.6.0", "@parcel/watcher-linux-arm-musl": "2.6.0", "@parcel/watcher-linux-arm64-glibc": "2.6.0", "@parcel/watcher-linux-arm64-musl": "2.6.0", "@parcel/watcher-linux-x64-glibc": "2.6.0", "@parcel/watcher-linux-x64-musl": "2.6.0", "@parcel/watcher-win32-arm64": "2.6.0", "@parcel/watcher-win32-x64": "2.6.0" } }, "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w=="], + + "@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.6.0", "", { "os": "android", "cpu": "arm64" }, "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA=="], + + "@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.6.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw=="], + + "@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.6.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw=="], + + "@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.6.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ=="], + + "@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.6.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg=="], + + "@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.6.0", "", { "os": "linux", "cpu": "arm" }, "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw=="], + + "@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.6.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g=="], + + "@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.6.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA=="], + + "@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.6.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A=="], + + "@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.6.0", "", { "os": "linux", "cpu": "x64" }, "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw=="], + + "@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.6.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ=="], + + "@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.6.0", "", { "os": "win32", "cpu": "x64" }, "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A=="], + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], + "@pkgr/core": ["@pkgr/core@0.3.6", "", {}, "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA=="], + "@polka/url": ["@polka/url@1.0.0-next.25", "", {}, "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ=="], "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="], @@ -392,65 +540,71 @@ "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.4", "", { "os": "android", "cpu": "arm" }, "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA=="], - - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.52.4", "", { "os": "android", "cpu": "arm64" }, "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w=="], + "@puppeteer/browsers": ["@puppeteer/browsers@2.6.1", "", { "dependencies": { "debug": "^4.4.0", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", "semver": "^7.6.3", "tar-fs": "^3.0.6", "unbzip2-stream": "^1.4.3", "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" } }, "sha512-aBSREisdsGH890S2rQqK82qmQYU3uFpSH8wcZWHgHzl3LfzsxAKbLNiAG9mO8v1Y0UICBeClICxPJvyr0rcuxg=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.52.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg=="], + "@sinclair/typebox": ["@sinclair/typebox@0.34.52", "", {}, "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.52.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw=="], + "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.52.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ=="], + "@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.52.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw=="], + "@sinonjs/fake-timers": ["@sinonjs/fake-timers@15.4.0", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.52.4", "", { "os": "linux", "cpu": "arm" }, "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ=="], + "@snavesutit/jestbench": ["@snavesutit/jestbench@0.2.0", "", { "dependencies": { "envbench": "^4.1.0", "jest-environment-node": ">=29 <31", "jiti": "^2.7.0", "puppeteer-core": "^23.11.1" }, "peerDependencies": { "jest": ">=29 <31" } }, "sha512-Iq+7Z1blL7PSUJag5rRrq/d/D2H389mClgFgeWsTmGqiwOknr99E5cOB6S7rGNxmLkZeqoBzCir3zdgMCOpa5A=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.52.4", "", { "os": "linux", "cpu": "arm" }, "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q=="], + "@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.9", "", {}, "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.52.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg=="], + "@swc/core": ["@swc/core@1.16.1", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.28" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.16.1", "@swc/core-darwin-x64": "1.16.1", "@swc/core-linux-arm-gnueabihf": "1.16.1", "@swc/core-linux-arm64-gnu": "1.16.1", "@swc/core-linux-arm64-musl": "1.16.1", "@swc/core-linux-ppc64-gnu": "1.16.1", "@swc/core-linux-s390x-gnu": "1.16.1", "@swc/core-linux-x64-gnu": "1.16.1", "@swc/core-linux-x64-musl": "1.16.1", "@swc/core-win32-arm64-msvc": "1.16.1", "@swc/core-win32-ia32-msvc": "1.16.1", "@swc/core-win32-x64-msvc": "1.16.1" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-nUaeu91O5QZKrQdaDCHd402ogUIoNOOjpkZNq0UomWK0G6gDaGmLhvddF1/3BXf5O8aLyo6ZPY/aMDWvaJQ/hg=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.52.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g=="], + "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.16.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zlJblJ8ncErD43lKdxjbUaUskJQf+LxiPXYcWXD8/8ZMV+7uuAT+CwjciLXpyZBd5Pq/S726bMpeeAwSeL1hhg=="], - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.52.4", "", { "os": "linux", "cpu": "none" }, "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ=="], + "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.16.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-IN0BmPWb0YAh/17mmlWB/HDBtTw2MfuW4hulf/tQAgTQBRH17l+z499bNJLK6LizSjqs0P7V+jU38Zj+vJC1DA=="], - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.52.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g=="], + "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.16.1", "", { "os": "linux", "cpu": "arm" }, "sha512-EYgrx2YOCQ2Twz2S793kqNjPkpvYVUPzzR95bIb7by+VQcyaai4lZZ2iz/tZvcFVKSNcN3/JTKwx+aBn2ZL52A=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.52.4", "", { "os": "linux", "cpu": "none" }, "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg=="], + "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.16.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-moyKm0YZlHdHohzm1YwgAyesqnE853rO0REMfJLFAova51wF9BNi+3ZW2PeS7Vqvn6HeJuepLpAHbBdZctxpHA=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.52.4", "", { "os": "linux", "cpu": "none" }, "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA=="], + "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.16.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-kKGBO9wdapiSzuf5ZzZ2fYtlu1BNSYtIIUxvH1ir/gcelTOREEHGDCLTDFx/2Knf878nU11A40z7LxwasEFxqA=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.52.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA=="], + "@swc/core-linux-ppc64-gnu": ["@swc/core-linux-ppc64-gnu@1.16.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nZ6qahtLxC3PM54cWOQZHxt4lTCF/3J4LIoWWzz6v7A+rLs8Dx54anYQf7mH3eIi8KlNpgKci/ie8ZSqFN8O7A=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.52.4", "", { "os": "linux", "cpu": "x64" }, "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg=="], + "@swc/core-linux-s390x-gnu": ["@swc/core-linux-s390x-gnu@1.16.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-4ji5PNzhYq193Z4/4xUaSoNJza6iCkDJSzhetrbB6KOYxsr+kxtQr8ePWhMJUiMt6JUWtXaZ1PYT8FhtED+nGA=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.52.4", "", { "os": "linux", "cpu": "x64" }, "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw=="], + "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.16.1", "", { "os": "linux", "cpu": "x64" }, "sha512-VJQxqrisHV+B394IgrOu8YsIIXZgffnf5tO+yc9Z/hoUpuZEvuQTjWwlnpZdpyD+0nx6LTD1/3k646JYm43yJA=="], - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.52.4", "", { "os": "none", "cpu": "arm64" }, "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA=="], + "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.16.1", "", { "os": "linux", "cpu": "x64" }, "sha512-r9oV1mwxxsIGcLV1IQ/tw76MW3doatKze1QFWuC+a7QqJUkhY/bKTSVk6NpKKUGm2LDsE33Va8VqSClfA7vSiQ=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.52.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ=="], + "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.16.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-6huNRessoBLxWEqBm5zJXyCQ27TO7anvkdiuQ5MDO4CJni0nOXEqKtV9RllQ2TdyENKKsUMXVnIfW2hIXx/R5Q=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.52.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw=="], + "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.16.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-OVKJFUzphrGmsh+BGtcZDesx0YryV7/Yvy5XGgTqnrZfjnyfcr5uaqYQugCckdIlupc5Vs3XtDjRAj12z4ZPlw=="], - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.52.4", "", { "os": "win32", "cpu": "x64" }, "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ=="], + "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.16.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Bt+VIhWYCGk4urklnkkteLUOeLv1VxigwTCeB/xC6rBZxY6IIKdDwCJf6on3E3SUGsIqmQS6QqtuJQc1VxF4Aw=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.52.4", "", { "os": "win32", "cpu": "x64" }, "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w=="], + "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], - "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], + "@swc/jest": ["@swc/jest@0.2.39", "", { "dependencies": { "@jest/create-cache-key-function": "^30.0.0", "@swc/counter": "^0.1.3", "jsonc-parser": "^3.2.0" }, "peerDependencies": { "@swc/core": "*" } }, "sha512-eyokjOwYd0Q8RnMHri+8/FS1HIrIUKK/sRrFp8c1dThUOfNeCWbLmBP1P5VsKdvmkd25JaH+OKYwEYiAYg9YAA=="], - "@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.9", "", {}, "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA=="], + "@swc/types": ["@swc/types@0.1.28", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-V6Mnml8v09QALx6K0elJ7o9K/MkVDtW3t6L+7Ou/JcWtb3xwId2AH4FeOceySd2JaO87IMw4+6vSZxLm34LPbw=="], "@szmarczak/http-timer": ["@szmarczak/http-timer@4.0.6", "", { "dependencies": { "defer-to-connect": "^2.0.0" } }, "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w=="], + "@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="], + + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], + "@types/aws-lambda": ["@types/aws-lambda@8.10.152", "", {}, "sha512-soT/c2gYBnT5ygwiHPmd9a1bftj462NWVk2tKCc1PYHSIacB2UwbTS2zYG4jzag1mRDuzg/OjtxQjQ2NKRB6Rw=="], - "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], - "@types/chai": ["@types/chai@5.2.2", "", { "dependencies": { "@types/deep-eql": "*" } }, "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg=="], + "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], - "@types/decompress": ["@types/decompress@4.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-9z+8yjKr5Wn73Pt17/ldnmQToaFHZxK0N1GHysuk/JIPT8RIdQeoInM01wWPgypRcvb6VH1drjuFpQ4zmY437g=="], + "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], + + "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], - "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], + + "@types/decompress": ["@types/decompress@4.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-9z+8yjKr5Wn73Pt17/ldnmQToaFHZxK0N1GHysuk/JIPT8RIdQeoInM01wWPgypRcvb6VH1drjuFpQ4zmY437g=="], "@types/dompurify": ["@types/dompurify@3.0.5", "", { "dependencies": { "@types/trusted-types": "*" } }, "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg=="], @@ -464,6 +618,12 @@ "@types/http-cache-semantics": ["@types/http-cache-semantics@4.0.4", "", {}, "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA=="], + "@types/istanbul-lib-coverage": ["@types/istanbul-lib-coverage@2.0.6", "", {}, "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w=="], + + "@types/istanbul-lib-report": ["@types/istanbul-lib-report@3.0.3", "", { "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA=="], + + "@types/istanbul-reports": ["@types/istanbul-reports@3.0.4", "", { "dependencies": { "@types/istanbul-lib-report": "*" } }, "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ=="], + "@types/jquery": ["@types/jquery@3.5.34", "", { "dependencies": { "@types/sizzle": "*" } }, "sha512-3m3939S3erqmTLJANS/uy0B6V7BorKx7RorcGZVjZ62dF5PAGbKEDZK1CuLtKombJkFA2T1jl8LAIIs7IV6gBQ=="], "@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="], @@ -484,6 +644,8 @@ "@types/sizzle": ["@types/sizzle@2.3.8", "", {}, "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg=="], + "@types/stack-utils": ["@types/stack-utils@2.0.3", "", {}, "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="], + "@types/three": ["@types/three@0.129.2", "", {}, "sha512-fZDNRtUFnq3baNjDiAzi4QoHYcczWtEdsduH/tpiwk91fbVk8COJiT/iLoN3tIOjLKMySoYsjUfP0VTmUfZKLw=="], "@types/tinycolor2": ["@types/tinycolor2@1.4.6", "", {}, "sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw=="], @@ -494,6 +656,10 @@ "@types/websocket": ["@types/websocket@1.0.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-svjGZvPB7EzuYS94cI7a+qhwgGU1y89wUgjT6E2wVUfmAGIvRfT7obBvRtnhXCSsoMdlG4gBFGE7MfkIXZLoww=="], + "@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="], + + "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], + "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@5.62.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/type-utils": "5.62.0", "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", "tsutils": "^3.21.0" } }, "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag=="], @@ -516,19 +682,51 @@ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@5.62.0", "", { "dependencies": { "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" } }, "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw=="], - "@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="], + "@ungap/structured-clone": ["@ungap/structured-clone@1.4.0", "", {}, "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ=="], + + "@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.12.2", "", { "os": "android", "cpu": "arm" }, "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w=="], + + "@unrs/resolver-binding-android-arm64": ["@unrs/resolver-binding-android-arm64@1.12.2", "", { "os": "android", "cpu": "arm64" }, "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ=="], + + "@unrs/resolver-binding-darwin-arm64": ["@unrs/resolver-binding-darwin-arm64@1.12.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w=="], + + "@unrs/resolver-binding-darwin-x64": ["@unrs/resolver-binding-darwin-x64@1.12.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA=="], + + "@unrs/resolver-binding-freebsd-x64": ["@unrs/resolver-binding-freebsd-x64@1.12.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg=="], + + "@unrs/resolver-binding-linux-arm-gnueabihf": ["@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2", "", { "os": "linux", "cpu": "arm" }, "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A=="], + + "@unrs/resolver-binding-linux-arm-musleabihf": ["@unrs/resolver-binding-linux-arm-musleabihf@1.12.2", "", { "os": "linux", "cpu": "arm" }, "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g=="], + + "@unrs/resolver-binding-linux-arm64-gnu": ["@unrs/resolver-binding-linux-arm64-gnu@1.12.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg=="], + + "@unrs/resolver-binding-linux-arm64-musl": ["@unrs/resolver-binding-linux-arm64-musl@1.12.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA=="], + + "@unrs/resolver-binding-linux-loong64-gnu": ["@unrs/resolver-binding-linux-loong64-gnu@1.12.2", "", { "os": "linux", "cpu": "none" }, "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q=="], - "@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" } }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="], + "@unrs/resolver-binding-linux-loong64-musl": ["@unrs/resolver-binding-linux-loong64-musl@1.12.2", "", { "os": "linux", "cpu": "none" }, "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew=="], - "@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="], + "@unrs/resolver-binding-linux-ppc64-gnu": ["@unrs/resolver-binding-linux-ppc64-gnu@1.12.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg=="], - "@vitest/runner": ["@vitest/runner@3.2.4", "", { "dependencies": { "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ=="], + "@unrs/resolver-binding-linux-riscv64-gnu": ["@unrs/resolver-binding-linux-riscv64-gnu@1.12.2", "", { "os": "linux", "cpu": "none" }, "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A=="], - "@vitest/snapshot": ["@vitest/snapshot@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ=="], + "@unrs/resolver-binding-linux-riscv64-musl": ["@unrs/resolver-binding-linux-riscv64-musl@1.12.2", "", { "os": "linux", "cpu": "none" }, "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w=="], - "@vitest/spy": ["@vitest/spy@3.2.4", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw=="], + "@unrs/resolver-binding-linux-s390x-gnu": ["@unrs/resolver-binding-linux-s390x-gnu@1.12.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw=="], - "@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="], + "@unrs/resolver-binding-linux-x64-gnu": ["@unrs/resolver-binding-linux-x64-gnu@1.12.2", "", { "os": "linux", "cpu": "x64" }, "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ=="], + + "@unrs/resolver-binding-linux-x64-musl": ["@unrs/resolver-binding-linux-x64-musl@1.12.2", "", { "os": "linux", "cpu": "x64" }, "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A=="], + + "@unrs/resolver-binding-openharmony-arm64": ["@unrs/resolver-binding-openharmony-arm64@1.12.2", "", { "os": "none", "cpu": "arm64" }, "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ=="], + + "@unrs/resolver-binding-wasm32-wasi": ["@unrs/resolver-binding-wasm32-wasi@1.12.2", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A=="], + + "@unrs/resolver-binding-win32-arm64-msvc": ["@unrs/resolver-binding-win32-arm64-msvc@1.12.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g=="], + + "@unrs/resolver-binding-win32-ia32-msvc": ["@unrs/resolver-binding-win32-ia32-msvc@1.12.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g=="], + + "@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.12.2", "", { "os": "win32", "cpu": "x64" }, "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA=="], "@vue/compiler-sfc": ["@vue/compiler-sfc@2.7.14", "", { "dependencies": { "@babel/parser": "^7.18.4", "postcss": "^8.4.14", "source-map": "^0.6.1" } }, "sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA=="], @@ -544,26 +742,56 @@ "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], + "ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], "aria-query": ["aria-query@5.3.1", "", {}, "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g=="], "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], - "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + "ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="], "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], + "b4a": ["b4a@1.8.1", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw=="], + + "babel-jest": ["babel-jest@30.5.1", "", { "dependencies": { "@jest/transform": "30.5.1", "@types/babel__core": "^7.20.5", "babel-plugin-istanbul": "^8.0.0", "babel-preset-jest": "30.5.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "slash": "^3.0.0" }, "peerDependencies": { "@babel/core": "^7.11.0 || ^8.0.0-0" } }, "sha512-ge1xUVZS91ml09YRMgRGgeKJ4YJpcOiuwteAxFBYLugQyp7cRw+hHej6Ho0vPjvLrjq60bb7JPHH9LAMA1/krA=="], + + "babel-plugin-istanbul": ["babel-plugin-istanbul@8.0.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-instrument": "^6.0.2", "test-exclude": "^7.0.1" } }, "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg=="], + + "babel-plugin-jest-hoist": ["babel-plugin-jest-hoist@30.5.0", "", { "dependencies": { "@types/babel__core": "^7.20.5" } }, "sha512-gtGo1B+u14jrZQv6TdSWIWkTqclboo7Qn+dFAGUOIuXLFuJKAdg3U5MIWzZnW4vfUb4dX9skmAMiby86e/SF4A=="], + + "babel-preset-current-node-syntax": ["babel-preset-current-node-syntax@1.2.0", "", { "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-import-attributes": "^7.24.7", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0 || ^8.0.0-0" } }, "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg=="], + + "babel-preset-jest": ["babel-preset-jest@30.5.0", "", { "dependencies": { "babel-plugin-jest-hoist": "30.5.0", "babel-preset-current-node-syntax": "^1.2.0" }, "peerDependencies": { "@babel/core": "^7.11.0 || ^8.0.0-beta.1 || ^8.0.0" } }, "sha512-ZGPn5ClP4lBDpuOK8W1yQIOy359HmbnZv3suucAlIe+SEE9yDsxV4S2PjSbH2Vc97U+WmzYD7vw3kr8NsQ/i6w=="], + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "bare-events": ["bare-events@2.9.2", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA=="], + + "bare-fs": ["bare-fs@4.8.1", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-N1nnXdHZAOSstz0XiHikGS4HGMH4CnSwhqWdGQQMqqdvp4Jybm9sE3R1WVnpWVd4SFkc8ryPDBLViNLwiEqECg=="], + + "bare-path": ["bare-path@3.1.2", "", {}, "sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw=="], + + "bare-stream": ["bare-stream@2.13.4", "", { "dependencies": { "b4a": "^1.8.1", "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-abort-controller", "bare-buffer", "bare-events"] }, "sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA=="], + + "bare-url": ["bare-url@2.5.3", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-3absfEzoyFosWT8v83ZcJgbTJxv+S/sI7jBfeCMlUVatSaefRmwweqBhFpMllQv+HTxs/FbbToVOw1c05NORkQ=="], + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.11.20", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-H0ulySigv6icDJ1F7SjtdCD6PrhTpdYCmP0CactWy1+ekh0AFd0o1Wn5T8b+hnTmdBx19u9yhL6wvCylXMY7zw=="], + + "basic-ftp": ["basic-ftp@5.3.1", "", {}, "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw=="], + "before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="], @@ -590,12 +818,14 @@ "braces": ["braces@3.0.2", "", { "dependencies": { "fill-range": "^7.0.1" } }, "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A=="], + "browserslist": ["browserslist@4.28.8", "", { "dependencies": { "baseline-browser-mapping": "^2.11.12", "caniuse-lite": "^1.0.30001809", "electron-to-chromium": "^1.5.402", "node-releases": "^2.0.53", "update-browserslist-db": "^1.3.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA=="], + + "bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="], + "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], "buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], - "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], - "cacache": ["cacache@18.0.4", "", { "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^4.0.0", "ssri": "^10.0.0", "tar": "^6.1.11", "unique-filename": "^3.0.0" } }, "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ=="], "cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="], @@ -604,28 +834,42 @@ "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], - "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], + "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001810", "", {}, "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg=="], "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], - "charenc": ["charenc@0.0.2", "", {}, "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA=="], + "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], - "check-error": ["check-error@2.1.1", "", {}, "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw=="], + "charenc": ["charenc@0.0.2", "", {}, "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA=="], "chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + "chroma-js": ["chroma-js@2.6.0", "", {}, "sha512-BLHvCB9s8Z1EV4ethr6xnkl/P2YRFOGqfgvuMG/MyCbZPrTA+NeiByY6XvgF0zP4/2deU2CXnWyMa3zu1LqQ3A=="], + + "chromium-bidi": ["chromium-bidi@0.11.0", "", { "dependencies": { "mitt": "3.0.1", "zod": "3.23.8" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-6CJWHkNRoyZyjV9Rwv2lYONZf1Xm0IuDyNq97nwSsxxP3wf5Bwy15K5rOvVKMtJ127jJBmxFUanSAOjgFRxgrA=="], + + "ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], + + "cjs-module-lexer": ["cjs-module-lexer@2.2.1", "", {}, "sha512-Ca8swihM+/4yKecYHY52kgJd300hi2lADU/a1RxNTRe+RJ9jvqQlESpbz9DnG9mowez8qwXHB8qYdIUw9e+F5Q=="], + "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], - "cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], "clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="], "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + "co": ["co@4.6.0", "", {}, "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ=="], + "code-red": ["code-red@1.0.4", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", "acorn": "^8.10.0", "estree-walker": "^3.0.3", "periscopic": "^3.1.0" } }, "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw=="], "codejar": ["codejar@3.7.0", "", {}, "sha512-rqyDu2zNwfu1EhXI++LEMQDzhykS+V0BV52RemtCj5lczgTgWSufyEa+tS7RP7qCXH/WXOkU0eIthmFUzvG78Q=="], + "collect-v8-coverage": ["collect-v8-coverage@1.0.3", "", {}, "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw=="], + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], @@ -634,12 +878,18 @@ "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + "commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="], + "commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="], + "compare-versions": ["compare-versions@6.1.1", "", {}, "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg=="], + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], "console-clear": ["console-clear@1.1.1", "", {}, "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ=="], + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], @@ -652,16 +902,22 @@ "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + "cwise-compiler": ["cwise-compiler@1.1.3", "", { "dependencies": { "uniq": "^1.0.0" } }, "sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ=="], + + "data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="], + "debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="], "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], - "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], + "dedent": ["dedent@1.7.2", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA=="], "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], + "deepslate": ["deepslate@0.19.2", "", { "dependencies": { "gl-matrix": "^3.3.0", "md5": "^2.3.0", "pako": "^2.0.3" } }, "sha512-sDOjpBXv5WBMmtsquJGNhOoZJKm4ra7pzzQP7FjNJHbZwoL+qlzrsfId4OU3C9WtfC6e0+2mcH+kd3KL5mjrSg=="], "defer-to-connect": ["defer-to-connect@2.0.1", "", {}, "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="], @@ -670,14 +926,20 @@ "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], + "degenerator": ["degenerator@5.0.1", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" } }, "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ=="], + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "detect-newline": ["detect-newline@3.1.0", "", {}, "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA=="], + "detect-node": ["detect-node@2.1.0", "", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="], "devalue": ["devalue@5.7.1", "", {}, "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA=="], + "devtools-protocol": ["devtools-protocol@0.0.1367902", "", {}, "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg=="], + "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], "dompurify": ["dompurify@3.1.3", "", {}, "sha512-5sOWYSNPaxz6o2MUPvtyxTTqR4D3L77pr5rUQoWgD5ROQtVIZQgJkXbo1DLlK3vj11YGw5+LnF4SYti4gZmwng=="], @@ -686,7 +948,11 @@ "electron": ["electron@40.8.5", "", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-pgTY/VPQKaiU4sTjfU96iyxCXrFm4htVPCMRT4b7q9ijNTRgtLmLvcmzp2G4e7xDrq9p7OLHSmu1rBKFf6Y1/A=="], - "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "electron-to-chromium": ["electron-to-chromium@1.5.420", "", {}, "sha512-2yD6XreGusOfNV+dUcvipJEXc3n/n7fgr7996aszTG+YY5E4mqM4tOq/3uhP129cazL9YHbVWSpc79ePotWtPA=="], + + "emittery": ["emittery@0.13.1", "", {}, "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ=="], + + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], @@ -694,13 +960,17 @@ "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + "envbench": ["envbench@4.1.0", "", { "dependencies": { "chalk": "^5.4.1", "commander": "^13.1.0", "compare-versions": "^6.1.1", "strip-ansi": "^7.1.0", "terminal-kit": "^3.1.1", "wrap-ansi": "^9.0.0", "yaml": "^2.8.2" }, "bin": { "envbench": "dist/cli.js" } }, "sha512-e7W0h91CLhser6SEqd3tKWvsE8rTwTpyuqwNUYU+OikeHVLx1ZpsfgMJU5NzXgCfhXeuGitPXjd/o/KDwPOUsQ=="], + "err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], + "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], + "es-define-property": ["es-define-property@1.0.0", "", { "dependencies": { "get-intrinsic": "^1.2.4" } }, "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], - "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + "es-module-lexer": ["es-module-lexer@2.3.2", "", {}, "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw=="], "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], @@ -720,6 +990,8 @@ "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + "escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="], + "eslint": ["eslint@9.37.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.4.0", "@eslint/core": "^0.16.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.37.0", "@eslint/plugin-kit": "^0.4.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" } }, "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig=="], "eslint-plugin-svelte": ["eslint-plugin-svelte@3.12.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.6.1", "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", "globals": "^16.0.0", "known-css-properties": "^0.37.0", "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^7.0.0", "semver": "^7.6.3", "svelte-eslint-parser": "^1.3.0" } }, "sha512-hD7wPe+vrPgx3U2X2b/wyTMtWobm660PygMGKrWWYTc9lvtY8DpNFDaU2CJQn1szLjGbn/aJ3g8WiXuKakrEkw=="], @@ -732,6 +1004,8 @@ "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], "esrap": ["esrap@2.2.5", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-/yLB1538mag+dn0wsePTe8C0rDIjUOaJpMs2McodSzmM2msWcZsBSdRtg6HOBt0A/r82BN+Md3pgwSc/uWt2Ig=="], @@ -744,9 +1018,15 @@ "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], + "events-universal": ["events-universal@1.0.1", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="], + + "execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], + + "exit-x": ["exit-x@0.2.2", "", {}, "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ=="], + "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], - "expect-type": ["expect-type@1.2.2", "", {}, "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA=="], + "expect": ["expect@30.5.1", "", { "dependencies": { "@jest/expect-utils": "30.5.1", "@jest/get-type": "30.5.0", "jest-matcher-utils": "30.5.1", "jest-message-util": "30.5.1", "jest-mock": "30.5.1", "jest-util": "30.5.1" } }, "sha512-m8YrYgvKe9+9gEnWEuKz+qCGfHqkrff7PPfyDnOFkjsfYRKqiYyOxDFMFieCGAuhtk/VNm63tvNgKZVzVy+Hvg=="], "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], @@ -756,6 +1036,8 @@ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="], + "fast-glob": ["fast-glob@3.3.2", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" } }, "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow=="], "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], @@ -766,9 +1048,11 @@ "faye-websocket": ["faye-websocket@0.11.4", "", { "dependencies": { "websocket-driver": ">=0.5.1" } }, "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g=="], + "fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="], + "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], - "fdir": ["fdir@6.5.0", "", {}, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], @@ -800,20 +1084,26 @@ "fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="], - "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], - "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], "generic-stream": ["generic-stream@3.0.1", "", {}, "sha512-hO6I0xmqm1FlIu51S5DCZPliLRACckiKlvjx654tC3YB10y43I8szT5ZkLOsmnL+N/hVzbGhXzopnRl9prhNtg=="], + "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + "get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="], + "get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="], + "get-package-type": ["get-package-type@0.1.0", "", {}, "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q=="], + "get-port": ["get-port@3.2.0", "", {}, "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg=="], "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + "get-uri": ["get-uri@6.0.5", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg=="], + "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="], "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], @@ -856,6 +1146,8 @@ "headless-three": ["headless-three@1.9.0", "", { "dependencies": { "gl": "^8.1.6", "sharp": "^0.34.5", "three": "0.162.0" } }, "sha512-4QuRO2VPE2Dlt7dhwkUU29oETHLjKNbZmd7vOks/GfDZnQG3WogF37QlUtrUr/uS7IHuzHodVr0uAg2uYszguA=="], + "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], + "http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="], "http-parser-js": ["http-parser-js@0.5.8", "", {}, "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q=="], @@ -866,6 +1158,8 @@ "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="], + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "idb": ["idb@7.1.1", "", {}, "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="], @@ -876,6 +1170,8 @@ "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + "import-local": ["import-local@3.2.0", "", { "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" }, "bin": { "import-local-fixture": "fixtures/cli.js" } }, "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA=="], + "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], @@ -884,14 +1180,20 @@ "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + "iota-array": ["iota-array@1.0.0", "", {}, "sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA=="], + "ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="], + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + "is-buffer": ["is-buffer@1.1.6", "", {}, "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="], "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + "is-generator-fn": ["is-generator-fn@2.1.0", "", {}, "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ=="], + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], "is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="], @@ -900,26 +1202,96 @@ "is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="], + "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], + "isarray": ["isarray@0.0.1", "", {}, "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], + + "istanbul-lib-instrument": ["istanbul-lib-instrument@6.0.3", "", { "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-coverage": "^3.2.0", "semver": "^7.5.4" } }, "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q=="], + + "istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="], + + "istanbul-lib-source-maps": ["istanbul-lib-source-maps@5.0.6", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0" } }, "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A=="], + + "istanbul-reports": ["istanbul-reports@3.2.0", "", { "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA=="], + "jackspeak": ["jackspeak@4.1.1", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" } }, "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ=="], + "jest": ["jest@30.5.1", "", { "dependencies": { "@jest/core": "30.5.1", "@jest/types": "30.5.1", "import-local": "^3.2.0", "jest-cli": "30.5.1" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"], "bin": { "jest": "bin/jest.js" } }, "sha512-3qrR8+ZXFnn7y0H2yjWQNkGGBLBY4zTRoTMAq9zJcgwLLtlyonfsCLviIXK9xuE2KgIyM+M36AFcoK2DgFR36w=="], + + "jest-changed-files": ["jest-changed-files@30.5.1", "", { "dependencies": { "execa": "^5.1.1", "jest-util": "30.5.1", "p-limit": "^3.1.0" } }, "sha512-0+bvMM/ENhDI29Z8q1r4HxiDIi4G5tnBmSw4esfPQoj9q8Nik7KIyuxHkTVnnniJQf05SxpGaKDQ+4h28ynGPg=="], + + "jest-circus": ["jest-circus@30.5.1", "", { "dependencies": { "@jest/environment": "30.5.1", "@jest/expect": "30.5.1", "@jest/test-result": "30.5.1", "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", "jest-each": "30.5.1", "jest-matcher-utils": "30.5.1", "jest-message-util": "30.5.1", "jest-runtime": "30.5.1", "jest-snapshot": "30.5.1", "jest-util": "30.5.1", "p-limit": "^3.1.0", "pretty-format": "30.5.1", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" } }, "sha512-NgliezXQ6yznqR4W5Gqw++0cZSbBZlF0NknNIAE5VmSJKWOtmWJmWnBq3TSkUOVBTPrT7FGGhVdA8DLWnxo2Sw=="], + + "jest-cli": ["jest-cli@30.5.1", "", { "dependencies": { "@jest/core": "30.5.1", "@jest/test-result": "30.5.1", "@jest/types": "30.5.1", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", "jest-config": "30.5.1", "jest-util": "30.5.1", "jest-validate": "30.5.1", "yargs": "^17.7.2" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"], "bin": { "jest": "bin/jest.js" } }, "sha512-uwNYepWgaNBCplm42fCIUZTf/tIEHIy5AYvx7eL1BrwIgyjPt+2poouR23UO2yopIP+kV8oZFHfv+l4pg/8prQ=="], + + "jest-config": ["jest-config@30.5.1", "", { "dependencies": { "@babel/core": "^7.27.4", "@jest/get-type": "30.5.0", "@jest/pattern": "30.5.0", "@jest/test-sequencer": "30.5.1", "@jest/types": "30.5.1", "babel-jest": "30.5.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", "glob": "^13.0.6", "graceful-fs": "^4.2.11", "jest-circus": "30.5.1", "jest-docblock": "30.5.0", "jest-environment-node": "30.5.1", "jest-regex-util": "30.5.0", "jest-resolve": "30.5.1", "jest-runner": "30.5.1", "jest-util": "30.5.1", "jest-validate": "30.5.1", "parse-json": "^5.2.0", "pretty-format": "30.5.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "peerDependencies": { "@types/node": "*", "esbuild-register": ">=3.4.0", "ts-node": ">=9.0.0" }, "optionalPeers": ["@types/node", "esbuild-register", "ts-node"] }, "sha512-L8PKM2X/ngG8PxfLMqglKGZjylPgw84bVPUlMY9W/o76TnLqPWrmQgsaT0HrheGdRtpGE5FbmREA0Kvb+Qx5gQ=="], + + "jest-diff": ["jest-diff@30.5.1", "", { "dependencies": { "@jest/diff-sequences": "30.5.0", "@jest/get-type": "30.5.0", "chalk": "^4.1.2", "pretty-format": "30.5.1" } }, "sha512-e3cNNMpv8Kh20MjjphTXs+3Vz7DQyLM1nft7KJhnh46atFhjVJRa+0Hq0beywuwsACtMQUBihQkFl8zxb7gt1Q=="], + + "jest-docblock": ["jest-docblock@30.5.0", "", { "dependencies": { "detect-newline": "^3.1.0" } }, "sha512-NwDqcxtoZi33RhuW+zJS/RVA3rmheQ8BnwpYZuc/Eruaz6seQb7+aoCeDZu/3X7W2XmD8DbSo9Pn72DbKsBFYw=="], + + "jest-each": ["jest-each@30.5.1", "", { "dependencies": { "@jest/get-type": "30.5.0", "@jest/types": "30.5.1", "chalk": "^4.1.2", "jest-util": "30.5.1", "pretty-format": "30.5.1" } }, "sha512-S1af0TU4v1EZ/AUlkFs/sxf/5KGsbAT9kRgdyoMX/x72y7C8ZEgETE5o1TPnbKRnrbprc5FR/moYLfdRmqEjsQ=="], + + "jest-environment-node": ["jest-environment-node@30.5.1", "", { "dependencies": { "@jest/environment": "30.5.1", "@jest/fake-timers": "30.5.1", "@jest/types": "30.5.1", "@types/node": "*", "jest-mock": "30.5.1", "jest-util": "30.5.1", "jest-validate": "30.5.1" } }, "sha512-LrPj3sPMjsQoOB3jrb8p/sa+XkSFNKo60TTsyc+EB2kxQJHgbwElpXnx1yX25fdFn5958FIObRtcLSHyV8VIAw=="], + + "jest-haste-map": ["jest-haste-map@30.5.1", "", { "dependencies": { "@jest/types": "30.5.1", "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", "fdir": "^6.5.0", "graceful-fs": "^4.2.11", "jest-regex-util": "30.5.0", "jest-util": "30.5.1", "jest-worker": "30.5.1", "picomatch": "^4.0.3" } }, "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ=="], + + "jest-leak-detector": ["jest-leak-detector@30.5.1", "", { "dependencies": { "@jest/get-type": "30.5.0", "pretty-format": "30.5.1" } }, "sha512-gt4GT2aWgEoCNTcBe4rqS74xTIUJxi+UD9SNSu9aOk5LmTEd6fS5KSTmAKAfitCCktQHNN+upUuL6EkBfFbMDQ=="], + + "jest-matcher-utils": ["jest-matcher-utils@30.5.1", "", { "dependencies": { "@jest/get-type": "30.5.0", "chalk": "^4.1.2", "jest-diff": "30.5.1", "pretty-format": "30.5.1" } }, "sha512-aroZVqwOz/wC2y6pC+obgFWKV9viaQWQTTSB6W5H55+egtUczIfXR/rxExTv92xD/ADYwpqaYfVWx1aqwKg7FA=="], + + "jest-message-util": ["jest-message-util@30.5.1", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "jest-util": "30.5.1", "picomatch": "^4.0.3", "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" } }, "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg=="], + + "jest-mock": ["jest-mock@30.5.1", "", { "dependencies": { "@jest/expect-utils": "30.5.1", "@jest/types": "30.5.1", "@types/node": "*", "jest-util": "30.5.1" } }, "sha512-9fVjc3leUpGID2/by/LU4Dvdcp7PFh9LlxS3QRWK3ABm+KtvEVsG/AEGeLY3gKOZsjkBxyfwGltoAVlW7dygHg=="], + + "jest-regex-util": ["jest-regex-util@30.5.0", "", {}, "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A=="], + + "jest-resolve": ["jest-resolve@30.5.1", "", { "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "jest-haste-map": "30.5.1", "jest-util": "30.5.1", "jest-validate": "30.5.1", "slash": "^3.0.0", "unrs-resolver": "^1.12.1" } }, "sha512-wprhLejRtwN6h8ZgaqC0eYjGJ1uMdGPT/+b3eFncbG4NWuuP9QL+vWwRinu9waw7hkOLcpMJGVJAMgBwsPssMQ=="], + + "jest-resolve-dependencies": ["jest-resolve-dependencies@30.5.1", "", { "dependencies": { "jest-regex-util": "30.5.0", "jest-snapshot": "30.5.1" } }, "sha512-JKpXGONDcTaunrNVn8KCl6qAnwl06jIkvv70lhq0Ze47lsPx9sH5HoeEUiXX6iFGnliHN/qpIbQ0l38wrVmXaw=="], + + "jest-runner": ["jest-runner@30.5.1", "", { "dependencies": { "@jest/console": "30.5.1", "@jest/environment": "30.5.1", "@jest/source-map": "30.5.0", "@jest/test-result": "30.5.1", "@jest/transform": "30.5.1", "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "emittery": "^0.13.1", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", "jest-docblock": "30.5.0", "jest-environment-node": "30.5.1", "jest-haste-map": "30.5.1", "jest-leak-detector": "30.5.1", "jest-message-util": "30.5.1", "jest-resolve": "30.5.1", "jest-runtime": "30.5.1", "jest-util": "30.5.1", "jest-watcher": "30.5.1", "jest-worker": "30.5.1", "p-limit": "^3.1.0" } }, "sha512-FPlQE4+mwnFxXmpPrSi836KV2ZzvK1g6/nPCT8o5BcoDUUNJQeHo1/Qdkoe/QeoL4M7OeJpbnGUhYKhC1VMdaQ=="], + + "jest-runtime": ["jest-runtime@30.5.1", "", { "dependencies": { "@jest/environment": "30.5.1", "@jest/fake-timers": "30.5.1", "@jest/globals": "30.5.1", "@jest/source-map": "30.5.0", "@jest/test-result": "30.5.1", "@jest/transform": "30.5.1", "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "cjs-module-lexer": "^2.2.0", "collect-v8-coverage": "^1.0.2", "es-module-lexer": "^2.1.0", "glob": "^13.0.6", "graceful-fs": "^4.2.11", "jest-haste-map": "30.5.1", "jest-message-util": "30.5.1", "jest-mock": "30.5.1", "jest-regex-util": "30.5.0", "jest-resolve": "30.5.1", "jest-snapshot": "30.5.1", "jest-util": "30.5.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "sha512-UB88+NRkK2Tw/OqV7dofYcyiUGrVZtD41k/N0xQOs9fG//57XHK7JLWG52HD1UYpUAhjK4xm6DBvFX3yWudsMA=="], + + "jest-snapshot": ["jest-snapshot@30.5.1", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", "@jest/expect-utils": "30.5.1", "@jest/get-type": "30.5.0", "@jest/snapshot-utils": "30.5.1", "@jest/transform": "30.5.1", "@jest/types": "30.5.1", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", "expect": "30.5.1", "graceful-fs": "^4.2.11", "jest-diff": "30.5.1", "jest-matcher-utils": "30.5.1", "jest-message-util": "30.5.1", "jest-util": "30.5.1", "pretty-format": "30.5.1", "semver": "^7.7.2", "synckit": "^0.11.8" } }, "sha512-cNWFdSb5xuDGl8hKkAZJ3YtI/PzHpAPFV+HUXWIOG8rMhpDTLVbvAc2d2wRicoYw2wGsJGLaurJT6BLC97bLXQ=="], + + "jest-util": ["jest-util@30.5.1", "", { "dependencies": { "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.3" } }, "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg=="], + + "jest-validate": ["jest-validate@30.5.1", "", { "dependencies": { "@jest/get-type": "30.5.0", "@jest/types": "30.5.1", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", "pretty-format": "30.5.1" } }, "sha512-i/buJ56wTpxihE93hQYNMfdOThS87+HGvLZzZJmU4xggPcdTYQq051iwALLCHp3q+SkCGH+EFejQZz5EbBSkkg=="], + + "jest-watcher": ["jest-watcher@30.5.1", "", { "dependencies": { "@jest/test-result": "30.5.1", "@jest/types": "30.5.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", "jest-util": "30.5.1", "string-length": "^4.0.2" } }, "sha512-+FHJ7C+S7b3ySfhA1aFmoa6TztsnwZVv84ycPRn0tVN93np2EU4b8C/KadqA3l6igdjgLBTnUotab9ER0HLG8A=="], + + "jest-worker": ["jest-worker@30.5.1", "", { "dependencies": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", "jest-util": "30.5.1", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" } }, "sha512-Cbxh5v7AoLuFRmFJSM4/aHdQ68rjXvUWr716EE0Dh3I7T+T/3FgFKhOERGXHcU2Meftq9+9zxPM3TSNyI9D+HA=="], + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - "js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], + "jpeg-js": ["jpeg-js@0.4.4", "", {}, "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], + "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], + "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], + "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], + "jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], @@ -930,10 +1302,16 @@ "ky": ["ky@2.0.1", "", {}, "sha512-HJPEjEpQPZQ5M3G5eu90/LWZDwysCnvqcfbLvq9FUvfizBZRi58WEixswyyI32LOLcFQd43w7kcfgkCPFxDt/Q=="], + "lazyness": ["lazyness@1.2.0", "", {}, "sha512-KenL6EFbwxBwRxG93t0gcUyi0Nw0Ub31FJKN1laA4UscdkL1K1AxUd0gYZdcLU3v+x+wcFi4uQKS5hL+fk500g=="], + + "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], + "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], "lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="], + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + "local-access": ["local-access@1.1.0", "", {}, "sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw=="], "locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="], @@ -946,8 +1324,6 @@ "long": ["long@4.0.0", "", {}, "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="], - "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="], - "lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="], "lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="], @@ -970,6 +1346,8 @@ "mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="], + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], "micromatch": ["micromatch@4.0.5", "", { "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" } }, "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA=="], @@ -978,6 +1356,8 @@ "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], @@ -998,6 +1378,8 @@ "minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], + "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], @@ -1016,30 +1398,56 @@ "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="], + "napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": { "napi-postinstall": "lib/cli.js" } }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="], + "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], "natural-compare-lite": ["natural-compare-lite@1.4.0", "", {}, "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g=="], + "ndarray": ["ndarray@1.1.1", "", { "dependencies": { "iota-array": "^1.0.0", "is-buffer": "^1.0.2" } }, "sha512-AsE8w/M2MS+0pD3nP5qbRRtJFeJJJaJ+qXZaZr0XjVGXhy6LIj2TERTlkpdK2AI3WufoOP+pwPk3q2ilAJcZ9g=="], + + "ndarray-pack": ["ndarray-pack@1.2.1", "", { "dependencies": { "cwise-compiler": "^1.1.2", "ndarray": "^1.0.13" } }, "sha512-51cECUJMT0rUZNQa09EoKsnFeDL4x2dHRT0VR5U2H5ZgEcm95ZDWcMA5JShroXjHOejmAD/fg8+H+OvUnVXz2g=="], + "negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], + "netmask": ["netmask@2.1.1", "", {}, "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA=="], + + "nextgen-events": ["nextgen-events@1.5.3", "", {}, "sha512-P6qw6kenNXP+J9XlKJNi/MNHUQ+Lx5K8FEcSfX7/w8KJdZan5+BB5MKzuNgL2RTjHG1Svg8SehfseVEp8zAqwA=="], + "node-abi": ["node-abi@3.92.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ=="], + "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + + "node-bitmap": ["node-bitmap@0.0.1", "", {}, "sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA=="], + "node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" } }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], "node-gyp": ["node-gyp@10.3.1", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "glob": "^10.3.10", "graceful-fs": "^4.2.6", "make-fetch-happen": "^13.0.0", "nopt": "^7.0.0", "proc-log": "^4.1.0", "semver": "^7.3.5", "tar": "^6.2.1", "which": "^4.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ=="], + "node-int64": ["node-int64@0.4.0", "", {}, "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="], + "node-modules-vscode-problems-patch": ["node-modules-vscode-problems-patch@1.0.9", "", { "dependencies": { "esbuild": "^0.25.0", "glob": "^11.0.1" }, "bin": { "node-modules-vscode-problems-patch": "dist/index.js" } }, "sha512-PYS8ozhWFbPvksJBIKbWrdrKOD2e+MZaxl75amn/oaVAzObgmGQeYnk4VT5tT/d5KHhWiuUwzWWSgbQ57GVMfA=="], + "node-releases": ["node-releases@2.0.54", "", {}, "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ=="], + "nopt": ["nopt@7.2.1", "", { "dependencies": { "abbrev": "^2.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w=="], + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + "normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="], + "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], + "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], "octokit": ["octokit@5.0.3", "", { "dependencies": { "@octokit/app": "^16.0.1", "@octokit/core": "^7.0.2", "@octokit/oauth-app": "^8.0.1", "@octokit/plugin-paginate-graphql": "^6.0.0", "@octokit/plugin-paginate-rest": "^13.0.0", "@octokit/plugin-rest-endpoint-methods": "^16.0.0", "@octokit/plugin-retry": "^8.0.1", "@octokit/plugin-throttling": "^11.0.1", "@octokit/request-error": "^7.0.0", "@octokit/types": "^14.0.0", "@octokit/webhooks": "^14.0.0" } }, "sha512-+bwYsAIRmYv30NTmBysPIlgH23ekVDriB07oRxlPIAH5PI0yTMSxg5i5Xy0OetcnZw+nk/caD4szD7a9YZ3QyQ=="], + "omggif": ["omggif@1.0.10", "", {}, "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="], + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], "p-cancelable": ["p-cancelable@2.1.1", "", {}, "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="], @@ -1052,6 +1460,10 @@ "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], + "pac-proxy-agent": ["pac-proxy-agent@7.2.0", "", { "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", "socks-proxy-agent": "^8.0.5" } }, "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA=="], + + "pac-resolver": ["pac-resolver@7.0.1", "", { "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" } }, "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg=="], + "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], "pako": ["pako@2.1.0", "", {}, "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="], @@ -1060,6 +1472,8 @@ "parenthesis": ["parenthesis@3.1.8", "", {}, "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw=="], + "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], + "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], @@ -1068,20 +1482,20 @@ "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], - "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - - "pathval": ["pathval@2.0.0", "", {}, "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA=="], - "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], "periscopic": ["periscopic@3.1.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", "is-reference": "^3.0.0" } }, "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "picomatch": ["picomatch@4.0.7", "", {}, "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA=="], + + "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], "pkg-dir": ["pkg-dir@4.2.0", "", { "dependencies": { "find-up": "^4.0.0" } }, "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ=="], + "pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="], + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], "postcss-load-config": ["postcss-load-config@3.1.4", "", { "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" } }, "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="], @@ -1098,6 +1512,8 @@ "prettier": ["prettier@3.8.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q=="], + "pretty-format": ["pretty-format@30.5.1", "", { "dependencies": { "@jest/react-is-18": "npm:react-is@^18.3.1", "@jest/react-is-19": "npm:react-is@^19.2.5", "@jest/schemas": "30.5.0", "ansi-styles": "^5.2.0" } }, "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg=="], + "prismjs": ["prismjs@1.29.0", "", {}, "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="], "proc-log": ["proc-log@4.2.0", "", {}, "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA=="], @@ -1108,10 +1524,18 @@ "protobufjs": ["protobufjs@6.11.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/long": "^4.0.1", "@types/node": ">=13.7.0", "long": "^4.0.0" }, "bin": { "pbjs": "bin/pbjs", "pbts": "bin/pbts" } }, "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw=="], + "proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="], + + "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "pump": ["pump@3.0.0", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "puppeteer-core": ["puppeteer-core@23.11.1", "", { "dependencies": { "@puppeteer/browsers": "2.6.1", "chromium-bidi": "0.11.0", "debug": "^4.4.0", "devtools-protocol": "0.0.1367902", "typed-query-selector": "^2.12.0", "ws": "^8.18.0" } }, "sha512-3HZ2/7hdDKZvZQ7dhhITOUg4/wOrDRjyK2ZBllRB0ZCOi9u0cwq1ACHDjBB+nX+7+kltHjQvBRdeY7+W0T+7Gg=="], + + "pure-rand": ["pure-rand@7.0.1", "", {}, "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ=="], + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], @@ -1126,6 +1550,8 @@ "resolve-alpn": ["resolve-alpn@1.2.1", "", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], + "resolve-cwd": ["resolve-cwd@3.0.0", "", { "dependencies": { "resolve-from": "^5.0.0" } }, "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg=="], + "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "responselike": ["responselike@2.0.1", "", { "dependencies": { "lowercase-keys": "^2.0.0" } }, "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw=="], @@ -1136,8 +1562,6 @@ "roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="], - "rollup": ["rollup@4.52.4", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.4", "@rollup/rollup-android-arm64": "4.52.4", "@rollup/rollup-darwin-arm64": "4.52.4", "@rollup/rollup-darwin-x64": "4.52.4", "@rollup/rollup-freebsd-arm64": "4.52.4", "@rollup/rollup-freebsd-x64": "4.52.4", "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", "@rollup/rollup-linux-arm-musleabihf": "4.52.4", "@rollup/rollup-linux-arm64-gnu": "4.52.4", "@rollup/rollup-linux-arm64-musl": "4.52.4", "@rollup/rollup-linux-loong64-gnu": "4.52.4", "@rollup/rollup-linux-ppc64-gnu": "4.52.4", "@rollup/rollup-linux-riscv64-gnu": "4.52.4", "@rollup/rollup-linux-riscv64-musl": "4.52.4", "@rollup/rollup-linux-s390x-gnu": "4.52.4", "@rollup/rollup-linux-x64-gnu": "4.52.4", "@rollup/rollup-linux-x64-musl": "4.52.4", "@rollup/rollup-openharmony-arm64": "4.52.4", "@rollup/rollup-win32-arm64-msvc": "4.52.4", "@rollup/rollup-win32-ia32-msvc": "4.52.4", "@rollup/rollup-win32-x64-gnu": "4.52.4", "@rollup/rollup-win32-x64-msvc": "4.52.4", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ=="], - "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], "sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="], @@ -1154,14 +1578,16 @@ "serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], + "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], + + "seventh": ["seventh@0.9.4", "", { "dependencies": { "setimmediate": "^1.0.5" } }, "sha512-O85mosi4sOfxG+slvqy0j7zLuFD4ylUgEMt7Pvt9Q/wnwNwG/6MNnHKzV9JkAoPoPM26t/DLFn17p7o7u5kIBA=="], + "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], - "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="], @@ -1192,13 +1618,17 @@ "ssri": ["ssri@10.0.6", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ=="], - "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="], - "std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="], + "streamx": ["streamx@2.28.1", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA=="], + + "string-kit": ["string-kit@0.19.5", "", {}, "sha512-MqNWtQQw6xMFbOSa26HfyS5uyDu1tR4OEPz44VDP6JWa/S0E0N11uw8CXrPt5hme/tBXRp5AmoIvFl5B9lt7PA=="], + + "string-length": ["string-length@4.0.2", "", { "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" } }, "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ=="], "string-split-by": ["string-split-by@1.0.0", "", { "dependencies": { "parenthesis": "^3.1.5" } }, "sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A=="], - "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], @@ -1208,9 +1638,11 @@ "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + "strip-bom": ["strip-bom@4.0.0", "", {}, "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w=="], - "strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="], + "strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="], + + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], "sumchecker": ["sumchecker@3.0.1", "", { "dependencies": { "debug": "^4.1.0" } }, "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="], @@ -1238,33 +1670,33 @@ "svelte-preprocess-esbuild": ["svelte-preprocess-esbuild@3.0.1", "", {}, "sha512-OV4P/onki7hfuzIpYOd92TT0JSm4y67PvkAAM7RigLd869VEvNh2f6J+ewrEqAgTnZzVQcOWzuaU4hPISNPFpA=="], + "synckit": ["synckit@0.11.13", "", { "dependencies": { "@pkgr/core": "^0.3.6" } }, "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg=="], + "tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], - "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="], + "tar-fs": ["tar-fs@3.1.3", "", { "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" }, "optionalDependencies": { "bare-fs": "^4.0.1", "bare-path": "^3.0.0" } }, "sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ=="], - "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], + "tar-stream": ["tar-stream@3.2.1", "", { "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-nqsEO8zLZJvrOMdEwkA0QdCLFbetHMn95Zqu4fKwX+hkaTWJPZZOrxx/PwtxoK0MMGQmBQNRW3CPs8IFYQz4cQ=="], - "three": ["three@0.162.0", "", {}, "sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ=="], + "teex": ["teex@1.0.1", "", { "dependencies": { "streamx": "^2.12.5" } }, "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg=="], - "throttleit": ["throttleit@1.0.1", "", {}, "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ=="], - - "through2": ["through2@0.6.5", "", { "dependencies": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" } }, "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg=="], + "terminal-kit": ["terminal-kit@3.1.4", "", { "dependencies": { "@cronvel/get-pixels": "^3.4.1", "chroma-js": "^2.4.2", "lazyness": "^1.2.0", "ndarray": "^1.0.19", "nextgen-events": "^1.5.3", "seventh": "^0.9.4", "string-kit": "^0.19.5", "tree-kit": "^0.8.10" } }, "sha512-0BfyIa7pY69E+UgV0P655uNk2rjp2eWTA0uZCTMlGzyrgcrH7kO6yZDGdHqB2vNF5uEjQ5+6ZilHfGtzrhLQNg=="], - "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + "test-exclude": ["test-exclude@7.0.2", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^10.4.1", "minimatch": "^10.2.2" } }, "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw=="], - "tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="], + "text-decoder": ["text-decoder@1.2.7", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ=="], - "tinydate": ["tinydate@1.3.0", "", {}, "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w=="], + "three": ["three@0.162.0", "", {}, "sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ=="], - "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + "throttleit": ["throttleit@1.0.1", "", {}, "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ=="], - "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + "through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="], - "tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="], + "through2": ["through2@0.6.5", "", { "dependencies": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" } }, "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg=="], - "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], + "tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="], - "tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="], + "tinydate": ["tinydate@1.3.0", "", {}, "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w=="], "to-fast-properties": ["to-fast-properties@2.0.0", "", {}, "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="], @@ -1276,6 +1708,8 @@ "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + "tree-kit": ["tree-kit@0.8.10", "", {}, "sha512-mwuV3lHL+utI9z7vxah/27wrMJprx925xhkw1N4KuGa1dqIi0DLHWfXJpHEyR+ZI0Ij80zN58ztiGp3KlH0wtw=="], + "ts-api-utils": ["ts-api-utils@2.1.0", "", {}, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="], "tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], @@ -1286,14 +1720,22 @@ "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], - "type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], + "type-detect": ["type-detect@4.0.8", "", {}, "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="], + + "type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], + + "typed-query-selector": ["typed-query-selector@2.12.2", "", {}, "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ=="], "typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], "typescript-eslint": ["typescript-eslint@8.45.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/parser": "8.45.0", "@typescript-eslint/typescript-estree": "8.45.0", "@typescript-eslint/utils": "8.45.0" } }, "sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg=="], + "unbzip2-stream": ["unbzip2-stream@1.4.3", "", { "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" } }, "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg=="], + "undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], + "uniq": ["uniq@1.0.1", "", {}, "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA=="], + "unique-filename": ["unique-filename@3.0.0", "", { "dependencies": { "unique-slug": "^4.0.0" } }, "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g=="], "unique-slug": ["unique-slug@4.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ=="], @@ -1304,15 +1746,15 @@ "universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], - "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + "unrs-resolver": ["unrs-resolver@1.12.2", "", { "dependencies": { "napi-postinstall": "^0.3.4" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.12.2", "@unrs/resolver-binding-android-arm64": "1.12.2", "@unrs/resolver-binding-darwin-arm64": "1.12.2", "@unrs/resolver-binding-darwin-x64": "1.12.2", "@unrs/resolver-binding-freebsd-x64": "1.12.2", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", "@unrs/resolver-binding-linux-x64-musl": "1.12.2", "@unrs/resolver-binding-openharmony-arm64": "1.12.2", "@unrs/resolver-binding-wasm32-wasi": "1.12.2", "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" } }, "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ=="], - "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + "update-browserslist-db": ["update-browserslist-db@1.3.2", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw=="], - "vite": ["vite@7.1.9", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="], + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], - "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="], + "v8-to-istanbul": ["v8-to-istanbul@9.3.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^2.0.0" } }, "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA=="], "vue": ["vue@2.7.14", "", { "dependencies": { "@vue/compiler-sfc": "2.7.14", "csstype": "^3.1.0" } }, "sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ=="], @@ -1326,29 +1768,31 @@ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - "wintersky": ["wintersky@1.3.0", "", { "dependencies": { "molangjs": "^1.6.3", "three": "^0.134.0", "tinycolor2": "^1.4.2" } }, "sha512-ibeUF+sgoIrFAfgqcNsPlr8+4l0KOfhGw+JgjxKcgtbckSy3gAxqAeNX5LjuQK9y7jcBZDwUIXg9sZDGQ1W+hQ=="], "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], - "wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], + "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + "write-file-atomic": ["write-file-atomic@5.0.1", "", { "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" } }, "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw=="], + + "ws": ["ws@8.21.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw=="], + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], - "yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="], + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], - "yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], - "yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], + "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], "yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="], @@ -1356,12 +1800,48 @@ "zimmerframe": ["zimmerframe@1.1.4", "", {}, "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ=="], - "@babel/parser/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + "zod": ["zod@3.23.8", "", {}, "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="], + + "@babel/code-frame/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/core/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@babel/core/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/generator/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@babel/generator/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-module-imports/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@babel/helper-module-transforms/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/helpers/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@babel/parser/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@babel/template/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@babel/traverse/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@babel/traverse/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], "@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "@emnapi/core/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + "@emnapi/runtime/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + "@emnapi/wasi-threads/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@eslint/config-array/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], @@ -1432,8 +1912,42 @@ "@grpc/grpc-js/@types/node": ["@types/node@20.12.12", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw=="], + "@grpc/proto-loader/yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], + "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], + "@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], + + "@istanbuljs/load-nyc-config/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="], + + "@istanbuljs/load-nyc-config/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + + "@istanbuljs/load-nyc-config/js-yaml": ["js-yaml@3.15.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w=="], + + "@istanbuljs/load-nyc-config/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + + "@jest/console/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "@jest/core/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "@jest/environment/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "@jest/fake-timers/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "@jest/pattern/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "@jest/reporters/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@jest/reporters/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "@jest/reporters/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + + "@jest/source-map/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@jest/transform/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@jest/types/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + "@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.4.15", "", {}, "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="], "@novacbn/svelte-codejar/svelte": ["svelte@3.59.2", "", {}, "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA=="], @@ -1446,6 +1960,24 @@ "@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@15.0.0", "", { "dependencies": { "@octokit/openapi-types": "^26.0.0" } }, "sha512-8o6yDfmoGJUIeR9OfYU0/TUJTnMPG2r68+1yEdUeG2Fdqpj8Qetg0ziKIgcBm0RW/j29H41WP37CYCEhp6GoHQ=="], + "@puppeteer/browsers/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "@puppeteer/browsers/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@snavesutit/jestbench/jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], + + "@tybys/wasm-util/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + + "@types/babel__core/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], + + "@types/babel__core/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + + "@types/babel__generator/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@types/babel__template/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + + "@types/babel__traverse/@babel/types": ["@babel/types@7.29.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg=="], + "@types/cacheable-request/@types/node": ["@types/node@20.12.12", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw=="], "@types/decompress/@types/node": ["@types/node@20.12.12", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw=="], @@ -1470,12 +2002,16 @@ "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], - "@vitest/mocker/magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], + "@unrs/resolver-binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], - "@vitest/snapshot/magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], + "@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], "@vue/compiler-sfc/postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], + "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "ast-types/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "blockbench-patch-manager/svelte": ["svelte@5.55.4", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.4", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-q8DFohk6vUswSng95IZb9nzWJnbINZsK7OiM1snAa3qCjJBL0ZQpvMyAaVXjUukdM75J/m8UE8xwqat8Ors/zQ=="], @@ -1490,7 +2026,7 @@ "cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "chai/loupe": ["loupe@3.1.2", "", {}, "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg=="], + "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -1506,6 +2042,8 @@ "electron/@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="], + "envbench/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "esbuild-plugin-import-folder/eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="], "esbuild-plugin-inline-worker/esbuild": ["esbuild@0.21.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.3", "@esbuild/android-arm": "0.21.3", "@esbuild/android-arm64": "0.21.3", "@esbuild/android-x64": "0.21.3", "@esbuild/darwin-arm64": "0.21.3", "@esbuild/darwin-x64": "0.21.3", "@esbuild/freebsd-arm64": "0.21.3", "@esbuild/freebsd-x64": "0.21.3", "@esbuild/linux-arm": "0.21.3", "@esbuild/linux-arm64": "0.21.3", "@esbuild/linux-ia32": "0.21.3", "@esbuild/linux-loong64": "0.21.3", "@esbuild/linux-mips64el": "0.21.3", "@esbuild/linux-ppc64": "0.21.3", "@esbuild/linux-riscv64": "0.21.3", "@esbuild/linux-s390x": "0.21.3", "@esbuild/linux-x64": "0.21.3", "@esbuild/netbsd-x64": "0.21.3", "@esbuild/openbsd-x64": "0.21.3", "@esbuild/sunos-x64": "0.21.3", "@esbuild/win32-arm64": "0.21.3", "@esbuild/win32-ia32": "0.21.3", "@esbuild/win32-x64": "0.21.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-Kgq0/ZsAPzKrbOjCQcjoSmPoWhlcVnGAUo7jvaLHoxW1Drto0KGkR1xBNg2Cp43b9ImvxmPEJZ9xkfcnqPsfBw=="], @@ -1524,10 +2062,16 @@ "estree-walker/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + "execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], + + "execa/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "get-uri/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "glob/minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], "http-proxy-agent/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], @@ -1536,6 +2080,44 @@ "is-reference/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + "istanbul-lib-instrument/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], + + "istanbul-lib-instrument/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "istanbul-lib-report/make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="], + + "istanbul-lib-source-maps/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "istanbul-lib-source-maps/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "jest-circus/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-config/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + + "jest-environment-node/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-haste-map/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-mock/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-runner/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-runtime/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-runtime/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + + "jest-snapshot/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + + "jest-snapshot/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "jest-util/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-watcher/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-worker/@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + "magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], "make-dir/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -1560,21 +2142,41 @@ "node-modules-vscode-problems-patch/esbuild": ["esbuild@0.25.10", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.10", "@esbuild/android-arm": "0.25.10", "@esbuild/android-arm64": "0.25.10", "@esbuild/android-x64": "0.25.10", "@esbuild/darwin-arm64": "0.25.10", "@esbuild/darwin-x64": "0.25.10", "@esbuild/freebsd-arm64": "0.25.10", "@esbuild/freebsd-x64": "0.25.10", "@esbuild/linux-arm": "0.25.10", "@esbuild/linux-arm64": "0.25.10", "@esbuild/linux-ia32": "0.25.10", "@esbuild/linux-loong64": "0.25.10", "@esbuild/linux-mips64el": "0.25.10", "@esbuild/linux-ppc64": "0.25.10", "@esbuild/linux-riscv64": "0.25.10", "@esbuild/linux-s390x": "0.25.10", "@esbuild/linux-x64": "0.25.10", "@esbuild/netbsd-arm64": "0.25.10", "@esbuild/netbsd-x64": "0.25.10", "@esbuild/openbsd-arm64": "0.25.10", "@esbuild/openbsd-x64": "0.25.10", "@esbuild/openharmony-arm64": "0.25.10", "@esbuild/sunos-x64": "0.25.10", "@esbuild/win32-arm64": "0.25.10", "@esbuild/win32-ia32": "0.25.10", "@esbuild/win32-x64": "0.25.10" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ=="], + "pac-proxy-agent/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "periscopic/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], "pkg-dir/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + "postcss-load-config/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="], + + "prebuild-install/tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="], + + "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + "protobufjs/@types/node": ["@types/node@20.12.12", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw=="], + "proxy-agent/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "proxy-agent/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + + "puppeteer-core/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], - "rollup/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + "resolve-cwd/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + + "serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], "sharp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], "socks-proxy-agent/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "stack-utils/escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="], + + "string-length/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -1588,9 +2190,9 @@ "tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], - "tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], + "test-exclude/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], - "tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "test-exclude/minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="], "typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.45.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/type-utils": "8.45.0", "@typescript-eslint/utils": "8.45.0", "@typescript-eslint/visitor-keys": "8.45.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" } }, "sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg=="], @@ -1600,25 +2202,57 @@ "typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.45.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/types": "8.45.0", "@typescript-eslint/typescript-estree": "8.45.0" } }, "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg=="], - "vite/esbuild": ["esbuild@0.25.10", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.10", "@esbuild/android-arm": "0.25.10", "@esbuild/android-arm64": "0.25.10", "@esbuild/android-x64": "0.25.10", "@esbuild/darwin-arm64": "0.25.10", "@esbuild/darwin-x64": "0.25.10", "@esbuild/freebsd-arm64": "0.25.10", "@esbuild/freebsd-x64": "0.25.10", "@esbuild/linux-arm": "0.25.10", "@esbuild/linux-arm64": "0.25.10", "@esbuild/linux-ia32": "0.25.10", "@esbuild/linux-loong64": "0.25.10", "@esbuild/linux-mips64el": "0.25.10", "@esbuild/linux-ppc64": "0.25.10", "@esbuild/linux-riscv64": "0.25.10", "@esbuild/linux-s390x": "0.25.10", "@esbuild/linux-x64": "0.25.10", "@esbuild/netbsd-arm64": "0.25.10", "@esbuild/netbsd-x64": "0.25.10", "@esbuild/openbsd-arm64": "0.25.10", "@esbuild/openbsd-x64": "0.25.10", "@esbuild/openharmony-arm64": "0.25.10", "@esbuild/sunos-x64": "0.25.10", "@esbuild/win32-arm64": "0.25.10", "@esbuild/win32-ia32": "0.25.10", "@esbuild/win32-x64": "0.25.10" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ=="], - - "vite-node/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "update-browserslist-db/escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], - "vitest/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - - "vitest/magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], + "v8-to-istanbul/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], "wintersky/three": ["three@0.134.0", "", {}, "sha512-LbBerg7GaSPjYtTOnu41AMp7tV6efUNR3p4Wk5NzkSsNTBuA5mDGOfwwZL1jhhVMLx9V20HolIUo0+U3AXehbg=="], "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - "wrap-ansi/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], + "wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + "yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "@babel/core/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/core/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/core/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "@babel/generator/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/generator/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/generator/@jridgewell/gen-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@babel/generator/@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "@babel/helper-module-imports/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/helper-module-imports/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/helpers/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/helpers/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], - "@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + "@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/template/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/template/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/traverse/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/traverse/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/traverse/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "@eslint/config-array/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], @@ -1628,21 +2262,75 @@ "@grpc/grpc-js/@grpc/proto-loader/protobufjs": ["protobufjs@7.3.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-YWD03n3shzV9ImZRX3ccbjqLxj7NokGN0V/ESiBV5xWqrommYHYiihuIyavq03pWSGqlyvYUFmfoMKd+1rPA/g=="], - "@grpc/grpc-js/@grpc/proto-loader/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + "@grpc/proto-loader/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], + + "@grpc/proto-loader/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "@grpc/proto-loader/yargs/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "@istanbuljs/load-nyc-config/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + + "@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + + "@jest/console/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@jest/core/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@jest/environment/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@jest/fake-timers/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@jest/pattern/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@jest/reporters/@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jest/reporters/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "@jest/reporters/glob/minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="], + + "@jest/reporters/glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "@jest/reporters/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + + "@jest/source-map/@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jest/transform/@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jest/types/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + "@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="], "@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@26.0.0", "", {}, "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA=="], + "@puppeteer/browsers/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "@types/babel__core/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@types/babel__core/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@types/babel__generator/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@types/babel__generator/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@types/babel__template/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@types/babel__template/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@types/babel__traverse/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@types/babel__traverse/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + "@typescript-eslint/utils/@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@typescript-eslint/utils/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="], - "@vitest/mocker/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + "@unrs/resolver-binding-wasm32-wasi/@emnapi/runtime/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], - "@vitest/snapshot/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + "@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], "bl/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], @@ -1658,6 +2346,8 @@ "cacache/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "electron/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], @@ -1732,10 +2422,54 @@ "eslint/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "get-uri/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "http-proxy-agent/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "https-proxy-agent/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "istanbul-lib-instrument/@babel/parser/@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + + "istanbul-lib-report/make-dir/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "istanbul-lib-source-maps/@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "istanbul-lib-source-maps/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "jest-circus/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "jest-config/glob/minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="], + + "jest-config/glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "jest-config/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + + "jest-environment-node/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "jest-haste-map/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "jest-mock/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "jest-runner/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "jest-runtime/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "jest-runtime/glob/minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="], + + "jest-runtime/glob/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "jest-runtime/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + + "jest-snapshot/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "jest-snapshot/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "jest-util/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "jest-watcher/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + + "jest-worker/@types/node/undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + "node-gyp/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], "node-gyp/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], @@ -1790,13 +2524,23 @@ "node-modules-vscode-problems-patch/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.10", "", { "os": "win32", "cpu": "x64" }, "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw=="], + "pac-proxy-agent/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "pkg-dir/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "prebuild-install/tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], + + "prebuild-install/tar-fs/tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], + + "proxy-agent/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "puppeteer-core/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "socks-proxy-agent/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "string-length/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "svelte-multiselect/svelte/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.4.15", "", {}, "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="], @@ -1812,7 +2556,13 @@ "svelte-patching-tools/svelte/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], - "tar-stream/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + "test-exclude/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], + + "test-exclude/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "test-exclude/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + + "test-exclude/minimatch/brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="], "typescript-eslint/@typescript-eslint/eslint-plugin/@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], @@ -1844,65 +2594,33 @@ "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.45.0", "", {}, "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA=="], - "vite-node/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - - "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.10", "", { "os": "aix", "cpu": "ppc64" }, "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw=="], - - "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.10", "", { "os": "android", "cpu": "arm" }, "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w=="], - - "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.10", "", { "os": "android", "cpu": "arm64" }, "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg=="], - - "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.10", "", { "os": "android", "cpu": "x64" }, "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg=="], - - "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA=="], + "v8-to-istanbul/@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg=="], + "wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.10", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg=="], - - "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.10", "", { "os": "freebsd", "cpu": "x64" }, "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA=="], - - "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.10", "", { "os": "linux", "cpu": "arm" }, "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg=="], - - "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ=="], - - "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.10", "", { "os": "linux", "cpu": "ia32" }, "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ=="], - - "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.10", "", { "os": "linux", "cpu": "none" }, "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg=="], - - "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.10", "", { "os": "linux", "cpu": "none" }, "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA=="], - - "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.10", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA=="], - - "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.10", "", { "os": "linux", "cpu": "none" }, "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA=="], - - "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.10", "", { "os": "linux", "cpu": "s390x" }, "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew=="], - - "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.10", "", { "os": "linux", "cpu": "x64" }, "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA=="], - - "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.10", "", { "os": "none", "cpu": "x64" }, "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig=="], + "wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.10", "", { "os": "openbsd", "cpu": "x64" }, "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw=="], + "yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.10", "", { "os": "sunos", "cpu": "x64" }, "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ=="], + "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw=="], + "@grpc/proto-loader/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.10", "", { "os": "win32", "cpu": "ia32" }, "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw=="], + "@grpc/proto-loader/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.10", "", { "os": "win32", "cpu": "x64" }, "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw=="], + "@grpc/proto-loader/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "vitest/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "@grpc/proto-loader/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "vitest/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + "@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], - "wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "@istanbuljs/load-nyc-config/js-yaml/argparse/sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], - "wrap-ansi/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + "@jest/reporters/glob/minimatch/brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="], - "@grpc/grpc-js/@grpc/proto-loader/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + "@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], - "@grpc/grpc-js/@grpc/proto-loader/yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + "@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], "cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], @@ -1914,14 +2632,30 @@ "esbuild-plugin-import-folder/eslint/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "istanbul-lib-instrument/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "istanbul-lib-instrument/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "jest-config/glob/minimatch/brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="], + + "jest-runtime/glob/minimatch/brace-expansion": ["brace-expansion@5.0.9", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="], + "node-gyp/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "node-gyp/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "pkg-dir/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + "prebuild-install/tar-fs/tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "svelte-multiselect/svelte/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], + "test-exclude/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "test-exclude/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "test-exclude/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.45.0", "", {}, "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA=="], "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/types": ["@typescript-eslint/types@8.45.0", "", {}, "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA=="], @@ -1936,18 +2670,28 @@ "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.45.0", "", { "dependencies": { "@typescript-eslint/types": "8.45.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag=="], - "@grpc/grpc-js/@grpc/proto-loader/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "@grpc/grpc-js/@grpc/proto-loader/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "@grpc/proto-loader/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "@grpc/proto-loader/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "@istanbuljs/load-nyc-config/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + + "@jest/reporters/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "jest-config/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "jest-runtime/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "pkg-dir/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + "prebuild-install/tar-fs/tar-stream/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + "typescript-eslint/@typescript-eslint/typescript-estree/fast-glob/micromatch/braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], "typescript-eslint/@typescript-eslint/typescript-estree/fast-glob/micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "@grpc/grpc-js/@grpc/proto-loader/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "typescript-eslint/@typescript-eslint/typescript-estree/fast-glob/micromatch/braces/fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], } } diff --git a/eslint.config.ts b/eslint.config.ts index bef3f6f7..45a4ddec 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -16,6 +16,10 @@ const IGNORE_PATTERNS = [ // Blockbench Plugin Template 'dist/**/*', + // Test-runner config (plain ESM, not part of the TS project) + 'jest.config.mjs', + 'blockbench.config.mjs', + // Ignore files for PNPM, NPM and YARN 'pnpm-lock.yaml', 'package-lock.json', diff --git a/jest.config.mjs b/jest.config.mjs new file mode 100644 index 00000000..10ce622a --- /dev/null +++ b/jest.config.mjs @@ -0,0 +1,24 @@ +import preset from '@snavesutit/jestbench/jest-preset.js' + +// jestbench's preset supplies the Blockbench test environment, global +// setup/teardown, custom matchers, `maxWorkers: 1` and an extended timeout. +// We only add the TypeScript transform and point it at our suite. + +/** @type {import('jest').Config} */ +export default { + ...preset, + rootDir: '.', + testMatch: ['/src/tests/**/*.test.ts'], + // Tests open blueprints, which fetch the target Minecraft version's assets + // (downloaded and cached on first run). + testTimeout: 120_000, + transform: { + '^.+\\.tsx?$': [ + '@swc/jest', + { + jsc: { parser: { syntax: 'typescript' }, target: 'es2022' }, + module: { type: 'commonjs' }, + }, + ], + }, +} diff --git a/package.json b/package.json index a5ecb15a..e22e3795 100644 --- a/package.json +++ b/package.json @@ -78,13 +78,17 @@ "dev": "yarn build:scripts && node ./dist/build.cjs --mode=dev", "prod": "node ./.scripts/cleanupDist.cjs && yarn build:scripts && node ./dist/build.cjs", "format": "prettier --write .", - "test": "yarn build:scripts && vitest run", - "coverage": "yarn build:scripts && vitest run --coverage", + "test": "yarn prod && jest", + "test:only": "jest", "check-formatting": "prettier . --check", "lint": "eslint . --max-warnings=0 --no-warn-ignored" }, "devDependencies": { + "@jest/globals": "^30.5.1", "@novacbn/svelte-codejar": "^0.1.2", + "@snavesutit/jestbench": "^0.2.0", + "@swc/core": "^1.16.1", + "@swc/jest": "^0.2.39", "@types/download": "^8.0.5", "@types/eslint": "^8.21.1", "@types/js-yaml": "^4.0.5", @@ -103,6 +107,7 @@ "eslint": "^9.37.0", "eslint-plugin-svelte": "^3.12.4", "firebase": "^9.19.0", + "jest": "^30", "jiti": "^2.6.1", "js-yaml": "^4.1.0", "mc-build": "^4.1.3", @@ -119,8 +124,7 @@ "svelte-preprocess": "^6.0.3", "svelte-preprocess-esbuild": "^3.0.1", "typescript": "^6.0.2", - "typescript-eslint": "^8.45.0", - "vitest": "^3.2.4" + "typescript-eslint": "^8.45.0" }, "dependencies": { "block-model-renderer": "^2.15.2", diff --git a/src/tests/pass.test.ts b/src/tests/pass.test.ts deleted file mode 100644 index 982a17e2..00000000 --- a/src/tests/pass.test.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { test } from 'vitest' - -test.todo('should pass') diff --git a/tsconfig.json b/tsconfig.json index 3b37fbd8..7072c051 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,6 @@ { "files": ["src/index.ts"], - "include": [ - "src/**/*", - ".scripts/**/**/*", - "./eslint.config.ts", - "./vitest.config.ts", - "./svelte.config.ts" - ], + "include": ["src/**/*", ".scripts/**/**/*", "./eslint.config.ts", "./svelte.config.ts"], "exclude": ["**/node_modules/**"], "compilerOptions": { "outDir": "./dist/", diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index 3f0b2fbd..00000000 --- a/vitest.config.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { defineConfig } from 'vitest/config' - -export default defineConfig({ - test: { - dir: 'src/tests', - server: { - deps: { - // `book-and-quill` and its `generic-stream` dep ship extensionless - // ESM imports that Node's native resolver rejects; inlining lets - // Vite/esbuild transform them the way the plugin build does. - inline: ['book-and-quill', 'generic-stream'], - }, - }, - }, -}) From 6238ac2471f6c02c58e80c10dd4c49c50fb97dd8 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 20:33:35 -0400 Subject: [PATCH 18/85] =?UTF-8?q?=F0=9F=90=9B=20Scope=20text-display=20gly?= =?UTF-8?q?ph=20caches=20to=20the=20active=20preview=20resource=20pack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - glyph/layout caches were keyed by Minecraft version only, so a render finishing right after a cache clear could refill them with the wrong font - a preview resource pack's custom fonts sometimes never showed up - fix: also key those caches by the active pack - expose previewResourcePack on the AnimatedJava global for the test --- src/index.ts | 3 +- src/systems/minecraft/fontRenderer.ts | 23 +++-- src/tests/preview-resource-pack-font.test.ts | 93 +++++++++++++++++++ .../assets/minecraft/font/default.json | 8 ++ test-packs/font-override-pack/pack.mcmeta | 6 ++ 5 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 src/tests/preview-resource-pack-font.test.ts create mode 100644 test-packs/font-override-pack/assets/minecraft/font/default.json create mode 100644 test-packs/font-override-pack/pack.mcmeta diff --git a/src/index.ts b/src/index.ts index 8dab4e00..73cd4896 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,7 +22,6 @@ import './systems/minecraft/assetManager' import './systems/minecraft/blockstateManager' import './systems/minecraft/fontManager' import './systems/minecraft/fontRenderer' -import './systems/minecraft/previewResourcePack' import './systems/minecraft/registryManager' import './systems/minecraft/versionManager' // Shaders @@ -52,6 +51,7 @@ import * as blockModelManager from './systems/minecraft/blockModelManager' import { BLOCKSTATE_REGISTRY, getBlockState } from './systems/minecraft/blockstateManager' import { MinecraftFont } from './systems/minecraft/fontManager' import * as itemModelManager from './systems/minecraft/itemModelManager' +import * as previewResourcePack from './systems/minecraft/previewResourcePack' import './systems/minecraft/registryManager' import resourcepackCompiler from './systems/resourcepackCompiler' import { @@ -86,6 +86,7 @@ const AnimatedJavaApi = { assetManager, itemModelManager, blockModelManager, + previewResourcePack, VanillaItemDisplay, VanillaBlockDisplay, debugBlockState, diff --git a/src/systems/minecraft/fontRenderer.ts b/src/systems/minecraft/fontRenderer.ts index 74d2f7c6..a3badf4d 100644 --- a/src/systems/minecraft/fontRenderer.ts +++ b/src/systems/minecraft/fontRenderer.ts @@ -55,7 +55,7 @@ interface GlyphGeo { width: number } -// version -> fontId -> char -> [styleFlags 0..15] +// (version + previewPackKey) -> fontId -> char -> [styleFlags 0..15] const GLYPH_GEO_CACHE = new Map>>>() // raw colour value -> resolved THREE colour + alpha, kept across renders const COLOR_CACHE = new Map() @@ -169,9 +169,9 @@ function buildGlyphGeo(font: MinecraftFont, char: string, flags: number): GlyphG return geo } -function getGlyphGeo(version: string, font: MinecraftFont, char: string, flags: number): GlyphGeo { - let byFont = GLYPH_GEO_CACHE.get(version) - if (!byFont) GLYPH_GEO_CACHE.set(version, (byFont = new Map())) +function getGlyphGeo(scope: string, font: MinecraftFont, char: string, flags: number): GlyphGeo { + let byFont = GLYPH_GEO_CACHE.get(scope) + if (!byFont) GLYPH_GEO_CACHE.set(scope, (byFont = new Map())) let byChar = byFont.get(font.id) if (!byChar) byFont.set(font.id, (byChar = new Map())) let byFlags = byChar.get(char) @@ -180,7 +180,7 @@ function getGlyphGeo(version: string, font: MinecraftFont, char: string, flags: } // --------------------------------------------------------------------------- -// Layout (wrap + place), cached per (version, text, maxLineWidth) +// Layout (wrap + place), cached per (version + previewPackKey, text, maxLineWidth) // --------------------------------------------------------------------------- interface GlyphPlacement { @@ -210,7 +210,7 @@ interface TextLayout { } function buildLayout( - version: string, + scope: string, baseFont: MinecraftFont, segments: ReturnType, maxLineWidth: number @@ -234,7 +234,7 @@ function buildLayout( const mainColor = style.color ?? (COLORS.white as Color) const shadowColor = style.shadow_color for (const char of segment.text) { - const geo = getGlyphGeo(version, styledFont, char, flags) + const geo = getGlyphGeo(scope, styledFont, char, flags) if (geo.tris || geo.decoTris.length > 0) { glyphs.push({ geo, relX, mainColor, shadowColor }) } @@ -355,18 +355,23 @@ export async function generateTextDisplayMesh({ const stopwatch = new Stopwatch('Generate Text Display Mesh').start() const version = Project.animated_java.target_minecraft_version + // Scope every glyph/layout cache entry to the active preview resource pack so a + // text-mesh build that started before an overlay swap (e.g. project-load renders + // racing the SELECT_AJ_PROJECT overlay apply) writes into its own now-orphaned + // bucket instead of poisoning the caches the post-swap rebuild reads. + const cacheScope = version + '\0' + getPreviewResourcePackKey() const font = await MinecraftFont.getById('minecraft:default') if (!font) throw new Error('Could not load the default Minecraft font') // --- Wrap + place (cached per component) ------------------------------ const layoutKey = - cacheKey === undefined ? undefined : version + '\0' + maxLineWidth + '\0' + cacheKey + cacheKey === undefined ? undefined : cacheScope + '\0' + maxLineWidth + '\0' + cacheKey let layout = layoutKey === undefined ? undefined : LAYOUT_CACHE.get(layoutKey) if (!layout) { const lang = await getLangMap(version) const segments = resolveComponent(jsonText, { translate: key => lang[key] }) await preloadReferencedFonts(segments) - layout = buildLayout(version, font, segments, maxLineWidth) + layout = buildLayout(cacheScope, font, segments, maxLineWidth) if (layoutKey !== undefined) { if (LAYOUT_CACHE.size >= LAYOUT_CACHE_LIMIT) LAYOUT_CACHE.clear() LAYOUT_CACHE.set(layoutKey, layout) diff --git a/src/tests/preview-resource-pack-font.test.ts b/src/tests/preview-resource-pack-font.test.ts new file mode 100644 index 00000000..b5d9e7f2 --- /dev/null +++ b/src/tests/preview-resource-pack-font.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it } from '@jest/globals' +import { blockbench } from '@snavesutit/jestbench' +import * as path from 'node:path' + +const BLUEPRINT_FORMAT_ID = 'animated-java:format/blueprint' +const FONT_OVERRIDE_PACK = path.resolve(process.cwd(), 'test-packs/font-override-pack') + +/** + * Regression test: preview resource pack font overlays silently failing to apply + * to text displays. + * + * On project open, text displays start rendering from `Canvas.updateAll()` a + * frame or two before `applyPreviewResourcePack()` runs. `applyPreviewResourcePack` + * clears the font registry and the glyph-geometry / layout caches, but a + * text-mesh build that is already in flight finishes just after that clear and + * repopulates the glyph / layout caches with vanilla-font data. Those caches + * were keyed by Minecraft version only, so the stale entry was then reused for + * every later render even though the overlay had loaded - the custom font never + * showed up. + * + * The scenario below reproduces that end state directly and deterministically: + * the layout cache holds a "no overlay" entry for the text while the active pack + * (and the font registry) have already moved on to the overlay. A fresh render + * must not be served that stale entry. + */ +describe('preview resource pack font overlays', () => { + it('are not served a stale layout cache from before the active pack changed', async () => { + await blockbench.evaluate((formatId: string) => { + const format = (globalThis as any).Formats[formatId] + if (!format) throw new Error(`Format '${formatId}' is not registered`) + ;(globalThis as any).newProject(format) + }, BLUEPRINT_FORMAT_ID) + + const result = await blockbench.evaluate(async (packPath: string) => { + const aj = (window as any).AnimatedJava + const { TextDisplay, MinecraftFont, assetManager, previewResourcePack } = aj + + const project = Project as any + project.animated_java.preview_resource_packs = [] + await previewResourcePack.applyPreviewResourcePack() + + const td = new TextDisplay({}).init() + td.text = '"A"' + + const rebuildAndMeasure = async (): Promise => { + td.needsMeshUpdate = true + td.updateTextMesh() + let last = Number.NaN + let stable = 0 + for (let i = 0; i < 400; i++) { + await new Promise(r => setTimeout(r, 25)) + const geo = td.mesh?.geometry + if (!geo?.attributes?.position) continue + geo.computeBoundingBox() + const width = geo.boundingBox.max.x - geo.boundingBox.min.x + if (width === last) { + if (++stable >= 3) return width + } else { + stable = 0 + } + last = width + } + return last + } + + // 1. Render "A" with no overlay - primes the glyph / layout caches + // with vanilla-font data. + const vanillaWidth = await rebuildAndMeasure() + + // 2. Reproduce the post-race state: the overlay pack is now active and + // the font registry has been cleared (both done by + // `applyPreviewResourcePack`), but the glyph / layout caches were + // re-dirtied by a straggler render right after they were cleared - + // so they still hold the step 1 vanilla entries. + await assetManager.setPreviewResourcePacks([packPath]) + MinecraftFont.all.clear() + const packKey = assetManager.getPreviewResourcePackKey() as string + + // 3. A fresh render must rebuild from the overlay, not reuse step 1. + const overriddenWidth = await rebuildAndMeasure() + + return { vanillaWidth, overriddenWidth, packKey } + }, FONT_OVERRIDE_PACK) + + // The fixture sets the advance of "A" to 100px; vanilla is ~6px. Widths + // are world units: (layoutWidth + 1) * 0.4, so ~2.8 vanilla vs ~40 with + // the overlay. + expect(result.packKey).toBeTruthy() + expect(result.vanillaWidth).toBeGreaterThan(0) + expect(result.vanillaWidth).toBeLessThan(10) + expect(result.overriddenWidth).toBeGreaterThan(20) + }) +}) diff --git a/test-packs/font-override-pack/assets/minecraft/font/default.json b/test-packs/font-override-pack/assets/minecraft/font/default.json new file mode 100644 index 00000000..1439e24d --- /dev/null +++ b/test-packs/font-override-pack/assets/minecraft/font/default.json @@ -0,0 +1,8 @@ +{ + "providers": [ + { + "type": "space", + "advances": { "A": 100 } + } + ] +} diff --git a/test-packs/font-override-pack/pack.mcmeta b/test-packs/font-override-pack/pack.mcmeta new file mode 100644 index 00000000..3b95b223 --- /dev/null +++ b/test-packs/font-override-pack/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "pack_format": 42, + "description": "Jestbench fixture: overrides the width of 'A' in minecraft:default so text-display font overlays are measurable." + } +} From 692100a7370d5de315bb6ae0e62f4f8b5540e8ae Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:20:32 -0400 Subject: [PATCH 19/85] =?UTF-8?q?=F0=9F=90=9B=20Localize=20Blueprint=20Set?= =?UTF-8?q?tings=20general,=20resource=20pack,=20and=20misc=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #525. - general, resourcepack, and misc pages rendered hardcoded English labels and descriptions instead of going through the localization system - route every visible string through createScopedTranslator, matching the already-localized datapack and rig pages - add the missing en.yml keys (target_environment, blueprint_name, resource_pack_export_mode option descriptions, resource_pack.folder/zip titles) and repoint the dead render-box keys at the copy actually shown --- .../blueprintSettings/pages/general.svelte | 27 ++++++------ .../blueprintSettings/pages/misc.svelte | 15 ++++--- .../pages/resourcepack.svelte | 23 +++++------ src/lang/en.yml | 41 +++++++++++++------ 4 files changed, 64 insertions(+), 42 deletions(-) diff --git a/src/dialogs/blueprintSettings/pages/general.svelte b/src/dialogs/blueprintSettings/pages/general.svelte index 2bd15e41..df727992 100644 --- a/src/dialogs/blueprintSettings/pages/general.svelte +++ b/src/dialogs/blueprintSettings/pages/general.svelte @@ -12,6 +12,9 @@ import BoxSelect from '../../../svelteComponents/sidebarDialogItems/boxSelect.svelte' import LineEdit from '../../../svelteComponents/sidebarDialogItems/lineEdit.svelte' import Vector2 from '../../../svelteComponents/sidebarDialogItems/vector2.svelte' + import { createScopedTranslator } from '../../../util/lang' + + const translate = createScopedTranslator('dialog.blueprint_settings') const DEFAULT_SETTINGS = getDefaultProjectSettings() @@ -37,17 +40,17 @@
{#if !autoRenderBox} {:else if resourcePackExportFormat === 'zip'} Date: Tue, 1 Sep 2026 21:21:37 -0400 Subject: [PATCH 20/85] =?UTF-8?q?=F0=9F=90=9B=20Give=20a=20descriptive=20e?= =?UTF-8?q?rror=20when=20user=20command=20content=20fails=20to=20compile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #315. - command keyframes and config functions (on-summon/tick/remove, variant apply, ...) are emitted verbatim into the mcb templates and only parsed during compiler.compile(), so a syntax error in any of them bubbled up as a raw MC-Build error that looked like a plugin crash - wrap compiler.compile() and rethrow as an IntentionalExportError that names the likely sources and includes the original compiler message --- src/systems/datapackCompiler/mcbCompiler.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/systems/datapackCompiler/mcbCompiler.ts b/src/systems/datapackCompiler/mcbCompiler.ts index b2564dc9..54559d91 100644 --- a/src/systems/datapackCompiler/mcbCompiler.ts +++ b/src/systems/datapackCompiler/mcbCompiler.ts @@ -2,6 +2,7 @@ import { Compiler, VariableMap } from 'mc-build/mcl/Compiler' import { Parser } from 'mc-build/mcl/Parser' import { TemplateRegisterer } from 'mc-build/mcl/TemplateRegisterer' import { Tokenizer } from 'mc-build/mcl/TokenizerImpl' +import { IntentionalExportError } from '../errors' import { getMisodeVersion } from '../minecraft/versionManager' import type { ExportedFile } from '../util' @@ -76,7 +77,21 @@ export async function compileMcbProject({ } } - compiler.compile(VariableMap.fromObject(variables)) + try { + compiler.compile(VariableMap.fromObject(variables)) + } catch (e) { + // User commands are emitted into the templates and only parsed here, so + // their syntax errors otherwise surface as a raw crash. + const original = e instanceof Error ? e.message : String(e) + throw new IntentionalExportError( + 'Failed to compile the Data Pack.\n\n' + + 'This is usually caused by an invalid command in a command keyframe, or in an ' + + 'On-Summon / On-Tick / On-Remove / variant apply function.\n\n' + + '```\n' + + original + + '\n```' + ) + } console.timeEnd('MC-Build compiled in') console.log('Exported files:', exportedFiles.keys()) console.groupEnd() From a650cfce5f48ba13637006922a2a25b5ada5c779 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:22:28 -0400 Subject: [PATCH 21/85] =?UTF-8?q?=F0=9F=90=9B=20Use=20custom=5Fmodel=5Fdat?= =?UTF-8?q?a=20for=20variant=20model=20swaps=20on=201.21.0/1.21.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #528. - the 1.21.0 data pack template swapped variant models by setting the minecraft:item_model component, but that component was only added in 1.21.2, so 1.21.0/1.21.1 exports logged "invalid item" and the swap silently did nothing - swap through minecraft:custom_model_data instead, matching the 1.20.5 template and the base-model assignment already done for >= 1.20.5 --- src/systems/datapackCompiler/1.21.0/main.mcb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/systems/datapackCompiler/1.21.0/main.mcb b/src/systems/datapackCompiler/1.21.0/main.mcb index 9dbef69c..313fefb4 100644 --- a/src/systems/datapackCompiler/1.21.0/main.mcb +++ b/src/systems/datapackCompiler/1.21.0/main.mcb @@ -2,7 +2,6 @@ # DIFFERENCES FROM 1.20.5: # - @n entity selector -# - minecraft:item_model item component: item.components."minecraft:custom_model_data" -> item.components."minecraft:item_model" function on_load { data modify storage <%project_storage%> rig_hash set value <%"'" + rig_hash + "'"%> @@ -1645,11 +1644,12 @@ IF (Object.keys(rig.variants).length > 1) { run \ block zzz/apply_to_node_<%node.storage_name%> { IF (node.type === 'bone' && variant.models[node.uuid] !== undefined) { + # minecraft:item_model does not exist until 1.21.2. # Special case for `animated_java:empty` model. IF (variant.models[node.uuid].model === null) { - data modify entity @s item.components."minecraft:item_model" set value "animated_java:empty" + data modify entity @s item.components."minecraft:custom_model_data" set value 1 } ELSE { - data modify entity @s item.components."minecraft:item_model" set value "<%variant.models[node.uuid].item_model%>" + data modify entity @s item.components."minecraft:custom_model_data" set value <%variant.models[node.uuid].custom_model_data%> } } IF (node.configs.variants[variant.uuid] || variant.is_default && node.configs.default) { From 40802e67802073c7673558dfb820afa3068b2681 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:26:07 -0400 Subject: [PATCH 22/85] =?UTF-8?q?=F0=9F=90=9B=20Persist=20texture=20groups?= =?UTF-8?q?=20in=20the=20Blueprint=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #407. - the codec saved and restored bone groups but never texture groups, so on reload every texture group vanished and its textures fell back to the root of the list - save TextureGroup.all and recreate the groups before textures load, so each texture's group reference resolves --- src/formats/blueprint/codec.ts | 12 ++++++ src/formats/blueprint/index.ts | 1 + src/tests/blueprint-texture-groups.test.ts | 44 ++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/tests/blueprint-texture-groups.test.ts diff --git a/src/formats/blueprint/codec.ts b/src/formats/blueprint/codec.ts index 7401d470..64f5b66b 100644 --- a/src/formats/blueprint/codec.ts +++ b/src/formats/blueprint/codec.ts @@ -95,6 +95,13 @@ export const BLUEPRINT_CODEC = registerDeletableHandlerPatch({ Project.last_used_blueprint_id = model.meta?.last_used_blueprint_id ?? Project.animated_java.blueprint_id + if (model.texture_groups) { + for (const textureGroup of model.texture_groups) { + // @ts-expect-error - add() type omits the undo arg + new TextureGroup(textureGroup, textureGroup.uuid).add(false) + } + } + if (model.textures) { for (const texture of model.textures) { const newTexture = new Texture(texture, texture.uuid).add(false) @@ -294,6 +301,11 @@ export const BLUEPRINT_CODEC = registerDeletableHandlerPatch({ model.outliner = Outliner.toJSON() + model.texture_groups = [] + for (const textureGroup of TextureGroup.all) { + model.texture_groups.push(textureGroup.getSaveCopy()) + } + model.textures = [] for (const texture of Texture.all) { const save = texture.getSaveCopy() as Texture diff --git a/src/formats/blueprint/index.ts b/src/formats/blueprint/index.ts index e1b2b227..cca8025a 100644 --- a/src/formats/blueprint/index.ts +++ b/src/formats/blueprint/index.ts @@ -162,6 +162,7 @@ export interface IBlueprintFormatJSON { elements?: any[] groups?: any[] + texture_groups?: any[] outliner?: any[] textures?: Texture[] animations?: AnimationOptions[] diff --git a/src/tests/blueprint-texture-groups.test.ts b/src/tests/blueprint-texture-groups.test.ts new file mode 100644 index 00000000..698828f7 --- /dev/null +++ b/src/tests/blueprint-texture-groups.test.ts @@ -0,0 +1,44 @@ +import { describe, expect, it } from '@jest/globals' +import { blockbench } from '@snavesutit/jestbench' + +const BLUEPRINT_FORMAT_ID = 'animated-java:format/blueprint' + +/** + * Regression test for #407: the Blueprint codec saved and restored bone groups + * but never texture groups, so reopening a project dropped every texture group + * and left its textures at the root of the list. + */ +describe('Blueprint format: texture groups', () => { + it('survive a compile / parse round-trip', async () => { + const result = await blockbench.evaluate((formatId: string) => { + const aj = (window as any).AnimatedJava + const codec = aj.BLUEPRINT_CODEC.get() + const g = globalThis as any + + g.newProject(g.Formats[formatId]) + const group = new g.TextureGroup({ name: 'my_group' }, undefined).add(false) + const grouped = new Texture({ name: 'in_group.png' }, undefined).add(false) + new Texture({ name: 'loose.png' }, undefined).add(false) + grouped.group = group.uuid + + const model = codec.compile({ raw: true, bitmaps: false }) + + g.newProject(g.Formats[formatId]) + codec.parse(model, 'roundtrip.ajblueprint') + + const groups = g.TextureGroup.all as Array<{ uuid: string; name: string }> + return { + groupCount: groups.length, + groupName: groups[0]?.name, + groupedRefMatches: + Texture.all.find(t => t.name === 'in_group.png')?.group === groups[0]?.uuid, + looseGroup: Texture.all.find(t => t.name === 'loose.png')?.group, + } + }, BLUEPRINT_FORMAT_ID) + + expect(result.groupCount).toBe(1) + expect(result.groupName).toBe('my_group') + expect(result.groupedRefMatches).toBe(true) + expect(result.looseGroup).toBeFalsy() + }) +}) From d79febc23f5a023c3fc8e53cd596d707eda6dd86 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:28:09 -0400 Subject: [PATCH 23/85] =?UTF-8?q?=F0=9F=90=9B=20Round=20camera=20keyframe?= =?UTF-8?q?=20positions=20on=20export?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #518. - locator and interaction frame positions were rounded to 4 decimals, but the camera branch wrote raw floats, so near-zero values serialized in scientific notation (e.g. 9.217e-7) and broke the macro-driven frame and last_frame_effects functions - round the camera px/py/pz/ry/rx the same way, in every version template --- src/systems/datapackCompiler/1.20.4/main.mcb | 10 +++++----- src/systems/datapackCompiler/1.20.5/main.mcb | 10 +++++----- src/systems/datapackCompiler/1.21.0/main.mcb | 10 +++++----- src/systems/datapackCompiler/1.21.2/main.mcb | 10 +++++----- src/systems/datapackCompiler/1.21.4/main.mcb | 10 +++++----- src/systems/datapackCompiler/1.21.5/main.mcb | 10 +++++----- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/systems/datapackCompiler/1.20.4/main.mcb b/src/systems/datapackCompiler/1.20.4/main.mcb index 3654e8c7..ea29f73c 100644 --- a/src/systems/datapackCompiler/1.20.4/main.mcb +++ b/src/systems/datapackCompiler/1.20.4/main.mcb @@ -564,11 +564,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.cameras[node.storage_name] = { - px: transform.pos[0], - py: transform.pos[1], - pz: transform.pos[2], - ry: transform.head_rot[1], - rx: transform.head_rot[0] + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } ;break diff --git a/src/systems/datapackCompiler/1.20.5/main.mcb b/src/systems/datapackCompiler/1.20.5/main.mcb index 540324c9..d434ea27 100644 --- a/src/systems/datapackCompiler/1.20.5/main.mcb +++ b/src/systems/datapackCompiler/1.20.5/main.mcb @@ -567,11 +567,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.cameras[node.storage_name] = { - px: transform.pos[0], - py: transform.pos[1], - pz: transform.pos[2], - ry: transform.head_rot[1], - rx: transform.head_rot[0] + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } ;break diff --git a/src/systems/datapackCompiler/1.21.0/main.mcb b/src/systems/datapackCompiler/1.21.0/main.mcb index 313fefb4..2e1b124b 100644 --- a/src/systems/datapackCompiler/1.21.0/main.mcb +++ b/src/systems/datapackCompiler/1.21.0/main.mcb @@ -567,11 +567,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.cameras[node.storage_name] = { - px: transform.pos[0], - py: transform.pos[1], - pz: transform.pos[2], - ry: transform.head_rot[1], - rx: transform.head_rot[0] + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } ;break diff --git a/src/systems/datapackCompiler/1.21.2/main.mcb b/src/systems/datapackCompiler/1.21.2/main.mcb index 09853d82..dc7e8c69 100644 --- a/src/systems/datapackCompiler/1.21.2/main.mcb +++ b/src/systems/datapackCompiler/1.21.2/main.mcb @@ -567,11 +567,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.cameras[node.storage_name] = { - px: transform.pos[0], - py: transform.pos[1], - pz: transform.pos[2], - ry: transform.head_rot[1], - rx: transform.head_rot[0] + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } ;break diff --git a/src/systems/datapackCompiler/1.21.4/main.mcb b/src/systems/datapackCompiler/1.21.4/main.mcb index 05a5b18d..8376101a 100644 --- a/src/systems/datapackCompiler/1.21.4/main.mcb +++ b/src/systems/datapackCompiler/1.21.4/main.mcb @@ -655,11 +655,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.cameras[node.storage_name] = { - px: transform.pos[0], - py: transform.pos[1], - pz: transform.pos[2], - ry: transform.head_rot[1], - rx: transform.head_rot[0] + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } ;break diff --git a/src/systems/datapackCompiler/1.21.5/main.mcb b/src/systems/datapackCompiler/1.21.5/main.mcb index 8e7e5a03..4d78d1e8 100644 --- a/src/systems/datapackCompiler/1.21.5/main.mcb +++ b/src/systems/datapackCompiler/1.21.5/main.mcb @@ -654,11 +654,11 @@ IF (has_animations) { lastActiveFrame[node.uuid] = transform ;if (!lastFrame || matrixToNbtFloatArray(transform.matrix).toString() !== matrixToNbtFloatArray(lastFrame.matrix).toString()) { toMerge.cameras[node.storage_name] = { - px: transform.pos[0], - py: transform.pos[1], - pz: transform.pos[2], - ry: transform.head_rot[1], - rx: transform.head_rot[0] + px: roundTo(transform.pos[0], 4), + py: roundTo(transform.pos[1], 4), + pz: roundTo(transform.pos[2], 4), + ry: roundTo(transform.head_rot[1], 4), + rx: roundTo(transform.head_rot[0], 4) }; } ;break From 9eede9ab806866529d1e58687c07587f6d6c8463 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:29:27 -0400 Subject: [PATCH 24/85] =?UTF-8?q?=F0=9F=90=9B=20Don't=20require=20pack=20f?= =?UTF-8?q?olders=20when=20exporting=20in=20plugin=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #524. - plugin mode exports a JSON file, but the export-time settings check still ran validateResourcePackFolder / validateDataPackFolder, so a blank pack folder (the norm in plugin mode) failed the export with a settings error - skip the pack folder checks when enable_plugin_mode is set --- src/formats/blueprint/settings.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/formats/blueprint/settings.ts b/src/formats/blueprint/settings.ts index c232a63f..a452818f 100644 --- a/src/formats/blueprint/settings.ts +++ b/src/formats/blueprint/settings.ts @@ -392,15 +392,20 @@ export async function validateThisProjectsBlueprintSettings(): Promise< Project.animated_java.render_box[0], Project.animated_java.render_box[1] ), + // Plugin mode exports a JSON file, not a resource/data pack, so the pack + // folders are irrelevant and must not block the export. resource_pack_folder: + !Project.animated_java.enable_plugin_mode && Project.animated_java.resource_pack_export_mode === 'folder' ? validateResourcePackFolder(Project.animated_java.resource_pack) : undefined, data_pack_folder: + !Project.animated_java.enable_plugin_mode && Project.animated_java.data_pack_export_mode === 'folder' ? validateDataPackFolder(Project.animated_java.data_pack) : undefined, data_pack_zip: + !Project.animated_java.enable_plugin_mode && Project.animated_java.data_pack_export_mode === 'zip' ? validateZipPath(Project.animated_java.data_pack) : undefined, From 7dc16cd072e613888b9d3c0adff104e951c7d2e3 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:32:42 -0400 Subject: [PATCH 25/85] =?UTF-8?q?=F0=9F=90=9B=20Sanitize=20and=20de-duplic?= =?UTF-8?q?ate=20internal=20texture=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #337. - internal texture names accepted any character and allowed duplicates, so an invalid or repeated name only failed much later at export - add a project mod that lowercases names, replaces anything outside [a-z0-9._-] with _, and suffixes collisions, on load, on add, and after any edit that touches textures - textures linked from a valid resource pack are referenced by resource location, not copied in, so they are left alone and may share a name with an internal texture --- src/mods/textureNameSanitizer.ts | 59 ++++++++++++++++++++++++ src/tests/texture-name-sanitizer.test.ts | 57 +++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 src/mods/textureNameSanitizer.ts create mode 100644 src/tests/texture-name-sanitizer.test.ts diff --git a/src/mods/textureNameSanitizer.ts b/src/mods/textureNameSanitizer.ts new file mode 100644 index 00000000..104d94a6 --- /dev/null +++ b/src/mods/textureNameSanitizer.ts @@ -0,0 +1,59 @@ +import { registerProjectPatch } from 'blockbench-patch-manager' +import { getFsModule } from '../constants' +import { activeProjectIsBlueprintFormat, BLUEPRINT_FORMAT_ID } from '../formats/blueprint' +import { isResourcePackPath } from '../util/minecraftUtil' + +/** + * Force internal texture names to Minecraft-safe characters and keep them unique. + * + * Textures linked from a valid resource pack are referenced by resource location + * and never written beside the blueprint's own textures, so their names are left + * alone and are allowed to collide with an internal texture's name. + */ +function sanitizeTextureNames() { + if (!activeProjectIsBlueprintFormat()) return + + const { existsSync } = getFsModule() + const isLinked = (texture: Texture) => + !!texture.path && isResourcePackPath(texture.path) && existsSync(texture.path) + + const taken = new Set() + for (const texture of Texture.all) { + if (isLinked(texture)) continue + + const ext = /\.[a-z0-9]+$/i.exec(texture.name)?.[0].toLowerCase() ?? '' + let stem = texture.name.slice(0, texture.name.length - ext.length) + stem = stem.toLowerCase().replace(/[^a-z0-9._-]/g, '_') || 'texture' + + let name = stem + ext + for (let i = 2; taken.has(name); i++) name = `${stem}_${i}${ext}` + taken.add(name) + + if (texture.name !== name) texture.name = name + } +} + +registerProjectPatch({ + id: `animated_java:texture-name-sanitizer`, + + condition: ({ project }) => project.format.id === BLUEPRINT_FORMAT_ID, + + apply() { + requestAnimationFrame(() => sanitizeTextureNames()) + + const onAddTexture = () => sanitizeTextureNames() + const onFinishEdit = ({ aspects }: BlockbenchEventMap['finish_edit']) => { + if (aspects.textures) sanitizeTextureNames() + } + + Blockbench.on('add_texture', onAddTexture) + Blockbench.on('finish_edit', onFinishEdit) + + return { onAddTexture, onFinishEdit } + }, + + revert({ onAddTexture, onFinishEdit }) { + Blockbench.removeListener('add_texture', onAddTexture) + Blockbench.removeListener('finish_edit', onFinishEdit) + }, +}) diff --git a/src/tests/texture-name-sanitizer.test.ts b/src/tests/texture-name-sanitizer.test.ts new file mode 100644 index 00000000..806c1056 --- /dev/null +++ b/src/tests/texture-name-sanitizer.test.ts @@ -0,0 +1,57 @@ +import { describe, expect, it } from '@jest/globals' +import { blockbench } from '@snavesutit/jestbench' +import * as path from 'node:path' + +const BLUEPRINT_FORMAT_ID = 'animated-java:format/blueprint' + +// A real texture inside a valid resource pack layout (assets//textures/...). +const LINKED_TEXTURE = path.resolve( + process.cwd(), + 'test-packs/1.20.5/resources/assets/animated_java/textures/blueprint/armor_stand/wood.png' +) + +/** + * Regression test for #337: internal texture names accepted any character and + * allowed duplicates. Textures linked from a resource pack are referenced by + * resource location, so their names are left alone and may collide with an + * internal texture's name. + */ +describe('texture name sanitizer', () => { + it('lowercases, replaces invalid characters, and de-duplicates internal textures', async () => { + const result = await blockbench.evaluate((formatId: string) => { + const g = globalThis as any + g.newProject(g.Formats[formatId]) + + const a = new Texture({ name: 'My Texture!.png' }, undefined).add(false) + const b = new Texture({ name: 'my texture_.png' }, undefined).add(false) + const c = new Texture({ name: '???.png' }, undefined).add(false) + + return { a: a.name, b: b.name, c: c.name } + }, BLUEPRINT_FORMAT_ID) + + expect(result.a).toBe('my_texture_.png') + expect(result.b).toBe('my_texture__2.png') + expect(result.c).toBe('___.png') + }) + + it('leaves resource-pack-linked textures alone, even when they duplicate an internal name', async () => { + const result = await blockbench.evaluate( + (arg: { formatId: string; linkedPath: string }) => { + const g = globalThis as any + g.newProject(g.Formats[arg.formatId]) + + const linked = new Texture( + { name: 'wood.png', path: arg.linkedPath }, + undefined + ).add(false) + const internal = new Texture({ name: 'wood.png' }, undefined).add(false) + + return { linked: linked.name, internal: internal.name } + }, + { formatId: BLUEPRINT_FORMAT_ID, linkedPath: LINKED_TEXTURE } + ) + + expect(result.linked).toBe('wood.png') + expect(result.internal).toBe('wood.png') + }) +}) From cec56be79b6533bdb1415fc997aebbc10d3448ea Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:34:14 -0400 Subject: [PATCH 26/85] =?UTF-8?q?=F0=9F=90=9B=20Inherit=20step=20interpola?= =?UTF-8?q?tion=20through=20the=20whole=20bone=20chain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #396. - a bone only checked its direct parent for step / pre-post interpolation, so a deeper descendant of a stepped bone still interpolated over 1 tick in-game while its ancestor snapped - walk up to the nearest keyframed ancestor and inherit its interpolation, stopping once an ancestor with normal interpolation is found --- src/systems/animationRenderer.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/systems/animationRenderer.ts b/src/systems/animationRenderer.ts index b67c48fc..6bd6caa4 100644 --- a/src/systems/animationRenderer.ts +++ b/src/systems/animationRenderer.ts @@ -170,16 +170,23 @@ export function getFrame( case 'block_display': case 'bone': { transform.matrix = getNodeMatrix(outlinerNode, node.base_scale) - // Inherit instant interpolation from parent - if (node.parent && node.parent !== 'root') { - const parentKeyframes = keyframeCache.get(node.parent) - const parentKeyframe = parentKeyframes?.get(time) - const prevParentKeyframe = parentKeyframes?.get(time - 0.05) - if (parentKeyframe?.interpolation === 'step') { + // Inherit instant interpolation from the nearest keyframed ancestor. + let ancestorUuid = node.parent + while (ancestorUuid && ancestorUuid !== 'root') { + const ancestorKeyframes = keyframeCache.get(ancestorUuid) + const ancestorKeyframe = ancestorKeyframes?.get(time) + const prevAncestorKeyframe = ancestorKeyframes?.get(time - 0.05) + if (ancestorKeyframe?.interpolation === 'step') { transform.interpolation = 'step' - } else if (prevParentKeyframe?.data_points.length === 2) { + break + } else if (prevAncestorKeyframe?.data_points.length === 2) { transform.interpolation = 'pre-post' + break + } else if (ancestorKeyframe) { + // This ancestor moved with normal interpolation; nothing to inherit. + break } + ancestorUuid = nodeMap[ancestorUuid]?.parent } // Only add the frame if the matrix has changed, this is the first frame, or there is an interpolation change. if ( From 30ff2ca3dc7210a21cf8a91e9e8713fb707d85bc Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:35:57 -0400 Subject: [PATCH 27/85] =?UTF-8?q?=F0=9F=90=9B=20Stop=20the=20variants=20li?= =?UTF-8?q?st=20scrolling=20forever=20after=20a=20drag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #408. - svelte-dnd-action 0.9.47 never cancelled its auto-scroll loop when a drop happened inside the scroll zone, so the variants list kept scrolling until the app was reloaded - bump to 0.9.79, which destroys the scroller on drop --- bun.lock | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bun.lock b/bun.lock index 9d61b625..5ed648c2 100644 --- a/bun.lock +++ b/bun.lock @@ -14,7 +14,7 @@ "marked-gfm-heading-id": "^3.0.0", "request-progress": "^3.0.0", "svelte-ace": "^1.0.21", - "svelte-dnd-action": "^0.9.38", + "svelte-dnd-action": "^0.9.79", }, "devDependencies": { "@jest/globals": "^30.5.1", @@ -1656,7 +1656,7 @@ "svelte-awesome-slider": ["svelte-awesome-slider@1.1.0", "", {}, "sha512-MgY6ZdBON42HVZqNWNjq2HOgyDlC35q0TNbV/YO1l1/bcb5yhM8EE97h1AJ/7F6t6sLzXhQ3qPf5nGyCdDSnCg=="], - "svelte-dnd-action": ["svelte-dnd-action@0.9.47", "", {}, "sha512-Z343HCJfrGHgK98LCrp0ziGUwwWOd8UrpXk7b7A61OQErrB8nUS2tLVRZlaGzhMfE1UCivuqTGFLqxJ14KehfQ=="], + "svelte-dnd-action": ["svelte-dnd-action@0.9.79", "", { "peerDependencies": { "svelte": ">=3.23.0 || ^5.0.0-next.0" } }, "sha512-zCKaG1Q9hVgfJFyZXhY+uIpo9+cjsG03CqwNz8yBlWCRBphC8U2zli9FzIcrL4rhXEs8yV+asS4rV0RHDuQqQQ=="], "svelte-eslint-parser": ["svelte-eslint-parser@1.3.3", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0" } }, "sha512-oTrDR8Z7Wnguut7QH3YKh7JR19xv1seB/bz4dxU5J/86eJtZOU4eh0/jZq4dy6tAlz/KROxnkRQspv5ZEt7t+Q=="], diff --git a/package.json b/package.json index e22e3795..a9aad36e 100644 --- a/package.json +++ b/package.json @@ -136,7 +136,7 @@ "marked-gfm-heading-id": "^3.0.0", "request-progress": "^3.0.0", "svelte-ace": "^1.0.21", - "svelte-dnd-action": "^0.9.38" + "svelte-dnd-action": "^0.9.79" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } From a5835765dd319e857dee45ac5f798ea73a19eb8c Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:50:38 -0400 Subject: [PATCH 28/85] =?UTF-8?q?=F0=9F=90=9B=20Refresh=20the=20texture=20?= =?UTF-8?q?link=20icon=20on=20any=20path=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - the icon only updated on change_texture_path (fired solely by "Reopen"), add, and select, so relinking a texture or editing its path in the properties dialog left a stale icon - also refresh on finished_edit whenever the edit touched textures - drop a leftover per-texture console.log --- src/mods/textureLinkIcon.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/mods/textureLinkIcon.ts b/src/mods/textureLinkIcon.ts index 0e541950..c6afa30f 100644 --- a/src/mods/textureLinkIcon.ts +++ b/src/mods/textureLinkIcon.ts @@ -22,26 +22,31 @@ registerProjectPatch({ }, apply() { - requestAnimationFrame(() => { - for (const texture of Texture.all) { - console.log('texture', texture) - updateTextureIcon(texture) - } - }) + const refreshAll = () => { + for (const texture of Texture.all) updateTextureIcon(texture) + } + requestAnimationFrame(refreshAll) const onTextureChange = ({ texture }: BlockbenchEventMap['change_texture_path']) => updateTextureIcon(texture) + // `change_texture_path` only fires on "Reopen"; catch every other path + // change (relink, properties dialog, undo/redo) via the edit it commits. + const onFinishedEdit = (data: BlockbenchEventMap['finished_edit']) => { + if ('remote' in data || data.aspects.textures) requestAnimationFrame(refreshAll) + } Blockbench.on('change_texture_path', onTextureChange) Blockbench.on('add_texture', onTextureChange) Blockbench.on('select_texture', onTextureChange) + Blockbench.on('finished_edit', onFinishedEdit) - return { onTextureChange } + return { onTextureChange, onFinishedEdit } }, - revert({ onTextureChange }) { + revert({ onTextureChange, onFinishedEdit }) { Blockbench.removeListener('change_texture_path', onTextureChange) Blockbench.removeListener('add_texture', onTextureChange) Blockbench.removeListener('select_texture', onTextureChange) + Blockbench.removeListener('finished_edit', onFinishedEdit) }, }) From 3b686754f803b423bc7c094f32de7f3f0e9592ae Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 21:56:18 -0400 Subject: [PATCH 29/85] =?UTF-8?q?=F0=9F=90=9B=20Show=20a=20distinct=20icon?= =?UTF-8?q?=20for=20internal=20textures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - an internal texture (embedded in the Blueprint, no file on disk) showed Blockbench's "save" prompt, which does not apply to it - show a `box` icon for internal textures, with an explanatory tooltip; give the linked icon one too - override Texture.save() to no-op for internal and linked textures so a click on the (informational) icon does nothing, without needing pointer-events: none, which would also suppress the tooltip - override Texture.fromPath() to refresh the icon and mark the Blueprint dirty when "Save As" turns an internal texture into a file-backed one (neither fires an event) - the file-backed branch fully restores the save / check_circle state so switching away from internal cleans up --- src/lang/en.yml | 8 +++++ src/mods/textureLinkIcon.ts | 63 ++++++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/lang/en.yml b/src/lang/en.yml index 323aba27..bf08846a 100644 --- a/src/lang/en.yml +++ b/src/lang/en.yml @@ -950,6 +950,14 @@ animated_java: title: Displayed Block description: The block to display. Supports block states! + textures: + linked_icon: |- + Linked texture + Loaded from a resource pack and referenced by its resource location. Not exported with the Blueprint. + internal_icon: |- + Internal texture + Stored in the Blueprint file and written to the Blueprint's texture folder on export. + animation: excluded_nodes: Excluded Nodes invert_excluded_nodes: Invert Excluded Nodes diff --git a/src/mods/textureLinkIcon.ts b/src/mods/textureLinkIcon.ts index c6afa30f..d4a92463 100644 --- a/src/mods/textureLinkIcon.ts +++ b/src/mods/textureLinkIcon.ts @@ -1,19 +1,72 @@ -import { registerProjectPatch } from 'blockbench-patch-manager' -import { BLUEPRINT_FORMAT_ID } from '../formats/blueprint' +import { registerProjectPatch, registerPropertyOverridePatch } from 'blockbench-patch-manager' +import { activeProjectIsBlueprintFormat, BLUEPRINT_FORMAT_ID } from '../formats/blueprint' +import { localize } from '../util/lang' import { isResourcePackPath } from '../util/minecraftUtil' +/** A texture that Animated Java does not write to a file of its own on export. */ +function isManagedByBlueprint(texture: Texture): boolean { + return !!texture.internal || (!!texture.path && isResourcePackPath(texture.path)) +} + export function updateTextureIcon(texture: Texture) { - const saveIcon = document.querySelector(`li[texid="${texture.uuid}"] .texture_save_icon`) + const saveIcon = document.querySelector( + `li[texid="${texture.uuid}"] .texture_save_icon` + ) if (!saveIcon) return if (texture.path && isResourcePackPath(texture.path)) { - saveIcon.innerHTML = 'link' - saveIcon.setAttribute('title', 'Linked to resource pack') + // Referenced from a resource pack by resource location. + saveIcon.textContent = 'link' + saveIcon.setAttribute('title', localize('panel.textures.linked_icon')) + saveIcon.classList.remove('clickable') + } else if (texture.internal) { + // Embedded in the Blueprint - there is nothing to save to disk. + saveIcon.textContent = 'box' + saveIcon.setAttribute('title', localize('panel.textures.internal_icon')) + saveIcon.classList.remove('clickable') } else { + // A file on disk - restore Blockbench's own save state. + saveIcon.textContent = texture.saved ? 'check_circle' : 'save' saveIcon.setAttribute('title', '') + saveIcon.classList.toggle('clickable', !texture.saved) } } +// The status icon is informational, but its element still carries Blockbench's +// `@click="texture.save()"` handler. Rather than block pointer events (which also +// kills the tooltip), make `save()` a no-op for textures the Blueprint manages. +registerPropertyOverridePatch({ + id: `animated_java:texture/skip-save-for-managed-textures`, + target: Texture.prototype, + key: 'save', + condition: () => activeProjectIsBlueprintFormat(), + get: original => { + return function (this: Texture, as?: any) { + if (!as && isManagedByBlueprint(this)) return this + return original.call(this, as) + } + }, +}) + +// `fromPath` is where a "Save As" (or a relink) turns an internal texture into a +// file-backed one. No event is fired for it, so refresh the icon here, and mark +// the Blueprint dirty since the texture's stored path just changed. +registerPropertyOverridePatch({ + id: `animated_java:texture/refresh-icon-on-from-path`, + target: Texture.prototype, + key: 'fromPath', + condition: () => activeProjectIsBlueprintFormat(), + get: original => { + return function (this: Texture, path: string, externalDataLoader?: any) { + const wasInternal = !!this.internal + const result = original.call(this, path, externalDataLoader) + requestAnimationFrame(() => updateTextureIcon(this)) + if (wasInternal && !this.internal && Project) Project.saved = false + return result + } + }, +}) + registerProjectPatch({ id: `animated_java:texture-link-icon`, From 047575910e542f51c1f7ca7ae4955165636689c3 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Tue, 1 Sep 2026 22:50:56 -0400 Subject: [PATCH 30/85] =?UTF-8?q?=E2=9C=A8=20Show=20texture=20thumbnails?= =?UTF-8?q?=20in=20the=20variant=20texture-map=20dropdowns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - native normalizeTintValue(index)} - /> - toggleExpanded(tint)} > + {isExpanded ? 'expand_more' : 'chevron_right'} + + {index} +
+ {#if isExpanded} + {getTypeDescription(tint.type)} + {:else} +
{@render fields(tint, false)}
+ {/if} +
- {/each} -
- {/if} + + {#if !supported} +

+ warning + {localize( + 'dialog.item_properties.unsupported_type', + getTypeName(tint.type), + targetVersion + )} +

+ {/if} + + {#if isExpanded} +
+ {@render fields(tint, true)} + {#if hasAlpha(tint.type)} +

+ info + {localize('dialog.item_properties.alpha_note')} +

+ {/if} +
+ {/if} +
+ {/each} + + + diff --git a/src/dialogs/itemModelProperties/itemModelProperties.ts b/src/dialogs/itemModelProperties/itemModelProperties.ts index fe5ec3cc..7743f9b7 100644 --- a/src/dialogs/itemModelProperties/itemModelProperties.ts +++ b/src/dialogs/itemModelProperties/itemModelProperties.ts @@ -5,6 +5,7 @@ import { activeProjectIsBlueprintFormat, projectTargetVersionIsAtLeast, } from '../../formats/blueprint' +import { TINT_SOURCES_MIN_VERSION } from '../../systems/minecraft/tintSources' import { localize } from '../../util/lang' import ItemModelProperties from './itemModelProperties.svelte' @@ -18,6 +19,7 @@ export function openItemPropertiesDialog(group: Group) { component: ItemModelProperties, props: { itemTints, + targetVersion: Project!.animated_java.target_minecraft_version, } as any, disableKeybinds: true, onConfirm() { @@ -43,7 +45,7 @@ registerDeletableHandlerPatch({ name: localize('action.open_item_model_properties.name'), condition: () => activeProjectIsBlueprintFormat() && - projectTargetVersionIsAtLeast('1.21.4') && + projectTargetVersionIsAtLeast(TINT_SOURCES_MIN_VERSION) && Group.first_selected?.children.some(child => child instanceof Cube), click: () => { const group = Group.first_selected diff --git a/src/dialogs/itemModelProperties/tintColorInput.svelte b/src/dialogs/itemModelProperties/tintColorInput.svelte new file mode 100644 index 00000000..71d0e28a --- /dev/null +++ b/src/dialogs/itemModelProperties/tintColorInput.svelte @@ -0,0 +1,91 @@ + + +
+
+
+ + {#if alpha} + ARGB + {/if} +
+
+ + diff --git a/src/dialogs/itemModelProperties/tintField.svelte b/src/dialogs/itemModelProperties/tintField.svelte new file mode 100644 index 00000000..a5f1fd68 --- /dev/null +++ b/src/dialogs/itemModelProperties/tintField.svelte @@ -0,0 +1,63 @@ + + +{#if detailed} +
+ +
+ {@render children()} +

{description}

+
+
+{:else} + {#if inlineLabel} + + {/if} + {@render children()} +{/if} + + diff --git a/src/dialogs/itemModelProperties/tintNumberInput.svelte b/src/dialogs/itemModelProperties/tintNumberInput.svelte new file mode 100644 index 00000000..61728818 --- /dev/null +++ b/src/dialogs/itemModelProperties/tintNumberInput.svelte @@ -0,0 +1,53 @@ + + +
+ + diff --git a/src/lang/en.yml b/src/lang/en.yml index 55a0d5c2..d2f4a5d8 100644 --- a/src/lang/en.yml +++ b/src/lang/en.yml @@ -109,14 +109,54 @@ animated_java: title: Animated Java Changelog item_properties: title: Item Model Properties - tint_constants: Tint Constants - description: |- - [Markdown] - Constant tints apply fixed color values to an item's tint layers, so the model always uses the same tint colors in-game. + description: Tints color this bone's faces by tint index. Expand a tint to see what it does. + target: Target + column: + type: Type + value: Value add_tint: Add Tint - empty_state: No tint constants configured. Add a tint to start. - tint_label: Tint Index %s - remove_tint: Remove + empty_state: No tints configured. The bone uses a white Dye tint by default. + expand_tint: Show details + collapse_tint: Hide details + remove_tint: Remove tint + color: Color + default_color: Default Color + index: Index + temperature: Temperature + downfall: Downfall + alpha_tooltip: Alpha only works on Dye and Firework tints, through a vanilla bug (MC-278626). It may stop working in a future Minecraft version. + alpha_note: Alpha only works on Dye and Firework tints, through a vanilla bug (MC-278626). With cutout textures, faces below ~10% alpha disappear and the rest render opaque. + unsupported_type: '%s is not supported in Minecraft %s. Change the type or remove this tint before exporting.' + tint_types: + constant: Constant + dye: Dye + firework: Firework + potion: Potion + map_color: Map Color + team: Team + grass: Grass + custom_model_data: Custom Model Data + tint_type_descriptions: + constant: Always applies the same color. + dye: Uses the item's dyed color component. + firework: Uses the colors of the item's firework explosion component. + potion: Uses the color of the item's potion contents. + map_color: Uses the item's map color component. + team: Uses the team color of the entity displaying the item. + grass: Samples the grass colormap at a temperature and downfall. + custom_model_data: Uses a color from the item's custom model data component. + field_descriptions: + color: The color applied to this tint index. + temperature: Grass colormap temperature, from 0 to 1. + downfall: Grass colormap downfall, from 0 to 1. + index: Which entry of the custom model data component's colors list to use. + default_color: + dye: Used when the item has no dyed color component. + firework: Used when the item has no firework explosion component. + potion: Used when the item has no potion contents, or they have no effects and no custom color. + map_color: Used when the item has no map color component. + team: Used when there is no entity, or it isn't on a team with a color. + custom_model_data: Used when the item's custom model data has no color at this index. unexpected_error: title: An Unexpected Error Occurred! close_button: Close @@ -1082,6 +1122,10 @@ animated_java: If you want to rotate a cube on multiple axes, put it in a bone and rotate the bone instead. All of the invalid cubes are outlined in red in the editor. Please fix them before exporting. + unsupported_tint_source: + message: |- + The bone "%s" uses a %s tint, which is not supported in Minecraft %s. + Change or remove it in the bone's Item Model Properties before exporting. rig_has_textures_but_no_custom_models: message: |- You have textures applied to your model, but have no custom models (Cubes) to use them! diff --git a/src/systems/exporter.ts b/src/systems/exporter.ts index 12f6a22e..86a69c97 100644 --- a/src/systems/exporter.ts +++ b/src/systems/exporter.ts @@ -22,6 +22,7 @@ import { Variant } from '../variants' import { hashAnimations, renderProjectAnimations } from './animationRenderer' import compileDataPack from './datapackCompiler' import { IntentionalExportError } from './errors' +import { isTintSourceTypeAvailable, TINT_SOURCES_MIN_VERSION } from './minecraft/tintSources' import { exportPluginBlueprint } from './pluginCompiler' import resourcepackCompiler from './resourcepackCompiler' import { hashRig, renderRig } from './rigRenderer' @@ -118,6 +119,24 @@ async function actuallyExportProject({ } } + if (!aj.enable_plugin_mode && projectTargetVersionIsAtLeast(TINT_SOURCES_MIN_VERSION)) { + for (const group of Group.all) { + if (!group.children.some(child => child instanceof Cube)) continue + const tint = group.itemModelProperties?.tints.find( + tint => !isTintSourceTypeAvailable(tint.type, aj.target_minecraft_version) + ) + if (!tint) continue + throw new IntentionalExportError( + translate( + 'misc.failed_to_export.unsupported_tint_source.message', + group.name, + tint.type, + aj.target_minecraft_version + ) + ) + } + } + const { resourcePackFolder, dataPackFolder, diff --git a/src/systems/minecraft/itemDefinitions.d.ts b/src/systems/minecraft/itemDefinitions.d.ts index f6a41aca..2a097446 100644 --- a/src/systems/minecraft/itemDefinitions.d.ts +++ b/src/systems/minecraft/itemDefinitions.d.ts @@ -9,10 +9,13 @@ type DisplayContext = | 'ground' | 'fixed' +/** A packed RGB (or, for dye/firework, ARGB) int, or an RGB float array in 0..1. */ +type TintColor = number | [number, number, number] + type TintSource = | { type: 'minecraft:constant' - value: number | [number, number, number] + value: TintColor } | { type: @@ -20,8 +23,8 @@ type TintSource = | 'minecraft:firework' | 'minecraft:potion' | 'minecraft:map_color' - | 'team' - default: [number, number, number] + | 'minecraft:team' + default: TintColor } | { type: 'minecraft:grass' @@ -31,7 +34,7 @@ type TintSource = | { type: 'minecraft:custom_model_data' index?: number - default: [number, number, number] + default: TintColor } type ItemModel = diff --git a/src/systems/minecraft/tintSources.ts b/src/systems/minecraft/tintSources.ts new file mode 100644 index 00000000..d401bbcd --- /dev/null +++ b/src/systems/minecraft/tintSources.ts @@ -0,0 +1,142 @@ +import type { TintColor, TintSource } from './itemDefinitions' + +export type TintSourceType = TintSource['type'] + +interface ITintSourceTypeInfo { + /** First Minecraft version that supports this type. */ + since: string + /** First Minecraft version that no longer supports this type. */ + until?: string + /** + * Whether an int color keeps its alpha channel. Only true for `dye` and `firework`, whose + * `default` is read as ARGB (MC-278626). Every other type forces its color opaque. + */ + alpha: boolean +} + +export const TINT_SOURCE_TYPES: Record = { + 'minecraft:constant': { since: '1.21.4', alpha: false }, + 'minecraft:dye': { since: '1.21.4', alpha: true }, + 'minecraft:firework': { since: '1.21.4', alpha: true }, + 'minecraft:potion': { since: '1.21.4', alpha: false }, + 'minecraft:map_color': { since: '1.21.4', until: '26.3', alpha: false }, + 'minecraft:team': { since: '1.21.4', alpha: false }, + 'minecraft:grass': { since: '1.21.4', alpha: false }, + 'minecraft:custom_model_data': { since: '1.21.4', alpha: false }, +} + +/** The oldest Minecraft version that supports item model tints at all. */ +export const TINT_SOURCES_MIN_VERSION = '1.21.4' + +export function isTintSourceTypeAvailable(type: TintSourceType, version: string): boolean { + const info = TINT_SOURCE_TYPES[type] + if (!info) return false + if (compareVersions(info.since, version)) return false + return !info.until || compareVersions(info.until, version) +} + +export function getAvailableTintSourceTypes(version: string): TintSourceType[] { + return (Object.keys(TINT_SOURCE_TYPES) as TintSourceType[]).filter(type => + isTintSourceTypeAvailable(type, version) + ) +} + +/** Opaque white, as stored for the given type. */ +function getWhite(type: TintSourceType): number { + return TINT_SOURCE_TYPES[type].alpha ? -1 : 0xffffff +} + +export function createDefaultTintSource(type: TintSourceType): TintSource { + switch (type) { + case 'minecraft:constant': + return { type, value: getWhite(type) } + case 'minecraft:grass': + return { type, temperature: 0.5, downfall: 1 } + case 'minecraft:custom_model_data': + return { type, index: 0, default: getWhite(type) } + default: + return { type, default: getWhite(type) } + } +} + +/** + * Converts a stored tint color into the int form the dialog edits: a signed ARGB int when the type + * keeps alpha, or an RGB int in `0..0xFFFFFF` otherwise. Float arrays become opaque. + */ +export function normalizeTintColor(color: TintColor, alpha: boolean): number { + let int: number + if (Array.isArray(color)) { + const [r, g, b] = color.map(c => + Math.round(Math.min(Math.max(Number.isFinite(c) ? c : 0, 0), 1) * 255) + ) + int = (0xff << 24) | (r << 16) | (g << 8) | b + } else { + int = Number.isFinite(color) ? Math.trunc(color) : 0 + } + return alpha ? int | 0 : int & 0xffffff +} + +/** Returns `#rrggbb`, or `#rrggbbaa` when the type keeps alpha. */ +export function tintColorToHex(color: number, alpha: boolean): string { + const rgb = (color & 0xffffff).toString(16).padStart(6, '0') + if (!alpha) return '#' + rgb + return '#' + rgb + (color >>> 24).toString(16).padStart(2, '0') +} + +/** Parses `#rrggbb` or `#rrggbbaa` into the int form used by {@link normalizeTintColor}. */ +export function tintColorFromHex(hex: string, alpha: boolean): number { + const digits = hex.replace(/^#/, '') + const rgb = parseInt(digits.slice(0, 6), 16) || 0 + if (!alpha) return rgb + const a = digits.length >= 8 ? parseInt(digits.slice(6, 8), 16) : 0xff + return (a << 24) | rgb +} + +function getTintColor(tint: TintSource): TintColor | undefined { + switch (tint.type) { + case 'minecraft:constant': + return tint.value + case 'minecraft:grass': + return undefined + default: + return tint.default + } +} + +function withTintColor(tint: TintSource, color: number): TintSource { + switch (tint.type) { + case 'minecraft:constant': + return { ...tint, value: color } + case 'minecraft:grass': + return { ...tint } + default: + return { ...tint, default: color } + } +} + +/** Returns a copy of `tint` with its color normalized for its type. */ +export function normalizeTintSource(tint: TintSource): TintSource { + const color = getTintColor(tint) + if (color === undefined) return { ...tint } + return withTintColor( + tint, + normalizeTintColor(color, TINT_SOURCE_TYPES[tint.type]?.alpha ?? false) + ) +} + +/** + * Creates a default tint of `type`, carrying over `tint`'s color if both types have one. Alpha is + * kept only when both types support it; otherwise the color becomes opaque. + */ +export function changeTintSourceType(tint: TintSource, type: TintSourceType): TintSource { + const next = createDefaultTintSource(type) + const color = getTintColor(tint) + if (color === undefined || getTintColor(next) === undefined) return next + + const alpha = TINT_SOURCE_TYPES[type].alpha + if (alpha && TINT_SOURCE_TYPES[tint.type]?.alpha) { + return withTintColor(next, normalizeTintColor(color, true)) + } + const rgb = normalizeTintColor(color, false) + return withTintColor(next, alpha ? (0xff << 24) | rgb : rgb) +} diff --git a/src/tests/unit/tintSources.test.ts b/src/tests/unit/tintSources.test.ts new file mode 100644 index 00000000..564f3d7a --- /dev/null +++ b/src/tests/unit/tintSources.test.ts @@ -0,0 +1,147 @@ +import { beforeAll, describe, expect, it } from '@jest/globals' +import { + changeTintSourceType, + createDefaultTintSource, + getAvailableTintSourceTypes, + isTintSourceTypeAvailable, + normalizeTintColor, + normalizeTintSource, + tintColorFromHex, + tintColorToHex, +} from '../../systems/minecraft/tintSources' + +beforeAll(() => { + // Blockbench's `compareVersions(a, b)` returns whether `a > b`, comparing dot-separated numbers. + ;(globalThis as Record).compareVersions = (a: string, b: string) => { + const pa = a.split('.').map(Number) + const pb = b.split('.').map(Number) + for (let i = 0; i < Math.max(pa.length, pb.length); i++) { + const diff = (pa[i] ?? 0) - (pb[i] ?? 0) + if (diff) return diff > 0 + } + return false + } +}) + +describe('getAvailableTintSourceTypes', () => { + it('has no types before 1.21.4', () => { + expect(getAvailableTintSourceTypes('1.21.2')).toEqual([]) + }) + + it('has all 8 types from 1.21.4 through 26.2', () => { + expect(getAvailableTintSourceTypes('1.21.4')).toHaveLength(8) + expect(getAvailableTintSourceTypes('26.2')).toHaveLength(8) + }) + + it('drops map_color in 26.3', () => { + const types = getAvailableTintSourceTypes('26.3') + expect(types).toHaveLength(7) + expect(types).not.toContain('minecraft:map_color') + expect(isTintSourceTypeAvailable('minecraft:map_color', '26.2')).toBe(true) + }) + + it('rejects unknown types', () => { + expect(isTintSourceTypeAvailable('team' as any, '1.21.4')).toBe(false) + }) +}) + +describe('normalizeTintColor', () => { + it('masks RGB colors to 24 bits', () => { + expect(normalizeTintColor(-1, false)).toBe(0xffffff) + expect(normalizeTintColor(0x12345678, false)).toBe(0x345678) + }) + + it('keeps ARGB colors as signed ints', () => { + expect(normalizeTintColor(0xffffffff, true)).toBe(-1) + expect(normalizeTintColor(-1, true)).toBe(-1) + }) + + it('converts float arrays to opaque ints', () => { + expect(normalizeTintColor([1, 0, 0.5], false)).toBe(0xff0080) + expect(normalizeTintColor([1, 1, 1], true)).toBe(-1) + }) + + it('treats invalid values as black', () => { + expect(normalizeTintColor(NaN, false)).toBe(0) + expect(normalizeTintColor(2.9, false)).toBe(2) + }) +}) + +describe('hex conversion', () => { + it('round-trips RGB colors', () => { + expect(tintColorToHex(0x00ff80, false)).toBe('#00ff80') + expect(tintColorFromHex('#00ff80', false)).toBe(0x00ff80) + }) + + it('round-trips ARGB colors with alpha last in the hex string', () => { + const color = (0x80 << 24) | 0x112233 + expect(tintColorToHex(color, true)).toBe('#11223380') + expect(tintColorFromHex('#11223380', true)).toBe(color) + }) + + it('treats a 6-digit hex as opaque when alpha is kept', () => { + expect(tintColorFromHex('#ffffff', true)).toBe(-1) + }) +}) + +describe('tint source helpers', () => { + it('creates opaque white defaults', () => { + expect(createDefaultTintSource('minecraft:constant')).toEqual({ + type: 'minecraft:constant', + value: 0xffffff, + }) + expect(createDefaultTintSource('minecraft:dye')).toEqual({ + type: 'minecraft:dye', + default: -1, + }) + expect(createDefaultTintSource('minecraft:custom_model_data')).toEqual({ + type: 'minecraft:custom_model_data', + index: 0, + default: 0xffffff, + }) + }) + + it('normalizes stored colors without touching other fields', () => { + expect( + normalizeTintSource({ + type: 'minecraft:custom_model_data', + index: 2, + default: [1, 0, 0], + }) + ).toEqual({ type: 'minecraft:custom_model_data', index: 2, default: 0xff0000 }) + expect( + normalizeTintSource({ type: 'minecraft:grass', temperature: 0.2, downfall: 0.3 }) + ).toEqual({ type: 'minecraft:grass', temperature: 0.2, downfall: 0.3 }) + }) + + it('keeps the color when changing type, making it opaque for alpha types', () => { + expect( + changeTintSourceType({ type: 'minecraft:constant', value: 0x123456 }, 'minecraft:dye') + ).toEqual({ type: 'minecraft:dye', default: (0xff << 24) | 0x123456 }) + }) + + it('keeps alpha only between alpha types', () => { + const translucent = (0x40 << 24) | 0x123456 + expect( + changeTintSourceType( + { type: 'minecraft:dye', default: translucent }, + 'minecraft:firework' + ) + ).toEqual({ type: 'minecraft:firework', default: translucent }) + expect( + changeTintSourceType({ type: 'minecraft:dye', default: translucent }, 'minecraft:team') + ).toEqual({ type: 'minecraft:team', default: 0x123456 }) + }) + + it('uses defaults when either type has no color', () => { + expect( + changeTintSourceType({ type: 'minecraft:constant', value: 0x123456 }, 'minecraft:grass') + ).toEqual({ type: 'minecraft:grass', temperature: 0.5, downfall: 1 }) + expect( + changeTintSourceType( + { type: 'minecraft:grass', temperature: 0, downfall: 0 }, + 'minecraft:potion' + ) + ).toEqual({ type: 'minecraft:potion', default: 0xffffff }) + }) +}) From dde57b3cfa9428ad9fcd6e6a9cf7dbe3c439d558 Mon Sep 17 00:00:00 2001 From: SnaveSutit Date: Wed, 7 Oct 2026 02:12:26 -0400 Subject: [PATCH 76/85] =?UTF-8?q?=F0=9F=90=9B=20Fix=20Enter=20not=20starti?= =?UTF-8?q?ng=20a=20new=20line=20in=20code=20editors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Chromium 150 (Blockbench 5.2) inserts
on Enter, which CodeJar drops from its value - Insert line breaks as `\n` text instead, in every CodeJar editor - Fixes #535 --- .../textDisplayElement.svelte | 7 ++++- src/svelteComponents/customCodeJar.svelte | 3 ++- src/tests/ui-behaviour.test.ts | 26 +++++++++++++++++++ src/util/codeJar.ts | 21 +++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/util/codeJar.ts diff --git a/src/panels/textDisplayElement/textDisplayElement.svelte b/src/panels/textDisplayElement/textDisplayElement.svelte index 3364f38c..74b87aee 100644 --- a/src/panels/textDisplayElement/textDisplayElement.svelte +++ b/src/panels/textDisplayElement/textDisplayElement.svelte @@ -1,6 +1,7 @@ -
+
{ expect(await blockbench.dialog().isOpen()).toBe(false) }) }) + + describe('code editors', () => { + it('Enter starts a new line in the On-Summon Function editor', async () => { + await blockbench.newProject(BLUEPRINT_FORMAT_ID) + await blockbench.action('animated_java:action/blueprint-settings').trigger() + await blockbench.evaluate(() => { + ;(globalThis as any).Dialog.open.sidebar.setPage('eventFunctions') + }) + await blockbench.waitFor(() => document.querySelector('.dialog pre[contenteditable]')) + await blockbench.page.click('.dialog pre[contenteditable]') + + const { keyboard } = blockbench.page + await keyboard.type('tag @s add a') + await keyboard.press('Enter') + await keyboard.type('tag @s add b') + await keyboard.press('Enter') + await keyboard.type('say hi') + await blockbench.dialog().cancel() + + expect( + await blockbench.evaluate( + () => (globalThis as any).Project.animated_java.on_summon_function + ) + ).toBe('tag @s add a\ntag @s add b\nsay hi') + }) + }) }) diff --git a/src/util/codeJar.ts b/src/util/codeJar.ts new file mode 100644 index 00000000..2bd16f03 --- /dev/null +++ b/src/util/codeJar.ts @@ -0,0 +1,21 @@ +/** + * `beforeinput` handler that inserts native line breaks into a CodeJar editor as `\n` text. + * + * Chromium 150+ (Blockbench 5.2+) inserts `
` on Enter, even in `plaintext-only` `
`
+ * editors, and CodeJar reads its value from `textContent`, which drops `
`. + */ +export function insertLineBreakAsText(event: InputEvent) { + if (event.inputType !== 'insertLineBreak' && event.inputType !== 'insertParagraph') return + const selection = getSelection() + if (!(event.target instanceof HTMLElement) || !selection?.rangeCount) return + + const afterCursor = document.createRange() + afterCursor.selectNodeContents(event.target) + const { endContainer, endOffset } = selection.getRangeAt(0) + afterCursor.setStart(endContainer, endOffset) + + event.preventDefault() + // A trailing `\n` doesn't render as a new line in a
, so pad it with a second one.
+	// The caret lands between them, since the browser can't place it after a trailing `\n`.
+	document.execCommand('insertHTML', false, afterCursor.toString() === '' ? '\n\n' : '\n')
+}

From 119705cd72ce44e527dca4fb51d14c807b5d8120 Mon Sep 17 00:00:00 2001
From: SnaveSutit 
Date: Wed, 7 Oct 2026 02:51:34 -0400
Subject: [PATCH 77/85] =?UTF-8?q?=F0=9F=91=B7=20Add=20release=20draft=20an?=
 =?UTF-8?q?d=20Discord=20announcement=20workflows?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Tag pushes build, test, and create a draft release with the plugin files
- Publishing a release announces it on Discord with version-based role pings
- Drafts post a no-ping preview to a test channel; previews can be re-run by hand
- Long notes are trimmed to fit Discord's 4000-character limit
- Release notes rendering moved out of the packager so the announcer can share it
- Templates now link the right release, escape URLs once, and drop the stale PR note
---
 .github/workflows/release-announce.yml        |  44 ++++++
 .github/workflows/release-draft.yml           |  83 +++++++++++
 .scripts/plugins/packagerPlugin.ts            |  64 ++++-----
 .../discord_release_notes_template            |   8 +-
 .../github_release_notes_template             |   6 +-
 .scripts/release/announce.ts                  | 110 +++++++++++++++
 .scripts/release/releaseNotes.ts              | 133 ++++++++++++++++++
 src/tests/unit/releaseNotes.test.ts           | 114 +++++++++++++++
 8 files changed, 513 insertions(+), 49 deletions(-)
 create mode 100644 .github/workflows/release-announce.yml
 create mode 100644 .github/workflows/release-draft.yml
 create mode 100644 .scripts/release/announce.ts
 create mode 100644 .scripts/release/releaseNotes.ts
 create mode 100644 src/tests/unit/releaseNotes.test.ts

diff --git a/.github/workflows/release-announce.yml b/.github/workflows/release-announce.yml
new file mode 100644
index 00000000..0186030b
--- /dev/null
+++ b/.github/workflows/release-announce.yml
@@ -0,0 +1,44 @@
+name: Announce Release
+
+on:
+  release:
+    types: [published]
+
+  # Re-run a preview (or the live post) by hand, e.g. after fixing the notes.
+  workflow_dispatch:
+    inputs:
+      tag:
+        description: Release tag (e.g. v1.11.0)
+        required: true
+      target:
+        description: Where to post
+        type: choice
+        options: [test, live]
+        default: test
+
+jobs:
+  announce:
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: read
+
+    env:
+      TAG: ${{ inputs.tag || github.event.release.tag_name }}
+      LIVE: ${{ github.event_name == 'release' || inputs.target == 'live' }}
+
+    steps:
+      - uses: actions/checkout@v5
+        with:
+          ref: ${{ env.TAG }}
+      - uses: oven-sh/setup-bun@v2
+
+      - name: Post announcement
+        run: bun .scripts/release/announce.ts "${TAG#v}" $([ "$LIVE" = true ] && echo --live)
+        env:
+          DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
+          DISCORD_CHANNEL_ID: ${{ env.LIVE == 'true' && vars.DISCORD_CHANNEL_ID || vars.DISCORD_TEST_CHANNEL_ID }}
+          DISCORD_ROLE_PRERELEASE: ${{ vars.DISCORD_ROLE_PRERELEASE }}
+          DISCORD_ROLE_MINOR: ${{ vars.DISCORD_ROLE_MINOR }}
+          DISCORD_ROLE_PATCH: ${{ vars.DISCORD_ROLE_PATCH }}
+          DISCORD_ROLE_BREAKING: ${{ vars.DISCORD_ROLE_BREAKING }}
diff --git a/.github/workflows/release-draft.yml b/.github/workflows/release-draft.yml
new file mode 100644
index 00000000..f91bd90f
--- /dev/null
+++ b/.github/workflows/release-draft.yml
@@ -0,0 +1,83 @@
+name: Draft Release
+
+on:
+  push:
+    tags: ['v*']
+
+jobs:
+  draft:
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: write
+
+    env:
+      GH_TOKEN: ${{ github.token }}
+      TAG: ${{ github.ref_name }}
+
+    steps:
+      - uses: actions/checkout@v5
+      - uses: oven-sh/setup-bun@v2
+      - uses: actions/setup-node@v4
+        with:
+          node-version: 24
+
+      - name: Check tag matches package.json
+        run: |
+          expected="v$(jq -r .version package.json)"
+          if [ "$TAG" != "$expected" ]; then
+            echo "::error::Tag $TAG doesn't match package.json version ($expected)"
+            exit 1
+          fi
+          if gh release view "$TAG" > /dev/null 2>&1; then
+            echo "::error::A release for $TAG already exists"
+            exit 1
+          fi
+
+      - name: Install dependencies
+        run: bun install --frozen-lockfile
+
+      - name: Run unit tests
+        run: bun run test:unit
+
+      - name: Build
+        run: bun run prod
+
+      # See build.yml
+      - name: Cache Blockbench test environment
+        uses: actions/cache@v4
+        with:
+          path: ~/.envbench
+          key: envbench-${{ runner.os }}-animated-java-tests
+
+      - name: Install xvfb
+        run: sudo apt-get update && sudo apt-get install -y xvfb
+
+      - name: Run tests
+        run: bun run test:only
+
+      - name: Create draft release
+        run: |
+          # The packager skips the notes when changelog.json has no entry for this version.
+          if [ ! -f dist/github_release_notes_template ]; then
+            echo "::error::No release notes were generated. Is there a changelog.json entry for $TAG?"
+            exit 1
+          fi
+          prerelease=$([[ "$TAG" == *-* ]] && echo --prerelease || true)
+          gh release create "$TAG" --draft --verify-tag $prerelease \
+            --title "$TAG" \
+            --notes-file dist/github_release_notes_template \
+            dist/pluginPackage/animated_java.js \
+            dist/pluginPackage/about.md \
+            dist/pluginPackage/changelog.json \
+            dist/pluginPackage/icon.svg
+
+      - name: Preview announcement in test channel
+        run: bun .scripts/release/announce.ts "${TAG#v}"
+        env:
+          DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
+          DISCORD_CHANNEL_ID: ${{ vars.DISCORD_TEST_CHANNEL_ID }}
+          DISCORD_ROLE_PRERELEASE: ${{ vars.DISCORD_ROLE_PRERELEASE }}
+          DISCORD_ROLE_MINOR: ${{ vars.DISCORD_ROLE_MINOR }}
+          DISCORD_ROLE_PATCH: ${{ vars.DISCORD_ROLE_PATCH }}
+          DISCORD_ROLE_BREAKING: ${{ vars.DISCORD_ROLE_BREAKING }}
diff --git a/.scripts/plugins/packagerPlugin.ts b/.scripts/plugins/packagerPlugin.ts
index 689d562b..e130348e 100644
--- a/.scripts/plugins/packagerPlugin.ts
+++ b/.scripts/plugins/packagerPlugin.ts
@@ -5,6 +5,12 @@ import { basename, join } from 'node:path'
 import { sveltePreprocess } from 'svelte-preprocess'
 // @ts-expect-error - Types are broken in nodenext for this package, but it works fine.
 import { typescript } from 'svelte-preprocess-esbuild'
+import {
+	type Changelog,
+	type ChangelogEntry,
+	getChangelogEntry,
+	renderReleaseNotes,
+} from '../release/releaseNotes'
 import type { CompileOptions, CompileResult } from 'svelte/compiler'
 import { compile, preprocess } from 'svelte/compiler'
 import { render } from 'svelte/server'
@@ -19,12 +25,6 @@ const DIST_PATH = './dist/'
 const DIST_PACKAGE_PATH = './dist/pluginPackage/'
 const CHANGELOG_PATH = './src/pluginPackage/changelog.json'
 const RELEASE_NOTES_TEMPLATES = './.scripts/plugins/releaseNoteTemplates/'
-const URL_REGEX =
-	/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9]{1,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/gm
-
-function replaceTemplateVars(str: string, items: Record) {
-	return str.replace(/\{(.+?)\}/g, str => items[str.replace(/[\{\}]/g, '')] ?? str)
-}
 
 /**
  * Convert a warning or error emitted from the svelte compiler for esbuild.
@@ -143,41 +143,25 @@ function plugin(): Plugin {
 
 				if (process.env.NODE_ENV === 'production') {
 					console.log('📝 Creating changelogs...')
-					const rawChangelog = fs.readFileSync(CHANGELOG_PATH, 'utf-8')
-					const changelog = JSON.parse(rawChangelog)
+					const changelog = JSON.parse(
+						fs.readFileSync(CHANGELOG_PATH, 'utf-8')
+					) as Changelog
+					let entry: ChangelogEntry
+					try {
+						entry = getChangelogEntry(changelog, PACKAGE.version)
+					} catch (e: any) {
+						console.warn(`⚠️  ${e.message} in ${CHANGELOG_PATH}`)
+						return
+					}
 					for (const file of fs.readdirSync(RELEASE_NOTES_TEMPLATES)) {
-						let content = fs.readFileSync(join(RELEASE_NOTES_TEMPLATES, file), 'utf-8')
-
-						const versionChangelog = changelog[PACKAGE.version]
-						if (!versionChangelog) {
-							console.warn(
-								`⚠️  No changelog found for version ${PACKAGE.version} in ${CHANGELOG_PATH}`
-							)
-							return
-						}
-
-						let categories = ''
-						for (const category of versionChangelog.categories) {
-							categories +=
-								`\n\n### ${category.title}\n\n` +
-								category.list
-									.map((v: string) => '- ' + v)
-									.join('\n')
-									.replaceAll('[BREAKING]', '⚠️ **BREAKING** —')
-						}
-
-						content = replaceTemplateVars(content, {
-							version: PACKAGE.version,
-							categories: categories.trim(),
-						})
-
-						if (content.includes('[[ESCAPE_URLS]]')) {
-							content = content
-								.replace('[[ESCAPE_URLS]]', '')
-								.replaceAll(URL_REGEX, (match: string) => '<' + match + '>')
-						}
-
-						fs.writeFileSync(join(DIST_PATH, file), content)
+						const template = fs.readFileSync(
+							join(RELEASE_NOTES_TEMPLATES, file),
+							'utf-8'
+						)
+						fs.writeFileSync(
+							join(DIST_PATH, file),
+							renderReleaseNotes(template, PACKAGE.version, entry)
+						)
 					}
 
 					// if (fs.existsSync(PLUGIN_REPO_PATH)) {
diff --git a/.scripts/plugins/releaseNoteTemplates/discord_release_notes_template b/.scripts/plugins/releaseNoteTemplates/discord_release_notes_template
index 353e14bf..62a6c208 100644
--- a/.scripts/plugins/releaseNoteTemplates/discord_release_notes_template
+++ b/.scripts/plugins/releaseNoteTemplates/discord_release_notes_template
@@ -1,13 +1,11 @@
 [[ESCAPE_URLS]]
 
-# :AnimatedJava: Animated Java Release v{version}
+# <:AnimatedJava:1349340042379661392> Animated Java Release v{version}
 
 {categories}
 
-## How to Install
+## [How to Install](https://animated-java.dev/docs/getting-started/installing)
 
-Download `animated_java.js` from the [release page](), then [Follow this tutorial]()
-
-Once [this PR]() has been merged, you can install the latest release of AJ directly from the Blockbench plugin list.
+It can take a while for new releases to appear in the Blockbench plugin list, so to get this one right away, either download `animated_java.js` from the [release page]({release_url}) or [install it via URL](https://animated-java.dev/docs/getting-started/installing#advanced-installation-url).
 
 -# {pings}
diff --git a/.scripts/plugins/releaseNoteTemplates/github_release_notes_template b/.scripts/plugins/releaseNoteTemplates/github_release_notes_template
index d95ebd97..84619937 100644
--- a/.scripts/plugins/releaseNoteTemplates/github_release_notes_template
+++ b/.scripts/plugins/releaseNoteTemplates/github_release_notes_template
@@ -2,8 +2,6 @@
 
 {categories}
 
-## How to Install
+## [How to Install](https://animated-java.dev/docs/getting-started/installing)
 
-Download `animated_java.js` from the [release page](https://github.com/Animated-Java/animated-java/releases/tag/v1.10.2), then [Follow this tutorial](https://animated-java.dev/docs/getting-started/installing#advanced-installation-url)
-
-Once [this PR](https://github.com/JannisX11/blockbench-plugins/pull/930) has been merged, you can install the latest release of AJ directly from the Blockbench plugin list.
+It can take a while for new releases to appear in the Blockbench plugin list, so to get this one right away, either download `animated_java.js` below or [install it via URL](https://animated-java.dev/docs/getting-started/installing#advanced-installation-url).
diff --git a/.scripts/release/announce.ts b/.scripts/release/announce.ts
new file mode 100644
index 00000000..7cec0b94
--- /dev/null
+++ b/.scripts/release/announce.ts
@@ -0,0 +1,110 @@
+/**
+ * Posts a release announcement to a Discord channel.
+ *
+ * Usage: `bun .scripts/release/announce.ts  [--live]`
+ *
+ * Without `--live`, role mentions are shown but don't ping anyone, and the message isn't
+ * crossposted. Used for previews in a private test channel.
+ *
+ * Env: `DISCORD_BOT_TOKEN`, `DISCORD_CHANNEL_ID`, and `DISCORD_ROLE_PRERELEASE`,
+ * `DISCORD_ROLE_MINOR`, `DISCORD_ROLE_PATCH`, `DISCORD_ROLE_BREAKING`.
+ */
+import { readFileSync } from 'node:fs'
+import {
+	type Changelog,
+	type ReleasePing,
+	getChangelogEntry,
+	getReleasePings,
+	getReleaseUrl,
+	renderReleaseNotes,
+} from './releaseNotes'
+
+const DISCORD_API = 'https://discord.com/api/v10'
+const USER_AGENT = 'DiscordBot (https://github.com/Animated-Java/animated-java, 1.0)'
+const TEMPLATE_PATH = './.scripts/plugins/releaseNoteTemplates/discord_release_notes_template'
+const CHANGELOG_PATH = './src/pluginPackage/changelog.json'
+const IS_COMPONENTS_V2 = 1 << 15
+// Shared by every text display in a Components V2 message.
+const MAX_TEXT_LENGTH = 4000
+const ACCENT_COLOR = 0x00aced
+const BREAKING_LABEL =
+	'<:BreakingEmoji0:1432852678903463976><:BreakingEmoji1:1432852680404893818><:BreakingEmoji2:1432852682091270144><:BreakingEmoji3:1432852683534110790>'
+const ROLE_ENV_VARS: Record = {
+	prerelease: 'DISCORD_ROLE_PRERELEASE',
+	minor: 'DISCORD_ROLE_MINOR',
+	patch: 'DISCORD_ROLE_PATCH',
+	breaking: 'DISCORD_ROLE_BREAKING',
+}
+
+function requireEnv(name: string) {
+	const value = process.env[name]
+	if (!value) throw new Error(`Missing environment variable ${name}`)
+	return value
+}
+
+async function discordPost(path: string, body?: unknown) {
+	const response = await fetch(DISCORD_API + path, {
+		method: 'POST',
+		headers: {
+			Authorization: `Bot ${requireEnv('DISCORD_BOT_TOKEN')}`,
+			'Content-Type': 'application/json',
+			'User-Agent': USER_AGENT,
+		},
+		body: body === undefined ? undefined : JSON.stringify(body),
+	})
+	if (!response.ok) {
+		throw new Error(`POST ${path} failed: ${response.status} ${await response.text()}`)
+	}
+	return (await response.json()) as { id: string }
+}
+
+async function main() {
+	const [version, flag] = process.argv.slice(2)
+	if (!version || (flag !== undefined && flag !== '--live')) {
+		throw new Error('Usage: bun .scripts/release/announce.ts  [--live]')
+	}
+	const live = flag === '--live'
+	const channelId = requireEnv('DISCORD_CHANNEL_ID')
+
+	const changelog = JSON.parse(readFileSync(CHANGELOG_PATH, 'utf-8')) as Changelog
+	const entry = getChangelogEntry(changelog, version)
+	const roleIds = getReleasePings(version, entry).map(ping => requireEnv(ROLE_ENV_VARS[ping]))
+	const notes = renderReleaseNotes(readFileSync(TEMPLATE_PATH, 'utf-8'), version, entry, {
+		vars: { pings: roleIds.map(id => `<@&${id}>`).join(' ') },
+		maxLength: MAX_TEXT_LENGTH,
+		breakingLabel: BREAKING_LABEL,
+	})
+
+	const message = await discordPost(`/channels/${channelId}/messages`, {
+		flags: IS_COMPONENTS_V2,
+		allowed_mentions: { parse: [], roles: live ? roleIds : [] },
+		components: [
+			{
+				type: 17, // Container
+				accent_color: ACCENT_COLOR,
+				components: [
+					{ type: 10, content: notes }, // Text Display
+					{
+						type: 1, // Action Row
+						components: [
+							{
+								type: 2,
+								style: 5,
+								label: 'View on GitHub',
+								url: getReleaseUrl(version),
+							},
+						],
+					},
+				],
+			},
+		],
+	})
+	console.log(`Posted v${version} announcement (message ${message.id}) to channel ${channelId}`)
+
+	if (live) {
+		await discordPost(`/channels/${channelId}/messages/${message.id}/crosspost`)
+		console.log('Crossposted to following servers')
+	}
+}
+
+await main()
diff --git a/.scripts/release/releaseNotes.ts b/.scripts/release/releaseNotes.ts
new file mode 100644
index 00000000..e6e72c0d
--- /dev/null
+++ b/.scripts/release/releaseNotes.ts
@@ -0,0 +1,133 @@
+export interface ChangelogCategory {
+	title: string
+	list: string[]
+}
+
+export interface ChangelogEntry {
+	title: string
+	author: string
+	date: string
+	categories: ChangelogCategory[]
+}
+
+export type Changelog = Record
+
+export type ReleasePing = 'prerelease' | 'minor' | 'patch' | 'breaking'
+
+export interface RenderOptions {
+	/** Extra `{name}` template variables, such as `pings`. */
+	vars?: Record
+	/** Drop changelog items from the end until the notes fit, noting that some were cut. */
+	maxLength?: number
+	/** Replaces `[BREAKING]` in changelog items. */
+	breakingLabel?: string
+}
+
+const REPO_URL = 'https://github.com/Animated-Java/animated-java'
+const BREAKING_TAG = '[BREAKING]'
+const DEFAULT_BREAKING_LABEL = '⚠️ **BREAKING** —'
+const ESCAPE_URLS_MARKER = '[[ESCAPE_URLS]]'
+const VERSION_REGEX = /^(\d+)\.(\d+)\.(\d+)(-.+)?$/
+// Skips URLs already wrapped in <>, so they aren't escaped twice.
+const URL_REGEX =
+	/(? category.list.some(item => item.includes(BREAKING_TAG))))
+		pings.push('breaking')
+	return pings
+}
+
+function replaceTemplateVars(str: string, items: Record) {
+	return str.replace(/\{(.+?)\}/g, str => items[str.replace(/[\{\}]/g, '')] ?? str)
+}
+
+function formatCategories(categories: ChangelogCategory[], breakingLabel: string) {
+	return categories
+		.filter(category => category.list.length > 0)
+		.map(
+			category =>
+				`### ${category.title}\n\n` +
+				category.list
+					.map(item => '- ' + item.replaceAll(BREAKING_TAG, breakingLabel))
+					.join('\n')
+		)
+		.join('\n\n')
+}
+
+/** Returns a copy of `categories` without its last item, or `undefined` if there are none left. */
+function dropLastItem(categories: ChangelogCategory[]) {
+	let index = categories.length - 1
+	while (index >= 0 && categories[index].list.length === 0) index--
+	if (index === -1) return
+	return categories.map((category, i) =>
+		i === index ? { ...category, list: category.list.slice(0, -1) } : category
+	)
+}
+
+export function renderReleaseNotes(
+	template: string,
+	version: string,
+	entry: ChangelogEntry,
+	options: RenderOptions = {}
+) {
+	const render = (categories: ChangelogCategory[], trimmed: boolean) => {
+		let formatted = formatCategories(
+			categories,
+			options.breakingLabel ?? DEFAULT_BREAKING_LABEL
+		)
+		if (trimmed) {
+			formatted += `\n\n-# …plus more in the [full release notes](${getReleaseUrl(version)})`
+		}
+		let content = replaceTemplateVars(template, {
+			...options.vars,
+			version,
+			release_url: getReleaseUrl(version),
+			categories: formatted,
+		})
+		if (content.includes(ESCAPE_URLS_MARKER)) {
+			content = content
+				.replace(ESCAPE_URLS_MARKER, '')
+				.replaceAll(URL_REGEX, match => `<${match}>`)
+		}
+		return content.trim() + '\n'
+	}
+
+	let categories: ChangelogCategory[] | undefined = entry.categories
+	let notes = render(categories, false)
+	if (options.maxLength === undefined) return notes
+
+	while (notes.length > options.maxLength) {
+		categories = dropLastItem(categories)
+		if (!categories) {
+			throw new Error(
+				`Release notes for ${version} don't fit in ${options.maxLength} characters, even with every changelog item removed`
+			)
+		}
+		notes = render(categories, true)
+	}
+	return notes
+}
diff --git a/src/tests/unit/releaseNotes.test.ts b/src/tests/unit/releaseNotes.test.ts
new file mode 100644
index 00000000..0e9ee16d
--- /dev/null
+++ b/src/tests/unit/releaseNotes.test.ts
@@ -0,0 +1,114 @@
+import { describe, expect, it } from '@jest/globals'
+import {
+	type ChangelogEntry,
+	getChangelogEntry,
+	getReleasePings,
+	getReleaseUrl,
+	renderReleaseNotes,
+} from '../../../.scripts/release/releaseNotes'
+
+function entry(...lists: string[][]): ChangelogEntry {
+	return {
+		title: 'test',
+		author: 'test',
+		date: '2026-01-01',
+		categories: lists.map((list, i) => ({ title: `Category ${i}`, list })),
+	}
+}
+
+describe('getChangelogEntry', () => {
+	it('throws for a missing version', () => {
+		expect(() => getChangelogEntry({}, '1.0.0')).toThrow(
+			'No changelog entry found for version 1.0.0'
+		)
+	})
+})
+
+describe('getReleasePings', () => {
+	it('pings minor for x.y.0', () => {
+		expect(getReleasePings('1.11.0', entry(['a']))).toEqual(['minor'])
+		expect(getReleasePings('2.0.0', entry(['a']))).toEqual(['minor'])
+	})
+
+	it('pings patch for x.y.z', () => {
+		expect(getReleasePings('1.11.3', entry(['a']))).toEqual(['patch'])
+	})
+
+	it('pings only prerelease for betas', () => {
+		expect(getReleasePings('1.11.0-beta.1', entry(['a']))).toEqual(['prerelease'])
+	})
+
+	it('adds breaking when any item is tagged', () => {
+		expect(getReleasePings('1.11.1', entry(['a'], ['[BREAKING] b']))).toEqual([
+			'patch',
+			'breaking',
+		])
+		expect(getReleasePings('1.11.0-beta.2', entry(['[BREAKING] a']))).toEqual([
+			'prerelease',
+			'breaking',
+		])
+	})
+
+	it('throws for an invalid version', () => {
+		expect(() => getReleasePings('v1.0', entry())).toThrow('Invalid version')
+	})
+})
+
+describe('renderReleaseNotes', () => {
+	it('fills template variables and formats categories', () => {
+		const notes = renderReleaseNotes(
+			'# v{version}\n\n{categories}\n\n[release]({release_url}) {pings} {unknown}',
+			'1.2.3',
+			entry(['[BREAKING] a', 'b'], [], ['c']),
+			{ vars: { pings: '<@&1>' } }
+		)
+		expect(notes).toBe(
+			'# v1.2.3\n\n' +
+				'### Category 0\n\n- ⚠️ **BREAKING** — a\n- b\n\n' +
+				'### Category 2\n\n- c\n\n' +
+				`[release](${getReleaseUrl('1.2.3')}) <@&1> {unknown}\n`
+		)
+	})
+
+	it('uses a custom breaking label', () => {
+		const notes = renderReleaseNotes('{categories}', '1.0.0', entry(['[BREAKING] a']), {
+			breakingLabel: '<:B:1>',
+		})
+		expect(notes).toBe('### Category 0\n\n- <:B:1> a\n')
+	})
+
+	it('escapes URLs once when the template asks for it', () => {
+		const notes = renderReleaseNotes(
+			'[[ESCAPE_URLS]]\n{categories}',
+			'1.0.0',
+			entry(['[x](https://a.com/b)', '[y]()'])
+		)
+		expect(notes).toBe('### Category 0\n\n- [x]()\n- [y]()\n')
+	})
+
+	it('leaves notes untouched when they fit', () => {
+		const template = '{categories}'
+		const full = renderReleaseNotes(template, '1.0.0', entry(['a', 'b']))
+		expect(
+			renderReleaseNotes(template, '1.0.0', entry(['a', 'b']), { maxLength: full.length })
+		).toBe(full)
+	})
+
+	it('drops items from the end until the notes fit', () => {
+		const changelog = entry(['a'.repeat(50), 'b'.repeat(50)], ['c'.repeat(50)])
+		const notes = renderReleaseNotes('{categories}', '1.0.0', changelog, { maxLength: 180 })
+		expect(notes.length).toBeLessThanOrEqual(180)
+		expect(notes).toContain('a'.repeat(50))
+		expect(notes).not.toContain('b'.repeat(50))
+		expect(notes).not.toContain('Category 1')
+		expect(notes).toContain(`[full release notes](${getReleaseUrl('1.0.0')})`)
+	})
+
+	it('throws when even an empty changelog does not fit', () => {
+		expect(() =>
+			renderReleaseNotes('x'.repeat(100) + '{categories}', '1.0.0', entry(['a']), {
+				maxLength: 50,
+			})
+		).toThrow("don't fit in 50 characters")
+	})
+})

From 279dbe5c38646532cb2d4b58b922c2f237303a28 Mon Sep 17 00:00:00 2001
From: SnaveSutit 
Date: Wed, 7 Oct 2026 04:49:36 -0400
Subject: [PATCH 78/85] =?UTF-8?q?=E2=9C=A8=20Add=20Texture=20Slot=20keyfra?=
 =?UTF-8?q?mes=20and=20Variant=20stacks?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Variant keyframes apply several Variants in order; old keyframes migrate in 1.11.0
- Texture Slot keyframes switch slots during an animation, on 1.21.4+ only
- Animate mode previews each bone from the animation's start state, leaving Edit mode alone
- Each frame's effects export to one function, shared by baked, storage, and loop paths
- Plugin JSON exports Variants and `variant` keyframes instead of flattening them
- Keyframe panel edits are undoable and mark the project unsaved
- Fix Variant keyframes never applying with storage animations
- Fix last-frame Variant and function keyframes skipped in loops without a moving Locator
---
 schemas/plugin-blueprint.schema.json          |  72 +++++-
 src/animationPreview.ts                       | 161 +++++++++++++
 .../animationProperties.svelte                |  26 ++
 .../animationProperties.ts                    |   7 +
 .../variantConfig/variantConfig.svelte        | 153 ++----------
 src/formats/blueprint/dfu.ts                  |  11 +-
 src/formats/blueprint/versions/1.11.0.ts      |  28 +++
 src/index.ts                                  |   2 +
 src/lang/en.yml                               |  39 ++-
 src/mods/animation.ts                         |  34 ++-
 src/mods/animationPreviewMod.ts               |  22 ++
 src/mods/cube.ts                              |   7 +-
 src/mods/customKeyframes.ts                   |  98 ++++----
 src/mods/variantPreviewCubeFaceMod.ts         |  19 +-
 src/outliner/vanillaItemDisplay.ts            |   7 +-
 .../customKeyframe/commandsKeyframe.svelte    |  18 +-
 src/panels/customKeyframe/customKeyframe.ts   |   9 +
 src/panels/customKeyframe/keyframeEdit.ts     |  54 +++++
 .../customKeyframe/textureSlotKeyframe.svelte | 227 ++++++++++++++++++
 .../customKeyframe/variantKeyframe.svelte     | 184 ++++++++++----
 .../slotTexturesEditor.svelte                 | 145 +++++++++++
 .../variantStackEditor.svelte                 | 146 +++++++++++
 src/systems/animationRenderer.ts              |  36 ++-
 src/systems/datapackCompiler/1.20.4/main.mcb  |  65 +++--
 src/systems/datapackCompiler/1.20.5/main.mcb  |  65 +++--
 src/systems/datapackCompiler/1.21.0/main.mcb  |  65 +++--
 src/systems/datapackCompiler/1.21.2/main.mcb  |  65 +++--
 src/systems/datapackCompiler/1.21.4/main.mcb  |  65 +++--
 src/systems/datapackCompiler/1.21.5/main.mcb  |  65 +++--
 src/systems/datapackCompiler/index.ts         |  78 ++++--
 src/systems/exporter.ts                       |  18 ++
 src/systems/jsonCompiler.ts                   |  13 +-
 src/systems/pluginCompiler.ts                 | 179 ++++++++++----
 src/tests/animation-preview.test.ts           | 169 +++++++++++++
 src/tests/custom-keyframes.test.ts            |  89 +++++--
 src/tests/effect-keyframe-export.test.ts      | 167 +++++++++++++
 src/tests/helpers/export.ts                   |  13 +
 src/tests/keyframe-panels.test.ts             | 134 +++++++++++
 src/tests/plugin-mode-export.test.ts          |  40 ++-
 .../unit/variantKeyframeMigration.test.ts     |  59 +++++
 40 files changed, 2379 insertions(+), 475 deletions(-)
 create mode 100644 src/animationPreview.ts
 create mode 100644 src/mods/animationPreviewMod.ts
 create mode 100644 src/panels/customKeyframe/keyframeEdit.ts
 create mode 100644 src/panels/customKeyframe/textureSlotKeyframe.svelte
 create mode 100644 src/svelteComponents/slotTexturesEditor.svelte
 create mode 100644 src/svelteComponents/variantStackEditor.svelte
 create mode 100644 src/tests/animation-preview.test.ts
 create mode 100644 src/tests/effect-keyframe-export.test.ts
 create mode 100644 src/tests/keyframe-panels.test.ts
 create mode 100644 src/tests/unit/variantKeyframeMigration.test.ts

diff --git a/schemas/plugin-blueprint.schema.json b/schemas/plugin-blueprint.schema.json
index 6c93dbcb..258d1fd4 100644
--- a/schemas/plugin-blueprint.schema.json
+++ b/schemas/plugin-blueprint.schema.json
@@ -36,6 +36,15 @@
 				}
 			}
 		},
+		"variants": {
+			"type": "object",
+			"default": {},
+			"patternProperties": {
+				"^[a-z0-9_]+$": {
+					"$ref": "#/definitions/variant"
+				}
+			}
+		},
 		"nodes": {
 			"type": "object",
 			"default": {},
@@ -149,6 +158,41 @@
 				}
 			}
 		},
+		"variant": {
+			"type": "object",
+			"description": "A named set of changes to the rig. Applying a Variant changes every node it doesn't exclude.",
+			"required": ["texture_slots", "excluded_nodes", "entity_properties"],
+			"properties": {
+				"is_default": {
+					"type": "boolean",
+					"default": false,
+					"description": "Whether this is the default Variant. Exactly one Variant is the default."
+				},
+				"texture_slots": {
+					"$ref": "#/definitions/texture_slot_changes",
+					"description": "The texture each slot switches to, on nodes this Variant doesn't exclude. Slots not listed are unchanged. The default Variant lists every slot with its default texture."
+				},
+				"excluded_nodes": {
+					"type": "array",
+					"default": [],
+					"description": "Keys from the 'nodes' section this Variant leaves unchanged, including their texture slots.",
+					"items": {
+						"type": "string",
+						"pattern": "^[a-z0-9_]+$"
+					}
+				},
+				"entity_properties": {
+					"type": "object",
+					"default": {},
+					"description": "Entity properties this Variant merges onto nodes, by key from the 'nodes' section. Each value has the same shape as that node's 'entity_properties'. For the default Variant, these are the nodes' default properties.",
+					"patternProperties": {
+						"^[a-z0-9_]+$": {
+							"type": "object"
+						}
+					}
+				}
+			}
+		},
 		"node": {
 			"type": "object",
 			"required": ["type"],
@@ -674,14 +718,25 @@
 				"global_keyframes": {
 					"type": "object",
 					"default": {},
+					"description": "Keyframes that aren't tied to a node. When a 'variant' and a 'texture_slot' keyframe share a timestamp, the Variants apply first.",
 					"properties": {
+						"variant": {
+							"type": "object",
+							"default": {},
+							"description": "A collection of variant keyframes, identified by a floating-point timestamp.",
+							"patternProperties": {
+								"^\\d+\\.\\d+$": {
+									"$ref": "#/definitions/variant_keyframe"
+								}
+							}
+						},
 						"texture_slot": {
 							"type": "object",
 							"default": {},
-							"description": "A collection of texture slot keyframes, identified by a floating-point timestamp.",
+							"description": "A collection of texture slot keyframes, identified by a floating-point timestamp. Each one changes every node with faces in the listed slots, regardless of Variant exclusions.",
 							"patternProperties": {
 								"^\\d+\\.\\d+$": {
-									"$ref": "#/definitions/texture_slot_keyframe"
+									"$ref": "#/definitions/texture_slot_changes"
 								}
 							}
 						},
@@ -751,10 +806,19 @@
 			"minItems": 3,
 			"maxItems": 3
 		},
-		"texture_slot_keyframe": {
+		"variant_keyframe": {
+			"type": "array",
+			"description": "Keys from the 'variants' section, applied in order. Later Variants override earlier ones on the nodes they change.",
+			"minItems": 1,
+			"items": {
+				"type": "string",
+				"pattern": "^[a-z0-9_]+$"
+			}
+		},
+		"texture_slot_changes": {
 			"type": "object",
 			"default": {},
-			"description": "Maps keys from the 'texture_slots' section to the texture each slot switches to. Slots not listed are unchanged.",
+			"description": "Maps keys from the 'texture_slots' section to the key of the texture each slot switches to. Slots not listed are unchanged.",
 			"patternProperties": {
 				"^[a-z0-9_]+$": {
 					"type": "string",
diff --git a/src/animationPreview.ts b/src/animationPreview.ts
new file mode 100644
index 00000000..d4841d0d
--- /dev/null
+++ b/src/animationPreview.ts
@@ -0,0 +1,161 @@
+import { EFFECT_ANIMATOR_CHANNELS } from './mods/customKeyframes'
+import { VanillaBlockDisplay } from './outliner/vanillaBlockDisplay'
+import { VanillaItemDisplay } from './outliner/vanillaItemDisplay'
+import { getSlotDefaultTexture, getSlotPreviewTexture, getSlotTextures } from './textureSlots'
+import { Variant } from './variants'
+
+/**
+ * What an animation has applied to the rig at the previewed time. Only exists in Animate mode with
+ * an animation selected. Otherwise the editor shows the Variant selected in the Variants panel.
+ */
+interface AnimationPreviewState {
+	/** Every Variant applied so far, in order. */
+	variants: Variant[]
+	/** Bone UUID -> slot UUID -> texture UUID. Slots left out show their default texture. */
+	boneSlots: Map>
+}
+
+type PreviewEvent =
+	| { time: number; variants: Variant[] }
+	| { time: number; textureSlots: Record }
+
+let state: AnimationPreviewState | undefined
+let stateKey = ''
+
+/**
+ * The Variant whose display entity config `node` shows: the last applied Variant that changes it.
+ */
+export function getPreviewVariant(node: OutlinerNode): Variant | undefined {
+	if (!state) return Variant.selected
+	for (let i = state.variants.length - 1; i >= 0; i--) {
+		const variant = state.variants[i]
+		if (variant.excludedNodes.has(node.uuid)) continue
+		const configs = (node as { configs?: { variants?: Record } }).configs
+		if (variant.isDefault || configs?.variants?.[variant.uuid] !== undefined) return variant
+	}
+	return Variant.getDefault()
+}
+
+/**
+ * The texture a slot shows on faces of `bone`.
+ */
+export function getPreviewSlotTexture(slot: Texture, bone: OutlinerNode | undefined) {
+	if (!state) {
+		// The selected Variant leaves the slots it sets on excluded bones at their default.
+		const variant = Variant.selected
+		const excluded =
+			bone && variant?.excludedNodes.has(bone.uuid) && variant.slotTextures.has(slot.uuid)
+		return excluded ? getSlotDefaultTexture(slot) : getSlotPreviewTexture(slot)
+	}
+	const uuid = bone && state.boneSlots.get(bone.uuid)?.get(slot.uuid)
+	const textures = getSlotTextures(slot)
+	return textures.find(t => t.uuid === uuid) ?? textures[0]
+}
+
+function getAnimationStartVariants(animation: _Animation): Variant[] {
+	const variants = (animation.preview_variants ?? [])
+		.map(uuid => Variant.getByUUID(uuid))
+		.filter((v): v is Variant => !!v)
+	return variants.length ? variants : [Variant.getDefault()]
+}
+
+function getPreviewEvents(animation: _Animation, time: number): PreviewEvent[] {
+	const effects = animation.animators.effects as unknown as EffectAnimator | undefined
+	const events: PreviewEvent[] = []
+	if (effects && !effects.muted[EFFECT_ANIMATOR_CHANNELS.VARIANT]) {
+		for (const kf of effects[EFFECT_ANIMATOR_CHANNELS.VARIANT] as _Keyframe[]) {
+			if (kf.time <= time) events.push({ time: kf.time, variants: kf.variants ?? [] })
+		}
+	}
+	if (effects && !effects.muted[EFFECT_ANIMATOR_CHANNELS.TEXTURE_SLOT]) {
+		for (const kf of effects[EFFECT_ANIMATOR_CHANNELS.TEXTURE_SLOT] as _Keyframe[]) {
+			if (kf.time <= time)
+				events.push({ time: kf.time, textureSlots: kf.texture_slots ?? {} })
+		}
+	}
+	// Variants apply before texture slots on the same frame, like in-game.
+	return events.sort(
+		(a, b) => a.time - b.time || Number('textureSlots' in a) - Number('textureSlots' in b)
+	)
+}
+
+/**
+ * Replays what `animation` applies to the rig, from its start state up to `time`.
+ */
+export function computeAnimationPreviewState(
+	animation: _Animation,
+	time: number
+): AnimationPreviewState {
+	const result: AnimationPreviewState = { variants: [], boneSlots: new Map() }
+	const bones = Group.all
+
+	const applyVariant = (variant: Variant) => {
+		result.variants.push(variant)
+		for (const bone of bones) {
+			if (variant.excludedNodes.has(bone.uuid)) continue
+			if (variant.isDefault) {
+				result.boneSlots.delete(bone.uuid)
+				continue
+			}
+			for (const [slotUuid, textureUuid] of variant.slotTextures) {
+				setBoneSlot(bone.uuid, slotUuid, textureUuid)
+			}
+		}
+	}
+	const applyTextureSlots = (textureSlots: Record) => {
+		for (const [slotUuid, textureUuid] of Object.entries(textureSlots)) {
+			for (const bone of bones) setBoneSlot(bone.uuid, slotUuid, textureUuid)
+		}
+	}
+	const setBoneSlot = (boneUuid: string, slotUuid: string, textureUuid: string) => {
+		let slots = result.boneSlots.get(boneUuid)
+		if (!slots) result.boneSlots.set(boneUuid, (slots = new Map()))
+		slots.set(slotUuid, textureUuid)
+	}
+
+	for (const variant of getAnimationStartVariants(animation)) applyVariant(variant)
+	applyTextureSlots(animation.preview_texture_slots ?? {})
+	for (const event of getPreviewEvents(animation, time)) {
+		if ('variants' in event) event.variants.forEach(applyVariant)
+		else applyTextureSlots(event.textureSlots)
+	}
+	return result
+}
+
+function getStateKey(previewState: AnimationPreviewState | undefined) {
+	if (!previewState) return ''
+	const slots = [...previewState.boneSlots].map(([bone, map]) => [bone, [...map]])
+	return JSON.stringify([previewState.variants.map(v => v.uuid), slots])
+}
+
+/**
+ * Forgets the previewed animation, so the next update starts fresh. Used when switching projects.
+ */
+export function resetAnimationPreview() {
+	state = undefined
+	stateKey = ''
+}
+
+/**
+ * Re-renders everything that depends on which Variant or slot texture is shown.
+ */
+export function refreshVariantPreview() {
+	Canvas.updateAllFaces()
+	VanillaBlockDisplay.forceUpdateAll()
+	VanillaItemDisplay.forceUpdateAll()
+}
+
+/**
+ * Previews the selected animation's Variants and texture slots in Animate mode, or the Variants
+ * panel's selection everywhere else. Only re-renders when what's shown changes.
+ */
+export function updateAnimationPreview() {
+	const animation = Modes.animate ? Blockbench.Animation.selected : undefined
+	const next = animation ? computeAnimationPreviewState(animation, animation.time) : undefined
+	const nextKey = getStateKey(next)
+	const wasActive = !!state
+	state = next
+	if (nextKey === stateKey && wasActive === !!next) return
+	stateKey = nextKey
+	refreshVariantPreview()
+}
diff --git a/src/dialogs/animationProperties/animationProperties.svelte b/src/dialogs/animationProperties/animationProperties.svelte
index 597a0d78..7d849c25 100644
--- a/src/dialogs/animationProperties/animationProperties.svelte
+++ b/src/dialogs/animationProperties/animationProperties.svelte
@@ -9,6 +9,8 @@
 
@@ -17,7 +11,6 @@
 	import { observable } from 'svelte-observable-store'
 	import CodeInput from '../../svelteComponents/dialogItems/codeInput.svelte'
 	import Collection from '../../svelteComponents/dialogItems/collection.svelte'
-	import TextureSelect from '../../svelteComponents/textureSelect.svelte'
 	import {
 		fromCollectionItems,
 		getAvailableNodes,
@@ -44,7 +37,7 @@
 		excludeEmptyGroups: true,
 	})
 
-	let slotTexturesUpdated = 0
+	let slotTextureRecord = Object.fromEntries(slotTextures)
 
 	displayName.subscribe(value => {
 		if ($generateNameFromDisplayName) {
@@ -57,36 +50,12 @@
 		name.set(Variant.makeNameUnique(variant, $displayName))
 	})
 
-	function openAddSlotMenu(e: MouseEvent) {
-		const available = getTextureSlots().filter(
-			slot => !slotTextures.has(slot.uuid) && getSlotDefaultTexture(slot)
-		)
-		if (!available.length) {
-			Blockbench.showQuickMessage(
-				translate('dialog.variant_config.slot_textures.all_slots_added')
-			)
-			return
+	function setSlotTextures(value: Record) {
+		slotTextureRecord = value
+		slotTextures.clear()
+		for (const [slotUuid, textureUuid] of Object.entries(value)) {
+			slotTextures.set(slotUuid, textureUuid)
 		}
-		new Menu(
-			available.map(slot => ({
-				name: slot.name,
-				icon: 'style',
-				click: () => {
-					slotTextures.set(slot.uuid, getSlotDefaultTexture(slot)!.uuid)
-					slotTexturesUpdated++
-				},
-			}))
-		).open(e)
-	}
-
-	function setSlotTexture(slotUuid: string, textureUuid: string) {
-		slotTextures.set(slotUuid, textureUuid)
-		slotTexturesUpdated++
-	}
-
-	function removeSlot(slotUuid: string) {
-		slotTextures.delete(slotUuid)
-		slotTexturesUpdated++
 	}
 
 
@@ -125,55 +94,13 @@
 	/>
 
 	{#if !variant.isDefault}
-		
-
- {translate('dialog.variant_config.slot_textures.title')} -
-
- -
openAddSlotMenu(e)} - > - add -
-
-
- {@html translate('dialog.variant_config.slot_textures.description')} -
- - {#key slotTexturesUpdated} -
    - {#each [...slotTextures.entries()] as [slotUuid, textureUuid] (slotUuid)} - {@const slot = getTextureSlot(slotUuid)} - {#if slot} -
  • -
    {slot.name}
    - - east - - setSlotTexture(slotUuid, uuid)} - /> - - - removeSlot(slotUuid)}>delete -
  • - {/if} - {:else} -
    - {translate('dialog.variant_config.slot_textures.no_slots')} -
    - {/each} -
- {/key} + diff --git a/src/formats/blueprint/dfu.ts b/src/formats/blueprint/dfu.ts index 68e65e07..453fd520 100644 --- a/src/formats/blueprint/dfu.ts +++ b/src/formats/blueprint/dfu.ts @@ -17,7 +17,11 @@ import v1_0_0_pre8 from './versions/1.0.0-pre8' import v1_10_0_beta_1 from './versions/1.10.0-beta.1' import v1_10_0_beta_4 from './versions/1.10.0-beta.4' import v1_10_0_beta_7 from './versions/1.10.0-beta.7' -import v1_11_0, { needsTextureSlotUpgrade } from './versions/1.11.0' +import v1_11_0, { + needsTextureSlotUpgrade, + needsVariantKeyframeUpgrade, + upgradeVariantKeyframes, +} from './versions/1.11.0' import v1_4_0 from './versions/1.4.0' import v1_6_3 from './versions/1.6.3' import v1_6_5 from './versions/1.6.5' @@ -33,8 +37,8 @@ export function upgradeAnimatedJavaBlueprint(model: any): IBlueprintFormatJSON { let needsUpgrade = model.meta.format_version.length === 3 needsUpgrade = needsUpgrade || VersionUtil.compare(PACKAGE.version, '>', model.meta.format_version) - // Blueprints saved by 1.11.0 dev builds can still hold an older slot format - needsUpgrade ||= needsTextureSlotUpgrade(model) + // Blueprints saved by 1.11.0 dev builds can still hold an older slot or keyframe format + needsUpgrade ||= needsTextureSlotUpgrade(model) || needsVariantKeyframeUpgrade(model) if (!needsUpgrade) return model console.groupCollapsed( @@ -107,6 +111,7 @@ export function upgradeAnimatedJavaBlueprint(model: any): IBlueprintFormatJSON { model = v1_10_0_beta_7(model) } if (needsTextureSlotUpgrade(model)) model = v1_11_0(model) + if (needsVariantKeyframeUpgrade(model)) model = upgradeVariantKeyframes(model) // Remove unknown blueprint settings const defaultSettings = getDefaultProjectSettings() diff --git a/src/formats/blueprint/versions/1.11.0.ts b/src/formats/blueprint/versions/1.11.0.ts index 3fc19f3c..b450657e 100644 --- a/src/formats/blueprint/versions/1.11.0.ts +++ b/src/formats/blueprint/versions/1.11.0.ts @@ -104,3 +104,31 @@ export default function upgrade(model: any): IBlueprintFormatJSON { return fixed } + +function getVariantKeyframeDataPoints(model: any): any[] { + return (model?.animations ?? []) + .flatMap((animation: any) => Object.values(animation?.animators ?? {})) + .flatMap((animator: any) => animator?.keyframes ?? []) + .filter((keyframe: any) => keyframe?.channel === 'variant') + .flatMap((keyframe: any) => keyframe.data_points ?? []) +} + +/** + * Whether any variant keyframe still holds a single `variant` instead of a `variants` list. + */ +export function needsVariantKeyframeUpgrade(model: any): boolean { + return getVariantKeyframeDataPoints(model).some(dataPoint => 'variant' in dataPoint) +} + +/** + * Turns each variant keyframe's single `variant` into a `variants` list. + */ +export function upgradeVariantKeyframes(model: any): IBlueprintFormatJSON { + const fixed: any = JSON.parse(JSON.stringify(model)) + for (const dataPoint of getVariantKeyframeDataPoints(fixed)) { + if (!('variant' in dataPoint)) continue + dataPoint.variants ??= dataPoint.variant ? [dataPoint.variant] : [] + delete dataPoint.variant + } + return fixed +} diff --git a/src/index.ts b/src/index.ts index 7626ff3f..82da7b48 100644 --- a/src/index.ts +++ b/src/index.ts @@ -67,6 +67,7 @@ import { toSmallCaps, } from './util/minecraftUtil' import * as textureSlots from './textureSlots' +import * as animationPreview from './animationPreview' import { Variant } from './variants' declare global { @@ -83,6 +84,7 @@ const AnimatedJavaApi = { resourcepackCompiler, Variant, textureSlots, + animationPreview, openExportProgressDialog, debugExportProgressDialog, isResourcePackPath, diff --git a/src/lang/en.yml b/src/lang/en.yml index d2f4a5d8..4f306d71 100644 --- a/src/lang/en.yml +++ b/src/lang/en.yml @@ -844,9 +844,7 @@ animated_java: slot_textures: title: Texture Slots description: The texture each Texture Slot switches to when this Variant is applied. Slots not listed here are left unchanged. - add_slot: Add Texture Slot no_slots: This Variant doesn't change any Texture Slots. - all_slots_added: Every Texture Slot is already listed. bone_lists: description: |- Specify which nodes the Variant should affect. @@ -915,6 +913,14 @@ animated_java: description: A list of nodes to include in the animation. Only these nodes will be modified by the animation. swap_columns_button: tooltip: Swap Lists + preview_variants: + title: Preview Variants + description: The Variants shown when previewing this animation starts, applied in order. Set these to match the rig's expected in-game state when the animation plays. Only affects the editor. + empty: The default Variant. + preview_texture_slots: + title: Preview Texture Slots + description: The textures Texture Slots show when previewing this animation starts, after the Preview Variants. Only affects the editor. + empty: Texture Slots show what the Preview Variants set. export_progress: title: Exporting... blueprint_loading: @@ -933,9 +939,15 @@ animated_java: cannot_delete_default_variant: Cannot delete the default variant! keyframe: keyframe_title: Keyframe (%s) + remove: Remove variant: - title: Variant - description: The Variant to apply to the keyframe. + title: Variants + description: The Variants to apply, in order. Later Variants override earlier ones on the nodes they change. + empty: This keyframe doesn't apply any Variants. + texture_slot: + title: Texture Slots + description: The texture each Texture Slot switches to, on every node with faces in that slot. Applied after Variant keyframes on the same frame. Slots not listed here are left unchanged. + empty: This keyframe doesn't change any Texture Slots. function: title: Function description: |- @@ -1039,12 +1051,25 @@ animated_java: excluded_nodes: Excluded Nodes invert_excluded_nodes: Invert Excluded Nodes + slot_textures_editor: + add_slot: Add Texture Slot + all_slots_added: Every Texture Slot is already listed. + + variant_stack_editor: + add_variant: Add Variant + all_variants_added: Every Variant is already listed. + move_up: Move Up + move_down: Move Down + missing_variant: Missing Variant + effect_animator: timeline: variant: Variant + texture_slot: Texture Slots function: Function keyframe_data_point: - variant: Variant + variant: Variants + texture_slots: Texture Slots function: Function execute_condition: Execute Condition repeat: Repeat @@ -1122,6 +1147,10 @@ animated_java: If you want to rotate a cube on multiple axes, put it in a bone and rotate the bone instead. All of the invalid cubes are outlined in red in the editor. Please fix them before exporting. + texture_slot_keyframes_old_version: + message: |- + The animation "%s" has Texture Slot keyframes, which aren't supported in Minecraft %s. + Remove them, or target Minecraft %s or newer. unsupported_tint_source: message: |- The bone "%s" uses a %s tint, which is not supported in Minecraft %s. diff --git a/src/mods/animation.ts b/src/mods/animation.ts index e5b644e4..1172244d 100644 --- a/src/mods/animation.ts +++ b/src/mods/animation.ts @@ -8,14 +8,22 @@ declare global { // eslint-disable-next-line @typescript-eslint/naming-convention interface _Animation { excluded_nodes: CollectionItem[] + /** Variant UUIDs applied, in order, before previewing the animation. Editor only. */ + preview_variants: string[] + /** Slot UUID -> texture UUID set before previewing the animation. Editor only. */ + preview_texture_slots: Record } interface AnimationUndoCopy { excluded_nodes: string[] + preview_variants: string[] + preview_texture_slots: Record } interface AnimationOptions { excluded_nodes: string[] + preview_variants: string[] + preview_texture_slots: Record } } @@ -102,11 +110,33 @@ registerPatch({ } ) - return { excludedNodesProperty } + const previewVariantsProperty = new Property( + Blockbench.Animation, + 'array', + 'preview_variants', + { + condition: () => activeProjectIsBlueprintFormat(), + default: [], + } + ) + + const previewTextureSlotsProperty = new Property( + Blockbench.Animation, + 'object', + 'preview_texture_slots', + { + condition: () => activeProjectIsBlueprintFormat(), + default: {}, + } + ) + + return { excludedNodesProperty, previewVariantsProperty, previewTextureSlotsProperty } }, - revert: ({ excludedNodesProperty }) => { + revert: ({ excludedNodesProperty, previewVariantsProperty, previewTextureSlotsProperty }) => { excludedNodesProperty.delete() + previewVariantsProperty.delete() + previewTextureSlotsProperty.delete() }, }) diff --git a/src/mods/animationPreviewMod.ts b/src/mods/animationPreviewMod.ts new file mode 100644 index 00000000..643b6de1 --- /dev/null +++ b/src/mods/animationPreviewMod.ts @@ -0,0 +1,22 @@ +import { registerProjectPatch } from 'blockbench-patch-manager' +import { resetAnimationPreview, updateAnimationPreview } from '../animationPreview' +import { BLUEPRINT_FORMAT_ID } from '../formats/blueprint' + +// Keeps the Variants and texture slots shown in step with the selected animation in Animate mode. +registerProjectPatch({ + id: 'animated_java:animation-preview', + + condition: ({ project }) => project.format.id === BLUEPRINT_FORMAT_ID, + + apply() { + const update = () => updateAnimationPreview() + const events: Array = ['display_animation_frame', 'select_mode'] + for (const event of events) Blockbench.on(event, update) + return { events, update } + }, + + revert({ events, update }) { + for (const event of events) Blockbench.removeListener(event, update) + resetAnimationPreview() + }, +}) diff --git a/src/mods/cube.ts b/src/mods/cube.ts index be86049a..8da6ae45 100644 --- a/src/mods/cube.ts +++ b/src/mods/cube.ts @@ -14,7 +14,7 @@ import { } from '../shaders/enchantmentGlint' import { isCubeValid } from '../systems/util' import { localize as translate } from '../util/lang' -import { Variant } from '../variants' +import { getPreviewVariant } from '../animationPreview' declare global { // @ts-expect-error - Broken BB types @@ -144,10 +144,11 @@ registerPropertyOverridePatch({ const parent = instance.parent let config: IBlueprintDisplayEntityConfigJSON if (parent instanceof Group) { - if (!Variant.selected || Variant.selected.isDefault) { + const variant = getPreviewVariant(parent) + if (!variant || variant.isDefault) { config = parent.configs.default } else { - config = parent.configs.variants[Variant.selected.uuid] + config = parent.configs.variants[variant.uuid] } if (config?.enchanted) { diff --git a/src/mods/customKeyframes.ts b/src/mods/customKeyframes.ts index d59bffc1..81cfbfd0 100644 --- a/src/mods/customKeyframes.ts +++ b/src/mods/customKeyframes.ts @@ -7,7 +7,10 @@ declare global { // @ts-expect-error - Broken BB types // eslint-disable-next-line @typescript-eslint/naming-convention interface _Keyframe { - variant?: Variant + /** Variants to apply, in order. */ + variants?: Variant[] + /** Slot UUID -> texture UUID. Slots left out are unchanged. */ + texture_slots?: Record function?: string execute_condition?: string repeat?: boolean @@ -21,10 +24,13 @@ export enum LOCATOR_CHANNELS { export enum EFFECT_ANIMATOR_CHANNELS { VARIANT = 'variant', + TEXTURE_SLOT = 'texture_slot', FUNCTION = 'function', } export enum KEYFRAME_DATA_POINTS { + VARIANTS = 'variants', + TEXTURE_SLOTS = 'texture_slots', EXECUTE_CONDITION = 'execute_condition', REPEAT = 'repeat', REPEAT_FREQUENCY = 'repeat_frequency', @@ -35,27 +41,48 @@ export function isCustomKeyframeChannel(channel: string) { } registerPropertyOverridePatch({ - id: `animated_java:keyframe/data-point/variant`, + id: `animated_java:keyframe/data-point/variants`, target: Blockbench.Keyframe.prototype, - key: EFFECT_ANIMATOR_CHANNELS.VARIANT, + key: KEYFRAME_DATA_POINTS.VARIANTS, condition: () => activeProjectIsBlueprintFormat(), get(this: _Keyframe) { - const uuid = this.data_points.at(0)?.[EFFECT_ANIMATOR_CHANNELS.VARIANT] as - | string - | undefined - if (uuid) return Variant.getByUUID(uuid) - console.error('Keyframe variant', uuid, 'not found!') + const uuids = (this.data_points.at(0)?.[KEYFRAME_DATA_POINTS.VARIANTS] ?? []) as string[] + return uuids.map(uuid => Variant.getByUUID(uuid)).filter((v): v is Variant => !!v) }, - set(this: _Keyframe, value: Variant | undefined) { + set(this: _Keyframe, value: Variant[]) { const dataPoint = this.data_points.at(0) if (dataPoint) { - dataPoint[EFFECT_ANIMATOR_CHANNELS.VARIANT] = value?.uuid + dataPoint[KEYFRAME_DATA_POINTS.VARIANTS] = value.map(variant => variant.uuid) return value } - return undefined + return undefined! + }, +}) + +registerPropertyOverridePatch({ + id: `animated_java:keyframe/data-point/texture-slots`, + target: Blockbench.Keyframe.prototype, + key: KEYFRAME_DATA_POINTS.TEXTURE_SLOTS, + + condition: () => activeProjectIsBlueprintFormat(), + + get(this: _Keyframe) { + return (this.data_points.at(0)?.[KEYFRAME_DATA_POINTS.TEXTURE_SLOTS] ?? {}) as Record< + string, + string + > + }, + + set(this: _Keyframe, value: Record) { + const dataPoint = this.data_points.at(0) + if (dataPoint) { + dataPoint[KEYFRAME_DATA_POINTS.TEXTURE_SLOTS] = { ...value } + return value + } + return undefined! }, }) @@ -157,6 +184,11 @@ registerProjectPatch({ mutable: true, max_data_points: 1, }) + EffectAnimator.addChannel(EFFECT_ANIMATOR_CHANNELS.TEXTURE_SLOT, { + name: translate('effect_animator.timeline.texture_slot'), + mutable: true, + max_data_points: 1, + }) EffectAnimator.addChannel(EFFECT_ANIMATOR_CHANNELS.FUNCTION, { name: translate('effect_animator.timeline.function'), mutable: true, @@ -165,12 +197,20 @@ registerProjectPatch({ // Add custom keyframe properties to the KeyframeDataPoint class const properties = [ - new Property(KeyframeDataPoint, 'string', EFFECT_ANIMATOR_CHANNELS.VARIANT, { + new Property(KeyframeDataPoint, 'array', KEYFRAME_DATA_POINTS.VARIANTS, { label: translate('effect_animator.keyframe_data_point.variant'), condition: datapoint => datapoint.keyframe.channel === EFFECT_ANIMATOR_CHANNELS.VARIANT, exposed: false, - default: () => Variant.getDefault().uuid, + default: () => [Variant.getDefault().uuid], + }), + + new Property(KeyframeDataPoint, 'object', KEYFRAME_DATA_POINTS.TEXTURE_SLOTS, { + label: translate('effect_animator.keyframe_data_point.texture_slots'), + condition: datapoint => + datapoint.keyframe.channel === EFFECT_ANIMATOR_CHANNELS.TEXTURE_SLOT, + exposed: false, + default: {}, }), new Property(KeyframeDataPoint, 'string', EFFECT_ANIMATOR_CHANNELS.FUNCTION, { @@ -211,41 +251,13 @@ registerProjectPatch({ delete EffectAnimator.prototype.channels[channel] } - // Modify the displayFrame method to handle custom keyframes + // Only keep Blockbench's sound keyframe handling. Variant and texture slot keyframes are + // previewed by `updateAnimationPreview`. const defaultEffectDisplayFrame = EffectAnimator.prototype.displayFrame EffectAnimator.prototype.displayFrame = function (this: EffectAnimator, inLoop: boolean) { this.muted.particle = true this.muted.timeline = true - // Default Blockbench Sound keyframe handling defaultEffectDisplayFrame.call(this, inLoop) - - if (!(Project && activeProjectIsBlueprintFormat())) return - if (!this.muted[EFFECT_ANIMATOR_CHANNELS.VARIANT]) { - let after, before, result: _Keyframe | undefined - - for (const kf of this[EFFECT_ANIMATOR_CHANNELS.VARIANT] as _Keyframe[]) { - if (kf.time < this.animation.time) { - if (!before || kf.time > before.time) { - before = kf - } - } else { - if (!after || kf.time < after.time) { - after = kf - } - } - } - - if (after && after.time === this.animation.time) { - result = after - } else if (before) { - result = before - } else if (after) { - result = this[EFFECT_ANIMATOR_CHANNELS.VARIANT].at(-1) - } - - result?.variant?.select() - } - this.last_displayed_time = this.animation.time } diff --git a/src/mods/variantPreviewCubeFaceMod.ts b/src/mods/variantPreviewCubeFaceMod.ts index b3c97f9d..9814305c 100644 --- a/src/mods/variantPreviewCubeFaceMod.ts +++ b/src/mods/variantPreviewCubeFaceMod.ts @@ -1,12 +1,7 @@ import { registerPatch } from 'blockbench-patch-manager' +import { getPreviewSlotTexture } from '../animationPreview' import { activeProjectIsBlueprintFormat } from '../formats/blueprint' -import { - getSlotDefaultTexture, - getSlotPreviewTexture, - getTextureSlot, - shouldResolveSlots, -} from '../textureSlots' -import { Variant } from '../variants' +import { getTextureSlot, shouldResolveSlots } from '../textureSlots' registerPatch({ id: `animated_java:variant-preview-cube-face`, @@ -23,14 +18,8 @@ registerPatch({ ) { const slot = getTextureSlot(this.texture) if (slot) { - const variant = Variant.selected - const excluded = - this.cube.parent instanceof Group && - variant?.excludedNodes.has(this.cube.parent.uuid) && - variant.slotTextures.has(slot.uuid) - const texture = excluded - ? getSlotDefaultTexture(slot) - : getSlotPreviewTexture(slot) + const bone = this.cube.parent instanceof Group ? this.cube.parent : undefined + const texture = getPreviewSlotTexture(slot, bone) if (texture) return texture } } diff --git a/src/outliner/vanillaItemDisplay.ts b/src/outliner/vanillaItemDisplay.ts index 8ee785d1..062e0439 100644 --- a/src/outliner/vanillaItemDisplay.ts +++ b/src/outliner/vanillaItemDisplay.ts @@ -1,6 +1,7 @@ import { registerDeletableHandlerPatch, registerPatch } from 'blockbench-patch-manager' import { observable } from 'svelte-observable-store' import { PACKAGE } from '../constants' +import { getPreviewVariant } from '../animationPreview' import { activeProjectIsBlueprintFormat } from '../formats/blueprint/index' import { applyEnchantmentGlintToMesh } from '../shaders/enchantmentGlint' import { getItemModel } from '../systems/minecraft/itemModelManager' @@ -9,7 +10,6 @@ import EVENTS from '../util/events' import { localize as translate } from '../util/lang' import { validateItem } from '../util/minecraftUtil' import { DeepClonedObjectProperty, fixClassPropertyInheritance } from '../util/property' -import { Variant } from '../variants' import { applyPivotOffset, getPivotedGeometryWorldCenter, @@ -243,8 +243,9 @@ export const PREVIEW_CONTROLLER: NodePreviewController = new NodePreviewControll mesh.outline.visible = el.selected resetPivotOffsetTracking(mesh.geometry, result.mesh, result.outline) - if (Variant.selected) { - const config = Variant.selected.getDisplayEntityConfig(el) + const variant = getPreviewVariant(el) + if (variant) { + const config = variant.getDisplayEntityConfig(el) if (config.enchanted) { for (const child of result.mesh.children) { if (!(child instanceof THREE.Mesh)) continue diff --git a/src/panels/customKeyframe/commandsKeyframe.svelte b/src/panels/customKeyframe/commandsKeyframe.svelte index 29575698..e4c1f407 100644 --- a/src/panels/customKeyframe/commandsKeyframe.svelte +++ b/src/panels/customKeyframe/commandsKeyframe.svelte @@ -1,6 +1,7 @@ -
+
-
+
-{#if keyframe?.repeat} -
+{#if repeat} +