minerender 2.1.0-alpha.134 → 2.1.0-alpha.136

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/browser/esm/assets/AssetDefaults.mjs +8 -0
  2. package/dist/browser/esm/assets/AssetDefaults.mjs.map +1 -0
  3. package/dist/browser/esm/assets/AssetKey.mjs +1 -1
  4. package/dist/browser/esm/assets/AssetKey.mjs.map +1 -1
  5. package/dist/browser/esm/assets/AssetLoader.mjs +1 -1
  6. package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
  7. package/dist/browser/esm/assets/Assets.mjs +1 -5
  8. package/dist/browser/esm/assets/Assets.mjs.map +1 -1
  9. package/dist/browser/esm/assets/BlockStates.mjs +1 -1
  10. package/dist/browser/esm/assets/BlockStates.mjs.map +1 -1
  11. package/dist/browser/esm/assets/Entities.mjs +1 -1
  12. package/dist/browser/esm/assets/Entities.mjs.map +1 -1
  13. package/dist/browser/esm/assets/Models.mjs +1 -1
  14. package/dist/browser/esm/assets/Models.mjs.map +1 -1
  15. package/dist/browser/esm/assets/_fonts/Unihex.mjs +1 -1
  16. package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -1
  17. package/dist/browser/esm/assets/index.mjs +1 -0
  18. package/dist/browser/esm/assets/index.mjs.map +1 -1
  19. package/dist/browser/esm/assets/source/HostedAssetSource.mjs +1 -1
  20. package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
  21. package/dist/browser/esm/index.browser.d.mts +3 -2
  22. package/dist/browser/esm/nbt/NBTHelper.mjs +5 -2
  23. package/dist/browser/esm/nbt/NBTHelper.mjs.map +1 -1
  24. package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
  25. package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
  26. package/dist/browser/index.d.ts +3 -2
  27. package/dist/browser/index.js +2712 -2705
  28. package/dist/browser/index.js.map +1 -1
  29. package/dist/bundle.js +7812 -7802
  30. package/dist/bundle.js.map +1 -1
  31. package/dist/node/index.d.mts +3 -2
  32. package/dist/node/index.d.ts +3 -2
  33. package/dist/node/index.js +2738 -2731
  34. package/dist/node/index.js.map +1 -1
  35. package/dist/node/index.mjs +2720 -2713
  36. package/dist/node/index.mjs.map +1 -1
  37. package/package.json +1 -1
@@ -0,0 +1,8 @@
1
+ // src/assets/AssetDefaults.ts
2
+ var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
3
+ var DEFAULT_NAMESPACE = "minecraft";
4
+ export {
5
+ DEFAULT_NAMESPACE,
6
+ DEFAULT_ROOT
7
+ };
8
+ //# sourceMappingURL=AssetDefaults.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/assets/AssetDefaults.ts"],"sourcesContent":["// Kept free of imports: AssetLoader reads DEFAULT_ROOT in a static initializer, and Assets.ts sits in an import\n// cycle with AssetLoader, so code-split bundles could run that initializer before the constant was assigned.\nexport const DEFAULT_ROOT = \"https://assets.mcasset.cloud/1.21.11\";\nexport const DEFAULT_NAMESPACE = \"minecraft\";\n"],"mappings":";AAEO,IAAM,eAAe;AACrB,IAAM,oBAAoB;","names":[]}
@@ -1,5 +1,5 @@
1
1
  // src/assets/AssetKey.ts
2
- import { DEFAULT_NAMESPACE } from "./Assets.mjs";
2
+ import { DEFAULT_NAMESPACE } from "./AssetDefaults.mjs";
3
3
  import { AssetLoader } from "./AssetLoader.mjs";
4
4
  var BasicAssetKey = class {
5
5
  constructor(namespaceOrKey, path) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/assets/AssetKey.ts"],"sourcesContent":["import { Serializable } from \"../Serializable\";\nimport { DEFAULT_NAMESPACE } from \"./Assets\";\nimport { AssetLoader } from \"./AssetLoader\";\n\nexport type AssetType = \"models\" | \"textures\" | \"blockstates\" | string;\n\n/** A Minecraft namespace and path, such as `minecraft` and `zombie`. */\nexport class BasicAssetKey implements Serializable {\n\n readonly namespace: string;\n readonly path: string;\n\n constructor(key: BasicAssetKey);\n constructor(namespace: string, path: string);\n constructor(namespaceOrKey: string | BasicAssetKey, path?: string) {\n if (path) {\n this.namespace = namespaceOrKey as string;\n this.path = path;\n } else {\n this.namespace = (namespaceOrKey as BasicAssetKey).namespace;\n this.path = (namespaceOrKey as BasicAssetKey).path\n }\n }\n\n toNamespacedString() {\n return this.namespace + \":\" + this.path;\n }\n\n toString() {\n return this.toNamespacedString();\n }\n\n serialize(): string {\n return this.toString();\n }\n}\n\n// TODO: rewrite this to be less dumb\n/** Locates an asset by namespace, directory, extension, and optional asset root. */\nexport class AssetKey extends BasicAssetKey {\n\n public readonly isAssetKey: true = true;\n\n /**\n * Creates a key from separate path components. Use {@link parse} for a combined reference.\n *\n * @param assetType - Asset directory, such as `models`, `textures`, or `blockstates`.\n * @param type - Subdirectory, such as `block` or `item`.\n * @param rootType - Top-level directory, usually `assets` or `data`.\n * @param root - Base URL override for hosted asset sources.\n */\n constructor(\n readonly namespace: string, readonly path: string,\n public assetType?: AssetType,\n public type?: string,\n public rootType: \"assets\" | \"data\" | string = \"assets\",\n public extension: \".json\" | \".png\" | string = \".json\",\n public root?: string,\n ) {\n super(namespace, path);\n }\n\n\n /**\n * Parses an asset reference such as `minecraft:block/stone`.\n * A missing namespace defaults to the origin's namespace or `minecraft`.\n *\n * @param assetType - Asset category, such as `models` or `textures`.\n * @param str - Path with an optional namespace and file extension.\n * @param origin - Supplies the asset root, default namespace, and non-texture extension.\n * @returns A key with the matching extension removed from its path. Textures use `.png`;\n * other assets use the origin's extension or `.json`.\n */\n public static parse(assetType: AssetType, str: string, origin?: AssetKey): AssetKey {\n let namespace = origin?.namespace || DEFAULT_NAMESPACE;\n if (str.includes(\":\")) {\n let split = str.split(\"\\:\");\n namespace = split[0];\n str = split[1];\n }\n\n let split = str.split(\"\\/\");\n let type: string | undefined = undefined;\n if (split.length > 1) {\n type = split[0];\n split.shift();\n }\n let path = split.join(\"/\");\n\n const extension = assetType === \"textures\" ? \".png\" :\n origin?.extension ?? \".json\";\n if (extension && path.endsWith(extension)) {\n path = path.slice(0, -extension.length);\n }\n\n return new AssetKey(namespace, path, assetType, type, \"assets\", extension, origin?.root);\n }\n\n toString(): string {\n let a = [\n this.root ?? AssetLoader.ROOT,\n this.rootType ?? \"__rootType__\",\n this.assetType ?? \"__assetType__\",\n this.type ?? \"__type__\",\n this.namespace,\n this.path\n ];\n return a.join(\"/\");\n }\n\n /** Joins the type subdirectory and path without adding a namespace or file extension. */\n getFullPath() {\n let p: string[] = [];\n if (this.type) {\n p.push(this.type);\n }\n p.push(this.path);\n return p.join(\"/\");\n }\n\n toNamespacedString() {\n return this.namespace + \":\" + this.getFullPath();\n }\n\n /** Returns a cache identifier that includes the explicit root or {@link AssetLoader.ROOT}. */\n serialize(): string {\n return this.toString();\n }\n}\n\nexport function isResourceLocation(value: unknown): value is string {\n return typeof value === \"string\" && /^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(value);\n}\n\nexport function isBasicAssetKey(obj: any): obj is BasicAssetKey {\n return obj !== null && typeof obj === \"object\"\n && typeof obj.namespace === \"string\" && typeof obj.path === \"string\";\n}\n\nexport function isAssetKey(obj: any): obj is AssetKey {\n return isBasicAssetKey(obj) && (<AssetKey>obj).isAssetKey === true;\n}\n"],"mappings":";AACA,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAKrB,IAAM,gBAAN,MAA4C;AAAA,EAO/C,YAAY,gBAAwC,MAAe;AAC/D,QAAI,MAAM;AACN,WAAK,YAAY;AACjB,WAAK,OAAO;AAAA,IAChB,OAAO;AACH,WAAK,YAAa,eAAiC;AACnD,WAAK,OAAQ,eAAiC;AAAA,IAClD;AAAA,EACJ;AAAA,EAEA,qBAAqB;AACjB,WAAO,KAAK,YAAY,MAAM,KAAK;AAAA,EACvC;AAAA,EAEA,WAAW;AACP,WAAO,KAAK,mBAAmB;AAAA,EACnC;AAAA,EAEA,YAAoB;AAChB,WAAO,KAAK,SAAS;AAAA,EACzB;AACJ;AAIO,IAAM,WAAN,MAAM,kBAAiB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYxC,YACa,WAA4B,MAC9B,WACA,MACA,WAAuC,UACvC,YAAuC,SACvC,MACT;AACE,UAAM,WAAW,IAAI;AAPZ;AAA4B;AAC9B;AACA;AACA;AACA;AACA;AAhBX,SAAgB,aAAmB;AAAA,EAmBnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,OAAc,MAAM,WAAsB,KAAa,QAA6B;AAChF,QAAI,YAAY,QAAQ,aAAa;AACrC,QAAI,IAAI,SAAS,GAAG,GAAG;AACnB,UAAIA,SAAQ,IAAI,MAAM,GAAI;AAC1B,kBAAYA,OAAM,CAAC;AACnB,YAAMA,OAAM,CAAC;AAAA,IACjB;AAEA,QAAI,QAAQ,IAAI,MAAM,GAAI;AAC1B,QAAI,OAA2B;AAC/B,QAAI,MAAM,SAAS,GAAG;AAClB,aAAO,MAAM,CAAC;AACd,YAAM,MAAM;AAAA,IAChB;AACA,QAAI,OAAO,MAAM,KAAK,GAAG;AAEzB,UAAM,YAAY,cAAc,aAAa,SACzC,QAAQ,aAAa;AACzB,QAAI,aAAa,KAAK,SAAS,SAAS,GAAG;AACvC,aAAO,KAAK,MAAM,GAAG,CAAC,UAAU,MAAM;AAAA,IAC1C;AAEA,WAAO,IAAI,UAAS,WAAW,MAAM,WAAW,MAAM,UAAU,WAAW,QAAQ,IAAI;AAAA,EAC3F;AAAA,EAEA,WAAmB;AACf,QAAI,IAAI;AAAA,MACJ,KAAK,QAAQ,YAAY;AAAA,MACzB,KAAK,YAAY;AAAA,MACjB,KAAK,aAAa;AAAA,MAClB,KAAK,QAAQ;AAAA,MACb,KAAK;AAAA,MACL,KAAK;AAAA,IACT;AACA,WAAO,EAAE,KAAK,GAAG;AAAA,EACrB;AAAA;AAAA,EAGA,cAAc;AACV,QAAI,IAAc,CAAC;AACnB,QAAI,KAAK,MAAM;AACX,QAAE,KAAK,KAAK,IAAI;AAAA,IACpB;AACA,MAAE,KAAK,KAAK,IAAI;AAChB,WAAO,EAAE,KAAK,GAAG;AAAA,EACrB;AAAA,EAEA,qBAAqB;AACjB,WAAO,KAAK,YAAY,MAAM,KAAK,YAAY;AAAA,EACnD;AAAA;AAAA,EAGA,YAAoB;AAChB,WAAO,KAAK,SAAS;AAAA,EACzB;AACJ;AAEO,SAAS,mBAAmB,OAAiC;AAChE,SAAO,OAAO,UAAU,YAAY,oCAAoC,KAAK,KAAK;AACtF;AAEO,SAAS,gBAAgB,KAAgC;AAC5D,SAAO,QAAQ,QAAQ,OAAO,QAAQ,YAC/B,OAAO,IAAI,cAAc,YAAY,OAAO,IAAI,SAAS;AACpE;AAEO,SAAS,WAAW,KAA2B;AAClD,SAAO,gBAAgB,GAAG,KAAgB,IAAK,eAAe;AAClE;","names":["split"]}
1
+ {"version":3,"sources":["../../../../src/assets/AssetKey.ts"],"sourcesContent":["import { Serializable } from \"../Serializable\";\nimport { DEFAULT_NAMESPACE } from \"./AssetDefaults\";\nimport { AssetLoader } from \"./AssetLoader\";\n\nexport type AssetType = \"models\" | \"textures\" | \"blockstates\" | string;\n\n/** A Minecraft namespace and path, such as `minecraft` and `zombie`. */\nexport class BasicAssetKey implements Serializable {\n\n readonly namespace: string;\n readonly path: string;\n\n constructor(key: BasicAssetKey);\n constructor(namespace: string, path: string);\n constructor(namespaceOrKey: string | BasicAssetKey, path?: string) {\n if (path) {\n this.namespace = namespaceOrKey as string;\n this.path = path;\n } else {\n this.namespace = (namespaceOrKey as BasicAssetKey).namespace;\n this.path = (namespaceOrKey as BasicAssetKey).path\n }\n }\n\n toNamespacedString() {\n return this.namespace + \":\" + this.path;\n }\n\n toString() {\n return this.toNamespacedString();\n }\n\n serialize(): string {\n return this.toString();\n }\n}\n\n// TODO: rewrite this to be less dumb\n/** Locates an asset by namespace, directory, extension, and optional asset root. */\nexport class AssetKey extends BasicAssetKey {\n\n public readonly isAssetKey: true = true;\n\n /**\n * Creates a key from separate path components. Use {@link parse} for a combined reference.\n *\n * @param assetType - Asset directory, such as `models`, `textures`, or `blockstates`.\n * @param type - Subdirectory, such as `block` or `item`.\n * @param rootType - Top-level directory, usually `assets` or `data`.\n * @param root - Base URL override for hosted asset sources.\n */\n constructor(\n readonly namespace: string, readonly path: string,\n public assetType?: AssetType,\n public type?: string,\n public rootType: \"assets\" | \"data\" | string = \"assets\",\n public extension: \".json\" | \".png\" | string = \".json\",\n public root?: string,\n ) {\n super(namespace, path);\n }\n\n\n /**\n * Parses an asset reference such as `minecraft:block/stone`.\n * A missing namespace defaults to the origin's namespace or `minecraft`.\n *\n * @param assetType - Asset category, such as `models` or `textures`.\n * @param str - Path with an optional namespace and file extension.\n * @param origin - Supplies the asset root, default namespace, and non-texture extension.\n * @returns A key with the matching extension removed from its path. Textures use `.png`;\n * other assets use the origin's extension or `.json`.\n */\n public static parse(assetType: AssetType, str: string, origin?: AssetKey): AssetKey {\n let namespace = origin?.namespace || DEFAULT_NAMESPACE;\n if (str.includes(\":\")) {\n let split = str.split(\"\\:\");\n namespace = split[0];\n str = split[1];\n }\n\n let split = str.split(\"\\/\");\n let type: string | undefined = undefined;\n if (split.length > 1) {\n type = split[0];\n split.shift();\n }\n let path = split.join(\"/\");\n\n const extension = assetType === \"textures\" ? \".png\" :\n origin?.extension ?? \".json\";\n if (extension && path.endsWith(extension)) {\n path = path.slice(0, -extension.length);\n }\n\n return new AssetKey(namespace, path, assetType, type, \"assets\", extension, origin?.root);\n }\n\n toString(): string {\n let a = [\n this.root ?? AssetLoader.ROOT,\n this.rootType ?? \"__rootType__\",\n this.assetType ?? \"__assetType__\",\n this.type ?? \"__type__\",\n this.namespace,\n this.path\n ];\n return a.join(\"/\");\n }\n\n /** Joins the type subdirectory and path without adding a namespace or file extension. */\n getFullPath() {\n let p: string[] = [];\n if (this.type) {\n p.push(this.type);\n }\n p.push(this.path);\n return p.join(\"/\");\n }\n\n toNamespacedString() {\n return this.namespace + \":\" + this.getFullPath();\n }\n\n /** Returns a cache identifier that includes the explicit root or {@link AssetLoader.ROOT}. */\n serialize(): string {\n return this.toString();\n }\n}\n\nexport function isResourceLocation(value: unknown): value is string {\n return typeof value === \"string\" && /^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(value);\n}\n\nexport function isBasicAssetKey(obj: any): obj is BasicAssetKey {\n return obj !== null && typeof obj === \"object\"\n && typeof obj.namespace === \"string\" && typeof obj.path === \"string\";\n}\n\nexport function isAssetKey(obj: any): obj is AssetKey {\n return isBasicAssetKey(obj) && (<AssetKey>obj).isAssetKey === true;\n}\n"],"mappings":";AACA,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAKrB,IAAM,gBAAN,MAA4C;AAAA,EAO/C,YAAY,gBAAwC,MAAe;AAC/D,QAAI,MAAM;AACN,WAAK,YAAY;AACjB,WAAK,OAAO;AAAA,IAChB,OAAO;AACH,WAAK,YAAa,eAAiC;AACnD,WAAK,OAAQ,eAAiC;AAAA,IAClD;AAAA,EACJ;AAAA,EAEA,qBAAqB;AACjB,WAAO,KAAK,YAAY,MAAM,KAAK;AAAA,EACvC;AAAA,EAEA,WAAW;AACP,WAAO,KAAK,mBAAmB;AAAA,EACnC;AAAA,EAEA,YAAoB;AAChB,WAAO,KAAK,SAAS;AAAA,EACzB;AACJ;AAIO,IAAM,WAAN,MAAM,kBAAiB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYxC,YACa,WAA4B,MAC9B,WACA,MACA,WAAuC,UACvC,YAAuC,SACvC,MACT;AACE,UAAM,WAAW,IAAI;AAPZ;AAA4B;AAC9B;AACA;AACA;AACA;AACA;AAhBX,SAAgB,aAAmB;AAAA,EAmBnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,OAAc,MAAM,WAAsB,KAAa,QAA6B;AAChF,QAAI,YAAY,QAAQ,aAAa;AACrC,QAAI,IAAI,SAAS,GAAG,GAAG;AACnB,UAAIA,SAAQ,IAAI,MAAM,GAAI;AAC1B,kBAAYA,OAAM,CAAC;AACnB,YAAMA,OAAM,CAAC;AAAA,IACjB;AAEA,QAAI,QAAQ,IAAI,MAAM,GAAI;AAC1B,QAAI,OAA2B;AAC/B,QAAI,MAAM,SAAS,GAAG;AAClB,aAAO,MAAM,CAAC;AACd,YAAM,MAAM;AAAA,IAChB;AACA,QAAI,OAAO,MAAM,KAAK,GAAG;AAEzB,UAAM,YAAY,cAAc,aAAa,SACzC,QAAQ,aAAa;AACzB,QAAI,aAAa,KAAK,SAAS,SAAS,GAAG;AACvC,aAAO,KAAK,MAAM,GAAG,CAAC,UAAU,MAAM;AAAA,IAC1C;AAEA,WAAO,IAAI,UAAS,WAAW,MAAM,WAAW,MAAM,UAAU,WAAW,QAAQ,IAAI;AAAA,EAC3F;AAAA,EAEA,WAAmB;AACf,QAAI,IAAI;AAAA,MACJ,KAAK,QAAQ,YAAY;AAAA,MACzB,KAAK,YAAY;AAAA,MACjB,KAAK,aAAa;AAAA,MAClB,KAAK,QAAQ;AAAA,MACb,KAAK;AAAA,MACL,KAAK;AAAA,IACT;AACA,WAAO,EAAE,KAAK,GAAG;AAAA,EACrB;AAAA;AAAA,EAGA,cAAc;AACV,QAAI,IAAc,CAAC;AACnB,QAAI,KAAK,MAAM;AACX,QAAE,KAAK,KAAK,IAAI;AAAA,IACpB;AACA,MAAE,KAAK,KAAK,IAAI;AAChB,WAAO,EAAE,KAAK,GAAG;AAAA,EACrB;AAAA,EAEA,qBAAqB;AACjB,WAAO,KAAK,YAAY,MAAM,KAAK,YAAY;AAAA,EACnD;AAAA;AAAA,EAGA,YAAoB;AAChB,WAAO,KAAK,SAAS;AAAA,EACzB;AACJ;AAEO,SAAS,mBAAmB,OAAiC;AAChE,SAAO,OAAO,UAAU,YAAY,oCAAoC,KAAK,KAAK;AACtF;AAEO,SAAS,gBAAgB,KAAgC;AAC5D,SAAO,QAAQ,QAAQ,OAAO,QAAQ,YAC/B,OAAO,IAAI,cAAc,YAAY,OAAO,IAAI,SAAS;AACpE;AAEO,SAAS,WAAW,KAA2B;AAClD,SAAO,gBAAgB,GAAG,KAAgB,IAAK,eAAe;AAClE;","names":["split"]}
@@ -1,5 +1,5 @@
1
1
  // src/assets/AssetLoader.ts
2
- import { DEFAULT_ROOT } from "./Assets.mjs";
2
+ import { DEFAULT_ROOT } from "./AssetDefaults.mjs";
3
3
  import { AssetKey } from "./AssetKey.mjs";
4
4
  import { prefix } from "../util/log.mjs";
5
5
  import { HostedAssetSource } from "./source/index.mjs";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/assets/AssetLoader.ts"],"sourcesContent":["import { Model, TextureAsset } from \"../model/Model\";\nimport { Maybe } from \"../util/util\";\nimport { Requests } from \"../request/Requests\";\nimport { MinecraftAsset } from \"../MinecraftAsset\";\nimport { ImageInfo, ImageLoader } from \"../image/ImageLoader\";\nimport { MinecraftTextureMeta } from \"../MinecraftTextureMeta\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { DEFAULT_NAMESPACE, DEFAULT_ROOT } from \"./Assets\";\nimport { ListAsset } from \"../ListAsset\";\nimport { AssetKey } from \"./AssetKey\";\nimport { NBTAsset, NBTHelper } from \"../nbt/NBTHelper\";\nimport { prefix } from \"../util/log\";\nimport { AssetSource } from \"./source/AssetSource\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { HostedAssetSource } from \"./source\";\nimport { Caching } from \"../cache/Caching\";\n\nconst p = prefix(\"AssetLoader\");\n\n\n/** Loads assets from a shared, ordered registry of hosted sources and resource packs. */\nexport class AssetLoader {\n\n /** Default asset base URL. Use {@link setVersion} to select a Minecraft version. */\n static ROOT: string = DEFAULT_ROOT;\n\n private static sources: AssetSourceReference[] | undefined;\n\n private static get _SOURCES(): AssetSourceReference[] {\n return this.sources ??= [{ key: \"mcassets\", source: new HostedAssetSource(this.ROOT, { retryDefaults: false }) }];\n }\n\n private static set _SOURCES(sources: AssetSourceReference[]) {\n this.sources = sources;\n }\n\n /** Used when a registered source cannot identify its content, so nothing persists past this session. */\n private static readonly SESSION_SCOPE = `session:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;\n\n public static get version(): string {\n return this.ROOT.substring(this.ROOT.lastIndexOf(\"/\") + 1);\n }\n\n /** Selects an mcasset.cloud version, updates the vanilla source, and clears in-memory caches. */\n public static setVersion(version: string): void {\n this.ROOT = `https://assets.mcasset.cloud/${version}`;\n const source = new HostedAssetSource(this.ROOT, { retryDefaults: false });\n const index = this._SOURCES.findIndex(s => s.key === \"mcassets\");\n if (index !== -1) {\n this._SOURCES[index] = { key: \"mcassets\", source };\n } else {\n this.addSource(\"mcassets\", source);\n }\n Caching.clear();\n }\n\n /**\n * Scope for persistent cache keys. Empty with only the default vanilla source, so its\n * entries stay valid across sessions; otherwise it names every added source (resource packs,\n * mirrors) so their results never masquerade as vanilla assets after a reload.\n */\n public static get persistentScope(): string {\n const parts: string[] = [];\n for (const { key, source } of this._SOURCES) {\n const id = source.cacheId;\n if (key === \"mcassets\" && id === `hosted:${this.ROOT}`) continue;\n if (id === undefined) return this.SESSION_SCOPE;\n parts.push(`${key}=${id}`);\n }\n return parts.join(\"|\");\n }\n\n /** Prefixes a persistent cache key with the current source scope. */\n public static persistentKey(key: string): string {\n const scope = this.persistentScope;\n return scope ? `${scope}\\n${key}` : key;\n }\n\n /**\n * Registers a source at the highest priority.\n * Call {@link Caching.clear} after changing sources to discard previously loaded assets.\n *\n * @param key - Name used to replace or remove this source.\n * @param override - Removes the first source with this name before adding the new one.\n */\n public static addSource(key: string, source: AssetSource, override: boolean = true) {\n if (override) {\n const existing = this.removeSource(key);\n if (existing) {\n console.log(p, \"Removed existing AssetSource\", key);\n }\n }\n\n this._SOURCES.unshift({key, source});\n console.log(p, \"Added AssetSource\", key);\n }\n\n /** Removes and returns the first source with this name. Call {@link Caching.clear} to reload assets. */\n public static removeSource(key: string): Maybe<AssetSource> {\n const index = this._SOURCES.findIndex(s => s.key === key);\n if (index != -1) {\n const spliced = this._SOURCES.splice(index, 1);\n if (spliced.length > 0) {\n return spliced[0].source;\n }\n }\n return undefined;\n }\n\n /** Loads from all sources and returns defined results in priority order. Any source failure rejects the call. */\n public static async getAll<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser | string): Promise<T[]> {\n const sources = [...this._SOURCES];\n const results: T[] = [];\n for (const { source } of sources) {\n const asset = await source.get<T>(key, parser);\n if (asset != undefined) results.push(asset);\n if (await source.blocks(key)) break;\n }\n return results;\n }\n\n /** Returns the first defined result in source-priority order, without merging assets. */\n public static async get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser | string): Promise<Maybe<T>> {\n const keys = [key];\n if (key.rootType === \"data\" && (key.assetType === \"structure\" || key.assetType === \"structures\")) {\n keys.push(new AssetKey(key.namespace, key.path,\n key.assetType === \"structure\" ? \"structures\" : \"structure\",\n key.type, key.rootType, key.extension, key.root));\n }\n return (await this.getFirst<T>(keys, parser))?.asset;\n }\n\n /** Tries each path within a source before considering lower-priority sources. */\n public static async getFirst<T extends MinecraftAsset>(keys: readonly AssetKey[], parser: AssetParser | string): Promise<Maybe<{ key: AssetKey; asset: T }>> {\n // Source changes affect later lookups, not the priority of an in-flight lookup.\n const sources = [...this._SOURCES];\n let remaining = [...keys];\n for (const source of sources) {\n for (const key of remaining) {\n const result = await source.source.get<T>(key, parser);\n if (result !== undefined) {\n return { key, asset: result };\n }\n }\n const blocked = await Promise.all(remaining.map(key => source.source.blocks(key)));\n remaining = remaining.filter((_, index) => !blocked[index]);\n if (!remaining.length) break;\n }\n return undefined;\n }\n\n}\n\ninterface AssetSourceReference {\n key: string;\n source: AssetSource;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/assets/AssetLoader.ts"],"sourcesContent":["import { Model, TextureAsset } from \"../model/Model\";\nimport { Maybe } from \"../util/util\";\nimport { Requests } from \"../request/Requests\";\nimport { MinecraftAsset } from \"../MinecraftAsset\";\nimport { ImageInfo, ImageLoader } from \"../image/ImageLoader\";\nimport { MinecraftTextureMeta } from \"../MinecraftTextureMeta\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { DEFAULT_NAMESPACE, DEFAULT_ROOT } from \"./AssetDefaults\";\nimport { ListAsset } from \"../ListAsset\";\nimport { AssetKey } from \"./AssetKey\";\nimport { NBTAsset, NBTHelper } from \"../nbt/NBTHelper\";\nimport { prefix } from \"../util/log\";\nimport { AssetSource } from \"./source/AssetSource\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { HostedAssetSource } from \"./source\";\nimport { Caching } from \"../cache/Caching\";\n\nconst p = prefix(\"AssetLoader\");\n\n\n/** Loads assets from a shared, ordered registry of hosted sources and resource packs. */\nexport class AssetLoader {\n\n /** Default asset base URL. Use {@link setVersion} to select a Minecraft version. */\n static ROOT: string = DEFAULT_ROOT;\n\n private static sources: AssetSourceReference[] | undefined;\n\n private static get _SOURCES(): AssetSourceReference[] {\n return this.sources ??= [{ key: \"mcassets\", source: new HostedAssetSource(this.ROOT, { retryDefaults: false }) }];\n }\n\n private static set _SOURCES(sources: AssetSourceReference[]) {\n this.sources = sources;\n }\n\n /** Used when a registered source cannot identify its content, so nothing persists past this session. */\n private static readonly SESSION_SCOPE = `session:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;\n\n public static get version(): string {\n return this.ROOT.substring(this.ROOT.lastIndexOf(\"/\") + 1);\n }\n\n /** Selects an mcasset.cloud version, updates the vanilla source, and clears in-memory caches. */\n public static setVersion(version: string): void {\n this.ROOT = `https://assets.mcasset.cloud/${version}`;\n const source = new HostedAssetSource(this.ROOT, { retryDefaults: false });\n const index = this._SOURCES.findIndex(s => s.key === \"mcassets\");\n if (index !== -1) {\n this._SOURCES[index] = { key: \"mcassets\", source };\n } else {\n this.addSource(\"mcassets\", source);\n }\n Caching.clear();\n }\n\n /**\n * Scope for persistent cache keys. Empty with only the default vanilla source, so its\n * entries stay valid across sessions; otherwise it names every added source (resource packs,\n * mirrors) so their results never masquerade as vanilla assets after a reload.\n */\n public static get persistentScope(): string {\n const parts: string[] = [];\n for (const { key, source } of this._SOURCES) {\n const id = source.cacheId;\n if (key === \"mcassets\" && id === `hosted:${this.ROOT}`) continue;\n if (id === undefined) return this.SESSION_SCOPE;\n parts.push(`${key}=${id}`);\n }\n return parts.join(\"|\");\n }\n\n /** Prefixes a persistent cache key with the current source scope. */\n public static persistentKey(key: string): string {\n const scope = this.persistentScope;\n return scope ? `${scope}\\n${key}` : key;\n }\n\n /**\n * Registers a source at the highest priority.\n * Call {@link Caching.clear} after changing sources to discard previously loaded assets.\n *\n * @param key - Name used to replace or remove this source.\n * @param override - Removes the first source with this name before adding the new one.\n */\n public static addSource(key: string, source: AssetSource, override: boolean = true) {\n if (override) {\n const existing = this.removeSource(key);\n if (existing) {\n console.log(p, \"Removed existing AssetSource\", key);\n }\n }\n\n this._SOURCES.unshift({key, source});\n console.log(p, \"Added AssetSource\", key);\n }\n\n /** Removes and returns the first source with this name. Call {@link Caching.clear} to reload assets. */\n public static removeSource(key: string): Maybe<AssetSource> {\n const index = this._SOURCES.findIndex(s => s.key === key);\n if (index != -1) {\n const spliced = this._SOURCES.splice(index, 1);\n if (spliced.length > 0) {\n return spliced[0].source;\n }\n }\n return undefined;\n }\n\n /** Loads from all sources and returns defined results in priority order. Any source failure rejects the call. */\n public static async getAll<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser | string): Promise<T[]> {\n const sources = [...this._SOURCES];\n const results: T[] = [];\n for (const { source } of sources) {\n const asset = await source.get<T>(key, parser);\n if (asset != undefined) results.push(asset);\n if (await source.blocks(key)) break;\n }\n return results;\n }\n\n /** Returns the first defined result in source-priority order, without merging assets. */\n public static async get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser | string): Promise<Maybe<T>> {\n const keys = [key];\n if (key.rootType === \"data\" && (key.assetType === \"structure\" || key.assetType === \"structures\")) {\n keys.push(new AssetKey(key.namespace, key.path,\n key.assetType === \"structure\" ? \"structures\" : \"structure\",\n key.type, key.rootType, key.extension, key.root));\n }\n return (await this.getFirst<T>(keys, parser))?.asset;\n }\n\n /** Tries each path within a source before considering lower-priority sources. */\n public static async getFirst<T extends MinecraftAsset>(keys: readonly AssetKey[], parser: AssetParser | string): Promise<Maybe<{ key: AssetKey; asset: T }>> {\n // Source changes affect later lookups, not the priority of an in-flight lookup.\n const sources = [...this._SOURCES];\n let remaining = [...keys];\n for (const source of sources) {\n for (const key of remaining) {\n const result = await source.source.get<T>(key, parser);\n if (result !== undefined) {\n return { key, asset: result };\n }\n }\n const blocked = await Promise.all(remaining.map(key => source.source.blocks(key)));\n remaining = remaining.filter((_, index) => !blocked[index]);\n if (!remaining.length) break;\n }\n return undefined;\n }\n\n}\n\ninterface AssetSourceReference {\n key: string;\n source: AssetSource;\n}\n"],"mappings":"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","names":[]}
@@ -2,8 +2,6 @@
2
2
  import { Models } from "./Models.mjs";
3
3
  import { BlockStates } from "./BlockStates.mjs";
4
4
  import { AssetKey } from "./AssetKey.mjs";
5
- var DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
6
- var DEFAULT_NAMESPACE = "minecraft";
7
5
  var Assets = class {
8
6
  /**
9
7
  * @deprecated
@@ -21,8 +19,6 @@ var Assets = class {
21
19
  }
22
20
  };
23
21
  export {
24
- Assets,
25
- DEFAULT_NAMESPACE,
26
- DEFAULT_ROOT
22
+ Assets
27
23
  };
28
24
  //# sourceMappingURL=Assets.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/assets/Assets.ts"],"sourcesContent":["import { Models } from \"./Models\";\nimport { Model } from \"../model/Model\";\nimport { Maybe } from \"../util/util\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { BlockStates } from \"./BlockStates\";\nimport { AssetKey, AssetType } from \"./AssetKey\";\n\nexport const DEFAULT_ROOT = \"https://assets.mcasset.cloud/1.21.11\";\nexport const DEFAULT_NAMESPACE = \"minecraft\";\n\n/** Convenience accessors for model and blockstate loading. */\nexport class Assets {\n\n /**\n * @deprecated\n */\n public static parseAssetKey(assetType: AssetType, str: string, origin?: AssetKey): AssetKey {\n return AssetKey.parse(assetType, str, origin);\n }\n\n /** Loads a model with its parent chain resolved. See {@link Models.getMerged}. */\n public static async getModel(key: AssetKey): Promise<Maybe<Model>> {\n return Models.getMerged(key);\n }\n\n /** Loads a blockstate definition. See {@link BlockStates.get}. */\n public static async getBlockState(key: AssetKey): Promise<Maybe<BlockState>> {\n return BlockStates.get(key);\n }\n\n}\n"],"mappings":";AAAA,SAAS,cAAc;AAIvB,SAAS,mBAAmB;AAC5B,SAAS,gBAA2B;AAE7B,IAAM,eAAe;AACrB,IAAM,oBAAoB;AAG1B,IAAM,SAAN,MAAa;AAAA;AAAA;AAAA;AAAA,EAKhB,OAAc,cAAc,WAAsB,KAAa,QAA6B;AACxF,WAAO,SAAS,MAAM,WAAW,KAAK,MAAM;AAAA,EAChD;AAAA;AAAA,EAGA,aAAoB,SAAS,KAAsC;AAC/D,WAAO,OAAO,UAAU,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,aAAoB,cAAc,KAA2C;AACzE,WAAO,YAAY,IAAI,GAAG;AAAA,EAC9B;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/assets/Assets.ts"],"sourcesContent":["import { Models } from \"./Models\";\nimport { Model } from \"../model/Model\";\nimport { Maybe } from \"../util/util\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { BlockStates } from \"./BlockStates\";\nimport { AssetKey, AssetType } from \"./AssetKey\";\n\n/** Convenience accessors for model and blockstate loading. */\nexport class Assets {\n\n /**\n * @deprecated\n */\n public static parseAssetKey(assetType: AssetType, str: string, origin?: AssetKey): AssetKey {\n return AssetKey.parse(assetType, str, origin);\n }\n\n /** Loads a model with its parent chain resolved. See {@link Models.getMerged}. */\n public static async getModel(key: AssetKey): Promise<Maybe<Model>> {\n return Models.getMerged(key);\n }\n\n /** Loads a blockstate definition. See {@link BlockStates.get}. */\n public static async getBlockState(key: AssetKey): Promise<Maybe<BlockState>> {\n return BlockStates.get(key);\n }\n\n}\n"],"mappings":";AAAA,SAAS,cAAc;AAIvB,SAAS,mBAAmB;AAC5B,SAAS,gBAA2B;AAG7B,IAAM,SAAN,MAAa;AAAA;AAAA;AAAA;AAAA,EAKhB,OAAc,cAAc,WAAsB,KAAa,QAA6B;AACxF,WAAO,SAAS,MAAM,WAAW,KAAK,MAAM;AAAA,EAChD;AAAA;AAAA,EAGA,aAAoB,SAAS,KAAsC;AAC/D,WAAO,OAAO,UAAU,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,aAAoB,cAAc,KAA2C;AACzE,WAAO,YAAY,IAAI,GAAG;AAAA,EAC9B;AAEJ;","names":[]}
@@ -1,7 +1,7 @@
1
1
  // src/assets/BlockStates.ts
2
2
  import { Caching } from "../cache/Caching.mjs";
3
3
  import { AssetLoader } from "./AssetLoader.mjs";
4
- import { DEFAULT_NAMESPACE } from "./Assets.mjs";
4
+ import { DEFAULT_NAMESPACE } from "./AssetDefaults.mjs";
5
5
  import { AssetKey } from "./AssetKey.mjs";
6
6
  import { PersistentCache } from "../cache/PersistentCache.mjs";
7
7
  import { AssetParser } from "./source/parser/AssetParsers.mjs";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/assets/BlockStates.ts"],"sourcesContent":["import { Maybe } from \"../util/util\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { Caching } from \"../cache/Caching\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"./Assets\";\nimport { BlockStatePropertyDefaults } from \"../model/block/BlockStateProperties\";\nimport { AssetKey } from \"./AssetKey\";\nimport { PersistentCache } from \"../cache/PersistentCache\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { ListAsset } from \"../ListAsset\";\nimport { MinecraftAsset } from \"../MinecraftAsset\";\nimport { Renames } from \"./Renames\";\nimport { MineRenderData } from \"./MineRenderData\";\n\n/** Loads blockstate definitions and the property defaults used to select block models. */\nexport class BlockStates {\n\n private static _persistentCache: PersistentCache | undefined;\n\n private static get PERSISTENT_CACHE(): PersistentCache {\n return this._persistentCache ??= PersistentCache.open(\"minerender-blockstates\");\n }\n\n // BlockState names are hardcoded\n /** Returns blockstate filenames from the selected version's `_list.json`, or an empty list. */\n public static async getList(): Promise<string[]> {\n const key = new AssetKey(\n DEFAULT_NAMESPACE,\n \"_list\",\n \"blockstates\",\n undefined,\n \"assets\",\n \".json\",\n AssetLoader.ROOT\n );\n return Caching.listAssetCache.get(key.serialize(), () => {\n return AssetLoader.get<ListAsset>(key, AssetParser.LIST);\n }).then(r => r?.files ?? []);\n }\n\n public static async getDefaultStates(root?: string): Promise<Maybe<DefaultBlockStates>> {\n return MineRenderData.get(\"blockStates\", root);\n }\n\n /** Looks up vanilla property definitions for the key's block path, or returns `undefined`. */\n public static async getDefaultState(key: AssetKey): Promise<Maybe<BlockStatePropertyDefaults>> {\n const defaultStates = await this.getDefaultStates(key.root);\n if (!defaultStates) {\n return undefined;\n }\n return defaultStates[key.toNamespacedString()] as BlockStatePropertyDefaults;\n }\n\n /** Loads a cached blockstate definition for {@link MineRenderScene.addBlock}, or returns `undefined`. */\n public static async get(key: AssetKey): Promise<Maybe<BlockState>> {\n if (!key.assetType) {\n key.assetType = \"blockstates\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n // An ID from an older version loads its replacement. The registry fallback can select a table\n // newer than the assets, so a missing replacement keeps the original ID.\n const renamed = await Renames.key(\"blocks\", key);\n const replacement = renamed && await this.get(renamed);\n if (replacement) return replacement;\n const keyStr = key.serialize();\n return Caching.blockStateCache.get(keyStr, k => {\n return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), k1 => {\n return AssetLoader.get<BlockState>(key, AssetParser.BLOCKSTATE);\n })\n }).then(asset => {\n if (asset) {\n asset.key = key;\n }\n return asset;\n })\n }\n\n public static getAll(keys: AssetKey[] | Iterable<AssetKey>): Promise<Maybe<BlockState>[]> {\n const promises: Promise<Maybe<BlockState>>[] = [];\n for (let key of keys) {\n promises.push(this.get(key));\n }\n return Promise.all(promises);\n }\n\n /** Clears persisted blockstates. Use {@link Caching.clear} to also discard in-memory assets. */\n public static async clearCache() {\n await this.PERSISTENT_CACHE.clear();\n }\n\n}\n\nexport class DefaultBlockStates implements MinecraftAsset {\n [k: string]: BlockStatePropertyDefaults;\n}\n"],"mappings":";AAEA,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAElC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAG5B,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAGxB,IAAM,cAAN,MAAkB;AAAA,EAIrB,WAAmB,mBAAoC;AACnD,WAAO,KAAK,qBAAL,KAAK,mBAAqB,gBAAgB,KAAK,wBAAwB;AAAA,EAClF;AAAA;AAAA;AAAA,EAIA,aAAoB,UAA6B;AAC7C,UAAM,MAAM,IAAI;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IAChB;AACA,WAAO,QAAQ,eAAe,IAAI,IAAI,UAAU,GAAG,MAAM;AACrD,aAAO,YAAY,IAAe,KAAK,YAAY,IAAI;AAAA,IAC3D,CAAC,EAAE,KAAK,OAAK,GAAG,SAAS,CAAC,CAAC;AAAA,EAC/B;AAAA,EAEA,aAAoB,iBAAiB,MAAmD;AACpF,WAAO,eAAe,IAAI,eAAe,IAAI;AAAA,EACjD;AAAA;AAAA,EAGA,aAAoB,gBAAgB,KAA2D;AAC3F,UAAM,gBAAgB,MAAM,KAAK,iBAAiB,IAAI,IAAI;AAC1D,QAAI,CAAC,eAAe;AAChB,aAAO;AAAA,IACX;AACA,WAAO,cAAc,IAAI,mBAAmB,CAAC;AAAA,EACjD;AAAA;AAAA,EAGA,aAAoB,IAAI,KAA2C;AAC/D,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AACA,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AAGA,UAAM,UAAU,MAAM,QAAQ,IAAI,UAAU,GAAG;AAC/C,UAAM,cAAc,WAAW,MAAM,KAAK,IAAI,OAAO;AACrD,QAAI,YAAa,QAAO;AACxB,UAAM,SAAS,IAAI,UAAU;AAC7B,WAAO,QAAQ,gBAAgB,IAAI,QAAQ,OAAK;AAC5C,aAAO,KAAK,iBAAiB,UAAU,YAAY,cAAc,MAAM,GAAG,QAAM;AAC5E,eAAO,YAAY,IAAgB,KAAK,YAAY,UAAU;AAAA,MAClE,CAAC;AAAA,IACL,CAAC,EAAE,KAAK,WAAS;AACb,UAAI,OAAO;AACP,cAAM,MAAM;AAAA,MAChB;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,OAAc,OAAO,MAAqE;AACtF,UAAM,WAAyC,CAAC;AAChD,aAAS,OAAO,MAAM;AAClB,eAAS,KAAK,KAAK,IAAI,GAAG,CAAC;AAAA,IAC/B;AACA,WAAO,QAAQ,IAAI,QAAQ;AAAA,EAC/B;AAAA;AAAA,EAGA,aAAoB,aAAa;AAC7B,UAAM,KAAK,iBAAiB,MAAM;AAAA,EACtC;AAEJ;AAEO,IAAM,qBAAN,MAAmD;AAE1D;","names":[]}
1
+ {"version":3,"sources":["../../../../src/assets/BlockStates.ts"],"sourcesContent":["import { Maybe } from \"../util/util\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { Caching } from \"../cache/Caching\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"./AssetDefaults\";\nimport { BlockStatePropertyDefaults } from \"../model/block/BlockStateProperties\";\nimport { AssetKey } from \"./AssetKey\";\nimport { PersistentCache } from \"../cache/PersistentCache\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { ListAsset } from \"../ListAsset\";\nimport { MinecraftAsset } from \"../MinecraftAsset\";\nimport { Renames } from \"./Renames\";\nimport { MineRenderData } from \"./MineRenderData\";\n\n/** Loads blockstate definitions and the property defaults used to select block models. */\nexport class BlockStates {\n\n private static _persistentCache: PersistentCache | undefined;\n\n private static get PERSISTENT_CACHE(): PersistentCache {\n return this._persistentCache ??= PersistentCache.open(\"minerender-blockstates\");\n }\n\n // BlockState names are hardcoded\n /** Returns blockstate filenames from the selected version's `_list.json`, or an empty list. */\n public static async getList(): Promise<string[]> {\n const key = new AssetKey(\n DEFAULT_NAMESPACE,\n \"_list\",\n \"blockstates\",\n undefined,\n \"assets\",\n \".json\",\n AssetLoader.ROOT\n );\n return Caching.listAssetCache.get(key.serialize(), () => {\n return AssetLoader.get<ListAsset>(key, AssetParser.LIST);\n }).then(r => r?.files ?? []);\n }\n\n public static async getDefaultStates(root?: string): Promise<Maybe<DefaultBlockStates>> {\n return MineRenderData.get(\"blockStates\", root);\n }\n\n /** Looks up vanilla property definitions for the key's block path, or returns `undefined`. */\n public static async getDefaultState(key: AssetKey): Promise<Maybe<BlockStatePropertyDefaults>> {\n const defaultStates = await this.getDefaultStates(key.root);\n if (!defaultStates) {\n return undefined;\n }\n return defaultStates[key.toNamespacedString()] as BlockStatePropertyDefaults;\n }\n\n /** Loads a cached blockstate definition for {@link MineRenderScene.addBlock}, or returns `undefined`. */\n public static async get(key: AssetKey): Promise<Maybe<BlockState>> {\n if (!key.assetType) {\n key.assetType = \"blockstates\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n // An ID from an older version loads its replacement. The registry fallback can select a table\n // newer than the assets, so a missing replacement keeps the original ID.\n const renamed = await Renames.key(\"blocks\", key);\n const replacement = renamed && await this.get(renamed);\n if (replacement) return replacement;\n const keyStr = key.serialize();\n return Caching.blockStateCache.get(keyStr, k => {\n return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), k1 => {\n return AssetLoader.get<BlockState>(key, AssetParser.BLOCKSTATE);\n })\n }).then(asset => {\n if (asset) {\n asset.key = key;\n }\n return asset;\n })\n }\n\n public static getAll(keys: AssetKey[] | Iterable<AssetKey>): Promise<Maybe<BlockState>[]> {\n const promises: Promise<Maybe<BlockState>>[] = [];\n for (let key of keys) {\n promises.push(this.get(key));\n }\n return Promise.all(promises);\n }\n\n /** Clears persisted blockstates. Use {@link Caching.clear} to also discard in-memory assets. */\n public static async clearCache() {\n await this.PERSISTENT_CACHE.clear();\n }\n\n}\n\nexport class DefaultBlockStates implements MinecraftAsset {\n [k: string]: BlockStatePropertyDefaults;\n}\n"],"mappings":";AAEA,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAElC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAG5B,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAGxB,IAAM,cAAN,MAAkB;AAAA,EAIrB,WAAmB,mBAAoC;AACnD,WAAO,KAAK,qBAAL,KAAK,mBAAqB,gBAAgB,KAAK,wBAAwB;AAAA,EAClF;AAAA;AAAA;AAAA,EAIA,aAAoB,UAA6B;AAC7C,UAAM,MAAM,IAAI;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IAChB;AACA,WAAO,QAAQ,eAAe,IAAI,IAAI,UAAU,GAAG,MAAM;AACrD,aAAO,YAAY,IAAe,KAAK,YAAY,IAAI;AAAA,IAC3D,CAAC,EAAE,KAAK,OAAK,GAAG,SAAS,CAAC,CAAC;AAAA,EAC/B;AAAA,EAEA,aAAoB,iBAAiB,MAAmD;AACpF,WAAO,eAAe,IAAI,eAAe,IAAI;AAAA,EACjD;AAAA;AAAA,EAGA,aAAoB,gBAAgB,KAA2D;AAC3F,UAAM,gBAAgB,MAAM,KAAK,iBAAiB,IAAI,IAAI;AAC1D,QAAI,CAAC,eAAe;AAChB,aAAO;AAAA,IACX;AACA,WAAO,cAAc,IAAI,mBAAmB,CAAC;AAAA,EACjD;AAAA;AAAA,EAGA,aAAoB,IAAI,KAA2C;AAC/D,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AACA,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AAGA,UAAM,UAAU,MAAM,QAAQ,IAAI,UAAU,GAAG;AAC/C,UAAM,cAAc,WAAW,MAAM,KAAK,IAAI,OAAO;AACrD,QAAI,YAAa,QAAO;AACxB,UAAM,SAAS,IAAI,UAAU;AAC7B,WAAO,QAAQ,gBAAgB,IAAI,QAAQ,OAAK;AAC5C,aAAO,KAAK,iBAAiB,UAAU,YAAY,cAAc,MAAM,GAAG,QAAM;AAC5E,eAAO,YAAY,IAAgB,KAAK,YAAY,UAAU;AAAA,MAClE,CAAC;AAAA,IACL,CAAC,EAAE,KAAK,WAAS;AACb,UAAI,OAAO;AACP,cAAM,MAAM;AAAA,MAChB;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,OAAc,OAAO,MAAqE;AACtF,UAAM,WAAyC,CAAC;AAChD,aAAS,OAAO,MAAM;AAClB,eAAS,KAAK,KAAK,IAAI,GAAG,CAAC;AAAA,IAC/B;AACA,WAAO,QAAQ,IAAI,QAAQ;AAAA,EAC/B;AAAA;AAAA,EAGA,aAAoB,aAAa;AAC7B,UAAM,KAAK,iBAAiB,MAAM;AAAA,EACtC;AAEJ;AAEO,IAAM,qBAAN,MAAmD;AAE1D;","names":[]}
@@ -3,7 +3,7 @@ import { AssetKey, isAssetKey } from "./AssetKey.mjs";
3
3
  import { AssetLoader } from "./AssetLoader.mjs";
4
4
  import { AssetParser } from "./source/index.mjs";
5
5
  import { Caching } from "../cache/Caching.mjs";
6
- import { DEFAULT_NAMESPACE } from "./Assets.mjs";
6
+ import { DEFAULT_NAMESPACE } from "./AssetDefaults.mjs";
7
7
  import { MineRenderError } from "../error/MineRenderError.mjs";
8
8
  import { ModelTextures } from "./ModelTextures.mjs";
9
9
  var Entities = class {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/assets/Entities.ts"],"sourcesContent":["import { AssetKey, BasicAssetKey, isAssetKey } from \"./AssetKey\";\nimport type { EntityLayer, EntityModel, EntityModelFile, EntityModelPass } from \"../entity/EntityModel\";\nimport type { EntityAnimation, EntityAnimationFile } from \"../entity/EntityAnimation\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { AssetParser } from \"./source\";\nimport { Maybe } from \"../util\";\nimport { Caching } from \"../cache/Caching\";\nimport { DEFAULT_NAMESPACE } from \"./Assets\";\nimport type { ListAsset } from \"../ListAsset\";\nimport { MineRenderError } from \"../error/MineRenderError\";\nimport { ModelTextures } from \"./ModelTextures\";\nimport type { MinecraftAsset } from \"../MinecraftAsset\";\n\n/** Loads entity and block-entity geometry, texture selections, and animation clips from the dataset. */\nexport class Entities {\n\n /** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */\n public static async getEntityList(): Promise<string[]> {\n const collect = async (path: string): Promise<string[]> => {\n const prefix = path ? `${path}/` : \"\";\n const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix}_list`, undefined, undefined, \"entity-models\", \".json\");\n const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get<ListAsset>(key, AssetParser.LIST));\n if (!list) return [];\n const files = list.files.filter(file => file.endsWith(\".json\") && file !== \"_list.json\")\n .map(file => `${prefix}${file.slice(0, -5)}`);\n const children = await Promise.all(list.directories.map(directory => collect(`${prefix}${directory}`)));\n return [...files, ...children.flat()];\n };\n return collect(\"\");\n }\n\n private static async getModelFile(modelKey: BasicAssetKey): Promise<Maybe<EntityModelFile>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models\", \".json\", isAssetKey(modelKey) ? modelKey.root : undefined);\n return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get<EntityModelFile>(key, AssetParser.JSON));\n }\n\n /** Returns selectable geometry-layer names, or an empty list when the model is missing. */\n public static async getLayerList(modelKey: BasicAssetKey): Promise<string[]> {\n return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});\n }\n\n /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */\n public static async getPassList(modelKey: BasicAssetKey): Promise<EntityModelPass[]> {\n return (await this.getModelFile(modelKey))?.passes ?? [];\n }\n\n /**\n * Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.\n * By default, selects `main`, unconditional passes, and passes enabled by `options.when`.\n *\n * @param modelKey - Dataset model, such as `new BasicAssetKey(\"minecraft\", \"zombie\")`.\n * @param textureKey - Texture override for the first selected layer.\n * @param options - Layer selection, conditional passes, and per-layer texture overrides.\n * @returns The selected model, or `undefined` when its dataset file is missing.\n */\n public static async getEntity(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>> {\n const model = await this.getModelFile(modelKey);\n if (!model) return undefined;\n // Without an explicit selection, draw what vanilla draws: main, then the passes enabled for the requested state.\n const passes = options?.layers || options?.layer !== undefined ? [] :\n (model.passes ?? []).filter(pass => pass.when === undefined || options?.when?.includes(pass.when));\n const draws: EntityModelPass[] = [...new Set(options?.layers ?? [options?.layer ?? \"main\"])].map(layer => ({ layer }));\n if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);\n draws.push(...passes);\n const names: string[] = [];\n const selected = draws.map(pass => {\n const layer = model.layers[pass.layer];\n if (!layer) {\n throw new MineRenderError(`Entity ${model.id} has no layer \"${pass.layer}\". Available layers: ${Object.keys(model.layers).join(\", \")}`);\n }\n // A pass may draw geometry that is already selected with another texture.\n let name = pass.layer;\n for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;\n names.push(name);\n return { name, layer, pass };\n });\n const layers: Record<string, EntityLayer> = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {\n const override = options?.textures?.[name] ?? (index === 0 ? textureKey : undefined);\n const textureLocation = pass.textureLocation ?? layer.textureLocation;\n let texture: Maybe<AssetKey>;\n if (override) {\n const path = isAssetKey(override) ? override.getFullPath() : override.path;\n texture = isAssetKey(override) && override.assetType === \"textures\" && path.startsWith(\"entity/\")\n ? override\n : new AssetKey(override.namespace, path, \"textures\", \"entity\", \"assets\", \".png\", isAssetKey(override) ? override.root : undefined);\n } else if (textureLocation !== undefined) {\n texture = AssetKey.parse(\"textures\", textureLocation.replace(/^([^:]+:)?textures\\//, \"$1\"));\n if (isAssetKey(modelKey)) texture.root = modelKey.root;\n } else {\n texture = await this.resolveTexture(modelKey);\n }\n const render = pass.render ?? layer.render;\n return [name, { key: override ?? modelKey, texture, layer, ...(render && { render }), ...(pass.tint && { tint: pass.tint }) }];\n })));\n return { ...layers[names[0]], id: model.id, layers, ...(model.transform && { transform: model.transform }) };\n }\n\n /**\n * Native and sampled vanilla clips by name, or undefined when the model or selected version has none.\n */\n public static async getAnimations(modelKey: BasicAssetKey): Promise<Maybe<Record<string, EntityAnimation>>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models/animations\", \".json\", isAssetKey(modelKey) ? modelKey.root : undefined);\n const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get<EntityAnimationFile>(key, AssetParser.JSON));\n return file?.animations;\n }\n\n /** Finds a fallback texture using the model path, its directory, and vanilla variant data. */\n public static async resolveTexture(modelKey: BasicAssetKey): Promise<Maybe<AssetKey>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const root = isAssetKey(modelKey) ? modelKey.root : undefined;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models\", \".json\", root);\n return Caching.entityTextureCache.get(key.serialize(), async () => {\n const name = path.split(\"/\").pop()!;\n for (const candidate of [path, `${path}/${name}`]) {\n const texture = new AssetKey(modelKey.namespace, candidate, \"textures\", \"entity\", \"assets\", \".png\", root);\n if (await ModelTextures.get(texture)) return texture;\n }\n const listKey = new AssetKey(modelKey.namespace, \"_list\", `${name}_variant`, undefined, \"data\", \".json\", root);\n const list = await AssetLoader.get<ListAsset>(listKey, AssetParser.LIST);\n const files = list?.files.filter(file => file.endsWith(\".json\") && file !== \"_list.json\");\n const file = files?.find(file => file === \"temperate.json\") ?? files?.[0];\n if (!file) return undefined;\n const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, undefined, \"data\", \".json\", root);\n const variant = await AssetLoader.get<EntityVariant>(variantKey, AssetParser.JSON);\n const assets = variant?.assets;\n const textureId = variant?.asset_id ?? (typeof assets?.wild === \"string\" ? assets.wild :\n Object.values(assets ?? {}).find(value => typeof value === \"string\"));\n if (typeof textureId !== \"string\") return undefined;\n const texture = AssetKey.parse(\"textures\", textureId);\n texture.root = root;\n return texture;\n });\n }\n\n /** @deprecated Use getEntityList(); block entities share the entity dataset. */\n public static getBlockList(): Promise<string[]> {\n return this.getEntityList();\n }\n\n /** @deprecated Use getEntity(); block entities share the entity dataset. */\n public static getBlock(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>> {\n return this.getEntity(modelKey, textureKey, options);\n }\n\n}\n\n/** Selection settings passed as the third argument to {@link Entities.getEntity}. */\nexport interface EntityModelOptions {\n /** Selects one geometry layer without dataset passes. `layers` takes precedence when supplied. */\n layer?: string;\n /** Layer names in draw order; an explicit selection draws exactly these layers and no dataset passes. */\n layers?: string[];\n /**\n * Entity states that enable the dataset's conditional passes, e.g. `[\"powered\"]` for a charged creeper.\n * Without `layer`/`layers`, `main` and every unconditional pass are always drawn.\n */\n when?: string[];\n /** Per-layer texture overrides, keyed like `EntityModel.layers`. The positional texture key applies to the first selected layer. */\n textures?: Record<string, BasicAssetKey>;\n}\n\ninterface EntityVariant extends MinecraftAsset {\n asset_id?: string;\n assets?: Record<string, unknown>;\n}\n"],"mappings":"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","names":["texture","file"]}
1
+ {"version":3,"sources":["../../../../src/assets/Entities.ts"],"sourcesContent":["import { AssetKey, BasicAssetKey, isAssetKey } from \"./AssetKey\";\nimport type { EntityLayer, EntityModel, EntityModelFile, EntityModelPass } from \"../entity/EntityModel\";\nimport type { EntityAnimation, EntityAnimationFile } from \"../entity/EntityAnimation\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { AssetParser } from \"./source\";\nimport { Maybe } from \"../util\";\nimport { Caching } from \"../cache/Caching\";\nimport { DEFAULT_NAMESPACE } from \"./AssetDefaults\";\nimport type { ListAsset } from \"../ListAsset\";\nimport { MineRenderError } from \"../error/MineRenderError\";\nimport { ModelTextures } from \"./ModelTextures\";\nimport type { MinecraftAsset } from \"../MinecraftAsset\";\n\n/** Loads entity and block-entity geometry, texture selections, and animation clips from the dataset. */\nexport class Entities {\n\n /** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */\n public static async getEntityList(): Promise<string[]> {\n const collect = async (path: string): Promise<string[]> => {\n const prefix = path ? `${path}/` : \"\";\n const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix}_list`, undefined, undefined, \"entity-models\", \".json\");\n const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get<ListAsset>(key, AssetParser.LIST));\n if (!list) return [];\n const files = list.files.filter(file => file.endsWith(\".json\") && file !== \"_list.json\")\n .map(file => `${prefix}${file.slice(0, -5)}`);\n const children = await Promise.all(list.directories.map(directory => collect(`${prefix}${directory}`)));\n return [...files, ...children.flat()];\n };\n return collect(\"\");\n }\n\n private static async getModelFile(modelKey: BasicAssetKey): Promise<Maybe<EntityModelFile>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models\", \".json\", isAssetKey(modelKey) ? modelKey.root : undefined);\n return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get<EntityModelFile>(key, AssetParser.JSON));\n }\n\n /** Returns selectable geometry-layer names, or an empty list when the model is missing. */\n public static async getLayerList(modelKey: BasicAssetKey): Promise<string[]> {\n return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});\n }\n\n /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */\n public static async getPassList(modelKey: BasicAssetKey): Promise<EntityModelPass[]> {\n return (await this.getModelFile(modelKey))?.passes ?? [];\n }\n\n /**\n * Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.\n * By default, selects `main`, unconditional passes, and passes enabled by `options.when`.\n *\n * @param modelKey - Dataset model, such as `new BasicAssetKey(\"minecraft\", \"zombie\")`.\n * @param textureKey - Texture override for the first selected layer.\n * @param options - Layer selection, conditional passes, and per-layer texture overrides.\n * @returns The selected model, or `undefined` when its dataset file is missing.\n */\n public static async getEntity(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>> {\n const model = await this.getModelFile(modelKey);\n if (!model) return undefined;\n // Without an explicit selection, draw what vanilla draws: main, then the passes enabled for the requested state.\n const passes = options?.layers || options?.layer !== undefined ? [] :\n (model.passes ?? []).filter(pass => pass.when === undefined || options?.when?.includes(pass.when));\n const draws: EntityModelPass[] = [...new Set(options?.layers ?? [options?.layer ?? \"main\"])].map(layer => ({ layer }));\n if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);\n draws.push(...passes);\n const names: string[] = [];\n const selected = draws.map(pass => {\n const layer = model.layers[pass.layer];\n if (!layer) {\n throw new MineRenderError(`Entity ${model.id} has no layer \"${pass.layer}\". Available layers: ${Object.keys(model.layers).join(\", \")}`);\n }\n // A pass may draw geometry that is already selected with another texture.\n let name = pass.layer;\n for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;\n names.push(name);\n return { name, layer, pass };\n });\n const layers: Record<string, EntityLayer> = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {\n const override = options?.textures?.[name] ?? (index === 0 ? textureKey : undefined);\n const textureLocation = pass.textureLocation ?? layer.textureLocation;\n let texture: Maybe<AssetKey>;\n if (override) {\n const path = isAssetKey(override) ? override.getFullPath() : override.path;\n texture = isAssetKey(override) && override.assetType === \"textures\" && path.startsWith(\"entity/\")\n ? override\n : new AssetKey(override.namespace, path, \"textures\", \"entity\", \"assets\", \".png\", isAssetKey(override) ? override.root : undefined);\n } else if (textureLocation !== undefined) {\n texture = AssetKey.parse(\"textures\", textureLocation.replace(/^([^:]+:)?textures\\//, \"$1\"));\n if (isAssetKey(modelKey)) texture.root = modelKey.root;\n } else {\n texture = await this.resolveTexture(modelKey);\n }\n const render = pass.render ?? layer.render;\n return [name, { key: override ?? modelKey, texture, layer, ...(render && { render }), ...(pass.tint && { tint: pass.tint }) }];\n })));\n return { ...layers[names[0]], id: model.id, layers, ...(model.transform && { transform: model.transform }) };\n }\n\n /**\n * Native and sampled vanilla clips by name, or undefined when the model or selected version has none.\n */\n public static async getAnimations(modelKey: BasicAssetKey): Promise<Maybe<Record<string, EntityAnimation>>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models/animations\", \".json\", isAssetKey(modelKey) ? modelKey.root : undefined);\n const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get<EntityAnimationFile>(key, AssetParser.JSON));\n return file?.animations;\n }\n\n /** Finds a fallback texture using the model path, its directory, and vanilla variant data. */\n public static async resolveTexture(modelKey: BasicAssetKey): Promise<Maybe<AssetKey>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const root = isAssetKey(modelKey) ? modelKey.root : undefined;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models\", \".json\", root);\n return Caching.entityTextureCache.get(key.serialize(), async () => {\n const name = path.split(\"/\").pop()!;\n for (const candidate of [path, `${path}/${name}`]) {\n const texture = new AssetKey(modelKey.namespace, candidate, \"textures\", \"entity\", \"assets\", \".png\", root);\n if (await ModelTextures.get(texture)) return texture;\n }\n const listKey = new AssetKey(modelKey.namespace, \"_list\", `${name}_variant`, undefined, \"data\", \".json\", root);\n const list = await AssetLoader.get<ListAsset>(listKey, AssetParser.LIST);\n const files = list?.files.filter(file => file.endsWith(\".json\") && file !== \"_list.json\");\n const file = files?.find(file => file === \"temperate.json\") ?? files?.[0];\n if (!file) return undefined;\n const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, undefined, \"data\", \".json\", root);\n const variant = await AssetLoader.get<EntityVariant>(variantKey, AssetParser.JSON);\n const assets = variant?.assets;\n const textureId = variant?.asset_id ?? (typeof assets?.wild === \"string\" ? assets.wild :\n Object.values(assets ?? {}).find(value => typeof value === \"string\"));\n if (typeof textureId !== \"string\") return undefined;\n const texture = AssetKey.parse(\"textures\", textureId);\n texture.root = root;\n return texture;\n });\n }\n\n /** @deprecated Use getEntityList(); block entities share the entity dataset. */\n public static getBlockList(): Promise<string[]> {\n return this.getEntityList();\n }\n\n /** @deprecated Use getEntity(); block entities share the entity dataset. */\n public static getBlock(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>> {\n return this.getEntity(modelKey, textureKey, options);\n }\n\n}\n\n/** Selection settings passed as the third argument to {@link Entities.getEntity}. */\nexport interface EntityModelOptions {\n /** Selects one geometry layer without dataset passes. `layers` takes precedence when supplied. */\n layer?: string;\n /** Layer names in draw order; an explicit selection draws exactly these layers and no dataset passes. */\n layers?: string[];\n /**\n * Entity states that enable the dataset's conditional passes, e.g. `[\"powered\"]` for a charged creeper.\n * Without `layer`/`layers`, `main` and every unconditional pass are always drawn.\n */\n when?: string[];\n /** Per-layer texture overrides, keyed like `EntityModel.layers`. The positional texture key applies to the first selected layer. */\n textures?: Record<string, BasicAssetKey>;\n}\n\ninterface EntityVariant extends MinecraftAsset {\n asset_id?: string;\n assets?: Record<string, unknown>;\n}\n"],"mappings":"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","names":["texture","file"]}
@@ -3,7 +3,7 @@ import { Renames } from "./Renames.mjs";
3
3
  import { Caching } from "../cache/Caching.mjs";
4
4
  import { ModelMerger } from "../model/ModelMerger.mjs";
5
5
  import { AssetLoader } from "./AssetLoader.mjs";
6
- import { DEFAULT_NAMESPACE } from "./Assets.mjs";
6
+ import { DEFAULT_NAMESPACE } from "./AssetDefaults.mjs";
7
7
  import { PersistentCache } from "../cache/PersistentCache.mjs";
8
8
  import { AssetKey, isAssetKey, isResourceLocation } from "./AssetKey.mjs";
9
9
  import { AssetParser } from "./source/parser/AssetParsers.mjs";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/assets/Models.ts"],"sourcesContent":["import { Renames } from \"./Renames\";\nimport { ItemModel, ItemTintSource, Model, SpecialItemRenderer } from \"../model/Model\";\nimport { Caching } from \"../cache/Caching\";\nimport { Maybe } from \"../util/util\";\nimport { ModelMerger } from \"../model/ModelMerger\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"./Assets\";\nimport { PersistentCache } from \"../cache/PersistentCache\";\nimport { AssetKey, isAssetKey, isResourceLocation } from \"./AssetKey\";\nimport { ListAsset } from \"../ListAsset\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { DisplayPosition } from \"../model/DisplayPosition\";\nimport { DYE_COLORS } from \"./BannerPatterns\";\nimport { ItemDefaults } from \"../model/ItemDefaults\";\nimport { MineRenderData } from \"./MineRenderData\";\nimport { ItemTints } from \"../model/ItemTints\";\n\n/** Caller-supplied item-preview state passed to {@link Models.getMerged}. */\nexport interface ItemModelContext {\n /** Context used by display-context selectors, overriding `properties`. Defaults to GUI. */\n displayContext?: DisplayPosition | \"none\";\n /** Explicit property overrides. Nodes with the same ID share one override, regardless of their parameters. */\n properties?: Record<string, boolean | string | number>;\n /** Supplied component JSON by ID, overriding built-in defaults. Component selectors compare structural JSON values. */\n components?: Record<string, unknown>;\n /** Stack count, as a nonnegative integer. Defaults to 1; items without listed defaults stack to 64. */\n count?: number;\n /** Item-model keys by reference-node ID, such as `minecraft:bundle/selected_item`. Unset references draw nothing. */\n itemReferences?: Record<string, AssetKey>;\n}\n\n/** Loads and caches Java block/item models, including inherited geometry and textures. */\nexport class Models {\n\n // Bump when the shape of cached item models changes.\n private static readonly ITEM_CACHE_VERSION = \"item-v8\";\n private static _persistentCache: PersistentCache | undefined;\n\n // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading\n // the library, and would require an EnvProvider before any entry has had a chance to register\n private static get PERSISTENT_CACHE(): PersistentCache {\n return this._persistentCache ??= PersistentCache.open(\"minerender-models\");\n }\n\n /** Lists item filenames from the asset source's `_list.json`, with a legacy model-directory fallback. */\n public static async getItemList(): Promise<string[]> {\n const key = new AssetKey(DEFAULT_NAMESPACE, \"_list\", \"items\");\n const legacyKey = new AssetKey(DEFAULT_NAMESPACE, \"_list\", \"models\", \"item\");\n return Caching.listAssetCache.get(key.serialize(), async () => {\n return (await AssetLoader.getFirst<ListAsset>([key, legacyKey], AssetParser.LIST))?.asset;\n }).then(r => r?.files ?? []);\n }\n\n public static async loadAndMerge(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n const model = key.type === \"item\" ? await this.getItemModel(key, context) : await this.getRaw(key);\n if (!model) {\n return undefined;\n }\n const merged = await ModelMerger.mergeWithParents(model);\n return merged;\n }\n\n private static async getItemModel(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n const preview = this.snapshotContext(key, context);\n const dataKey = await this.applyDefaults(key, preview);\n return this.getPreparedItemModel(key, preview, dataKey);\n }\n\n private static async getPreparedItemModel(key: AssetKey, preview: Required<ItemModelContext>, dataKey: string): Promise<Maybe<Model>> {\n const itemId = `${key.namespace}:${key.path}`;\n const itemKey = new AssetKey(key.namespace, key.path, \"items\", undefined, key.rootType, \".json\", key.root);\n const cacheKey = itemKey.serialize() + this.contextKey(preview) + dataKey;\n const model = await this.PERSISTENT_CACHE.getOrLoad(`${this.ITEM_CACHE_VERSION}:${AssetLoader.persistentKey(cacheKey)}`, async () => {\n const result = await AssetLoader.getFirst<Model & { model?: ItemModelNode }>([itemKey, key], AssetParser.JSON);\n if (!result) return undefined;\n if (result.key.assetType !== \"items\") return { ...result.asset, key, itemId, components: preview.components } as ItemModel;\n\n const load = async (selected: SelectedItemModel): Promise<ItemModel> => {\n if (\"parts\" in selected) {\n return { key, itemId, parts: await Promise.all(selected.parts.map(load)) };\n }\n if (\"item\" in selected) {\n // Referenced items start with their own default stack state and references.\n const model = await this.getItemModel(selected.item, { displayContext: preview.displayContext });\n if (!model) throw new Error(`Item ${key.toNamespacedString()} references missing item ${selected.item.toNamespacedString()}`);\n return model as ItemModel;\n }\n const modelKey = AssetKey.parse(\"models\", selected.model);\n modelKey.root = key.root;\n const model = await this.getRaw(modelKey);\n if (!model) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);\n // Relative texture paths belong to the referenced model's namespace.\n return { ...model, itemId, components: preview.components, ...(selected.special && { special: selected.special }), ...(selected.tints && { tints: selected.tints }) } as ItemModel;\n };\n const model = await load(this.selectItemModel(result.asset.model, key, preview));\n return model;\n });\n const restore = (model: ItemModel): ItemModel => ({\n ...model, key: Object.assign(new AssetKey(\"\", \"\"), model.key),\n ...(model.parts && { parts: model.parts.map(restore) })\n });\n return model ? restore(model) : undefined;\n }\n\n private static contextIdentifier(id: string): string {\n if (!isResourceLocation(id)) {\n throw new Error(`Invalid item-preview identifier: ${id}`);\n }\n return id.includes(\":\") ? id : `minecraft:${id}`;\n }\n\n /** @internal */\n public static componentValue(components: Record<string, unknown>, id: string): unknown {\n const normalized = this.contextIdentifier(id);\n const short = normalized.replace(/^minecraft:/, \"\");\n if (short !== normalized && Object.prototype.hasOwnProperty.call(components, short)\n && Object.prototype.hasOwnProperty.call(components, normalized)) {\n throw new Error(`Duplicate item-preview component: ${normalized}`);\n }\n return Object.prototype.hasOwnProperty.call(components, short) ? components[short] : components[normalized];\n }\n\n private static snapshotContext(key: AssetKey, context: ItemModelContext): Required<ItemModelContext> {\n const displayContext = context.displayContext ?? DisplayPosition.GUI;\n if (displayContext !== \"none\" && !Object.values(DisplayPosition).includes(displayContext)) {\n throw new Error(`Unsupported item display context: ${displayContext}`);\n }\n for (const map of [context.properties, context.components, context.itemReferences]) {\n if (map !== undefined && (!map || typeof map !== \"object\" || Array.isArray(map))) {\n throw new Error(\"Item-preview properties, components, and references must be objects keyed by identifier\");\n }\n }\n const count = context.count === undefined ? 1 : context.count;\n if (!Number.isSafeInteger(count) || count < 0) throw new Error(\"Item-preview count must be a nonnegative safe integer\");\n const properties: Required<ItemModelContext>[\"properties\"] = {};\n for (const [id, value] of Object.entries(context.properties ?? {})) {\n const property = this.contextIdentifier(id);\n if (![\"boolean\", \"string\", \"number\"].includes(typeof value) || typeof value === \"number\" && !Number.isFinite(value)) {\n throw new Error(`Item-preview property ${property} must be a boolean, string, or finite number`);\n }\n if (Object.prototype.hasOwnProperty.call(properties, property)) throw new Error(`Duplicate item-preview property: ${property}`);\n properties[property] = value;\n }\n const components: Record<string, unknown> = {};\n for (const [id, value] of Object.entries(context.components ?? {})) {\n const component = this.contextIdentifier(id);\n if (Object.prototype.hasOwnProperty.call(components, component)) throw new Error(`Duplicate item-preview component: ${component}`);\n components[component] = this.snapshotJson(value);\n }\n const itemReferences: Record<string, AssetKey> = {};\n for (const [id, value] of Object.entries(context.itemReferences ?? {})) {\n const reference = this.contextIdentifier(id);\n if (!isAssetKey(value) || value.assetType !== \"models\" || value.type !== \"item\") {\n throw new Error(`Item-preview reference ${reference} must be an item-model AssetKey`);\n }\n this.contextIdentifier(`${value.namespace}:${value.path}`);\n if (Object.prototype.hasOwnProperty.call(itemReferences, reference)) throw new Error(`Duplicate item-preview reference: ${reference}`);\n itemReferences[reference] = Object.assign(new AssetKey(\"\", \"\"), value, { root: value.root ?? key.root });\n }\n return { displayContext, properties, components, count, itemReferences };\n }\n\n private static async applyDefaults(key: AssetKey, preview: Required<ItemModelContext>): Promise<string> {\n if (key.type !== \"item\") return \"\";\n const resolved = await MineRenderData.resolve(key.root);\n const defaults = await ItemDefaults.get(`${key.namespace}:${key.path}`, key.root);\n preview.components = { ...defaults, ...preview.components };\n if (resolved.manifest.dataVersion < 3337 && key.namespace === DEFAULT_NAMESPACE\n && [\"potion\", \"splash_potion\", \"lingering_potion\"].includes(key.path)\n && !Object.prototype.hasOwnProperty.call(preview.components, \"minecraft:enchantment_glint_override\")\n && await ItemTints.hasPotionEffects(preview.components[\"minecraft:potion_contents\"], key.root)) {\n preview.components[\"minecraft:enchantment_glint_override\"] = true;\n }\n return `|data:${resolved.root}:${resolved.manifest.datasets.itemDefaults?.sha256}:${resolved.manifest.datasets.potionColors?.sha256}`;\n }\n\n private static contextKey(context: Required<ItemModelContext>): string {\n const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));\n return `|${this.ITEM_CACHE_VERSION}:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;\n }\n\n private static snapshotJson(value: unknown, ancestors = new Set<object>()): unknown {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\" || typeof value === \"number\" && Number.isFinite(value)) return value;\n if (typeof value !== \"object\" || ancestors.has(value) || !Array.isArray(value)\n && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {\n throw new Error(\"Item-preview components must contain finite JSON values without circular references\");\n }\n ancestors.add(value);\n const copy = Array.isArray(value) ? Array.from(value, entry => this.snapshotJson(entry, ancestors))\n : Object.fromEntries(Object.keys(value).sort().map(key => [key, this.snapshotJson((value as Record<string, unknown>)[key], ancestors)]));\n ancestors.delete(value);\n return copy;\n }\n\n private static propertyValue(node: ItemModelNode, context: Required<ItemModelContext>): unknown {\n const kind = node.type.replace(/^minecraft:/, \"\");\n const property = node.property ? this.contextIdentifier(node.property) : undefined;\n if (kind === \"select\" && property === \"minecraft:display_context\") return context.displayContext;\n if (property && Object.prototype.hasOwnProperty.call(context.properties, property)) return context.properties[property];\n const fallback = kind === \"condition\" ? false : kind === \"range_dispatch\" ? 0 : undefined;\n const component = (id: string) => context.components[this.contextIdentifier(id)];\n if (property === \"minecraft:custom_model_data\") {\n const index = node.index ?? 0;\n if (!Number.isSafeInteger(index) || index < 0) throw new Error(\"Item-model custom_model_data index must be a nonnegative integer\");\n const data = component(\"custom_model_data\");\n if (data === undefined) return fallback;\n if (!data || typeof data !== \"object\" || Array.isArray(data)) throw new Error(\"Item-preview custom_model_data must be an object\");\n const field = kind === \"condition\" ? \"flags\" : kind === \"select\" ? \"strings\" : \"floats\";\n const values = (data as Record<string, unknown>)[field];\n if (values === undefined) return fallback;\n if (!Array.isArray(values)) throw new Error(`Item-preview custom_model_data.${field} must be an array`);\n return index < values.length ? values[index] : fallback;\n }\n if (kind === \"condition\" && property === \"minecraft:has_component\") {\n if (node.ignore_default) throw new Error(\"Item-preview has_component with ignore_default requires an explicit properties override; default component comparisons are unsupported\");\n return Object.prototype.hasOwnProperty.call(context.components, this.contextIdentifier(node.component!));\n }\n if (kind === \"select\") {\n switch (property) {\n case \"minecraft:component\": return component(node.component!);\n case \"minecraft:block_state\": {\n const state = component(\"block_state\");\n if (state === undefined) return undefined;\n if (!state || typeof state !== \"object\" || Array.isArray(state)) throw new Error(\"Item-preview block_state must be an object\");\n if (typeof node.block_state_property !== \"string\") throw new Error(\"Item-model block_state requires block_state_property\");\n return Object.prototype.hasOwnProperty.call(state, node.block_state_property)\n ? (state as Record<string, unknown>)[node.block_state_property] : undefined;\n }\n case \"minecraft:charge_type\": {\n const projectiles = component(\"charged_projectiles\");\n if (projectiles === undefined) return \"none\";\n if (!Array.isArray(projectiles)) throw new Error(\"Item-preview charged_projectiles must be an array of item stacks\");\n const ids = projectiles.map(stack => {\n if (!stack || typeof stack !== \"object\" || Array.isArray(stack)) throw new Error(\"Item-preview charged_projectiles must contain item-stack objects\");\n return this.contextIdentifier((stack as { id: string }).id);\n });\n return !ids.length ? \"none\" : ids.includes(\"minecraft:firework_rocket\") ? \"rocket\" : \"arrow\";\n }\n }\n }\n if (kind === \"range_dispatch\" && (property === \"minecraft:damage\" || property === \"minecraft:count\")) {\n const damage = property === \"minecraft:damage\";\n const maximumComponent = component(damage ? \"max_damage\" : \"max_stack_size\");\n const maximum = maximumComponent === undefined ? damage ? 0 : 1 : maximumComponent;\n const damageComponent = component(\"damage\");\n const value = damage ? damageComponent === undefined ? 0 : damageComponent : context.count;\n if (typeof value !== \"number\" || typeof maximum !== \"number\" || maximum < 0) throw new Error(`Item-preview ${property} requires numeric components and a nonnegative maximum`);\n const clamped = Math.max(0, Math.min(maximum, value));\n return node.normalize === false ? clamped : clamped / maximum;\n }\n return fallback;\n }\n\n private static selectItemModel(node: ItemModelNode | undefined, key: AssetKey, context: Required<ItemModelContext>): SelectedItemModel {\n if (!node || typeof node.type !== \"string\") {\n throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);\n }\n switch (node.type.replace(/^minecraft:/, \"\")) {\n case \"composite\":\n if (Array.isArray(node.models)) return { parts: node.models.map(child => this.selectItemModel(child, key, context)) };\n break;\n case \"bundle/selected_item\": {\n const item = context.itemReferences[\"minecraft:bundle/selected_item\"];\n return item ? { item } : { parts: [] };\n }\n case \"model\":\n if (typeof node.model === \"string\" && node.model) return { model: node.model, tints: node.tints };\n break;\n case \"special\": {\n if (!node.base || !node.model || typeof node.model !== \"object\") break;\n const special = node.model;\n switch (special.type) {\n case \"copper_golem_statue\":\n case \"minecraft:copper_golem_statue\":\n if (isResourceLocation(special.texture)\n && [\"standing\", \"sitting\", \"running\", \"star\"].includes(special.pose)) return { model: node.base, special };\n break;\n case \"banner\":\n case \"minecraft:banner\":\n if (typeof special.color === \"string\" && Object.prototype.hasOwnProperty.call(DYE_COLORS, special.color)) return { model: node.base, special };\n break;\n case \"shield\":\n case \"minecraft:shield\":\n case \"trident\":\n case \"minecraft:trident\":\n case \"conduit\":\n case \"minecraft:conduit\":\n case \"decorated_pot\":\n case \"minecraft:decorated_pot\":\n case \"player_head\":\n case \"minecraft:player_head\":\n return { model: node.base, special };\n case \"shulker_box\":\n case \"minecraft:shulker_box\":\n if (typeof special.texture === \"string\" && special.texture\n && (special.openness === undefined || typeof special.openness === \"number\" && Number.isFinite(special.openness))\n && (special.orientation === undefined || [\"down\", \"up\", \"north\", \"south\", \"west\", \"east\"].includes(special.orientation))) {\n return { model: node.base, special };\n }\n break;\n case \"chest\":\n case \"minecraft:chest\":\n case \"bed\":\n case \"minecraft:bed\":\n if (typeof special.texture === \"string\" && special.texture) return { model: node.base, special };\n break;\n case \"head\":\n case \"minecraft:head\":\n if (typeof special.kind === \"string\" && special.kind) return { model: node.base, special };\n break;\n }\n throw new Error(`Unsupported special item renderer ${special.type} for ${key.toNamespacedString()}`);\n }\n case \"condition\": {\n const value = this.propertyValue(node, context);\n if (typeof value !== \"boolean\") throw new Error(`Item-preview condition ${node.property} requires a boolean`);\n return this.selectItemModel(value ? node.on_true : node.on_false, key, context);\n }\n case \"select\": {\n const value = this.propertyValue(node, context);\n const component = node.property && this.contextIdentifier(node.property) === \"minecraft:component\";\n if (!component && value !== undefined && typeof value !== \"string\") throw new Error(`Item-preview selector ${node.property} requires a string`);\n const matches = (candidate: unknown) => component\n ? JSON.stringify(this.snapshotJson(candidate)) === JSON.stringify(this.snapshotJson(value)) : candidate === value;\n const selected = value === undefined ? undefined\n : node.cases?.find(entry => matches(entry.when) || Array.isArray(entry.when) && entry.when.some(matches))?.model;\n return this.selectItemModel(selected ?? node.fallback, key, context);\n }\n case \"range_dispatch\": {\n const value = this.propertyValue(node, context);\n if (typeof value !== \"number\") throw new Error(`Item-preview range ${node.property} requires a number`);\n if (Number.isNaN(value)) return this.selectItemModel(node.fallback, key, context);\n const scaled = value * (node.scale ?? 1);\n if (!Number.isFinite(scaled)) throw new Error(`Item-preview range ${node.property} requires a finite value and scale`);\n const selected = node.entries?.reduce<{ threshold: number; model: ItemModelNode } | undefined>((match, entry) => {\n return entry.threshold <= scaled && (!match || entry.threshold >= match.threshold) ? entry : match;\n }, undefined);\n return this.selectItemModel(selected?.model ?? node.fallback, key, context);\n }\n }\n throw new Error(`Unsupported item model ${node?.type ?? \"definition\"} for ${key.toNamespacedString()}`);\n }\n\n /** Loads one model file without resolving its parents. Returns `undefined` when the file is missing. */\n public static async getRaw(key: AssetKey): Promise<Maybe<Model>> {\n if (!key.assetType) {\n key.assetType = \"models\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n const keyStr = key.serialize();\n //TODO: maybe add the asset source to the key\n return Caching.rawModelCache.get(keyStr, k => {\n return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), k1 => {\n return AssetLoader.get<Model>(key, AssetParser.MODEL);\n })\n }).then(asset => {\n if (asset) {\n asset.key = key;\n }\n return asset;\n })\n }\n\n /**\n * Loads a model and resolves its parent chain. Returns `undefined` when the model is missing.\n * Item keys default to GUI context and a stack count of 1. Unresolved conditions are false and numeric properties are zero.\n * Versioned stack-size, durability, and glint defaults apply unless components override them.\n * Pass `context` to supply component values, property overrides, and item references for a preview.\n * Composite items retain independently merged children in `ItemModel.parts`.\n *\n * @param key - Model key, for example `AssetKey.parse(\"models\", \"minecraft:item/diamond_sword\")`.\n */\n public static async getMerged(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n if (!key.assetType) {\n key.assetType = \"models\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n const preview = this.snapshotContext(key, context);\n if (key.type === \"item\") {\n const renamed = await Renames.key(\"items\", key);\n const replacement = renamed && await this.getMerged(renamed, preview);\n if (replacement) return replacement;\n }\n const dataKey = await this.applyDefaults(key, preview);\n const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === \"item\" ? this.contextKey(preview) + dataKey : \"\"));\n const model = await Caching.mergedModelCache.get(keyStr, async () => {\n //TODO: persistent cache\n const raw = key.type === \"item\" ? await this.getPreparedItemModel(key, preview, dataKey) : await this.getRaw(key);\n const merged = raw ? await ModelMerger.mergeWithParents(raw) : undefined;\n return merged;\n });\n return model;\n }\n\n /** Alias for {@link getMerged}. */\n public static async get(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n return this.getMerged(key, context);\n }\n\n /** Clears persisted models. Use {@link Caching.clear} to also discard in-memory assets. */\n public static async clearCache() {\n return this.PERSISTENT_CACHE.clear();\n }\n\n}\n\ninterface ItemModelNode {\n type: string;\n model?: string | SpecialItemRenderer;\n tints?: ItemTintSource[];\n base?: string;\n property?: string;\n index?: number;\n component?: string;\n ignore_default?: boolean;\n normalize?: boolean;\n block_state_property?: string;\n on_false?: ItemModelNode;\n on_true?: ItemModelNode;\n fallback?: ItemModelNode;\n cases?: Array<{ when: unknown; model: ItemModelNode }>;\n entries?: Array<{ threshold: number; model: ItemModelNode }>;\n scale?: number;\n models?: ItemModelNode[];\n}\n\ntype SelectedItemModel = { model: string; special?: SpecialItemRenderer; tints?: ItemTintSource[] }\n | { parts: SelectedItemModel[] }\n | { item: AssetKey };\n"],"mappings":"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","names":["model"]}
1
+ {"version":3,"sources":["../../../../src/assets/Models.ts"],"sourcesContent":["import { Renames } from \"./Renames\";\nimport { ItemModel, ItemTintSource, Model, SpecialItemRenderer } from \"../model/Model\";\nimport { Caching } from \"../cache/Caching\";\nimport { Maybe } from \"../util/util\";\nimport { ModelMerger } from \"../model/ModelMerger\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"./AssetDefaults\";\nimport { PersistentCache } from \"../cache/PersistentCache\";\nimport { AssetKey, isAssetKey, isResourceLocation } from \"./AssetKey\";\nimport { ListAsset } from \"../ListAsset\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { DisplayPosition } from \"../model/DisplayPosition\";\nimport { DYE_COLORS } from \"./BannerPatterns\";\nimport { ItemDefaults } from \"../model/ItemDefaults\";\nimport { MineRenderData } from \"./MineRenderData\";\nimport { ItemTints } from \"../model/ItemTints\";\n\n/** Caller-supplied item-preview state passed to {@link Models.getMerged}. */\nexport interface ItemModelContext {\n /** Context used by display-context selectors, overriding `properties`. Defaults to GUI. */\n displayContext?: DisplayPosition | \"none\";\n /** Explicit property overrides. Nodes with the same ID share one override, regardless of their parameters. */\n properties?: Record<string, boolean | string | number>;\n /** Supplied component JSON by ID, overriding built-in defaults. Component selectors compare structural JSON values. */\n components?: Record<string, unknown>;\n /** Stack count, as a nonnegative integer. Defaults to 1; items without listed defaults stack to 64. */\n count?: number;\n /** Item-model keys by reference-node ID, such as `minecraft:bundle/selected_item`. Unset references draw nothing. */\n itemReferences?: Record<string, AssetKey>;\n}\n\n/** Loads and caches Java block/item models, including inherited geometry and textures. */\nexport class Models {\n\n // Bump when the shape of cached item models changes.\n private static readonly ITEM_CACHE_VERSION = \"item-v8\";\n private static _persistentCache: PersistentCache | undefined;\n\n // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading\n // the library, and would require an EnvProvider before any entry has had a chance to register\n private static get PERSISTENT_CACHE(): PersistentCache {\n return this._persistentCache ??= PersistentCache.open(\"minerender-models\");\n }\n\n /** Lists item filenames from the asset source's `_list.json`, with a legacy model-directory fallback. */\n public static async getItemList(): Promise<string[]> {\n const key = new AssetKey(DEFAULT_NAMESPACE, \"_list\", \"items\");\n const legacyKey = new AssetKey(DEFAULT_NAMESPACE, \"_list\", \"models\", \"item\");\n return Caching.listAssetCache.get(key.serialize(), async () => {\n return (await AssetLoader.getFirst<ListAsset>([key, legacyKey], AssetParser.LIST))?.asset;\n }).then(r => r?.files ?? []);\n }\n\n public static async loadAndMerge(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n const model = key.type === \"item\" ? await this.getItemModel(key, context) : await this.getRaw(key);\n if (!model) {\n return undefined;\n }\n const merged = await ModelMerger.mergeWithParents(model);\n return merged;\n }\n\n private static async getItemModel(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n const preview = this.snapshotContext(key, context);\n const dataKey = await this.applyDefaults(key, preview);\n return this.getPreparedItemModel(key, preview, dataKey);\n }\n\n private static async getPreparedItemModel(key: AssetKey, preview: Required<ItemModelContext>, dataKey: string): Promise<Maybe<Model>> {\n const itemId = `${key.namespace}:${key.path}`;\n const itemKey = new AssetKey(key.namespace, key.path, \"items\", undefined, key.rootType, \".json\", key.root);\n const cacheKey = itemKey.serialize() + this.contextKey(preview) + dataKey;\n const model = await this.PERSISTENT_CACHE.getOrLoad(`${this.ITEM_CACHE_VERSION}:${AssetLoader.persistentKey(cacheKey)}`, async () => {\n const result = await AssetLoader.getFirst<Model & { model?: ItemModelNode }>([itemKey, key], AssetParser.JSON);\n if (!result) return undefined;\n if (result.key.assetType !== \"items\") return { ...result.asset, key, itemId, components: preview.components } as ItemModel;\n\n const load = async (selected: SelectedItemModel): Promise<ItemModel> => {\n if (\"parts\" in selected) {\n return { key, itemId, parts: await Promise.all(selected.parts.map(load)) };\n }\n if (\"item\" in selected) {\n // Referenced items start with their own default stack state and references.\n const model = await this.getItemModel(selected.item, { displayContext: preview.displayContext });\n if (!model) throw new Error(`Item ${key.toNamespacedString()} references missing item ${selected.item.toNamespacedString()}`);\n return model as ItemModel;\n }\n const modelKey = AssetKey.parse(\"models\", selected.model);\n modelKey.root = key.root;\n const model = await this.getRaw(modelKey);\n if (!model) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);\n // Relative texture paths belong to the referenced model's namespace.\n return { ...model, itemId, components: preview.components, ...(selected.special && { special: selected.special }), ...(selected.tints && { tints: selected.tints }) } as ItemModel;\n };\n const model = await load(this.selectItemModel(result.asset.model, key, preview));\n return model;\n });\n const restore = (model: ItemModel): ItemModel => ({\n ...model, key: Object.assign(new AssetKey(\"\", \"\"), model.key),\n ...(model.parts && { parts: model.parts.map(restore) })\n });\n return model ? restore(model) : undefined;\n }\n\n private static contextIdentifier(id: string): string {\n if (!isResourceLocation(id)) {\n throw new Error(`Invalid item-preview identifier: ${id}`);\n }\n return id.includes(\":\") ? id : `minecraft:${id}`;\n }\n\n /** @internal */\n public static componentValue(components: Record<string, unknown>, id: string): unknown {\n const normalized = this.contextIdentifier(id);\n const short = normalized.replace(/^minecraft:/, \"\");\n if (short !== normalized && Object.prototype.hasOwnProperty.call(components, short)\n && Object.prototype.hasOwnProperty.call(components, normalized)) {\n throw new Error(`Duplicate item-preview component: ${normalized}`);\n }\n return Object.prototype.hasOwnProperty.call(components, short) ? components[short] : components[normalized];\n }\n\n private static snapshotContext(key: AssetKey, context: ItemModelContext): Required<ItemModelContext> {\n const displayContext = context.displayContext ?? DisplayPosition.GUI;\n if (displayContext !== \"none\" && !Object.values(DisplayPosition).includes(displayContext)) {\n throw new Error(`Unsupported item display context: ${displayContext}`);\n }\n for (const map of [context.properties, context.components, context.itemReferences]) {\n if (map !== undefined && (!map || typeof map !== \"object\" || Array.isArray(map))) {\n throw new Error(\"Item-preview properties, components, and references must be objects keyed by identifier\");\n }\n }\n const count = context.count === undefined ? 1 : context.count;\n if (!Number.isSafeInteger(count) || count < 0) throw new Error(\"Item-preview count must be a nonnegative safe integer\");\n const properties: Required<ItemModelContext>[\"properties\"] = {};\n for (const [id, value] of Object.entries(context.properties ?? {})) {\n const property = this.contextIdentifier(id);\n if (![\"boolean\", \"string\", \"number\"].includes(typeof value) || typeof value === \"number\" && !Number.isFinite(value)) {\n throw new Error(`Item-preview property ${property} must be a boolean, string, or finite number`);\n }\n if (Object.prototype.hasOwnProperty.call(properties, property)) throw new Error(`Duplicate item-preview property: ${property}`);\n properties[property] = value;\n }\n const components: Record<string, unknown> = {};\n for (const [id, value] of Object.entries(context.components ?? {})) {\n const component = this.contextIdentifier(id);\n if (Object.prototype.hasOwnProperty.call(components, component)) throw new Error(`Duplicate item-preview component: ${component}`);\n components[component] = this.snapshotJson(value);\n }\n const itemReferences: Record<string, AssetKey> = {};\n for (const [id, value] of Object.entries(context.itemReferences ?? {})) {\n const reference = this.contextIdentifier(id);\n if (!isAssetKey(value) || value.assetType !== \"models\" || value.type !== \"item\") {\n throw new Error(`Item-preview reference ${reference} must be an item-model AssetKey`);\n }\n this.contextIdentifier(`${value.namespace}:${value.path}`);\n if (Object.prototype.hasOwnProperty.call(itemReferences, reference)) throw new Error(`Duplicate item-preview reference: ${reference}`);\n itemReferences[reference] = Object.assign(new AssetKey(\"\", \"\"), value, { root: value.root ?? key.root });\n }\n return { displayContext, properties, components, count, itemReferences };\n }\n\n private static async applyDefaults(key: AssetKey, preview: Required<ItemModelContext>): Promise<string> {\n if (key.type !== \"item\") return \"\";\n const resolved = await MineRenderData.resolve(key.root);\n const defaults = await ItemDefaults.get(`${key.namespace}:${key.path}`, key.root);\n preview.components = { ...defaults, ...preview.components };\n if (resolved.manifest.dataVersion < 3337 && key.namespace === DEFAULT_NAMESPACE\n && [\"potion\", \"splash_potion\", \"lingering_potion\"].includes(key.path)\n && !Object.prototype.hasOwnProperty.call(preview.components, \"minecraft:enchantment_glint_override\")\n && await ItemTints.hasPotionEffects(preview.components[\"minecraft:potion_contents\"], key.root)) {\n preview.components[\"minecraft:enchantment_glint_override\"] = true;\n }\n return `|data:${resolved.root}:${resolved.manifest.datasets.itemDefaults?.sha256}:${resolved.manifest.datasets.potionColors?.sha256}`;\n }\n\n private static contextKey(context: Required<ItemModelContext>): string {\n const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));\n return `|${this.ITEM_CACHE_VERSION}:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;\n }\n\n private static snapshotJson(value: unknown, ancestors = new Set<object>()): unknown {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\" || typeof value === \"number\" && Number.isFinite(value)) return value;\n if (typeof value !== \"object\" || ancestors.has(value) || !Array.isArray(value)\n && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {\n throw new Error(\"Item-preview components must contain finite JSON values without circular references\");\n }\n ancestors.add(value);\n const copy = Array.isArray(value) ? Array.from(value, entry => this.snapshotJson(entry, ancestors))\n : Object.fromEntries(Object.keys(value).sort().map(key => [key, this.snapshotJson((value as Record<string, unknown>)[key], ancestors)]));\n ancestors.delete(value);\n return copy;\n }\n\n private static propertyValue(node: ItemModelNode, context: Required<ItemModelContext>): unknown {\n const kind = node.type.replace(/^minecraft:/, \"\");\n const property = node.property ? this.contextIdentifier(node.property) : undefined;\n if (kind === \"select\" && property === \"minecraft:display_context\") return context.displayContext;\n if (property && Object.prototype.hasOwnProperty.call(context.properties, property)) return context.properties[property];\n const fallback = kind === \"condition\" ? false : kind === \"range_dispatch\" ? 0 : undefined;\n const component = (id: string) => context.components[this.contextIdentifier(id)];\n if (property === \"minecraft:custom_model_data\") {\n const index = node.index ?? 0;\n if (!Number.isSafeInteger(index) || index < 0) throw new Error(\"Item-model custom_model_data index must be a nonnegative integer\");\n const data = component(\"custom_model_data\");\n if (data === undefined) return fallback;\n if (!data || typeof data !== \"object\" || Array.isArray(data)) throw new Error(\"Item-preview custom_model_data must be an object\");\n const field = kind === \"condition\" ? \"flags\" : kind === \"select\" ? \"strings\" : \"floats\";\n const values = (data as Record<string, unknown>)[field];\n if (values === undefined) return fallback;\n if (!Array.isArray(values)) throw new Error(`Item-preview custom_model_data.${field} must be an array`);\n return index < values.length ? values[index] : fallback;\n }\n if (kind === \"condition\" && property === \"minecraft:has_component\") {\n if (node.ignore_default) throw new Error(\"Item-preview has_component with ignore_default requires an explicit properties override; default component comparisons are unsupported\");\n return Object.prototype.hasOwnProperty.call(context.components, this.contextIdentifier(node.component!));\n }\n if (kind === \"select\") {\n switch (property) {\n case \"minecraft:component\": return component(node.component!);\n case \"minecraft:block_state\": {\n const state = component(\"block_state\");\n if (state === undefined) return undefined;\n if (!state || typeof state !== \"object\" || Array.isArray(state)) throw new Error(\"Item-preview block_state must be an object\");\n if (typeof node.block_state_property !== \"string\") throw new Error(\"Item-model block_state requires block_state_property\");\n return Object.prototype.hasOwnProperty.call(state, node.block_state_property)\n ? (state as Record<string, unknown>)[node.block_state_property] : undefined;\n }\n case \"minecraft:charge_type\": {\n const projectiles = component(\"charged_projectiles\");\n if (projectiles === undefined) return \"none\";\n if (!Array.isArray(projectiles)) throw new Error(\"Item-preview charged_projectiles must be an array of item stacks\");\n const ids = projectiles.map(stack => {\n if (!stack || typeof stack !== \"object\" || Array.isArray(stack)) throw new Error(\"Item-preview charged_projectiles must contain item-stack objects\");\n return this.contextIdentifier((stack as { id: string }).id);\n });\n return !ids.length ? \"none\" : ids.includes(\"minecraft:firework_rocket\") ? \"rocket\" : \"arrow\";\n }\n }\n }\n if (kind === \"range_dispatch\" && (property === \"minecraft:damage\" || property === \"minecraft:count\")) {\n const damage = property === \"minecraft:damage\";\n const maximumComponent = component(damage ? \"max_damage\" : \"max_stack_size\");\n const maximum = maximumComponent === undefined ? damage ? 0 : 1 : maximumComponent;\n const damageComponent = component(\"damage\");\n const value = damage ? damageComponent === undefined ? 0 : damageComponent : context.count;\n if (typeof value !== \"number\" || typeof maximum !== \"number\" || maximum < 0) throw new Error(`Item-preview ${property} requires numeric components and a nonnegative maximum`);\n const clamped = Math.max(0, Math.min(maximum, value));\n return node.normalize === false ? clamped : clamped / maximum;\n }\n return fallback;\n }\n\n private static selectItemModel(node: ItemModelNode | undefined, key: AssetKey, context: Required<ItemModelContext>): SelectedItemModel {\n if (!node || typeof node.type !== \"string\") {\n throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);\n }\n switch (node.type.replace(/^minecraft:/, \"\")) {\n case \"composite\":\n if (Array.isArray(node.models)) return { parts: node.models.map(child => this.selectItemModel(child, key, context)) };\n break;\n case \"bundle/selected_item\": {\n const item = context.itemReferences[\"minecraft:bundle/selected_item\"];\n return item ? { item } : { parts: [] };\n }\n case \"model\":\n if (typeof node.model === \"string\" && node.model) return { model: node.model, tints: node.tints };\n break;\n case \"special\": {\n if (!node.base || !node.model || typeof node.model !== \"object\") break;\n const special = node.model;\n switch (special.type) {\n case \"copper_golem_statue\":\n case \"minecraft:copper_golem_statue\":\n if (isResourceLocation(special.texture)\n && [\"standing\", \"sitting\", \"running\", \"star\"].includes(special.pose)) return { model: node.base, special };\n break;\n case \"banner\":\n case \"minecraft:banner\":\n if (typeof special.color === \"string\" && Object.prototype.hasOwnProperty.call(DYE_COLORS, special.color)) return { model: node.base, special };\n break;\n case \"shield\":\n case \"minecraft:shield\":\n case \"trident\":\n case \"minecraft:trident\":\n case \"conduit\":\n case \"minecraft:conduit\":\n case \"decorated_pot\":\n case \"minecraft:decorated_pot\":\n case \"player_head\":\n case \"minecraft:player_head\":\n return { model: node.base, special };\n case \"shulker_box\":\n case \"minecraft:shulker_box\":\n if (typeof special.texture === \"string\" && special.texture\n && (special.openness === undefined || typeof special.openness === \"number\" && Number.isFinite(special.openness))\n && (special.orientation === undefined || [\"down\", \"up\", \"north\", \"south\", \"west\", \"east\"].includes(special.orientation))) {\n return { model: node.base, special };\n }\n break;\n case \"chest\":\n case \"minecraft:chest\":\n case \"bed\":\n case \"minecraft:bed\":\n if (typeof special.texture === \"string\" && special.texture) return { model: node.base, special };\n break;\n case \"head\":\n case \"minecraft:head\":\n if (typeof special.kind === \"string\" && special.kind) return { model: node.base, special };\n break;\n }\n throw new Error(`Unsupported special item renderer ${special.type} for ${key.toNamespacedString()}`);\n }\n case \"condition\": {\n const value = this.propertyValue(node, context);\n if (typeof value !== \"boolean\") throw new Error(`Item-preview condition ${node.property} requires a boolean`);\n return this.selectItemModel(value ? node.on_true : node.on_false, key, context);\n }\n case \"select\": {\n const value = this.propertyValue(node, context);\n const component = node.property && this.contextIdentifier(node.property) === \"minecraft:component\";\n if (!component && value !== undefined && typeof value !== \"string\") throw new Error(`Item-preview selector ${node.property} requires a string`);\n const matches = (candidate: unknown) => component\n ? JSON.stringify(this.snapshotJson(candidate)) === JSON.stringify(this.snapshotJson(value)) : candidate === value;\n const selected = value === undefined ? undefined\n : node.cases?.find(entry => matches(entry.when) || Array.isArray(entry.when) && entry.when.some(matches))?.model;\n return this.selectItemModel(selected ?? node.fallback, key, context);\n }\n case \"range_dispatch\": {\n const value = this.propertyValue(node, context);\n if (typeof value !== \"number\") throw new Error(`Item-preview range ${node.property} requires a number`);\n if (Number.isNaN(value)) return this.selectItemModel(node.fallback, key, context);\n const scaled = value * (node.scale ?? 1);\n if (!Number.isFinite(scaled)) throw new Error(`Item-preview range ${node.property} requires a finite value and scale`);\n const selected = node.entries?.reduce<{ threshold: number; model: ItemModelNode } | undefined>((match, entry) => {\n return entry.threshold <= scaled && (!match || entry.threshold >= match.threshold) ? entry : match;\n }, undefined);\n return this.selectItemModel(selected?.model ?? node.fallback, key, context);\n }\n }\n throw new Error(`Unsupported item model ${node?.type ?? \"definition\"} for ${key.toNamespacedString()}`);\n }\n\n /** Loads one model file without resolving its parents. Returns `undefined` when the file is missing. */\n public static async getRaw(key: AssetKey): Promise<Maybe<Model>> {\n if (!key.assetType) {\n key.assetType = \"models\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n const keyStr = key.serialize();\n //TODO: maybe add the asset source to the key\n return Caching.rawModelCache.get(keyStr, k => {\n return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), k1 => {\n return AssetLoader.get<Model>(key, AssetParser.MODEL);\n })\n }).then(asset => {\n if (asset) {\n asset.key = key;\n }\n return asset;\n })\n }\n\n /**\n * Loads a model and resolves its parent chain. Returns `undefined` when the model is missing.\n * Item keys default to GUI context and a stack count of 1. Unresolved conditions are false and numeric properties are zero.\n * Versioned stack-size, durability, and glint defaults apply unless components override them.\n * Pass `context` to supply component values, property overrides, and item references for a preview.\n * Composite items retain independently merged children in `ItemModel.parts`.\n *\n * @param key - Model key, for example `AssetKey.parse(\"models\", \"minecraft:item/diamond_sword\")`.\n */\n public static async getMerged(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n if (!key.assetType) {\n key.assetType = \"models\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n const preview = this.snapshotContext(key, context);\n if (key.type === \"item\") {\n const renamed = await Renames.key(\"items\", key);\n const replacement = renamed && await this.getMerged(renamed, preview);\n if (replacement) return replacement;\n }\n const dataKey = await this.applyDefaults(key, preview);\n const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === \"item\" ? this.contextKey(preview) + dataKey : \"\"));\n const model = await Caching.mergedModelCache.get(keyStr, async () => {\n //TODO: persistent cache\n const raw = key.type === \"item\" ? await this.getPreparedItemModel(key, preview, dataKey) : await this.getRaw(key);\n const merged = raw ? await ModelMerger.mergeWithParents(raw) : undefined;\n return merged;\n });\n return model;\n }\n\n /** Alias for {@link getMerged}. */\n public static async get(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n return this.getMerged(key, context);\n }\n\n /** Clears persisted models. Use {@link Caching.clear} to also discard in-memory assets. */\n public static async clearCache() {\n return this.PERSISTENT_CACHE.clear();\n }\n\n}\n\ninterface ItemModelNode {\n type: string;\n model?: string | SpecialItemRenderer;\n tints?: ItemTintSource[];\n base?: string;\n property?: string;\n index?: number;\n component?: string;\n ignore_default?: boolean;\n normalize?: boolean;\n block_state_property?: string;\n on_false?: ItemModelNode;\n on_true?: ItemModelNode;\n fallback?: ItemModelNode;\n cases?: Array<{ when: unknown; model: ItemModelNode }>;\n entries?: Array<{ threshold: number; model: ItemModelNode }>;\n scale?: number;\n models?: ItemModelNode[];\n}\n\ntype SelectedItemModel = { model: string; special?: SpecialItemRenderer; tints?: ItemTintSource[] }\n | { parts: SelectedItemModel[] }\n | { item: AssetKey };\n"],"mappings":";AAAA,SAAS,eAAe;AAExB,SAAS,eAAe;AAExB,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAChC,SAAS,UAAU,YAAY,0BAA0B;AAEzD,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAiBnB,IAAM,SAAN,MAAa;AAAA;AAAA;AAAA,EAQhB,WAAmB,mBAAoC;AACnD,WAAO,KAAK,qBAAL,KAAK,mBAAqB,gBAAgB,KAAK,mBAAmB;AAAA,EAC7E;AAAA;AAAA,EAGA,aAAoB,cAAiC;AACjD,UAAM,MAAM,IAAI,SAAS,mBAAmB,SAAS,OAAO;AAC5D,UAAM,YAAY,IAAI,SAAS,mBAAmB,SAAS,UAAU,MAAM;AAC3E,WAAO,QAAQ,eAAe,IAAI,IAAI,UAAU,GAAG,YAAY;AAC3D,cAAQ,MAAM,YAAY,SAAoB,CAAC,KAAK,SAAS,GAAG,YAAY,IAAI,IAAI;AAAA,IACxF,CAAC,EAAE,KAAK,OAAK,GAAG,SAAS,CAAC,CAAC;AAAA,EAC/B;AAAA,EAEA,aAAoB,aAAa,KAAe,UAA4B,CAAC,GAA0B;AACnG,UAAM,QAAQ,IAAI,SAAS,SAAS,MAAM,KAAK,aAAa,KAAK,OAAO,IAAI,MAAM,KAAK,OAAO,GAAG;AACjG,QAAI,CAAC,OAAO;AACR,aAAO;AAAA,IACX;AACA,UAAM,SAAS,MAAM,YAAY,iBAAiB,KAAK;AACvD,WAAO;AAAA,EACX;AAAA,EAEA,aAAqB,aAAa,KAAe,UAA4B,CAAC,GAA0B;AACpG,UAAM,UAAU,KAAK,gBAAgB,KAAK,OAAO;AACjD,UAAM,UAAU,MAAM,KAAK,cAAc,KAAK,OAAO;AACrD,WAAO,KAAK,qBAAqB,KAAK,SAAS,OAAO;AAAA,EAC1D;AAAA,EAEA,aAAqB,qBAAqB,KAAe,SAAqC,SAAwC;AAClI,UAAM,SAAS,GAAG,IAAI,SAAS,IAAI,IAAI,IAAI;AAC3C,UAAM,UAAU,IAAI,SAAS,IAAI,WAAW,IAAI,MAAM,SAAS,QAAW,IAAI,UAAU,SAAS,IAAI,IAAI;AACzG,UAAM,WAAW,QAAQ,UAAU,IAAI,KAAK,WAAW,OAAO,IAAI;AAClE,UAAM,QAAQ,MAAM,KAAK,iBAAiB,UAAU,GAAG,KAAK,kBAAkB,IAAI,YAAY,cAAc,QAAQ,CAAC,IAAI,YAAY;AACjI,YAAM,SAAS,MAAM,YAAY,SAA4C,CAAC,SAAS,GAAG,GAAG,YAAY,IAAI;AAC7G,UAAI,CAAC,OAAQ,QAAO;AACpB,UAAI,OAAO,IAAI,cAAc,QAAS,QAAO,EAAE,GAAG,OAAO,OAAO,KAAK,QAAQ,YAAY,QAAQ,WAAW;AAE5G,YAAM,OAAO,OAAO,aAAoD;AACpE,YAAI,WAAW,UAAU;AACrB,iBAAO,EAAE,KAAK,QAAQ,OAAO,MAAM,QAAQ,IAAI,SAAS,MAAM,IAAI,IAAI,CAAC,EAAE;AAAA,QAC7E;AACA,YAAI,UAAU,UAAU;AAEpB,gBAAMA,SAAQ,MAAM,KAAK,aAAa,SAAS,MAAM,EAAE,gBAAgB,QAAQ,eAAe,CAAC;AAC/F,cAAI,CAACA,OAAO,OAAM,IAAI,MAAM,QAAQ,IAAI,mBAAmB,CAAC,4BAA4B,SAAS,KAAK,mBAAmB,CAAC,EAAE;AAC5H,iBAAOA;AAAA,QACX;AACA,cAAM,WAAW,SAAS,MAAM,UAAU,SAAS,KAAK;AACxD,iBAAS,OAAO,IAAI;AACpB,cAAMA,SAAQ,MAAM,KAAK,OAAO,QAAQ;AACxC,YAAI,CAACA,OAAO,OAAM,IAAI,MAAM,QAAQ,IAAI,mBAAmB,CAAC,6BAA6B,SAAS,KAAK,EAAE;AAEzG,eAAO,EAAE,GAAGA,QAAO,QAAQ,YAAY,QAAQ,YAAY,GAAI,SAAS,WAAW,EAAE,SAAS,SAAS,QAAQ,GAAI,GAAI,SAAS,SAAS,EAAE,OAAO,SAAS,MAAM,EAAG;AAAA,MACxK;AACA,YAAMA,SAAQ,MAAM,KAAK,KAAK,gBAAgB,OAAO,MAAM,OAAO,KAAK,OAAO,CAAC;AAC/E,aAAOA;AAAA,IACX,CAAC;AACD,UAAM,UAAU,CAACA,YAAiC;AAAA,MAC9C,GAAGA;AAAA,MAAO,KAAK,OAAO,OAAO,IAAI,SAAS,IAAI,EAAE,GAAGA,OAAM,GAAG;AAAA,MAC5D,GAAIA,OAAM,SAAS,EAAE,OAAOA,OAAM,MAAM,IAAI,OAAO,EAAE;AAAA,IACzD;AACA,WAAO,QAAQ,QAAQ,KAAK,IAAI;AAAA,EACpC;AAAA,EAEA,OAAe,kBAAkB,IAAoB;AACjD,QAAI,CAAC,mBAAmB,EAAE,GAAG;AACzB,YAAM,IAAI,MAAM,oCAAoC,EAAE,EAAE;AAAA,IAC5D;AACA,WAAO,GAAG,SAAS,GAAG,IAAI,KAAK,aAAa,EAAE;AAAA,EAClD;AAAA;AAAA,EAGA,OAAc,eAAe,YAAqC,IAAqB;AACnF,UAAM,aAAa,KAAK,kBAAkB,EAAE;AAC5C,UAAM,QAAQ,WAAW,QAAQ,eAAe,EAAE;AAClD,QAAI,UAAU,cAAc,OAAO,UAAU,eAAe,KAAK,YAAY,KAAK,KAC3E,OAAO,UAAU,eAAe,KAAK,YAAY,UAAU,GAAG;AACjE,YAAM,IAAI,MAAM,qCAAqC,UAAU,EAAE;AAAA,IACrE;AACA,WAAO,OAAO,UAAU,eAAe,KAAK,YAAY,KAAK,IAAI,WAAW,KAAK,IAAI,WAAW,UAAU;AAAA,EAC9G;AAAA,EAEA,OAAe,gBAAgB,KAAe,SAAuD;AACjG,UAAM,iBAAiB,QAAQ,kBAAkB,gBAAgB;AACjE,QAAI,mBAAmB,UAAU,CAAC,OAAO,OAAO,eAAe,EAAE,SAAS,cAAc,GAAG;AACvF,YAAM,IAAI,MAAM,qCAAqC,cAAc,EAAE;AAAA,IACzE;AACA,eAAW,OAAO,CAAC,QAAQ,YAAY,QAAQ,YAAY,QAAQ,cAAc,GAAG;AAChF,UAAI,QAAQ,WAAc,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,IAAI;AAC9E,cAAM,IAAI,MAAM,yFAAyF;AAAA,MAC7G;AAAA,IACJ;AACA,UAAM,QAAQ,QAAQ,UAAU,SAAY,IAAI,QAAQ;AACxD,QAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,EAAG,OAAM,IAAI,MAAM,uDAAuD;AACtH,UAAM,aAAuD,CAAC;AAC9D,eAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,QAAQ,cAAc,CAAC,CAAC,GAAG;AAChE,YAAM,WAAW,KAAK,kBAAkB,EAAE;AAC1C,UAAI,CAAC,CAAC,WAAW,UAAU,QAAQ,EAAE,SAAS,OAAO,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACjH,cAAM,IAAI,MAAM,yBAAyB,QAAQ,8CAA8C;AAAA,MACnG;AACA,UAAI,OAAO,UAAU,eAAe,KAAK,YAAY,QAAQ,EAAG,OAAM,IAAI,MAAM,oCAAoC,QAAQ,EAAE;AAC9H,iBAAW,QAAQ,IAAI;AAAA,IAC3B;AACA,UAAM,aAAsC,CAAC;AAC7C,eAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,QAAQ,cAAc,CAAC,CAAC,GAAG;AAChE,YAAM,YAAY,KAAK,kBAAkB,EAAE;AAC3C,UAAI,OAAO,UAAU,eAAe,KAAK,YAAY,SAAS,EAAG,OAAM,IAAI,MAAM,qCAAqC,SAAS,EAAE;AACjI,iBAAW,SAAS,IAAI,KAAK,aAAa,KAAK;AAAA,IACnD;AACA,UAAM,iBAA2C,CAAC;AAClD,eAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,QAAQ,kBAAkB,CAAC,CAAC,GAAG;AACpE,YAAM,YAAY,KAAK,kBAAkB,EAAE;AAC3C,UAAI,CAAC,WAAW,KAAK,KAAK,MAAM,cAAc,YAAY,MAAM,SAAS,QAAQ;AAC7E,cAAM,IAAI,MAAM,0BAA0B,SAAS,iCAAiC;AAAA,MACxF;AACA,WAAK,kBAAkB,GAAG,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE;AACzD,UAAI,OAAO,UAAU,eAAe,KAAK,gBAAgB,SAAS,EAAG,OAAM,IAAI,MAAM,qCAAqC,SAAS,EAAE;AACrI,qBAAe,SAAS,IAAI,OAAO,OAAO,IAAI,SAAS,IAAI,EAAE,GAAG,OAAO,EAAE,MAAM,MAAM,QAAQ,IAAI,KAAK,CAAC;AAAA,IAC3G;AACA,WAAO,EAAE,gBAAgB,YAAY,YAAY,OAAO,eAAe;AAAA,EAC3E;AAAA,EAEA,aAAqB,cAAc,KAAe,SAAsD;AACpG,QAAI,IAAI,SAAS,OAAQ,QAAO;AAChC,UAAM,WAAW,MAAM,eAAe,QAAQ,IAAI,IAAI;AACtD,UAAM,WAAW,MAAM,aAAa,IAAI,GAAG,IAAI,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAChF,YAAQ,aAAa,EAAE,GAAG,UAAU,GAAG,QAAQ,WAAW;AAC1D,QAAI,SAAS,SAAS,cAAc,QAAQ,IAAI,cAAc,qBACvD,CAAC,UAAU,iBAAiB,kBAAkB,EAAE,SAAS,IAAI,IAAI,KACjE,CAAC,OAAO,UAAU,eAAe,KAAK,QAAQ,YAAY,sCAAsC,KAChG,MAAM,UAAU,iBAAiB,QAAQ,WAAW,2BAA2B,GAAG,IAAI,IAAI,GAAG;AAChG,cAAQ,WAAW,sCAAsC,IAAI;AAAA,IACjE;AACA,WAAO,SAAS,SAAS,IAAI,IAAI,SAAS,SAAS,SAAS,cAAc,MAAM,IAAI,SAAS,SAAS,SAAS,cAAc,MAAM;AAAA,EACvI;AAAA,EAEA,OAAe,WAAW,SAA6C;AACnE,UAAM,iBAAiB,OAAO,YAAY,OAAO,QAAQ,QAAQ,cAAc,EAAE,IAAI,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC;AAC1H,WAAO,IAAI,KAAK,kBAAkB,IAAI,KAAK,UAAU,KAAK,aAAa,EAAE,GAAG,SAAS,eAAe,CAAC,CAAC,CAAC;AAAA,EAC3G;AAAA,EAEA,OAAe,aAAa,OAAgB,YAAY,oBAAI,IAAY,GAAY;AAChF,QAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,OAAO,UAAU,aAAa,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAC7I,QAAI,OAAO,UAAU,YAAY,UAAU,IAAI,KAAK,KAAK,CAAC,MAAM,QAAQ,KAAK,KACtE,OAAO,eAAe,KAAK,MAAM,OAAO,aAAa,OAAO,eAAe,KAAK,MAAM,MAAM;AAC/F,YAAM,IAAI,MAAM,qFAAqF;AAAA,IACzG;AACA,cAAU,IAAI,KAAK;AACnB,UAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,OAAO,WAAS,KAAK,aAAa,OAAO,SAAS,CAAC,IAC5F,OAAO,YAAY,OAAO,KAAK,KAAK,EAAE,KAAK,EAAE,IAAI,SAAO,CAAC,KAAK,KAAK,aAAc,MAAkC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC;AAC3I,cAAU,OAAO,KAAK;AACtB,WAAO;AAAA,EACX;AAAA,EAEA,OAAe,cAAc,MAAqB,SAA8C;AAC5F,UAAM,OAAO,KAAK,KAAK,QAAQ,eAAe,EAAE;AAChD,UAAM,WAAW,KAAK,WAAW,KAAK,kBAAkB,KAAK,QAAQ,IAAI;AACzE,QAAI,SAAS,YAAY,aAAa,4BAA6B,QAAO,QAAQ;AAClF,QAAI,YAAY,OAAO,UAAU,eAAe,KAAK,QAAQ,YAAY,QAAQ,EAAG,QAAO,QAAQ,WAAW,QAAQ;AACtH,UAAM,WAAW,SAAS,cAAc,QAAQ,SAAS,mBAAmB,IAAI;AAChF,UAAM,YAAY,CAAC,OAAe,QAAQ,WAAW,KAAK,kBAAkB,EAAE,CAAC;AAC/E,QAAI,aAAa,+BAA+B;AAC5C,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,EAAG,OAAM,IAAI,MAAM,kEAAkE;AACjI,YAAM,OAAO,UAAU,mBAAmB;AAC1C,UAAI,SAAS,OAAW,QAAO;AAC/B,UAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,EAAG,OAAM,IAAI,MAAM,kDAAkD;AAChI,YAAM,QAAQ,SAAS,cAAc,UAAU,SAAS,WAAW,YAAY;AAC/E,YAAM,SAAU,KAAiC,KAAK;AACtD,UAAI,WAAW,OAAW,QAAO;AACjC,UAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,OAAM,IAAI,MAAM,kCAAkC,KAAK,mBAAmB;AACtG,aAAO,QAAQ,OAAO,SAAS,OAAO,KAAK,IAAI;AAAA,IACnD;AACA,QAAI,SAAS,eAAe,aAAa,2BAA2B;AAChE,UAAI,KAAK,eAAgB,OAAM,IAAI,MAAM,wIAAwI;AACjL,aAAO,OAAO,UAAU,eAAe,KAAK,QAAQ,YAAY,KAAK,kBAAkB,KAAK,SAAU,CAAC;AAAA,IAC3G;AACA,QAAI,SAAS,UAAU;AACnB,cAAQ,UAAU;AAAA,QACd,KAAK;AAAuB,iBAAO,UAAU,KAAK,SAAU;AAAA,QAC5D,KAAK,yBAAyB;AAC1B,gBAAM,QAAQ,UAAU,aAAa;AACrC,cAAI,UAAU,OAAW,QAAO;AAChC,cAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,OAAM,IAAI,MAAM,4CAA4C;AAC7H,cAAI,OAAO,KAAK,yBAAyB,SAAU,OAAM,IAAI,MAAM,sDAAsD;AACzH,iBAAO,OAAO,UAAU,eAAe,KAAK,OAAO,KAAK,oBAAoB,IACrE,MAAkC,KAAK,oBAAoB,IAAI;AAAA,QAC1E;AAAA,QACA,KAAK,yBAAyB;AAC1B,gBAAM,cAAc,UAAU,qBAAqB;AACnD,cAAI,gBAAgB,OAAW,QAAO;AACtC,cAAI,CAAC,MAAM,QAAQ,WAAW,EAAG,OAAM,IAAI,MAAM,kEAAkE;AACnH,gBAAM,MAAM,YAAY,IAAI,WAAS;AACjC,gBAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,OAAM,IAAI,MAAM,kEAAkE;AACnJ,mBAAO,KAAK,kBAAmB,MAAyB,EAAE;AAAA,UAC9D,CAAC;AACD,iBAAO,CAAC,IAAI,SAAS,SAAS,IAAI,SAAS,2BAA2B,IAAI,WAAW;AAAA,QACzF;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,SAAS,qBAAqB,aAAa,sBAAsB,aAAa,oBAAoB;AAClG,YAAM,SAAS,aAAa;AAC5B,YAAM,mBAAmB,UAAU,SAAS,eAAe,gBAAgB;AAC3E,YAAM,UAAU,qBAAqB,SAAY,SAAS,IAAI,IAAI;AAClE,YAAM,kBAAkB,UAAU,QAAQ;AAC1C,YAAM,QAAQ,SAAS,oBAAoB,SAAY,IAAI,kBAAkB,QAAQ;AACrF,UAAI,OAAO,UAAU,YAAY,OAAO,YAAY,YAAY,UAAU,EAAG,OAAM,IAAI,MAAM,gBAAgB,QAAQ,wDAAwD;AAC7K,YAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,KAAK,CAAC;AACpD,aAAO,KAAK,cAAc,QAAQ,UAAU,UAAU;AAAA,IAC1D;AACA,WAAO;AAAA,EACX;AAAA,EAEA,OAAe,gBAAgB,MAAiC,KAAe,SAAwD;AACnI,QAAI,CAAC,QAAQ,OAAO,KAAK,SAAS,UAAU;AACxC,YAAM,IAAI,MAAM,yCAAyC,IAAI,mBAAmB,CAAC,EAAE;AAAA,IACvF;AACA,YAAQ,KAAK,KAAK,QAAQ,eAAe,EAAE,GAAG;AAAA,MAC1C,KAAK;AACD,YAAI,MAAM,QAAQ,KAAK,MAAM,EAAG,QAAO,EAAE,OAAO,KAAK,OAAO,IAAI,WAAS,KAAK,gBAAgB,OAAO,KAAK,OAAO,CAAC,EAAE;AACpH;AAAA,MACJ,KAAK,wBAAwB;AACzB,cAAM,OAAO,QAAQ,eAAe,gCAAgC;AACpE,eAAO,OAAO,EAAE,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE;AAAA,MACzC;AAAA,MACA,KAAK;AACD,YAAI,OAAO,KAAK,UAAU,YAAY,KAAK,MAAO,QAAO,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,MAAM;AAChG;AAAA,MACJ,KAAK,WAAW;AACZ,YAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,SAAS,OAAO,KAAK,UAAU,SAAU;AACjE,cAAM,UAAU,KAAK;AACrB,gBAAQ,QAAQ,MAAM;AAAA,UAClB,KAAK;AAAA,UACL,KAAK;AACD,gBAAI,mBAAmB,QAAQ,OAAO,KAC/B,CAAC,YAAY,WAAW,WAAW,MAAM,EAAE,SAAS,QAAQ,IAAI,EAAG,QAAO,EAAE,OAAO,KAAK,MAAM,QAAQ;AAC7G;AAAA,UACJ,KAAK;AAAA,UACL,KAAK;AACD,gBAAI,OAAO,QAAQ,UAAU,YAAY,OAAO,UAAU,eAAe,KAAK,YAAY,QAAQ,KAAK,EAAG,QAAO,EAAE,OAAO,KAAK,MAAM,QAAQ;AAC7I;AAAA,UACJ,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AACD,mBAAO,EAAE,OAAO,KAAK,MAAM,QAAQ;AAAA,UACvC,KAAK;AAAA,UACL,KAAK;AACD,gBAAI,OAAO,QAAQ,YAAY,YAAY,QAAQ,YAC3C,QAAQ,aAAa,UAAa,OAAO,QAAQ,aAAa,YAAY,OAAO,SAAS,QAAQ,QAAQ,OAC1G,QAAQ,gBAAgB,UAAa,CAAC,QAAQ,MAAM,SAAS,SAAS,QAAQ,MAAM,EAAE,SAAS,QAAQ,WAAW,IAAI;AAC1H,qBAAO,EAAE,OAAO,KAAK,MAAM,QAAQ;AAAA,YACvC;AACA;AAAA,UACJ,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AACD,gBAAI,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAS,QAAO,EAAE,OAAO,KAAK,MAAM,QAAQ;AAC/F;AAAA,UACJ,KAAK;AAAA,UACL,KAAK;AACD,gBAAI,OAAO,QAAQ,SAAS,YAAY,QAAQ,KAAM,QAAO,EAAE,OAAO,KAAK,MAAM,QAAQ;AACzF;AAAA,QACR;AACA,cAAM,IAAI,MAAM,qCAAqC,QAAQ,IAAI,QAAQ,IAAI,mBAAmB,CAAC,EAAE;AAAA,MACvG;AAAA,MACA,KAAK,aAAa;AACd,cAAM,QAAQ,KAAK,cAAc,MAAM,OAAO;AAC9C,YAAI,OAAO,UAAU,UAAW,OAAM,IAAI,MAAM,0BAA0B,KAAK,QAAQ,qBAAqB;AAC5G,eAAO,KAAK,gBAAgB,QAAQ,KAAK,UAAU,KAAK,UAAU,KAAK,OAAO;AAAA,MAClF;AAAA,MACA,KAAK,UAAU;AACX,cAAM,QAAQ,KAAK,cAAc,MAAM,OAAO;AAC9C,cAAM,YAAY,KAAK,YAAY,KAAK,kBAAkB,KAAK,QAAQ,MAAM;AAC7E,YAAI,CAAC,aAAa,UAAU,UAAa,OAAO,UAAU,SAAU,OAAM,IAAI,MAAM,yBAAyB,KAAK,QAAQ,oBAAoB;AAC9I,cAAM,UAAU,CAAC,cAAuB,YAClC,KAAK,UAAU,KAAK,aAAa,SAAS,CAAC,MAAM,KAAK,UAAU,KAAK,aAAa,KAAK,CAAC,IAAI,cAAc;AAChH,cAAM,WAAW,UAAU,SAAY,SACjC,KAAK,OAAO,KAAK,WAAS,QAAQ,MAAM,IAAI,KAAK,MAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,OAAO,CAAC,GAAG;AAC/G,eAAO,KAAK,gBAAgB,YAAY,KAAK,UAAU,KAAK,OAAO;AAAA,MACvE;AAAA,MACA,KAAK,kBAAkB;AACnB,cAAM,QAAQ,KAAK,cAAc,MAAM,OAAO;AAC9C,YAAI,OAAO,UAAU,SAAU,OAAM,IAAI,MAAM,sBAAsB,KAAK,QAAQ,oBAAoB;AACtG,YAAI,OAAO,MAAM,KAAK,EAAG,QAAO,KAAK,gBAAgB,KAAK,UAAU,KAAK,OAAO;AAChF,cAAM,SAAS,SAAS,KAAK,SAAS;AACtC,YAAI,CAAC,OAAO,SAAS,MAAM,EAAG,OAAM,IAAI,MAAM,sBAAsB,KAAK,QAAQ,oCAAoC;AACrH,cAAM,WAAW,KAAK,SAAS,OAAgE,CAAC,OAAO,UAAU;AAC7G,iBAAO,MAAM,aAAa,WAAW,CAAC,SAAS,MAAM,aAAa,MAAM,aAAa,QAAQ;AAAA,QACjG,GAAG,MAAS;AACZ,eAAO,KAAK,gBAAgB,UAAU,SAAS,KAAK,UAAU,KAAK,OAAO;AAAA,MAC9E;AAAA,IACJ;AACA,UAAM,IAAI,MAAM,0BAA0B,MAAM,QAAQ,YAAY,QAAQ,IAAI,mBAAmB,CAAC,EAAE;AAAA,EAC1G;AAAA;AAAA,EAGA,aAAoB,OAAO,KAAsC;AAC7D,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AACA,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AACA,UAAM,SAAS,IAAI,UAAU;AAE7B,WAAO,QAAQ,cAAc,IAAI,QAAQ,OAAK;AAC1C,aAAO,KAAK,iBAAiB,UAAU,YAAY,cAAc,MAAM,GAAG,QAAM;AAC5E,eAAO,YAAY,IAAW,KAAK,YAAY,KAAK;AAAA,MACxD,CAAC;AAAA,IACL,CAAC,EAAE,KAAK,WAAS;AACb,UAAI,OAAO;AACP,cAAM,MAAM;AAAA,MAChB;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,aAAoB,UAAU,KAAe,UAA4B,CAAC,GAA0B;AAChG,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AACA,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AACA,UAAM,UAAU,KAAK,gBAAgB,KAAK,OAAO;AACjD,QAAI,IAAI,SAAS,QAAQ;AACrB,YAAM,UAAU,MAAM,QAAQ,IAAI,SAAS,GAAG;AAC9C,YAAM,cAAc,WAAW,MAAM,KAAK,UAAU,SAAS,OAAO;AACpE,UAAI,YAAa,QAAO;AAAA,IAC5B;AACA,UAAM,UAAU,MAAM,KAAK,cAAc,KAAK,OAAO;AACrD,UAAM,SAAS,YAAY,cAAc,IAAI,UAAU,KAAK,IAAI,SAAS,SAAS,KAAK,WAAW,OAAO,IAAI,UAAU,GAAG;AAC1H,UAAM,QAAQ,MAAM,QAAQ,iBAAiB,IAAI,QAAQ,YAAY;AAEjE,YAAM,MAAM,IAAI,SAAS,SAAS,MAAM,KAAK,qBAAqB,KAAK,SAAS,OAAO,IAAI,MAAM,KAAK,OAAO,GAAG;AAChH,YAAM,SAAS,MAAM,MAAM,YAAY,iBAAiB,GAAG,IAAI;AAC/D,aAAO;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACX;AAAA;AAAA,EAGA,aAAoB,IAAI,KAAe,UAA4B,CAAC,GAA0B;AAC1F,WAAO,KAAK,UAAU,KAAK,OAAO;AAAA,EACtC;AAAA;AAAA,EAGA,aAAoB,aAAa;AAC7B,WAAO,KAAK,iBAAiB,MAAM;AAAA,EACvC;AAEJ;AAAA;AAxXa,OAGe,qBAAqB;","names":["model"]}
@@ -2,7 +2,7 @@
2
2
  import { TextWriter, Uint8ArrayReader, ZipReader } from "@zip.js/zip.js";
3
3
  import { AssetKey } from "../AssetKey.mjs";
4
4
  import { AssetLoader } from "../AssetLoader.mjs";
5
- import { DEFAULT_NAMESPACE } from "../Assets.mjs";
5
+ import { DEFAULT_NAMESPACE } from "../AssetDefaults.mjs";
6
6
  import { Caching } from "../../cache/Caching.mjs";
7
7
  import { AssetParser } from "../source/parser/AssetParsers.mjs";
8
8
  import { createCanvas } from "../../canvas/CanvasCompat.mjs";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/assets/_fonts/Unihex.ts"],"sourcesContent":["import { TextWriter, Uint8ArrayReader, ZipReader } from \"@zip.js/zip.js\";\nimport { AssetKey } from \"../AssetKey\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"../Assets\";\nimport { Caching } from \"../../cache/Caching\";\nimport { AssetParser } from \"../source/parser/AssetParsers\";\nimport { createCanvas, type CompatCanvas } from \"../../canvas/CanvasCompat\";\nimport type { BitmapGlyph } from \"../Fonts\";\nimport type { BinaryAsset } from \"../source/HostedAssetSource\";\n\nexport interface UnihexProvider {\n type: \"unihex\" | \"minecraft:unihex\";\n hex_file: string;\n size_overrides?: { from: string; to: string; left: number; right: number }[];\n}\n\ninterface HexGlyph {\n rows: Uint32Array;\n bitWidth: number;\n left: number;\n right: number;\n}\n\nexport interface UnihexFile {\n indices: Int32Array;\n rows: Uint32Array;\n metrics: Uint8Array;\n}\n\nconst ATLAS_SIZE = 512;\nconst GLYPH_HEIGHT = 16;\n\n/** Packs glyphs into shared pages only when their pixels or source rectangles are requested. */\nclass UnihexAtlas {\n private image?: CompatCanvas;\n private x = 0;\n private y = 0;\n\n public draw(glyph: HexGlyph): { image: CompatCanvas; x: number; y: number } {\n const width = glyph.right - glyph.left + 1;\n if (this.image && this.x + width > this.image.width) {\n this.x = 0;\n this.y += GLYPH_HEIGHT;\n }\n if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {\n this.image = createCanvas(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);\n this.x = 0;\n this.y = 0;\n }\n const context = this.image.getContext(\"2d\") as CanvasRenderingContext2D;\n const pixels = context.createImageData(width, GLYPH_HEIGHT);\n for (let y = 0; y < GLYPH_HEIGHT; y++) {\n for (let x = 0; x < width; x++) {\n const column = glyph.left + x;\n if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> (glyph.bitWidth - column - 1) & 1)) continue;\n pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);\n }\n }\n const result = { image: this.image, x: this.x, y: this.y };\n context.putImageData(pixels, this.x, this.y);\n this.x += width;\n return result;\n }\n}\n\nfunction readHex(text: string, filename: string, glyphs: Map<number, HexGlyph>): void {\n const lines = text.split(\"\\n\");\n if (lines[lines.length - 1] === \"\") lines.pop();\n lines.forEach((line, index) => {\n const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);\n if (!match || ![32, 64, 96, 128].includes(match[2].length)) {\n throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);\n }\n const codepoint = parseInt(match[1], 16);\n if (codepoint > 0x10ffff) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);\n const bitWidth = match[2].length / 4;\n const rowLength = bitWidth / 4;\n const rows = new Uint32Array(GLYPH_HEIGHT);\n let mask = 0;\n for (let y = 0; y < GLYPH_HEIGHT; y++) {\n rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);\n mask |= rows[y];\n }\n let left = 0, right = bitWidth;\n if (mask) {\n while (!(mask >>> (bitWidth - left - 1) & 1)) left++;\n right = bitWidth - 1;\n while (!(mask >>> (bitWidth - right - 1) & 1)) right--;\n }\n glyphs.set(codepoint, { rows, bitWidth, left, right });\n });\n}\n\nconst atlases = new WeakMap<UnihexProvider, UnihexAtlas>();\n\nasync function parseUnihex(key: AssetKey): Promise<UnihexFile | undefined> {\n try {\n const asset = await AssetLoader.get<BinaryAsset>(key, AssetParser.BINARY);\n if (!asset) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);\n const records = new Map<number, HexGlyph>();\n const reader = new ZipReader(new Uint8ArrayReader(asset.data), { useWebWorkers: false, useCompressionStream: false });\n try {\n for (const entry of await reader.getEntries()) {\n if (!entry.directory && entry.filename.endsWith(\".hex\")) {\n readHex(await entry.getData!(new TextWriter(), { checkSignature: true }), entry.filename, records);\n }\n }\n } finally {\n await reader.close();\n }\n const indices = new Int32Array(0x110000).fill(-1);\n const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);\n let index = 0;\n for (const [codepoint, record] of records) {\n indices[codepoint] = index;\n rows.set(record.rows, index * GLYPH_HEIGHT);\n metrics.set([record.bitWidth, record.left, record.right], index * 3);\n index++;\n }\n return { indices, rows, metrics };\n } catch (error) {\n console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);\n return undefined;\n }\n}\n\n/** Resolves Unihex characters with vanilla metrics and lazily rasterized, half-resolution glyphs. */\nexport async function loadUnihex(provider: UnihexProvider, fontKey: AssetKey, characters: string): Promise<Map<string, BitmapGlyph>> {\n const origin = new AssetKey(DEFAULT_NAMESPACE, \"\", undefined, undefined, \"assets\", \"\", fontKey.root);\n const key = AssetKey.parse(\"font\", provider.hex_file, origin);\n // Archive references already include their directory beneath the namespace root.\n key.assetType = undefined;\n const glyphs = new Map<string, BitmapGlyph>();\n let overrides;\n try {\n overrides = (provider.size_overrides ?? []).map(override => {\n const from = override.from.codePointAt(0), to = override.to.codePointAt(0);\n if ([...override.from].length !== 1 || [...override.to].length !== 1 || from! >= to!\n || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {\n throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);\n }\n return { ...override, from: from!, to: to! };\n });\n } catch (error) {\n console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);\n return glyphs;\n }\n const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));\n if (!file) return glyphs;\n let atlas = atlases.get(provider);\n if (!atlas) { atlas = new UnihexAtlas(); atlases.set(provider, atlas); }\n for (const character of characters) {\n const codepoint = character.codePointAt(0)!, index = file.indices[codepoint];\n if (index < 0) continue;\n const record = { rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),\n bitWidth: file.metrics[index * 3], left: file.metrics[index * 3 + 1], right: file.metrics[index * 3 + 2] };\n const override = overrides.find(range => codepoint >= range.from && codepoint <= range.to);\n if (override) { record.left = override.left; record.right = override.right; }\n const width = record.right - record.left + 1;\n let rendered: ReturnType<UnihexAtlas[\"draw\"]> | undefined;\n const render = () => rendered ??= atlas!.draw(record);\n glyphs.set(character, {\n get image() { return render().image; },\n get x() { return render().x; },\n get y() { return render().y; },\n width, height: GLYPH_HEIGHT, scale: 0.5, ascent: 7, advance: Math.floor(width / 2) + 1,\n boldOffset: 0.5, shadowOffset: 0.5\n });\n }\n return glyphs;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/assets/_fonts/Unihex.ts"],"sourcesContent":["import { TextWriter, Uint8ArrayReader, ZipReader } from \"@zip.js/zip.js\";\nimport { AssetKey } from \"../AssetKey\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"../AssetDefaults\";\nimport { Caching } from \"../../cache/Caching\";\nimport { AssetParser } from \"../source/parser/AssetParsers\";\nimport { createCanvas, type CompatCanvas } from \"../../canvas/CanvasCompat\";\nimport type { BitmapGlyph } from \"../Fonts\";\nimport type { BinaryAsset } from \"../source/HostedAssetSource\";\n\nexport interface UnihexProvider {\n type: \"unihex\" | \"minecraft:unihex\";\n hex_file: string;\n size_overrides?: { from: string; to: string; left: number; right: number }[];\n}\n\ninterface HexGlyph {\n rows: Uint32Array;\n bitWidth: number;\n left: number;\n right: number;\n}\n\nexport interface UnihexFile {\n indices: Int32Array;\n rows: Uint32Array;\n metrics: Uint8Array;\n}\n\nconst ATLAS_SIZE = 512;\nconst GLYPH_HEIGHT = 16;\n\n/** Packs glyphs into shared pages only when their pixels or source rectangles are requested. */\nclass UnihexAtlas {\n private image?: CompatCanvas;\n private x = 0;\n private y = 0;\n\n public draw(glyph: HexGlyph): { image: CompatCanvas; x: number; y: number } {\n const width = glyph.right - glyph.left + 1;\n if (this.image && this.x + width > this.image.width) {\n this.x = 0;\n this.y += GLYPH_HEIGHT;\n }\n if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {\n this.image = createCanvas(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);\n this.x = 0;\n this.y = 0;\n }\n const context = this.image.getContext(\"2d\") as CanvasRenderingContext2D;\n const pixels = context.createImageData(width, GLYPH_HEIGHT);\n for (let y = 0; y < GLYPH_HEIGHT; y++) {\n for (let x = 0; x < width; x++) {\n const column = glyph.left + x;\n if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> (glyph.bitWidth - column - 1) & 1)) continue;\n pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);\n }\n }\n const result = { image: this.image, x: this.x, y: this.y };\n context.putImageData(pixels, this.x, this.y);\n this.x += width;\n return result;\n }\n}\n\nfunction readHex(text: string, filename: string, glyphs: Map<number, HexGlyph>): void {\n const lines = text.split(\"\\n\");\n if (lines[lines.length - 1] === \"\") lines.pop();\n lines.forEach((line, index) => {\n const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);\n if (!match || ![32, 64, 96, 128].includes(match[2].length)) {\n throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);\n }\n const codepoint = parseInt(match[1], 16);\n if (codepoint > 0x10ffff) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);\n const bitWidth = match[2].length / 4;\n const rowLength = bitWidth / 4;\n const rows = new Uint32Array(GLYPH_HEIGHT);\n let mask = 0;\n for (let y = 0; y < GLYPH_HEIGHT; y++) {\n rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);\n mask |= rows[y];\n }\n let left = 0, right = bitWidth;\n if (mask) {\n while (!(mask >>> (bitWidth - left - 1) & 1)) left++;\n right = bitWidth - 1;\n while (!(mask >>> (bitWidth - right - 1) & 1)) right--;\n }\n glyphs.set(codepoint, { rows, bitWidth, left, right });\n });\n}\n\nconst atlases = new WeakMap<UnihexProvider, UnihexAtlas>();\n\nasync function parseUnihex(key: AssetKey): Promise<UnihexFile | undefined> {\n try {\n const asset = await AssetLoader.get<BinaryAsset>(key, AssetParser.BINARY);\n if (!asset) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);\n const records = new Map<number, HexGlyph>();\n const reader = new ZipReader(new Uint8ArrayReader(asset.data), { useWebWorkers: false, useCompressionStream: false });\n try {\n for (const entry of await reader.getEntries()) {\n if (!entry.directory && entry.filename.endsWith(\".hex\")) {\n readHex(await entry.getData!(new TextWriter(), { checkSignature: true }), entry.filename, records);\n }\n }\n } finally {\n await reader.close();\n }\n const indices = new Int32Array(0x110000).fill(-1);\n const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);\n let index = 0;\n for (const [codepoint, record] of records) {\n indices[codepoint] = index;\n rows.set(record.rows, index * GLYPH_HEIGHT);\n metrics.set([record.bitWidth, record.left, record.right], index * 3);\n index++;\n }\n return { indices, rows, metrics };\n } catch (error) {\n console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);\n return undefined;\n }\n}\n\n/** Resolves Unihex characters with vanilla metrics and lazily rasterized, half-resolution glyphs. */\nexport async function loadUnihex(provider: UnihexProvider, fontKey: AssetKey, characters: string): Promise<Map<string, BitmapGlyph>> {\n const origin = new AssetKey(DEFAULT_NAMESPACE, \"\", undefined, undefined, \"assets\", \"\", fontKey.root);\n const key = AssetKey.parse(\"font\", provider.hex_file, origin);\n // Archive references already include their directory beneath the namespace root.\n key.assetType = undefined;\n const glyphs = new Map<string, BitmapGlyph>();\n let overrides;\n try {\n overrides = (provider.size_overrides ?? []).map(override => {\n const from = override.from.codePointAt(0), to = override.to.codePointAt(0);\n if ([...override.from].length !== 1 || [...override.to].length !== 1 || from! >= to!\n || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {\n throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);\n }\n return { ...override, from: from!, to: to! };\n });\n } catch (error) {\n console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);\n return glyphs;\n }\n const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));\n if (!file) return glyphs;\n let atlas = atlases.get(provider);\n if (!atlas) { atlas = new UnihexAtlas(); atlases.set(provider, atlas); }\n for (const character of characters) {\n const codepoint = character.codePointAt(0)!, index = file.indices[codepoint];\n if (index < 0) continue;\n const record = { rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),\n bitWidth: file.metrics[index * 3], left: file.metrics[index * 3 + 1], right: file.metrics[index * 3 + 2] };\n const override = overrides.find(range => codepoint >= range.from && codepoint <= range.to);\n if (override) { record.left = override.left; record.right = override.right; }\n const width = record.right - record.left + 1;\n let rendered: ReturnType<UnihexAtlas[\"draw\"]> | undefined;\n const render = () => rendered ??= atlas!.draw(record);\n glyphs.set(character, {\n get image() { return render().image; },\n get x() { return render().x; },\n get y() { return render().y; },\n width, height: GLYPH_HEIGHT, scale: 0.5, ascent: 7, advance: Math.floor(width / 2) + 1,\n boldOffset: 0.5, shadowOffset: 0.5\n });\n }\n return glyphs;\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,5 @@
1
1
  // src/assets/index.ts
2
+ export * from "./AssetDefaults.mjs";
2
3
  export * from "./AssetKey.mjs";
3
4
  export * from "./AssetLoader.mjs";
4
5
  export * from "./Assets.mjs";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/assets/index.ts"],"sourcesContent":["// autogenerated\nexport * from './AssetKey';\nexport * from './AssetLoader';\nexport * from './Assets';\nexport * from './BannerPatterns';\nexport * from './Biomes';\nexport * from './BlockEntities';\nexport * from './BlockStates';\nexport * from './DecoratedPots';\nexport * from './Entities';\nexport * from './Fonts';\nexport * from './MineRenderData';\nexport * from './ModelTextures';\nexport * from './Models';\nexport * from './Renames';\nexport * from './source';\n"],"mappings":";AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../../src/assets/index.ts"],"sourcesContent":["// autogenerated\nexport * from './AssetDefaults';\nexport * from './AssetKey';\nexport * from './AssetLoader';\nexport * from './Assets';\nexport * from './BannerPatterns';\nexport * from './Biomes';\nexport * from './BlockEntities';\nexport * from './BlockStates';\nexport * from './DecoratedPots';\nexport * from './Entities';\nexport * from './Fonts';\nexport * from './MineRenderData';\nexport * from './ModelTextures';\nexport * from './Models';\nexport * from './Renames';\nexport * from './source';\n"],"mappings":";AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -4,7 +4,7 @@ import { prefix } from "../../util/index.mjs";
4
4
  import { NBTHelper } from "../../nbt/index.mjs";
5
5
  import { ImageLoader } from "../../image/index.mjs";
6
6
  import { AssetKey } from "../AssetKey.mjs";
7
- import { DEFAULT_NAMESPACE } from "../Assets.mjs";
7
+ import { DEFAULT_NAMESPACE } from "../AssetDefaults.mjs";
8
8
  import { RequestError, Requests } from "../../request/index.mjs";
9
9
  import { AssetLoader } from "../AssetLoader.mjs";
10
10
  import { AssetParser } from "./parser/index.mjs";