roavatar-renderer 1.2.5 → 1.2.7

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.
package/dist/index.js CHANGED
@@ -27346,6 +27346,9 @@ const animNamesR15 = {
27346
27346
  ],
27347
27347
  toollunge: [
27348
27348
  { id: "http://www.roblox.com/asset/?id=522638767", weight: 10 }
27349
+ ],
27350
+ mood: [
27351
+ { id: "http://www.roblox.com/asset/?id=14366558676", weight: 10 }
27349
27352
  ]
27350
27353
  /*wave: [
27351
27354
  { id: "http://www.roblox.com/asset/?id=507770239", weight: 10 }
@@ -28284,7 +28287,7 @@ const FLAGS = {
28284
28287
  HSR_SHOW_RAY: false,
28285
28288
  HIDE_LAYERED_CLOTHING: false,
28286
28289
  HSR_RAY_COUNT: 3,
28287
- HSR_RAY_LENGTH: 0.5,
28290
+ HSR_RAY_LENGTH: 0.4,
28288
28291
  CACHE_HSR_HITS: true,
28289
28292
  //debug
28290
28293
  SEARCH_FOR_STRING: void 0,
@@ -30328,6 +30331,9 @@ class RNG {
30328
30331
  return this.nextInt() / (this.m - 1);
30329
30332
  }
30330
30333
  }
30334
+ function cleanString(inputString) {
30335
+ return inputString.replace("'", "").replace(/[^a-zA-Z0-9]/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
30336
+ }
30331
30337
  function getXMLProperty(doc, propertyName) {
30332
30338
  const propertyNode = doc.querySelector('[name="' + propertyName + '"]');
30333
30339
  if (!propertyNode) {
@@ -30624,11 +30630,14 @@ class ItemInfo {
30624
30630
  price;
30625
30631
  limitedType;
30626
30632
  offsale;
30627
- constructor(itemType, type, id, name2) {
30633
+ supportsHeadShapes;
30634
+ headShape;
30635
+ constructor(itemType, type, id, name2, supportsHeadShapes) {
30628
30636
  this.itemType = itemType;
30629
30637
  this.type = type;
30630
30638
  this.id = id;
30631
30639
  this.name = name2;
30640
+ this.supportsHeadShapes = supportsHeadShapes;
30632
30641
  }
30633
30642
  }
30634
30643
  class AssetType {
@@ -30688,6 +30697,7 @@ class AssetMeta {
30688
30697
  copy.order = this.order;
30689
30698
  copy.puffiness = this.puffiness;
30690
30699
  copy.headShape = this.headShape;
30700
+ copy.staticFacialAnimation = this.staticFacialAnimation;
30691
30701
  if (this.position) copy.position = cloneVecXYZ(this.position);
30692
30702
  if (this.rotation) copy.rotation = cloneVecXYZ(this.rotation);
30693
30703
  if (this.scale) copy.scale = cloneVecXYZ(this.scale);
@@ -30736,11 +30746,9 @@ class AssetMeta {
30736
30746
  this.scale = toVecXYZ(assetMetaJson.scale);
30737
30747
  }
30738
30748
  if (assetMetaJson.headShape && assetMetaJson.headShape !== "Invalid") {
30739
- this.headShape = assetMetaJson.headShape;
30740
- }
30741
- if (assetMetaJson.staticFacialAnimation) {
30742
- this.staticFacialAnimation = assetMetaJson.staticFacialAnimation;
30749
+ this.headShape = String(assetMetaJson.headShape);
30743
30750
  }
30751
+ this.staticFacialAnimation = assetMetaJson.staticFacialAnimation;
30744
30752
  }
30745
30753
  }
30746
30754
  let uuidCount = 0;
@@ -31540,7 +31548,7 @@ class Outfit {
31540
31548
  }
31541
31549
  }
31542
31550
  }
31543
- addAsset(id, type, name2) {
31551
+ addAsset(id, type, name2, supportsHeadShapes) {
31544
31552
  if (this.containsAsset(id)) {
31545
31553
  return;
31546
31554
  }
@@ -31565,6 +31573,9 @@ class Outfit {
31565
31573
  const asset = new Asset();
31566
31574
  asset.id = id;
31567
31575
  asset.name = name2;
31576
+ if (supportsHeadShapes !== void 0) {
31577
+ asset.supportsHeadShapes = supportsHeadShapes;
31578
+ }
31568
31579
  asset.assetType = new AssetType();
31569
31580
  asset.assetType.id = typeId;
31570
31581
  if (LayeredClothingAssetOrder[asset.assetType.id]) {
@@ -31603,7 +31614,20 @@ class Outfit {
31603
31614
  }
31604
31615
  return order;
31605
31616
  }
31606
- async addAssetId(assetId) {
31617
+ async addAssetId(assetId, auth) {
31618
+ const assetDetailsResponse = await API.Catalog.GetItemDetails(auth, [{ itemType: "Asset", id: assetId }]);
31619
+ if (assetDetailsResponse instanceof Response) {
31620
+ return false;
31621
+ }
31622
+ const assetDetails = assetDetailsResponse;
31623
+ if (assetDetails.data.length > 0) {
31624
+ this.addAsset(assetId, assetDetails.data[0].assetType, assetDetails.data[0].name, assetDetails.data[0].supportsHeadShapes);
31625
+ } else {
31626
+ return this.addAssetIdEconomy(assetId);
31627
+ }
31628
+ return true;
31629
+ }
31630
+ async addAssetIdEconomy(assetId) {
31607
31631
  const assetDetailsResponse = await API.Economy.GetAssetDetails(assetId);
31608
31632
  if (assetDetailsResponse.status !== 200) {
31609
31633
  return false;
@@ -31624,7 +31648,7 @@ class Outfit {
31624
31648
  const result = await API.Avatar.GetOutfitDetails(item.id, this.creatorId || 1);
31625
31649
  if (result instanceof Outfit) {
31626
31650
  for (const asset of result.assets) {
31627
- this.addAsset(asset.id, asset.assetType.id, asset.name);
31651
+ this.addAsset(asset.id, asset.assetType.id, asset.name, asset.supportsHeadShapes);
31628
31652
  }
31629
31653
  if (bundleType === "Character") {
31630
31654
  this.scale = result.scale.clone();
@@ -31646,7 +31670,7 @@ class Outfit {
31646
31670
  }
31647
31671
  }
31648
31672
  }
31649
- async fromLook(look) {
31673
+ async fromLook(look, auth) {
31650
31674
  this.origin = "Look";
31651
31675
  this.creatorId = look.curator.id;
31652
31676
  this.creationDate = new Date(look.createdTime).getUTCMilliseconds();
@@ -31659,9 +31683,35 @@ class Outfit {
31659
31683
  if (item.itemType === "Asset" && item.assetType !== null) {
31660
31684
  this.addAsset(item.id, item.assetType, item.name);
31661
31685
  } else if (item.itemType === "Bundle") {
31686
+ const assetsList = [];
31687
+ const assetMetaList = [];
31688
+ const assetIdList = [];
31662
31689
  for (const asset of item.assetsInBundle) {
31663
31690
  if (asset.isIncluded) {
31664
- assetPromises.push(this.addAssetId(asset.id));
31691
+ assetsList.push({ itemType: "Asset", id: asset.id });
31692
+ if (asset.meta) {
31693
+ assetMetaList.push(asset.meta);
31694
+ } else {
31695
+ assetMetaList.push(void 0);
31696
+ }
31697
+ assetIdList.push(asset.id);
31698
+ }
31699
+ }
31700
+ const assetDetails = await API.Catalog.GetItemDetails(auth, assetsList);
31701
+ if (assetDetails instanceof Response) {
31702
+ return false;
31703
+ } else {
31704
+ for (const assetDetail of assetDetails.data) {
31705
+ this.addAsset(assetDetail.id, assetDetail.assetType, assetDetail.name, assetDetail.supportsHeadShapes);
31706
+ const index = assetIdList.indexOf(assetDetail.id);
31707
+ const meta = assetMetaList[index];
31708
+ if (meta) {
31709
+ const addedAsset = this.getAssetId(assetDetail.id);
31710
+ if (addedAsset) {
31711
+ addedAsset.meta = new AssetMeta();
31712
+ addedAsset.meta.fromJson(meta);
31713
+ }
31714
+ }
31665
31715
  }
31666
31716
  }
31667
31717
  }
@@ -31683,7 +31733,7 @@ class Outfit {
31683
31733
  }
31684
31734
  return true;
31685
31735
  }
31686
- async fromBuffer(buffer) {
31736
+ async fromBuffer(buffer, auth) {
31687
31737
  const view = new SimpleView(buffer);
31688
31738
  const outfitFlags = view.readUint8();
31689
31739
  const allSameColor = !!(outfitFlags & 2);
@@ -31714,6 +31764,7 @@ class Outfit {
31714
31764
  this.bodyColors[bodyColor] = color;
31715
31765
  }
31716
31766
  }
31767
+ const assetsToAdd = [];
31717
31768
  const assetPromises = [];
31718
31769
  while (view.viewOffset < view.buffer.byteLength) {
31719
31770
  const flags = view.readUint8();
@@ -31749,36 +31800,65 @@ class Outfit {
31749
31800
  const scaleZ = mapNum(view.readUint8(), 0, 255, 0.5, 2);
31750
31801
  assetScale = { X: scaleX, Y: scaleY, Z: scaleZ };
31751
31802
  }
31752
- let assetHeadShape = void 0;
31753
31803
  if (flags & 32) {
31754
- assetHeadShape = Number(view.readUint64());
31804
+ view.readUint64();
31805
+ }
31806
+ let assetHeadShape = void 0;
31807
+ if (flags & 128) {
31808
+ assetHeadShape = view.readUtf8String();
31755
31809
  }
31756
31810
  let staticFacialAnimation = void 0;
31757
31811
  if (flags & 64) {
31758
31812
  staticFacialAnimation = true;
31759
31813
  }
31760
- assetPromises.push(new Promise((resolve) => {
31761
- this.addAssetId(id).then(() => {
31762
- let asset = void 0;
31763
- for (const assetIn of this.assets) {
31764
- if (assetIn.id === id) {
31765
- asset = assetIn;
31766
- }
31767
- }
31768
- if (asset && (assetOrder || assetPos || assetRot || assetScale || assetHeadShape !== void 0)) {
31769
- asset.meta = new AssetMeta();
31770
- asset.meta.order = assetOrder;
31771
- asset.meta.position = assetPos;
31772
- asset.meta.rotation = assetRot;
31773
- asset.meta.scale = assetScale;
31774
- asset.meta.headShape = assetHeadShape;
31775
- asset.meta.staticFacialAnimation = staticFacialAnimation;
31776
- }
31777
- resolve(void 0);
31778
- });
31779
- }));
31814
+ let meta = void 0;
31815
+ if (assetOrder || assetPos || assetRot || assetScale || assetHeadShape !== void 0) {
31816
+ meta = new AssetMeta();
31817
+ meta.order = assetOrder;
31818
+ meta.position = assetPos;
31819
+ meta.rotation = assetRot;
31820
+ meta.scale = assetScale;
31821
+ meta.headShape = assetHeadShape;
31822
+ meta.staticFacialAnimation = staticFacialAnimation;
31823
+ }
31824
+ assetsToAdd.push({
31825
+ id,
31826
+ meta
31827
+ });
31828
+ }
31829
+ const assetDetailsRequest = [];
31830
+ for (const assetToAdd of assetsToAdd) {
31831
+ assetDetailsRequest.push({ itemType: "Asset", id: assetToAdd.id });
31832
+ }
31833
+ const assetDetails = await API.Catalog.GetItemDetails(auth, assetDetailsRequest);
31834
+ if (assetDetails instanceof Response) {
31835
+ return assetDetails;
31836
+ }
31837
+ for (const assetDetail of assetDetails.data) {
31838
+ this.addAsset(assetDetail.id, assetDetail.assetType, assetDetail.name, assetDetail.supportsHeadShapes);
31839
+ }
31840
+ for (const asset of assetsToAdd) {
31841
+ const assetId = asset.id;
31842
+ if (assetId && !this.getAssetId(assetId)) {
31843
+ assetPromises.push(new Promise((resolve) => {
31844
+ this.addAssetIdEconomy(assetId).then(() => {
31845
+ resolve(void 0);
31846
+ });
31847
+ }));
31848
+ }
31780
31849
  }
31781
31850
  await Promise.all(assetPromises);
31851
+ for (const assetToAdd of assetsToAdd) {
31852
+ let asset = void 0;
31853
+ for (const assetIn of this.assets) {
31854
+ if (assetIn.id === assetToAdd.id) {
31855
+ asset = assetIn;
31856
+ }
31857
+ }
31858
+ if (asset) {
31859
+ asset.meta = assetToAdd.meta;
31860
+ }
31861
+ }
31782
31862
  this.fixOrders();
31783
31863
  return this;
31784
31864
  }
@@ -31815,7 +31895,7 @@ class Outfit {
31815
31895
  if (pos) bufferSize += 3;
31816
31896
  if (rot) bufferSize += 3;
31817
31897
  if (scale) bufferSize += 3;
31818
- if (headShape !== void 0) bufferSize += 8;
31898
+ if (headShape !== void 0) bufferSize += 4 + headShape.length;
31819
31899
  }
31820
31900
  const buffer = new ArrayBuffer(bufferSize);
31821
31901
  const view = new SimpleView(buffer);
@@ -31880,8 +31960,8 @@ class Outfit {
31880
31960
  if (rot) flags += 4;
31881
31961
  if (scale) flags += 8;
31882
31962
  if (idIs64bit) flags += 16;
31883
- if (headShape !== void 0) flags += 32;
31884
31963
  if (asset.meta?.staticFacialAnimation) flags += 64;
31964
+ if (headShape) flags += 128;
31885
31965
  view.writeUint8(flags);
31886
31966
  if (!idIs64bit) {
31887
31967
  view.writeUint32(id);
@@ -31906,8 +31986,8 @@ class Outfit {
31906
31986
  view.writeUint8(Math.floor(mapNum(scale.Y, 0.5, 2, 0, 255)));
31907
31987
  view.writeUint8(Math.floor(mapNum(scale.Z, 0.5, 2, 0, 255)));
31908
31988
  }
31909
- if (headShape !== void 0) {
31910
- view.writeUint64(BigInt(headShape));
31989
+ if (headShape) {
31990
+ view.writeUtf8String(headShape);
31911
31991
  }
31912
31992
  }
31913
31993
  return view.buffer;
@@ -31949,15 +32029,184 @@ class LocalOutfit {
31949
32029
  this.buffer = arrayBufferToBase64(outfit.toBuffer());
31950
32030
  this.image = void 0;
31951
32031
  }
31952
- async toOutfit() {
32032
+ async toOutfit(auth) {
31953
32033
  const outfit = new Outfit();
31954
32034
  outfit.name = this.name;
31955
32035
  outfit.id = this.id;
31956
32036
  outfit.creatorId = this.creator;
31957
- await outfit.fromBuffer(base64ToArrayBuffer(this.buffer));
32037
+ await outfit.fromBuffer(base64ToArrayBuffer(this.buffer), auth);
31958
32038
  return outfit;
31959
32039
  }
31960
32040
  }
32041
+ class ItemSort {
32042
+ subType;
32043
+ itemType;
32044
+ constructor(subType, itemType = "Asset") {
32045
+ this.subType = subType;
32046
+ this.itemType = itemType;
32047
+ }
32048
+ }
32049
+ class SortInfo {
32050
+ sortOption;
32051
+ itemCategories = [];
32052
+ constructor(itemCategories, sortOption = "1") {
32053
+ this.itemCategories = itemCategories;
32054
+ this.sortOption = sortOption;
32055
+ }
32056
+ }
32057
+ class SpecialInfo {
32058
+ type;
32059
+ constructor(type) {
32060
+ this.type = type;
32061
+ }
32062
+ }
32063
+ const AllAccessorySorts = [
32064
+ new ItemSort(19),
32065
+ new ItemSort(8),
32066
+ new ItemSort(42),
32067
+ new ItemSort(43),
32068
+ new ItemSort(44),
32069
+ new ItemSort(45),
32070
+ new ItemSort(46),
32071
+ new ItemSort(47)
32072
+ ];
32073
+ if (!FLAGS.HAIR_IS_BODYPART) {
32074
+ AllAccessorySorts.push(new ItemSort(41));
32075
+ }
32076
+ const AllClothingSorts = [
32077
+ new ItemSort(12),
32078
+ new ItemSort(11),
32079
+ new ItemSort(2),
32080
+ new ItemSort(72),
32081
+ new ItemSort(67),
32082
+ new ItemSort(70),
32083
+ new ItemSort(71),
32084
+ new ItemSort(66),
32085
+ new ItemSort(65),
32086
+ new ItemSort(69),
32087
+ new ItemSort(68),
32088
+ new ItemSort(64)
32089
+ ];
32090
+ const AllBodyPartsSorts = [
32091
+ new ItemSort(18),
32092
+ new ItemSort(17),
32093
+ new ItemSort(29),
32094
+ new ItemSort(30),
32095
+ new ItemSort(28),
32096
+ new ItemSort(31),
32097
+ new ItemSort(27)
32098
+ ];
32099
+ if (FLAGS.HAIR_IS_BODYPART) {
32100
+ AllBodyPartsSorts.push(new ItemSort(41));
32101
+ }
32102
+ const AllAnimationSorts = [
32103
+ new ItemSort(48),
32104
+ new ItemSort(50),
32105
+ new ItemSort(51),
32106
+ new ItemSort(52),
32107
+ new ItemSort(53),
32108
+ new ItemSort(54),
32109
+ new ItemSort(55)
32110
+ //new ItemSort(61)
32111
+ ];
32112
+ const AllCharacterSorts = [
32113
+ new ItemSort(1, "Outfit"),
32114
+ new ItemSort(5, "Outfit")
32115
+ ];
32116
+ const CategoryDictionary = {
32117
+ "Inventory": {
32118
+ "Recent": {
32119
+ "All": new SortInfo([], "recentAdded"),
32120
+ "Recent Worn": new SortInfo([], "2"),
32121
+ "Accessories": new SortInfo(AllAccessorySorts, "recentEquipped"),
32122
+ "Clothing": new SortInfo(AllClothingSorts, "recentEquipped"),
32123
+ "Body": new SortInfo(AllBodyPartsSorts, "recentEquipped"),
32124
+ "Animations": new SortInfo(AllAnimationSorts, "recentEquipped"),
32125
+ "Characters": new SortInfo([new ItemSort(1, "Outfit")], "recentEquipped")
32126
+ },
32127
+ "Avatars": {
32128
+ "Creations": new SortInfo([new ItemSort(3, "Outfit")]),
32129
+ "Purchased": new SortInfo(AllCharacterSorts),
32130
+ "Local": new SpecialInfo("LocalOutfits"),
32131
+ "Published": new SpecialInfo("Looks")
32132
+ },
32133
+ "Clothing": {
32134
+ "All": new SortInfo(AllClothingSorts),
32135
+ "Shirts": new SortInfo([new ItemSort(AssetTypeNameToId.get("Shirt") || 0)]),
32136
+ "Pants": new SortInfo([new ItemSort(AssetTypeNameToId.get("Pants") || 0)]),
32137
+ "T-Shirts": new SortInfo([new ItemSort(AssetTypeNameToId.get("TShirt") || 0)]),
32138
+ "Tops": new SortInfo([new ItemSort(AssetTypeNameToId.get("TShirtAccessory") || 0), new ItemSort(AssetTypeNameToId.get("ShirtAccessory") || 0), new ItemSort(AssetTypeNameToId.get("SweaterAccessory") || 0)]),
32139
+ "Outerwear": new SortInfo([new ItemSort(AssetTypeNameToId.get("JacketAccessory") || 0)]),
32140
+ "Bottoms": new SortInfo([new ItemSort(AssetTypeNameToId.get("PantsAccessory") || 0), new ItemSort(AssetTypeNameToId.get("ShortsAccessory") || 0), new ItemSort(AssetTypeNameToId.get("DressSkirtAccessory") || 0)]),
32141
+ "Shoes": new SortInfo([new ItemSort(AssetTypeNameToId.get("LeftShoeAccessory") || 0), new ItemSort(AssetTypeNameToId.get("RightShoeAccessory") || 0)])
32142
+ },
32143
+ "Accessories": {
32144
+ "All": new SortInfo(AllAccessorySorts),
32145
+ "Hair": new SortInfo([new ItemSort(41)]),
32146
+ "Head": new SortInfo([new ItemSort(AssetTypeNameToId.get("Hat") || 0)]),
32147
+ "Face": new SortInfo([new ItemSort(AssetTypeNameToId.get("FaceAccessory") || 0)]),
32148
+ "Neck": new SortInfo([new ItemSort(AssetTypeNameToId.get("NeckAccessory") || 0)]),
32149
+ "Shoulders": new SortInfo([new ItemSort(AssetTypeNameToId.get("ShoulderAccessory") || 0)]),
32150
+ "Front": new SortInfo([new ItemSort(AssetTypeNameToId.get("FrontAccessory") || 0)]),
32151
+ "Back": new SortInfo([new ItemSort(AssetTypeNameToId.get("BackAccessory") || 0)]),
32152
+ "Waist": new SortInfo([new ItemSort(AssetTypeNameToId.get("WaistAccessory") || 0)]),
32153
+ "Gear": new SortInfo([new ItemSort(AssetTypeNameToId.get("Gear") || 0)])
32154
+ },
32155
+ "Head": {
32156
+ "Dynamic Heads": new SortInfo([new ItemSort(2, "Outfit")]),
32157
+ "Adjustment": new SpecialInfo("HeadAdjustment"),
32158
+ "Heads": new SortInfo([new ItemSort(17)], "inventory"),
32159
+ "Faces": new SortInfo([new ItemSort(18)], "inventory")
32160
+ },
32161
+ "Body": {
32162
+ "Skin Color": new SpecialInfo("Skin Color"),
32163
+ "Scale": new SpecialInfo("Scale"),
32164
+ "Torso": new SortInfo([new ItemSort(27)]),
32165
+ "Left Arm": new SortInfo([new ItemSort(29)]),
32166
+ "Right Arm": new SortInfo([new ItemSort(28)]),
32167
+ "Left Leg": new SortInfo([new ItemSort(30)]),
32168
+ "Right Leg": new SortInfo([new ItemSort(31)])
32169
+ },
32170
+ "Makeup": {
32171
+ "Eyebrows": new SortInfo([new ItemSort(AssetTypeNameToId.get("EyebrowAccessory") || 0)], "inventory"),
32172
+ "Eyelashes": new SortInfo([new ItemSort(AssetTypeNameToId.get("EyelashAccessory") || 0)], "inventory"),
32173
+ "Lip": new SortInfo([new ItemSort(AssetTypeNameToId.get("LipMakeup") || 0)], "inventory"),
32174
+ "Face": new SortInfo([new ItemSort(AssetTypeNameToId.get("FaceMakeup") || 0)], "inventory"),
32175
+ "Eye": new SortInfo([new ItemSort(AssetTypeNameToId.get("EyeMakeup") || 0)], "inventory")
32176
+ },
32177
+ "Animations": {
32178
+ "All": new SortInfo(AllAnimationSorts),
32179
+ "Emotes": new SpecialInfo("Emotes"),
32180
+ "_Emotes": new SortInfo([new ItemSort(AssetTypeNameToId.get("EmoteAnimation") || 0)]),
32181
+ "Idle": new SortInfo([new ItemSort(51)]),
32182
+ "Walk": new SortInfo([new ItemSort(55)]),
32183
+ "Run": new SortInfo([new ItemSort(53)]),
32184
+ "Fall": new SortInfo([new ItemSort(50)]),
32185
+ "Jump": new SortInfo([new ItemSort(52)]),
32186
+ "Swim": new SortInfo([new ItemSort(54)]),
32187
+ "Climb": new SortInfo([new ItemSort(48)]),
32188
+ "Mood": new SortInfo([new ItemSort(AssetTypeNameToId.get("MoodAnimation") || 0)], "inventory")
32189
+ }
32190
+ }
32191
+ };
32192
+ const DefaultSearchData = {
32193
+ "Inventory": {
32194
+ includeOffsale: true,
32195
+ limitedOnly: false
32196
+ },
32197
+ "Marketplace": {
32198
+ includeOffsale: false,
32199
+ limitedOnly: false
32200
+ }
32201
+ };
32202
+ const SortTypes = {
32203
+ "Relevance": void 0,
32204
+ "MostFavorited": 1,
32205
+ "MostPopular": 2,
32206
+ "RecentlyPublished": 3,
32207
+ "PriceHighToLow": 5,
32208
+ "PriceLowToHigh": 4
32209
+ };
31961
32210
  class KDNode {
31962
32211
  point;
31963
32212
  index;
@@ -34492,9 +34741,9 @@ async function RBLXDelete(url, auth, body, attempt = 0) {
34492
34741
  async function RBLXPatch(url, auth, body, attempt = 0) {
34493
34742
  return RBLXPost(url, auth, body, attempt, "PATCH");
34494
34743
  }
34495
- async function getAssetBufferInternal(url, headers) {
34744
+ async function getAssetBufferInternal(url, headers, extraStr) {
34496
34745
  API.Misc.startCurrentlyLoadingAssets();
34497
- const fetchStr = await API.Misc.assetURLToCDNURL(url, headers);
34746
+ const fetchStr = await API.Misc.assetURLToCDNURL(url, headers, extraStr);
34498
34747
  if (fetchStr instanceof Response) {
34499
34748
  API.Misc.stopCurrentlyLoadingAssets();
34500
34749
  return fetchStr;
@@ -34612,10 +34861,13 @@ const API = {
34612
34861
  }
34613
34862
  },
34614
34863
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
34615
- "assetURLToCDNURL": async function(url, headers) {
34864
+ "assetURLToCDNURL": async function(url, headers, extraStr) {
34616
34865
  url = String(url);
34617
- if (url.includes("rbxcdn.com")) return url;
34618
- const fetchStr = API.Misc.parseAssetString(url) || url;
34866
+ if (url.includes("rbxcdn.com")) return extraStr ? url + extraStr : url;
34867
+ let fetchStr = API.Misc.parseAssetString(url) || url;
34868
+ if (extraStr) {
34869
+ fetchStr += extraStr;
34870
+ }
34619
34871
  const cdnURL = await API.Misc.getCDNURLFromAssetDelivery(fetchStr, headers);
34620
34872
  return cdnURL;
34621
34873
  }
@@ -34790,6 +35042,10 @@ const API = {
34790
35042
  return response;
34791
35043
  }
34792
35044
  },
35045
+ GetHeadShapes: async function(pageToken) {
35046
+ const itemSort = new ItemSort(1, "headshape");
35047
+ return API.Avatar.GetAvatarInventory("1", pageToken, [itemSort]);
35048
+ },
34793
35049
  GetAvatarInventory: async function(sortOption, pageToken, itemInfos = []) {
34794
35050
  let requestUrl = "https://avatar.roblox.com/v1/avatar-inventory?";
34795
35051
  let needsAnd = false;
@@ -34898,17 +35154,20 @@ const API = {
34898
35154
  }
34899
35155
  },
34900
35156
  "Asset": {
34901
- GetAssetBuffer: async function(url, headers) {
35157
+ GetAssetBuffer: async function(url, headers, extraStr) {
34902
35158
  let cacheStr = API.Misc.parseAssetString(url) || url;
34903
35159
  if (headers) {
34904
35160
  cacheStr += JSON.stringify(headers);
34905
35161
  }
35162
+ if (extraStr) {
35163
+ cacheStr += extraStr;
35164
+ }
34906
35165
  const cachedBuffer = CACHE.AssetBuffer.get(cacheStr);
34907
35166
  if (cachedBuffer) {
34908
35167
  return cachedBuffer;
34909
35168
  } else {
34910
35169
  const promise = new Promise((resolve) => {
34911
- getAssetBufferInternal(url, headers).then((result) => {
35170
+ getAssetBufferInternal(url, headers, extraStr).then((result) => {
34912
35171
  resolve(result);
34913
35172
  });
34914
35173
  });
@@ -34918,17 +35177,26 @@ const API = {
34918
35177
  return promise;
34919
35178
  }
34920
35179
  },
34921
- GetRBX: async function(url, headers) {
35180
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35181
+ GetRBX: async function(url, headers, contentRepresentationPriorityList) {
34922
35182
  const fetchStr = url;
34923
35183
  let cacheStr = fetchStr;
34924
35184
  if (headers) {
34925
35185
  cacheStr += JSON.stringify(headers);
34926
35186
  }
35187
+ const contentRepresentationPriorityListBASE64 = contentRepresentationPriorityList ? btoa(JSON.stringify(contentRepresentationPriorityList)) : void 0;
35188
+ if (contentRepresentationPriorityListBASE64) {
35189
+ cacheStr += contentRepresentationPriorityListBASE64;
35190
+ }
34927
35191
  const cachedRBX = CACHE.RBX.get(cacheStr);
34928
35192
  if (cachedRBX) {
34929
35193
  return cachedRBX.clone();
34930
35194
  } else {
34931
- const response = await this.GetAssetBuffer(fetchStr, headers);
35195
+ let extraStr = "";
35196
+ if (contentRepresentationPriorityListBASE64) {
35197
+ extraStr += `&contentRepresentationPriorityList=${contentRepresentationPriorityListBASE64}`;
35198
+ }
35199
+ const response = await this.GetAssetBuffer(fetchStr, headers, extraStr);
34932
35200
  if (response instanceof ArrayBuffer) {
34933
35201
  const buffer = response;
34934
35202
  const rbx = new RBX();
@@ -35134,11 +35402,12 @@ const API = {
35134
35402
  }
35135
35403
  },
35136
35404
  "Thumbnails": {
35137
- GetThumbnail: function(auth, type, id, size2 = "150x150") {
35405
+ GetThumbnail: function(auth, type, id, size2 = "150x150", headShape) {
35138
35406
  const thisThumbnailInfo = {
35139
35407
  type,
35140
35408
  id,
35141
- size: size2
35409
+ size: size2,
35410
+ headShape
35142
35411
  };
35143
35412
  const cachedThumbnail = CACHE.Thumbnails.get(requestIdFromThumbnailInfo(thisThumbnailInfo));
35144
35413
  if (CACHE.Thumbnails.has(requestIdFromThumbnailInfo(thisThumbnailInfo))) {
@@ -35147,7 +35416,7 @@ const API = {
35147
35416
  });
35148
35417
  }
35149
35418
  for (const thumbnailInfo of ThumbnailsToBatch) {
35150
- if (thumbnailInfo.id === id && thumbnailInfo.type === type && thumbnailInfo.size === size2) {
35419
+ if (requestIdFromThumbnailInfo(thumbnailInfo) === requestIdFromThumbnailInfo(thisThumbnailInfo)) {
35151
35420
  return new Promise((resolve) => {
35152
35421
  thumbnailInfo.resolves.push(resolve);
35153
35422
  });
@@ -35161,15 +35430,17 @@ const API = {
35161
35430
  size: size2,
35162
35431
  resolves: [resolve],
35163
35432
  attempt: 0,
35164
- lastTryTimestamp: 0
35433
+ lastTryTimestamp: 0,
35434
+ headShape
35165
35435
  });
35166
35436
  });
35167
35437
  },
35168
- UncacheThumbnail: function(type, id, size2 = "150x150") {
35438
+ UncacheThumbnail: function(type, id, size2 = "150x150", headShape) {
35169
35439
  const thisThumbnailInfo = {
35170
35440
  type,
35171
35441
  id,
35172
- size: size2
35442
+ size: size2,
35443
+ headShape
35173
35444
  };
35174
35445
  CACHE.Thumbnails.delete(requestIdFromThumbnailInfo(thisThumbnailInfo));
35175
35446
  },
@@ -35285,7 +35556,11 @@ const API = {
35285
35556
  };
35286
35557
  let currentLoadingThumbnails = false;
35287
35558
  function requestIdFromThumbnailInfo(thumbnailInfo) {
35288
- return thumbnailInfo.id + ":undefined:" + thumbnailInfo.type + ":" + thumbnailInfo.size + ":webp:regular";
35559
+ let requestId = thumbnailInfo.id + ":undefined:" + thumbnailInfo.type + ":" + thumbnailInfo.size + ":webp:regular";
35560
+ if (thumbnailInfo.headShape) {
35561
+ requestId += `:${thumbnailInfo.headShape}`;
35562
+ }
35563
+ return requestId;
35289
35564
  }
35290
35565
  function PurgeFailedThumbnails() {
35291
35566
  ThumbnailsToBatch = ThumbnailsToBatch.filter((val) => {
@@ -35314,7 +35589,8 @@ function BatchThumbnails() {
35314
35589
  "requestId": requestIdFromThumbnailInfo(thumbnailInfo),
35315
35590
  "size": thumbnailInfo.size,
35316
35591
  "targetId": thumbnailInfo.id,
35317
- "type": thumbnailInfo.type
35592
+ "type": thumbnailInfo.type,
35593
+ "headShape": thumbnailInfo.headShape
35318
35594
  });
35319
35595
  auth = thumbnailInfo.auth;
35320
35596
  thumbnailInfo.lastTryTimestamp = Date.now() / 1e3;
@@ -35388,174 +35664,6 @@ function browserSendMessage(data) {
35388
35664
  function browserOpenURL(url) {
35389
35665
  browserSendMessage({ "type": "openURL", "URL": url });
35390
35666
  }
35391
- class ItemSort {
35392
- subType;
35393
- itemType;
35394
- constructor(subType, itemType = "Asset") {
35395
- this.subType = subType;
35396
- this.itemType = itemType;
35397
- }
35398
- }
35399
- class SortInfo {
35400
- sortOption;
35401
- itemCategories = [];
35402
- constructor(itemCategories, sortOption = "1") {
35403
- this.itemCategories = itemCategories;
35404
- this.sortOption = sortOption;
35405
- }
35406
- }
35407
- class SpecialInfo {
35408
- type;
35409
- constructor(type) {
35410
- this.type = type;
35411
- }
35412
- }
35413
- const AllAccessorySorts = [
35414
- new ItemSort(19),
35415
- new ItemSort(8),
35416
- new ItemSort(42),
35417
- new ItemSort(43),
35418
- new ItemSort(44),
35419
- new ItemSort(45),
35420
- new ItemSort(46),
35421
- new ItemSort(47)
35422
- ];
35423
- if (!FLAGS.HAIR_IS_BODYPART) {
35424
- AllAccessorySorts.push(new ItemSort(41));
35425
- }
35426
- const AllClothingSorts = [
35427
- new ItemSort(12),
35428
- new ItemSort(11),
35429
- new ItemSort(2),
35430
- new ItemSort(72),
35431
- new ItemSort(67),
35432
- new ItemSort(70),
35433
- new ItemSort(71),
35434
- new ItemSort(66),
35435
- new ItemSort(65),
35436
- new ItemSort(69),
35437
- new ItemSort(68),
35438
- new ItemSort(64)
35439
- ];
35440
- const AllBodyPartsSorts = [
35441
- new ItemSort(18),
35442
- new ItemSort(17),
35443
- new ItemSort(29),
35444
- new ItemSort(30),
35445
- new ItemSort(28),
35446
- new ItemSort(31),
35447
- new ItemSort(27)
35448
- ];
35449
- if (FLAGS.HAIR_IS_BODYPART) {
35450
- AllBodyPartsSorts.push(new ItemSort(41));
35451
- }
35452
- const AllAnimationSorts = [
35453
- new ItemSort(48),
35454
- new ItemSort(50),
35455
- new ItemSort(51),
35456
- new ItemSort(52),
35457
- new ItemSort(53),
35458
- new ItemSort(54),
35459
- new ItemSort(55)
35460
- //new ItemSort(61)
35461
- ];
35462
- const AllCharacterSorts = [
35463
- new ItemSort(1, "Outfit"),
35464
- new ItemSort(5, "Outfit")
35465
- ];
35466
- const CategoryDictionary = {
35467
- "Inventory": {
35468
- "Recent": {
35469
- "All": new SortInfo([], "recentAdded"),
35470
- "Recent Worn": new SortInfo([], "2"),
35471
- "Accessories": new SortInfo(AllAccessorySorts, "recentEquipped"),
35472
- "Clothing": new SortInfo(AllClothingSorts, "recentEquipped"),
35473
- "Body": new SortInfo(AllBodyPartsSorts, "recentEquipped"),
35474
- "Animations": new SortInfo(AllAnimationSorts, "recentEquipped"),
35475
- "Characters": new SortInfo([new ItemSort(1, "Outfit")], "recentEquipped")
35476
- },
35477
- "Avatars": {
35478
- "Creations": new SortInfo([new ItemSort(3, "Outfit")]),
35479
- "Purchased": new SortInfo(AllCharacterSorts),
35480
- "Local": new SpecialInfo("LocalOutfits"),
35481
- "Published": new SpecialInfo("Looks")
35482
- },
35483
- "Clothing": {
35484
- "All": new SortInfo(AllClothingSorts),
35485
- "Shirts": new SortInfo([new ItemSort(AssetTypeNameToId.get("Shirt") || 0)]),
35486
- "Pants": new SortInfo([new ItemSort(AssetTypeNameToId.get("Pants") || 0)]),
35487
- "T-Shirts": new SortInfo([new ItemSort(AssetTypeNameToId.get("TShirt") || 0)]),
35488
- "Tops": new SortInfo([new ItemSort(AssetTypeNameToId.get("TShirtAccessory") || 0), new ItemSort(AssetTypeNameToId.get("ShirtAccessory") || 0), new ItemSort(AssetTypeNameToId.get("SweaterAccessory") || 0)]),
35489
- "Outerwear": new SortInfo([new ItemSort(AssetTypeNameToId.get("JacketAccessory") || 0)]),
35490
- "Bottoms": new SortInfo([new ItemSort(AssetTypeNameToId.get("PantsAccessory") || 0), new ItemSort(AssetTypeNameToId.get("ShortsAccessory") || 0), new ItemSort(AssetTypeNameToId.get("DressSkirtAccessory") || 0)]),
35491
- "Shoes": new SortInfo([new ItemSort(AssetTypeNameToId.get("LeftShoeAccessory") || 0), new ItemSort(AssetTypeNameToId.get("RightShoeAccessory") || 0)])
35492
- },
35493
- "Accessories": {
35494
- "All": new SortInfo(AllAccessorySorts),
35495
- "Hair": new SortInfo([new ItemSort(41)]),
35496
- "Head": new SortInfo([new ItemSort(AssetTypeNameToId.get("Hat") || 0)]),
35497
- "Face": new SortInfo([new ItemSort(AssetTypeNameToId.get("FaceAccessory") || 0)]),
35498
- "Neck": new SortInfo([new ItemSort(AssetTypeNameToId.get("NeckAccessory") || 0)]),
35499
- "Shoulders": new SortInfo([new ItemSort(AssetTypeNameToId.get("ShoulderAccessory") || 0)]),
35500
- "Front": new SortInfo([new ItemSort(AssetTypeNameToId.get("FrontAccessory") || 0)]),
35501
- "Back": new SortInfo([new ItemSort(AssetTypeNameToId.get("BackAccessory") || 0)]),
35502
- "Waist": new SortInfo([new ItemSort(AssetTypeNameToId.get("WaistAccessory") || 0)]),
35503
- "Gear": new SortInfo([new ItemSort(AssetTypeNameToId.get("Gear") || 0)])
35504
- },
35505
- "Head": {
35506
- "Dynamic Heads": new SortInfo([new ItemSort(2, "Outfit")]),
35507
- "Heads": new SortInfo([new ItemSort(17)]),
35508
- "Faces": new SortInfo([new ItemSort(18)])
35509
- },
35510
- "Body": {
35511
- "Skin Color": new SpecialInfo("Skin Color"),
35512
- "Scale": new SpecialInfo("Scale"),
35513
- "Torso": new SortInfo([new ItemSort(27)]),
35514
- "Left Arm": new SortInfo([new ItemSort(29)]),
35515
- "Right Arm": new SortInfo([new ItemSort(28)]),
35516
- "Left Leg": new SortInfo([new ItemSort(30)]),
35517
- "Right Leg": new SortInfo([new ItemSort(31)])
35518
- },
35519
- "Makeup": {
35520
- "Eyebrows": new SortInfo([new ItemSort(AssetTypeNameToId.get("EyebrowAccessory") || 0)], "inventory"),
35521
- "Eyelashes": new SortInfo([new ItemSort(AssetTypeNameToId.get("EyelashAccessory") || 0)], "inventory"),
35522
- "Lip": new SortInfo([new ItemSort(AssetTypeNameToId.get("LipMakeup") || 0)], "inventory"),
35523
- "Face": new SortInfo([new ItemSort(AssetTypeNameToId.get("FaceMakeup") || 0)], "inventory"),
35524
- "Eye": new SortInfo([new ItemSort(AssetTypeNameToId.get("EyeMakeup") || 0)], "inventory")
35525
- },
35526
- "Animations": {
35527
- "All": new SortInfo(AllAnimationSorts),
35528
- "Emotes": new SpecialInfo("Emotes"),
35529
- "_Emotes": new SortInfo([new ItemSort(AssetTypeNameToId.get("EmoteAnimation") || 0)]),
35530
- "Idle": new SortInfo([new ItemSort(51)]),
35531
- "Walk": new SortInfo([new ItemSort(55)]),
35532
- "Run": new SortInfo([new ItemSort(53)]),
35533
- "Fall": new SortInfo([new ItemSort(50)]),
35534
- "Jump": new SortInfo([new ItemSort(52)]),
35535
- "Swim": new SortInfo([new ItemSort(54)]),
35536
- "Climb": new SortInfo([new ItemSort(48)]),
35537
- "Mood": new SortInfo([new ItemSort(AssetTypeNameToId.get("MoodAnimation") || 0)], "inventory")
35538
- }
35539
- }
35540
- };
35541
- const DefaultSearchData = {
35542
- "Inventory": {
35543
- includeOffsale: true,
35544
- limitedOnly: false
35545
- },
35546
- "Marketplace": {
35547
- includeOffsale: false,
35548
- limitedOnly: false
35549
- }
35550
- };
35551
- const SortTypes = {
35552
- "Relevance": void 0,
35553
- "MostFavorited": 1,
35554
- "MostPopular": 2,
35555
- "RecentlyPublished": 3,
35556
- "PriceHighToLow": 5,
35557
- "PriceLowToHigh": 4
35558
- };
35559
35667
  function _extends() {
35560
35668
  return _extends = Object.assign ? Object.assign.bind() : function(n) {
35561
35669
  for (var e = 1; e < arguments.length; e++) {
@@ -48999,7 +49107,7 @@ class WorkerPool {
48999
49107
  const func = WorkerTypeToFunction[type];
49000
49108
  return func(data);
49001
49109
  }
49002
- async work(type, data) {
49110
+ async work(type, data, transferables) {
49003
49111
  const taskId = idCounter;
49004
49112
  idCounter += 1;
49005
49113
  if (this.workers.length > 0) {
@@ -49008,7 +49116,11 @@ class WorkerPool {
49008
49116
  const promise = new Promise((resolve) => {
49009
49117
  this.workersResolves[workerIndex].push([taskId, resolve]);
49010
49118
  });
49011
- this.workers[workerIndex].postMessage([taskId, type, data]);
49119
+ if (transferables) {
49120
+ this.workers[workerIndex].postMessage([taskId, type, data], transferables);
49121
+ } else {
49122
+ this.workers[workerIndex].postMessage([taskId, type, data]);
49123
+ }
49012
49124
  return promise;
49013
49125
  } else {
49014
49126
  return this._emulateWorker(type, data);
@@ -49278,7 +49390,8 @@ class RBFDeformerPatch {
49278
49390
  by[i] = dr[1] - rr[1];
49279
49391
  bz[i] = dr[2] - rr[2];
49280
49392
  }
49281
- weightPromises[p2] = WorkerPool.instance.work("patchRBF", [A.map((r) => r.buffer), bx.buffer, by.buffer, bz.buffer]);
49393
+ const Abuffers = A.map((r) => r.buffer);
49394
+ weightPromises[p2] = WorkerPool.instance.work("patchRBF", [Abuffers, bx.buffer, by.buffer, bz.buffer], [...Abuffers, bx.buffer, by.buffer, bz.buffer]);
49282
49395
  }
49283
49396
  const weights = await Promise.all(weightPromises);
49284
49397
  for (let i = 0; i < weights.length; i++) {
@@ -55597,12 +55710,14 @@ class _TextureComposer {
55597
55710
  this.add(threeMesh);
55598
55711
  }
55599
55712
  render(skipRenderTargetSet = false) {
55713
+ const rbxRenderer = RBXRenderer.getRenderer();
55714
+ if (!rbxRenderer) return this.renderTarget;
55600
55715
  if (!skipRenderTargetSet) {
55601
- RBXRenderer.getRenderer().setRenderTarget(this.renderTarget);
55716
+ rbxRenderer.setRenderTarget(this.renderTarget);
55602
55717
  } else {
55603
- RBXRenderer.getRenderer().setRenderTarget(null);
55718
+ rbxRenderer.setRenderTarget(null);
55604
55719
  }
55605
- RBXRenderer.getRenderer().render(this.scene, this.camera);
55720
+ rbxRenderer.render(this.scene, this.camera);
55606
55721
  return this.renderTarget;
55607
55722
  }
55608
55723
  }
@@ -56207,9 +56322,10 @@ class MaterialDesc {
56207
56322
  lineartexture.dispose();
56208
56323
  }
56209
56324
  let hasTransparency = false;
56210
- if (!hasColorLayer) {
56325
+ const rbxRenderer = RBXRenderer.getRenderer();
56326
+ if (!hasColorLayer && rbxRenderer) {
56211
56327
  const data = new Uint8Array(width * height * 4);
56212
- await RBXRenderer.getRenderer().readRenderTargetPixelsAsync(renderTarget, 0, 0, width, height, data);
56328
+ await rbxRenderer.readRenderTargetPixelsAsync(renderTarget, 0, 0, width, height, data);
56213
56329
  for (let i = 3; i < data.length; i += 4) {
56214
56330
  if (data[i] < 255) {
56215
56331
  hasTransparency = true;
@@ -56264,16 +56380,17 @@ class MaterialDesc {
56264
56380
  ctx.fillRect(0, 0, canvas.width, canvas.height);
56265
56381
  }
56266
56382
  }
56267
- const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
56268
- const data = imageData.data;
56269
56383
  let hasTransparency = false;
56270
- for (let i = 3; i < data.length; i += 4) {
56271
- if (data[i] < 255) {
56272
- hasTransparency = true;
56273
- break;
56384
+ if (this.transparent) {
56385
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
56386
+ const data = imageData.data;
56387
+ for (let i = 3; i < data.length; i += 4) {
56388
+ if (data[i] < 255) {
56389
+ hasTransparency = true;
56390
+ break;
56391
+ }
56274
56392
  }
56275
- }
56276
- if (!this.transparent) {
56393
+ } else {
56277
56394
  hasTransparency = false;
56278
56395
  }
56279
56396
  texture.needsUpdate = true;
@@ -56635,7 +56752,7 @@ class MaterialDesc {
56635
56752
  }
56636
56753
  affectedByHumanoid = false;
56637
56754
  }
56638
- if (affectedByHumanoid && child.parent) {
56755
+ if (affectedByHumanoid && child.parent && !surfaceAppearance) {
56639
56756
  const bodyPart = BodyPartNameToEnum[child.Prop("Name")];
56640
56757
  if (Object.hasOwn(BodyPartNameToEnum, child.Prop("Name"))) {
56641
56758
  this.bodyPart = bodyPart;
@@ -59493,6 +59610,10 @@ class AnimatorWrapper extends InstanceWrapper {
59493
59610
  }
59494
59611
  }
59495
59612
  renderAnimation(addTime = 1 / 60) {
59613
+ const humanoid = this.instance.parent;
59614
+ if (!humanoid) {
59615
+ throw new Error("Parent is missing from Animator");
59616
+ }
59496
59617
  this.restPose();
59497
59618
  this._fixUnloaded();
59498
59619
  for (const track of this.data.animationTracks.values()) {
@@ -59503,25 +59624,26 @@ class AnimatorWrapper extends InstanceWrapper {
59503
59624
  this._switchAnimation(this.data.currentAnimation);
59504
59625
  }
59505
59626
  }
59627
+ const humanoidDescription = humanoid.FindFirstChildOfClass("HumanoidDescription");
59628
+ if (humanoidDescription) {
59629
+ if (humanoidDescription.Prop("StaticFacialAnimation")) {
59630
+ this.restPose(false, true);
59631
+ }
59632
+ }
59506
59633
  for (const track of this.data.animationTracks.values()) {
59507
59634
  if (!this.data.moodTracks.includes(track)) continue;
59508
59635
  const looped = track.tick(addTime);
59509
- if (this.data.currentAnimationTrack === track && looped && this.data.currentAnimation) {
59510
- this._switchAnimation(this.data.currentAnimation);
59636
+ if (this.data.currentMoodAnimationTrack === track && looped && this.data.currentMoodAnimation) {
59637
+ this._switchMoodAnimation(this.data.currentMoodAnimation);
59511
59638
  }
59512
59639
  }
59513
59640
  for (const track of this.data.animationTracks.values()) {
59514
59641
  if (!this.data.toolTracks.includes(track)) continue;
59515
59642
  const looped = track.tick(addTime);
59516
- if (this.data.currentAnimationTrack === track && looped && this.data.currentAnimation) {
59517
- this._switchAnimation(this.data.currentAnimation);
59643
+ if (this.data.currentToolAnimationTrack === track && looped && this.data.currentToolAnimation) {
59644
+ this._switchToolAnimation(this.data.currentToolAnimation);
59518
59645
  }
59519
59646
  }
59520
- const hasMood = this.data.currentMoodAnimation && this.data.currentMoodAnimation.length > 0;
59521
- const isEmote = this.data.currentAnimation?.startsWith("emote.");
59522
- if (!hasMood && !isEmote) {
59523
- this.restPose(false, true);
59524
- }
59525
59647
  const rig = this.instance.parent?.parent;
59526
59648
  if (rig) {
59527
59649
  const descedants = rig.GetDescendants();
@@ -59737,12 +59859,13 @@ class BodyColorsWrapper extends InstanceWrapper {
59737
59859
  }
59738
59860
  class BodyPartDescriptionWrapper extends InstanceWrapper {
59739
59861
  static className = "BodyPartDescription";
59740
- static requiredProperties = ["Name", "AssetId", "BodyPart", "Color", "Instance"];
59862
+ static requiredProperties = ["Name", "AssetId", "BodyPart", "Color", "HeadShape", "Instance"];
59741
59863
  setup() {
59742
59864
  if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), "BodyPartDescription");
59743
59865
  if (!this.instance.HasProperty("AssetId")) this.instance.addProperty(new Property("AssetId", DataType.Int64), 0n);
59744
59866
  if (!this.instance.HasProperty("BodyPart")) this.instance.addProperty(new Property("BodyPart", DataType.Enum), BodyPart.Head);
59745
59867
  if (!this.instance.HasProperty("Color")) this.instance.addProperty(new Property("Color", DataType.Color3), new Color3(0, 0, 0));
59868
+ if (!this.instance.HasProperty("HeadShape")) this.instance.addProperty(new Property("HeadShape", DataType.String), "");
59746
59869
  if (!this.instance.HasProperty("Instance")) this.instance.addProperty(new Property("Instance", DataType.Referent), void 0);
59747
59870
  }
59748
59871
  }
@@ -59910,6 +60033,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
59910
60033
  "RunAnimation",
59911
60034
  "SwimAnimation",
59912
60035
  "WalkAnimation",
60036
+ "StaticFacialAnimation",
59913
60037
  "GraphicTShirt",
59914
60038
  "Pants",
59915
60039
  "Shirt",
@@ -59934,6 +60058,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
59934
60058
  if (!this.instance.HasProperty("RunAnimation")) this.instance.addProperty(new Property("RunAnimation", DataType.Int64), 0n);
59935
60059
  if (!this.instance.HasProperty("SwimAnimation")) this.instance.addProperty(new Property("SwimAnimation", DataType.Int64), 0n);
59936
60060
  if (!this.instance.HasProperty("WalkAnimation")) this.instance.addProperty(new Property("WalkAnimation", DataType.Int64), 0n);
60061
+ if (!this.instance.HasProperty("StaticFacialAnimation")) this.instance.addProperty(new Property("StaticFacialAnimation", DataType.Bool), false);
59937
60062
  if (!this.instance.HasProperty("GraphicTShirt")) this.instance.addProperty(new Property("GraphicTShirt", DataType.Int64), 0n);
59938
60063
  if (!this.instance.HasProperty("Pants")) this.instance.addProperty(new Property("Pants", DataType.Int64), 0n);
59939
60064
  if (!this.instance.HasProperty("Shirt")) this.instance.addProperty(new Property("Shirt", DataType.Int64), 0n);
@@ -59989,6 +60114,9 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
59989
60114
  if (this.getBodyPartId(bodyPart) !== originalW.getBodyPartId(bodyPart)) {
59990
60115
  bodyPartsSame = false;
59991
60116
  }
60117
+ if (this.getBodyPartHeadShape(bodyPart) !== originalW.getBodyPartHeadShape(bodyPart)) {
60118
+ bodyPartsSame = false;
60119
+ }
59992
60120
  }
59993
60121
  if (!bodyColorsSame) {
59994
60122
  diffs.push("bodyColor");
@@ -59996,6 +60124,9 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
59996
60124
  if (!bodyPartsSame) {
59997
60125
  diffs.push("bodyPart");
59998
60126
  }
60127
+ if (this.instance.Prop("StaticFacialAnimation") !== originalW.instance.Prop("StaticFacialAnimation")) {
60128
+ diffs.push("staticFacialAnimation");
60129
+ }
59999
60130
  const clothingSame = hasSameVal(self2, other, "Shirt") && hasSameVal(self2, other, "Pants") && hasSameVal(self2, other, "GraphicTShirt");
60000
60131
  if (!clothingSame) {
60001
60132
  diffs.push("clothing");
@@ -60156,6 +60287,12 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
60156
60287
  bodyPartDesc.setProperty("AssetId", id);
60157
60288
  }
60158
60289
  }
60290
+ setBodyPartHeadShape(bodyPart, headShape) {
60291
+ const bodyPartDesc = this.getBodyPartDescription(bodyPart);
60292
+ if (bodyPartDesc) {
60293
+ bodyPartDesc.setProperty("HeadShape", headShape);
60294
+ }
60295
+ }
60159
60296
  getBodyPartId(bodyPart) {
60160
60297
  const bodyPartDesc = this.getBodyPartDescription(bodyPart);
60161
60298
  if (bodyPartDesc) {
@@ -60163,6 +60300,13 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
60163
60300
  }
60164
60301
  return 0n;
60165
60302
  }
60303
+ getBodyPartHeadShape(bodyPart) {
60304
+ const bodyPartDesc = this.getBodyPartDescription(bodyPart);
60305
+ if (bodyPartDesc) {
60306
+ return bodyPartDesc.Prop("HeadShape");
60307
+ }
60308
+ return "";
60309
+ }
60166
60310
  createRigData() {
60167
60311
  const humanoid = this.instance.parent;
60168
60312
  const rig = humanoid?.parent;
@@ -60246,6 +60390,9 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
60246
60390
  const assetPromises = [];
60247
60391
  for (const asset of outfit.assets) {
60248
60392
  const assetType = asset.assetType.name;
60393
+ if (asset.meta?.staticFacialAnimation) {
60394
+ this.instance.setProperty("StaticFacialAnimation", true);
60395
+ }
60249
60396
  switch (assetType) {
60250
60397
  case "TShirt":
60251
60398
  this.instance.setProperty("GraphicTShirt", BigInt(asset.id));
@@ -60343,6 +60490,9 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
60343
60490
  }
60344
60491
  const bodyPart = BodyPart[bodyPartName];
60345
60492
  this.setBodyPartId(bodyPart, BigInt(asset.id));
60493
+ if (asset.meta?.headShape && assetType === "DynamicHead") {
60494
+ this.setBodyPartHeadShape(bodyPart, asset.meta?.headShape);
60495
+ }
60346
60496
  }
60347
60497
  break;
60348
60498
  case "ClimbAnimation":
@@ -60472,7 +60622,16 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
60472
60622
  if (avatarType === AvatarType.R15 && bodyPart === BodyPart.Head) {
60473
60623
  headers = { "Roblox-AssetFormat": "avatar_meshpart_head" };
60474
60624
  }
60475
- API.Asset.GetRBX(`rbxassetid://${assetId}`, headers).then((bodyPartRBX) => {
60625
+ const headShape = this.getBodyPartHeadShape(BodyPart.Head);
60626
+ let contentRepresentationPriorityList = void 0;
60627
+ if (bodyPart === BodyPart.Head && headShape.length > 0) {
60628
+ contentRepresentationPriorityList = [{ "format": headShape, "majorVersion": "1" }];
60629
+ if (avatarType === AvatarType.R15) {
60630
+ contentRepresentationPriorityList.push({ "format": "avatar_meshpart_head", "majorVersion": "1" });
60631
+ }
60632
+ headers = void 0;
60633
+ }
60634
+ API.Asset.GetRBX(`rbxassetid://${assetId}`, headers, contentRepresentationPriorityList).then((bodyPartRBX) => {
60476
60635
  if (this.cancelApply) resolve(void 0);
60477
60636
  if (!(bodyPartRBX instanceof RBX)) {
60478
60637
  resolve(bodyPartRBX);
@@ -60519,6 +60678,19 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
60519
60678
  bodyHeadMesh.Destroy();
60520
60679
  }
60521
60680
  headMesh.setParent(rig.FindFirstChild("Head"));
60681
+ } else {
60682
+ const headMesh2 = dataModel.FindFirstChildOfClass("MeshPart");
60683
+ if (headMesh2) {
60684
+ const bodyHeadMesh = rig.FindFirstChild("Head")?.FindFirstChildOfClass("SpecialMesh");
60685
+ if (bodyHeadMesh) {
60686
+ bodyHeadMesh.setProperty("MeshType", MeshType.FileMesh);
60687
+ bodyHeadMesh.setProperty("MeshId", headMesh2.Prop("MeshId"));
60688
+ bodyHeadMesh.setProperty("TextureId", headMesh2.Prop("TextureID"));
60689
+ bodyHeadMesh.setProperty("Scale", new Vector32(1, 1, 1));
60690
+ bodyHeadMesh.setProperty("Offset", new Vector32(0, 0, 0));
60691
+ bodyHeadMesh.setProperty("VertexColor", new Vector32(1, 1, 1));
60692
+ }
60693
+ }
60522
60694
  }
60523
60695
  } else {
60524
60696
  const head = dataModel.FindFirstChildOfClass("MeshPart");
@@ -60879,14 +61051,15 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
60879
61051
  if (!rig) {
60880
61052
  return void 0;
60881
61053
  }
60882
- if (!rig.FindFirstChild("Head")) {
61054
+ const head = rig.FindFirstChild("Head");
61055
+ if (!head) {
60883
61056
  return void 0;
60884
61057
  }
60885
61058
  const avatarType = humanoid.Prop("RigType") === HumanoidRigType.R15 ? AvatarType.R15 : AvatarType.R6;
60886
61059
  if (avatarType === AvatarType.R6) return void 0;
60887
61060
  if (!originalW) {
60888
- for (const makeup of rig.GetChildren()) {
60889
- if (makeup.className === "Decal" && makeup.GetChildren().length > 0) {
61061
+ for (const makeup of head.GetChildren()) {
61062
+ if (makeup.className === "Decal" && makeup.FindFirstChildOfClass("WrapTextureTransfer")) {
60890
61063
  makeup.Destroy();
60891
61064
  }
60892
61065
  }
@@ -60935,7 +61108,6 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
60935
61108
  return value;
60936
61109
  }
60937
61110
  }
60938
- const head = rig.FindFirstChild("Head");
60939
61111
  if (head) {
60940
61112
  for (const decal of head.GetChildren()) {
60941
61113
  if (decal.className === "Decal" && decal.GetChildren().length > 0) {
@@ -61076,7 +61248,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
61076
61248
  if (diffs.includes("bodyPart")) {
61077
61249
  const toChange = [];
61078
61250
  for (const bodyPart of AllBodyParts) {
61079
- if (this.getBodyPartId(bodyPart) !== originalDescriptionW.getBodyPartId(bodyPart)) {
61251
+ if (this.getBodyPartId(bodyPart) !== originalDescriptionW.getBodyPartId(bodyPart) || this.getBodyPartHeadShape(bodyPart) !== originalDescriptionW.getBodyPartHeadShape(bodyPart)) {
61080
61252
  toChange.push(bodyPart);
61081
61253
  }
61082
61254
  }
@@ -61526,7 +61698,7 @@ class RBXRenderer {
61526
61698
  static scene = new Scene();
61527
61699
  static camera = new PerspectiveCamera(70, 1 / 1, 0.1, 100);
61528
61700
  static controls;
61529
- static renderer = new WebGLRenderer({ antialias: true, alpha: true });
61701
+ static renderer;
61530
61702
  static effectComposer;
61531
61703
  static shadowEnabled = true;
61532
61704
  static shadowResolution = [256, 256];
@@ -61542,21 +61714,85 @@ class RBXRenderer {
61542
61714
  static ambientLight;
61543
61715
  static directionalLight;
61544
61716
  static directionalLight2;
61717
+ static failedToCreate = false;
61718
+ static error;
61545
61719
  static async boilerplateSetup() {
61546
61720
  RegisterWrappers();
61547
61721
  setupWorkerPool();
61548
61722
  loadCompositMeshes();
61549
61723
  }
61550
- /**Fully sets up renderer with scene, camera and frame rendering*/
61724
+ static async showErrorHTML() {
61725
+ console.log("Displaying WebGL2 error in canvasContainer...");
61726
+ const errorDiv = document.createElement("div");
61727
+ errorDiv.style = `
61728
+ display: flex;
61729
+ flex-direction: column;
61730
+ justify-content: flex-start;
61731
+ align-items: center;
61732
+ width: 100%;
61733
+ height: 100%;
61734
+ background-color: rgb(237, 22, 97);
61735
+ `;
61736
+ const errorTitle = document.createElement("span");
61737
+ errorTitle.style = `
61738
+ font-family: Arial, Helvetica, sans-serif;
61739
+ font-size: 48px;
61740
+ color: #fff;
61741
+ margin-top: 8px;
61742
+ text-align: center;
61743
+ `;
61744
+ errorTitle.innerText = "No WebGL2?";
61745
+ errorDiv.appendChild(errorTitle);
61746
+ const errorText = document.createElement("span");
61747
+ errorText.style = `
61748
+ font-family: Arial, Helvetica, sans-serif;
61749
+ font-size: 24px;
61750
+ color: #fff;
61751
+ text-align: center;
61752
+ `;
61753
+ errorText.innerText = "Your browser, device or settings do not support WebGL2";
61754
+ errorDiv.appendChild(errorText);
61755
+ const errorLink = document.createElement("a");
61756
+ errorLink.style = `
61757
+ font-family: Arial, Helvetica, sans-serif;
61758
+ font-size: 24px;
61759
+ color: #fff;
61760
+ text-align: center;
61761
+ `;
61762
+ errorLink.innerText = "Learn more";
61763
+ errorLink.href = "https://webglreport.com/?v=2";
61764
+ errorDiv.appendChild(errorLink);
61765
+ RBXRenderer.canvasContainer.append(errorDiv);
61766
+ }
61767
+ /**Fully sets up renderer with scene, camera and frame rendering
61768
+ * @returns success
61769
+ */
61551
61770
  static async fullSetup(includeScene = true, includeControls = true) {
61552
- await RBXRenderer.boilerplateSetup();
61553
- RBXRenderer.create();
61554
- if (includeScene) RBXRenderer.setupScene();
61555
- if (includeControls) RBXRenderer.setupControls();
61556
- RBXRenderer.animate();
61771
+ try {
61772
+ RBXRenderer.createContainer();
61773
+ await RBXRenderer.boilerplateSetup();
61774
+ RBXRenderer.create();
61775
+ if (includeScene) RBXRenderer.setupScene();
61776
+ if (includeControls) RBXRenderer.setupControls();
61777
+ RBXRenderer.animate();
61778
+ } catch (error) {
61779
+ console.error(error);
61780
+ RBXRenderer.failedToCreate = true;
61781
+ RBXRenderer.error = error;
61782
+ RBXRenderer.showErrorHTML();
61783
+ }
61784
+ return !RBXRenderer.failedToCreate;
61785
+ }
61786
+ /**Creates canvasContainer */
61787
+ static createContainer() {
61788
+ RBXRenderer.canvasContainer = document.createElement("div");
61789
+ RBXRenderer.canvasContainer.style.position = "relative";
61790
+ RBXRenderer.canvasContainer.style.width = `${RBXRenderer.resolution[0]}px`;
61791
+ RBXRenderer.canvasContainer.style.height = `${RBXRenderer.resolution[1]}px`;
61557
61792
  }
61558
61793
  /**Sets up the THREE.js renderer */
61559
61794
  static create() {
61795
+ RBXRenderer.renderer = new WebGLRenderer({ antialias: true, alpha: true });
61560
61796
  RBXRenderer.renderer.setClearColor(new Color(1, 0, 1), 0);
61561
61797
  RBXRenderer.renderer.outputColorSpace = SRGBColorSpace;
61562
61798
  RBXRenderer.renderer.shadowMap.enabled = true;
@@ -61567,10 +61803,6 @@ class RBXRenderer {
61567
61803
  RBXRenderer.renderer.setSize(RBXRenderer.resolution[0] * 2, RBXRenderer.resolution[1] * 2);
61568
61804
  }
61569
61805
  RBXRenderer.renderer.domElement.setAttribute("id", "OutfitInfo-outfit-image-3d");
61570
- RBXRenderer.canvasContainer = document.createElement("div");
61571
- RBXRenderer.canvasContainer.style.position = "relative";
61572
- RBXRenderer.canvasContainer.style.width = `${RBXRenderer.resolution[0]}px`;
61573
- RBXRenderer.canvasContainer.style.height = `${RBXRenderer.resolution[1]}px`;
61574
61806
  RBXRenderer.canvasContainer.appendChild(RBXRenderer.renderer.domElement);
61575
61807
  if (RBXRenderer.createLoadingIcon) {
61576
61808
  RBXRenderer.loadingIcon = document.createElement("span");
@@ -61705,6 +61937,7 @@ class RBXRenderer {
61705
61937
  }
61706
61938
  /**Sets up orbit controls */
61707
61939
  static setupControls() {
61940
+ if (!RBXRenderer.renderer) return;
61708
61941
  const controls = new OrbitControls(RBXRenderer.camera, RBXRenderer.renderer.domElement);
61709
61942
  controls.maxDistance = 25;
61710
61943
  controls.zoomSpeed = 2;
@@ -61749,6 +61982,7 @@ class RBXRenderer {
61749
61982
  }
61750
61983
  /**Makes the renderer render a new frame on every animationFrame */
61751
61984
  static animate() {
61985
+ if (!RBXRenderer.renderer) return;
61752
61986
  RBXRenderer.renderer.setRenderTarget(null);
61753
61987
  if (RBXRenderer.effectComposer) {
61754
61988
  RBXRenderer.effectComposer.render();
@@ -61760,6 +61994,7 @@ class RBXRenderer {
61760
61994
  });
61761
61995
  }
61762
61996
  static _createEffectComposer() {
61997
+ if (!RBXRenderer.renderer) return;
61763
61998
  RBXRenderer.effectComposer = new EffectComposer(RBXRenderer.renderer);
61764
61999
  const renderPass = new RenderPass(RBXRenderer.scene, RBXRenderer.camera);
61765
62000
  RBXRenderer.effectComposer.addPass(renderPass);
@@ -61775,6 +62010,7 @@ class RBXRenderer {
61775
62010
  }
61776
62011
  /**Removes an instance from the renderer */
61777
62012
  static removeInstance(instance) {
62013
+ if (!RBXRenderer.renderer) return;
61778
62014
  console.log("Removed instance:", instance.Prop("Name"), instance.id);
61779
62015
  const desc = RBXRenderer.renderDescs.get(instance);
61780
62016
  if (desc) {
@@ -61787,6 +62023,7 @@ class RBXRenderer {
61787
62023
  }
61788
62024
  }
61789
62025
  static _addRenderDesc(instance, auth, DescClass) {
62026
+ if (!RBXRenderer.renderer) return;
61790
62027
  const oldDesc = RBXRenderer.renderDescs.get(instance);
61791
62028
  const newDesc = new DescClass();
61792
62029
  newDesc.fromInstance(instance);
@@ -61803,7 +62040,7 @@ class RBXRenderer {
61803
62040
  newDesc.compileResults(RBXRenderer.renderer, RBXRenderer.scene).then((results) => {
61804
62041
  if (results && !(results instanceof Response)) {
61805
62042
  newDesc.updateResults();
61806
- if (RBXRenderer.renderDescs.get(instance)) {
62043
+ if (RBXRenderer.renderDescs.get(instance) && RBXRenderer.renderer) {
61807
62044
  oldDesc?.dispose(RBXRenderer.renderer, RBXRenderer.scene);
61808
62045
  for (const result of results) {
61809
62046
  if (result instanceof SkinnedMesh && newDesc instanceof ObjectDesc) {
@@ -61826,7 +62063,7 @@ class RBXRenderer {
61826
62063
  }
61827
62064
  RBXRenderer.isRenderingMesh.set(instance, false);
61828
62065
  RBXRenderer.addInstance(instance, auth);
61829
- } else {
62066
+ } else if (RBXRenderer.renderer) {
61830
62067
  newDesc.dispose(RBXRenderer.renderer, RBXRenderer.scene);
61831
62068
  }
61832
62069
  } else {
@@ -61867,6 +62104,7 @@ class RBXRenderer {
61867
62104
  }
61868
62105
  }
61869
62106
  static setRendererSize(width, height) {
62107
+ if (!RBXRenderer.renderer) return;
61870
62108
  RBXRenderer.resolution = [width, height];
61871
62109
  RBXRenderer.renderer.domElement.setAttribute("style", `width: ${RBXRenderer.resolution[0]}px; height: ${RBXRenderer.resolution[1]}px; border-radius: 0px;`);
61872
62110
  RBXRenderer.canvasContainer.style.width = `${RBXRenderer.resolution[0]}px`;
@@ -61883,6 +62121,7 @@ class RBXRenderer {
61883
62121
  * @returns The element for the renderer canvas
61884
62122
  */
61885
62123
  static getRendererDom() {
62124
+ if (!RBXRenderer.renderer) return;
61886
62125
  return RBXRenderer.renderer.domElement;
61887
62126
  }
61888
62127
  /**
@@ -61920,6 +62159,7 @@ class RBXRenderer {
61920
62159
  }
61921
62160
  }
61922
62161
  function mount(container) {
62162
+ if (!RBXRenderer.renderer) return;
61923
62163
  if (container) {
61924
62164
  container.insertBefore(RBXRenderer.renderer.domElement, container.firstChild);
61925
62165
  } else {
@@ -62199,11 +62439,6 @@ class OutfitRenderer {
62199
62439
  animatorW.playAnimation(name2);
62200
62440
  });
62201
62441
  }
62202
- if (this.outfit.containsAssetType("MoodAnimation") && !name2.startsWith("emote.")) {
62203
- animatorW.playAnimation("mood", "mood");
62204
- } else {
62205
- animatorW.stopMoodAnimation();
62206
- }
62207
62442
  }
62208
62443
  }
62209
62444
  }
@@ -62345,6 +62580,7 @@ export {
62345
62580
  calculateMagnitude3D,
62346
62581
  calculateMotor6Doffset,
62347
62582
  clamp$1 as clamp,
62583
+ cleanString,
62348
62584
  clonePrimitiveArray,
62349
62585
  cloneSearch_Payload,
62350
62586
  closestPointTriangle,