three-usd-robot 0.5.0 → 0.7.0

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.
@@ -1,4 +1,4 @@
1
- import { AssetPath, identity4, multiply, computeLocalTransform, invert, interpolate, DefaultAssetResolver, CrateReader, openUsdz, extractRobotDescription, buildKinematicTree, Stage, composeLayer, composeFile, crateToUsdaFile } from './chunk-36T6YOEX.js';
1
+ import { getMaterialSubsets, resolveBoundMaterial, COLLISION_API, isNonVisualPurpose, computeWorldTransform, identity4, multiply, computeLocalTransform, invert, interpolate, DefaultAssetResolver, CrateReader, openUsdz, extractRobotDescription, buildKinematicTree, Stage, composeLayer, composeFile, crateToUsdaFile } from './chunk-4GPCBXUS.js';
2
2
  import * as THREE4 from 'three';
3
3
 
4
4
  function axisVector(axis) {
@@ -70,178 +70,6 @@ var LinkObject = class extends THREE4.Object3D {
70
70
  this.matrixAutoUpdate = false;
71
71
  }
72
72
  };
73
-
74
- // src/three/MaterialBinding.ts
75
- var DIFFUSE_INPUTS = [
76
- "inputs:diffuseColor",
77
- // UsdPreviewSurface
78
- "inputs:diffuse_color_constant",
79
- // OmniPBR
80
- "inputs:diffuse_tint",
81
- "inputs:base_color",
82
- "inputs:baseColor"
83
- ];
84
- var OPACITY_INPUTS = ["inputs:opacity", "inputs:opacity_constant"];
85
- var OPACITY_THRESHOLD_INPUTS = ["inputs:opacityThreshold", "inputs:opacity_threshold"];
86
- var METALLIC_INPUTS = ["inputs:metallic", "inputs:metallic_constant"];
87
- var ROUGHNESS_INPUTS = ["inputs:roughness", "inputs:reflection_roughness_constant"];
88
- var EMISSIVE_INPUTS = ["inputs:emissiveColor", "inputs:emissive_color"];
89
- var SURFACE_OUTPUTS = ["outputs:surface", "outputs:mdl:surface"];
90
- var TEXTURE_LOOKUPS = {
91
- color: {
92
- surface: ["inputs:diffuseColor"],
93
- direct: ["inputs:diffuse_texture", "inputs:diffuse_color_texture"]
94
- },
95
- opacity: {
96
- surface: ["inputs:opacity"],
97
- direct: ["inputs:opacity_texture", "inputs:opacity_color_texture"]
98
- },
99
- normal: {
100
- surface: ["inputs:normal"],
101
- direct: ["inputs:normalmap_texture", "inputs:normal_texture"]
102
- },
103
- roughness: {
104
- surface: ["inputs:roughness"],
105
- direct: ["inputs:reflectionroughness_texture", "inputs:roughness_texture"]
106
- },
107
- metalness: {
108
- surface: ["inputs:metallic"],
109
- direct: ["inputs:metallic_texture"]
110
- },
111
- occlusion: {
112
- surface: ["inputs:occlusion"],
113
- direct: ["inputs:ao_texture", "inputs:occlusion_texture"]
114
- },
115
- emissive: {
116
- surface: ["inputs:emissiveColor"],
117
- direct: ["inputs:emissive_color_texture", "inputs:emissive_mask_texture"]
118
- }
119
- };
120
- function resolveBoundMaterial(stage, prim) {
121
- const materialPath = findBinding(prim);
122
- if (!materialPath) return void 0;
123
- const material = stage.GetPrimAtPath(materialPath);
124
- if (!material) return void 0;
125
- const shader = findSurfaceShader(material);
126
- if (!shader) return void 0;
127
- const result = {};
128
- const color = firstColor(shader, DIFFUSE_INPUTS);
129
- if (color) result.color = color;
130
- const opacity = firstNumber(shader, OPACITY_INPUTS);
131
- if (opacity !== void 0) result.opacity = opacity;
132
- const opacityThreshold = firstNumber(shader, OPACITY_THRESHOLD_INPUTS);
133
- if (opacityThreshold !== void 0) result.opacityThreshold = opacityThreshold;
134
- const metalness = firstNumber(shader, METALLIC_INPUTS);
135
- if (metalness !== void 0) result.metalness = metalness;
136
- const roughness = firstNumber(shader, ROUGHNESS_INPUTS);
137
- if (roughness !== void 0) result.roughness = roughness;
138
- const emissive = firstColor(shader, EMISSIVE_INPUTS);
139
- if (emissive && shader.GetAttribute("inputs:enable_emission").Get() !== false) {
140
- result.emissiveColor = emissive;
141
- }
142
- const colorTex = findTexture(shader, TEXTURE_LOOKUPS.color);
143
- if (colorTex !== void 0) result.colorTexture = colorTex;
144
- const opacityTex = findTexture(shader, TEXTURE_LOOKUPS.opacity);
145
- if (opacityTex !== void 0) result.opacityTexture = opacityTex;
146
- const normal = findTexture(shader, TEXTURE_LOOKUPS.normal);
147
- if (normal !== void 0) result.normalTexture = normal;
148
- const roughTex = findTexture(shader, TEXTURE_LOOKUPS.roughness);
149
- if (roughTex !== void 0) result.roughnessTexture = roughTex;
150
- const metalTex = findTexture(shader, TEXTURE_LOOKUPS.metalness);
151
- if (metalTex !== void 0) result.metalnessTexture = metalTex;
152
- const aoTex = findTexture(shader, TEXTURE_LOOKUPS.occlusion);
153
- if (aoTex !== void 0) result.occlusionTexture = aoTex;
154
- const emissiveTex = findTexture(shader, TEXTURE_LOOKUPS.emissive);
155
- if (emissiveTex !== void 0) result.emissiveTexture = emissiveTex;
156
- return result;
157
- }
158
- function findTexture(shader, lookup) {
159
- for (const name of lookup.direct) {
160
- const v = shader.GetAttribute(name).Get();
161
- if (v instanceof AssetPath && v.path) return { path: v.path };
162
- }
163
- for (const name of lookup.surface) {
164
- const conn = shader.GetAttribute(name).GetConnections()[0];
165
- if (!conn) continue;
166
- const texPrim = shader.GetStage().GetPrimAtPath(conn.split(".")[0]);
167
- if (!texPrim) continue;
168
- const file = texPrim.GetAttribute("inputs:file").Get();
169
- if (file instanceof AssetPath && file.path) return readUvTexture(texPrim, file.path);
170
- }
171
- return void 0;
172
- }
173
- var WRAP_VALUES = /* @__PURE__ */ new Set(["repeat", "clamp", "mirror", "black"]);
174
- function readUvTexture(texPrim, path) {
175
- const tex = { path };
176
- const wrapS = texPrim.GetAttribute("inputs:wrapS").Get();
177
- if (typeof wrapS === "string" && WRAP_VALUES.has(wrapS)) tex.wrapS = wrapS;
178
- const wrapT = texPrim.GetAttribute("inputs:wrapT").Get();
179
- if (typeof wrapT === "string" && WRAP_VALUES.has(wrapT)) tex.wrapT = wrapT;
180
- const scale = numArray(texPrim, "inputs:scale", 4);
181
- if (scale) tex.scale = scale;
182
- const bias = numArray(texPrim, "inputs:bias", 4);
183
- if (bias) tex.bias = bias;
184
- const transform = readTransform2d(texPrim);
185
- if (transform) tex.transform = transform;
186
- return tex;
187
- }
188
- function readTransform2d(texPrim) {
189
- const conn = texPrim.GetAttribute("inputs:st").GetConnections()[0];
190
- if (!conn) return void 0;
191
- const node = texPrim.GetStage().GetPrimAtPath(conn.split(".")[0]);
192
- if (!node || node.GetAttribute("info:id").Get() !== "UsdTransform2d") return void 0;
193
- const transform = {};
194
- const translation = numArray(node, "inputs:translation", 2);
195
- if (translation) transform.translation = translation;
196
- const scale = numArray(node, "inputs:scale", 2);
197
- if (scale) transform.scale = scale;
198
- const rotation = node.GetAttribute("inputs:rotation").Get();
199
- if (typeof rotation === "number") transform.rotation = rotation;
200
- return Object.keys(transform).length > 0 ? transform : void 0;
201
- }
202
- function numArray(prim, name, length) {
203
- const v = prim.GetAttribute(name).Get();
204
- if (Array.isArray(v) && v.length >= length && v.every((n) => typeof n === "number")) {
205
- return v.slice(0, length);
206
- }
207
- return void 0;
208
- }
209
- function findBinding(prim) {
210
- let p = prim;
211
- while (p) {
212
- const targets = p.GetRelationship("material:binding").GetTargets();
213
- if (targets.length > 0) return targets[0];
214
- p = p.GetParent();
215
- }
216
- return void 0;
217
- }
218
- function findSurfaceShader(material) {
219
- for (const out of SURFACE_OUTPUTS) {
220
- const conn = material.GetAttribute(out).GetConnections()[0];
221
- if (conn) {
222
- const shaderPath = conn.split(".")[0];
223
- const shader = material.GetStage().GetPrimAtPath(shaderPath);
224
- if (shader) return shader;
225
- }
226
- }
227
- return material.GetChildren().find((c) => c.GetTypeName() === "Shader") ?? void 0;
228
- }
229
- function firstColor(shader, names) {
230
- for (const name of names) {
231
- const v = shader.GetAttribute(name).Get();
232
- if (Array.isArray(v) && v.length >= 3 && v.every((n) => typeof n === "number")) {
233
- return [v[0], v[1], v[2]];
234
- }
235
- }
236
- return void 0;
237
- }
238
- function firstNumber(shader, names) {
239
- for (const name of names) {
240
- const v = shader.GetAttribute(name).Get();
241
- if (typeof v === "number") return v;
242
- }
243
- return void 0;
244
- }
245
73
  var DEFAULT_COLOR = 10132122;
246
74
  function buildMeshGeometry(meshPrim) {
247
75
  const points = meshPrim.GetAttribute("points").Get();
@@ -251,7 +79,12 @@ function buildMeshGeometry(meshPrim) {
251
79
  const counts = meshPrim.GetAttribute("faceVertexCounts").Get();
252
80
  const indices = meshPrim.GetAttribute("faceVertexIndices").Get();
253
81
  if (isNumberArray(counts) && isNumberArray(indices)) {
254
- geometry.setIndex(triangulate(counts, indices));
82
+ const subsets = getMaterialSubsets(meshPrim);
83
+ if (subsets.length > 0) {
84
+ geometry.setIndex(triangulateBySubset(geometry, counts, indices, subsets));
85
+ } else {
86
+ geometry.setIndex(triangulate(counts, indices));
87
+ }
255
88
  } else if (isNumberArray(indices)) {
256
89
  geometry.setIndex(indices.slice());
257
90
  }
@@ -267,10 +100,10 @@ function buildMeshGeometry(meshPrim) {
267
100
  }
268
101
  return geometry;
269
102
  }
270
- function buildMeshMaterial(meshPrim, stage, textures) {
103
+ function buildMeshMaterial(meshPrim, stage, textures, bindingPrim) {
271
104
  const color = new THREE4.Color(DEFAULT_COLOR);
272
105
  let opacity = 1;
273
- const bound = stage ? resolveBoundMaterial(stage, meshPrim) : void 0;
106
+ const bound = stage ? resolveBoundMaterial(stage, bindingPrim ?? meshPrim) : void 0;
274
107
  if (bound?.color) {
275
108
  color.setRGB(bound.color[0], bound.color[1], bound.color[2]);
276
109
  } else {
@@ -314,7 +147,7 @@ function buildMeshMaterial(meshPrim, stage, textures) {
314
147
  const alphaTest = threshold !== void 0 && threshold > 0 ? threshold : 0;
315
148
  const transparent = alphaTest === 0 && hasAlphaSource;
316
149
  const doubleSided = meshPrim.GetAttribute("doubleSided").Get() === true;
317
- return new THREE4.MeshStandardMaterial({
150
+ const material = new THREE4.MeshStandardMaterial({
318
151
  color,
319
152
  metalness,
320
153
  roughness,
@@ -331,6 +164,8 @@ function buildMeshMaterial(meshPrim, stage, textures) {
331
164
  ...aoMap ? { aoMap } : {},
332
165
  ...emissiveMap ? { emissiveMap } : {}
333
166
  });
167
+ if (bound?.name) material.name = bound.name;
168
+ return material;
334
169
  }
335
170
  function bindRobotMeshes(stage, robot3d, desc, options = {}) {
336
171
  const loadVisuals = options.loadVisuals ?? true;
@@ -340,26 +175,60 @@ function bindRobotMeshes(stage, robot3d, desc, options = {}) {
340
175
  const linkObj = robot3d.getLinkObject(key);
341
176
  const linkPrim = stage.GetPrimAtPath(link.primPath);
342
177
  if (!linkObj || !linkPrim) continue;
343
- const collisionSet = new Set(link.collisionPrims ?? []);
178
+ const visualSet = new Set(link.visualPrims);
344
179
  if (loadVisuals) {
345
180
  for (const meshPath of link.visualPrims) {
346
- if (collisionSet.has(meshPath)) continue;
347
181
  attachMesh(stage, linkPrim, meshPath, linkObj, "visual", textures);
348
182
  }
349
183
  }
350
184
  if (loadCollisions) {
351
185
  for (const meshPath of link.collisionPrims ?? []) {
186
+ if (loadVisuals && visualSet.has(meshPath)) continue;
352
187
  attachMesh(stage, linkPrim, meshPath, linkObj, "collision", textures);
353
188
  }
354
189
  }
355
190
  }
356
191
  }
192
+ function bindSceneMeshes(stage, robot3d, desc, options = {}) {
193
+ const owned = /* @__PURE__ */ new Set();
194
+ for (const link of Object.values(desc.links)) {
195
+ for (const path of link.visualPrims) owned.add(path);
196
+ for (const path of link.collisionPrims ?? []) owned.add(path);
197
+ owned.add(link.primPath);
198
+ }
199
+ let attached = 0;
200
+ for (const prim of stage.Traverse()) {
201
+ if (prim.GetTypeName() !== "Mesh" || owned.has(prim.GetPath())) continue;
202
+ if (prim.HasAPI(COLLISION_API) || isNonVisualPurpose(prim)) continue;
203
+ if ([...owned].some((path) => prim.GetPath().startsWith(`${path}/`))) continue;
204
+ const geometry = buildMeshGeometry(prim);
205
+ if (!geometry) continue;
206
+ const mesh = new THREE4.Mesh(geometry, buildMeshMaterial(prim, stage, options.textureProvider));
207
+ mesh.name = prim.GetName();
208
+ mesh.userData.kind = "scene";
209
+ mesh.userData.primPath = prim.GetPath();
210
+ mesh.matrixAutoUpdate = false;
211
+ mesh.matrix.fromArray(computeWorldTransform(prim));
212
+ mesh.matrixWorldNeedsUpdate = true;
213
+ robot3d.add(mesh);
214
+ attached++;
215
+ }
216
+ return attached;
217
+ }
218
+ function buildMeshMaterials(meshPrim, stage, textures) {
219
+ const subsets = stage ? getMaterialSubsets(meshPrim) : [];
220
+ if (subsets.length === 0) return buildMeshMaterial(meshPrim, stage, textures);
221
+ return [
222
+ ...subsets.map((s) => buildMeshMaterial(meshPrim, stage, textures, s.prim)),
223
+ buildMeshMaterial(meshPrim, stage, textures)
224
+ ];
225
+ }
357
226
  function attachMesh(stage, linkPrim, meshPath, parent, kind, textures) {
358
227
  const meshPrim = stage.GetPrimAtPath(meshPath);
359
228
  if (!meshPrim) return;
360
229
  const geometry = buildMeshGeometry(meshPrim);
361
230
  if (!geometry) return;
362
- const mesh = new THREE4.Mesh(geometry, buildMeshMaterial(meshPrim, stage, textures));
231
+ const mesh = new THREE4.Mesh(geometry, buildMeshMaterials(meshPrim, stage, textures));
363
232
  mesh.name = meshPrim.GetName();
364
233
  mesh.userData.kind = kind;
365
234
  mesh.userData.primPath = meshPath;
@@ -399,6 +268,42 @@ function triangulate(faceVertexCounts, faceVertexIndices) {
399
268
  }
400
269
  return tris;
401
270
  }
271
+ function triangulateBySubset(geometry, faceVertexCounts, faceVertexIndices, subsets) {
272
+ const faceStart = [];
273
+ let offset = 0;
274
+ for (const count of faceVertexCounts) {
275
+ faceStart.push(offset);
276
+ offset += count;
277
+ }
278
+ const tris = [];
279
+ const emit = (face) => {
280
+ const start = faceStart[face];
281
+ const count = faceVertexCounts[face];
282
+ for (let k = 2; k < count; k++) {
283
+ tris.push(
284
+ faceVertexIndices[start],
285
+ faceVertexIndices[start + k - 1],
286
+ faceVertexIndices[start + k]
287
+ );
288
+ }
289
+ };
290
+ const claimed = new Uint8Array(faceVertexCounts.length);
291
+ subsets.forEach((subset, index) => {
292
+ const begin2 = tris.length;
293
+ for (const face of subset.faces) {
294
+ if (face < 0 || face >= faceVertexCounts.length || claimed[face]) continue;
295
+ claimed[face] = 1;
296
+ emit(face);
297
+ }
298
+ if (tris.length > begin2) geometry.addGroup(begin2, tris.length - begin2, index);
299
+ });
300
+ const begin = tris.length;
301
+ for (let face = 0; face < faceVertexCounts.length; face++) {
302
+ if (!claimed[face]) emit(face);
303
+ }
304
+ if (tris.length > begin) geometry.addGroup(begin, tris.length - begin, subsets.length);
305
+ return tris;
306
+ }
402
307
  function flat3(v) {
403
308
  const out = new Array(v.length * 3);
404
309
  for (let i = 0; i < v.length; i++) {
@@ -547,9 +452,12 @@ var ThreeUsdRobot = class extends THREE4.Object3D {
547
452
  const rootObj = this.linkObjects.get(this.tree.root);
548
453
  if (!rootObj) return;
549
454
  const rootJointKey = this.tree.rootJoint;
455
+ const rootLink = this.robot.links[this.tree.root];
550
456
  if (rootJointKey) {
551
457
  const j = this.robot.joints[rootJointKey];
552
458
  if (j) setMatrix(rootObj, multiply(j.jointFrame0, invert(j.jointFrame1)));
459
+ } else if (rootLink?.worldTransform) {
460
+ setMatrix(rootObj, rootLink.worldTransform);
553
461
  }
554
462
  this.add(rootObj);
555
463
  }
@@ -582,7 +490,10 @@ var ThreeUsdRobot = class extends THREE4.Object3D {
582
490
  attachIsolatedLinks() {
583
491
  for (const key of this.tree.isolatedLinks) {
584
492
  const obj = this.linkObjects.get(key);
585
- if (obj && !obj.parent) this.add(obj);
493
+ if (!obj || obj.parent) continue;
494
+ const worldTransform = this.robot.links[key]?.worldTransform;
495
+ if (worldTransform) setMatrix(obj, worldTransform);
496
+ this.add(obj);
586
497
  }
587
498
  }
588
499
  // -- Joint control -------------------------------------------------------
@@ -795,13 +706,21 @@ var ThreeUsdRobotLoader = class {
795
706
  const robot3d = new ThreeUsdRobot(robot, tree, this.robotOptions());
796
707
  const loadVisuals = this.options.loadVisuals ?? true;
797
708
  const loadCollisions = this.options.loadCollisions ?? false;
798
- if (loadVisuals || loadCollisions) {
709
+ const loadScene = this.options.loadSceneGeometry ?? false;
710
+ if (loadVisuals || loadCollisions || loadScene) {
799
711
  const textureProvider = this.options.loadTextures ?? true ? createTextureProvider(resolver, baseUrl) : void 0;
800
- bindRobotMeshes(stage, robot3d, robot, {
801
- loadVisuals,
802
- loadCollisions,
803
- ...textureProvider ? { textureProvider } : {}
804
- });
712
+ if (loadVisuals || loadCollisions) {
713
+ bindRobotMeshes(stage, robot3d, robot, {
714
+ loadVisuals,
715
+ loadCollisions,
716
+ ...textureProvider ? { textureProvider } : {}
717
+ });
718
+ }
719
+ if (loadScene) {
720
+ bindSceneMeshes(stage, robot3d, robot, {
721
+ ...textureProvider ? { textureProvider } : {}
722
+ });
723
+ }
805
724
  }
806
725
  return robot3d;
807
726
  }
@@ -836,6 +755,6 @@ var ThreeUsdRobotLoader = class {
836
755
  }
837
756
  };
838
757
 
839
- export { JointObject, LinkObject, ThreeUsdRobot, ThreeUsdRobotLoader, axisVector, bindRobotMeshes, buildMeshGeometry, buildMeshMaterial, createTextureProvider, resolveBoundMaterial };
840
- //# sourceMappingURL=chunk-Y3NXBSX3.js.map
841
- //# sourceMappingURL=chunk-Y3NXBSX3.js.map
758
+ export { JointObject, LinkObject, ThreeUsdRobot, ThreeUsdRobotLoader, axisVector, bindRobotMeshes, bindSceneMeshes, buildMeshGeometry, buildMeshMaterial, createTextureProvider };
759
+ //# sourceMappingURL=chunk-FL554IS5.js.map
760
+ //# sourceMappingURL=chunk-FL554IS5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/three/axis.ts","../src/three/JointObject.ts","../src/three/LinkObject.ts","../src/three/MeshBinding.ts","../src/three/TextureBinding.ts","../src/three/ThreeUsdRobot.ts","../src/three/ThreeUsdRobotLoader.ts"],"names":["THREE","THREE2","THREE3","begin","THREE5","THREE6"],"mappings":";;;AAIO,SAAS,WAAW,IAAA,EAA2B;AACpD,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,GAAA;AACH,MAAA,OAAO,IAAUA,MAAA,CAAA,OAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,IAClC,KAAK,GAAA;AACH,MAAA,OAAO,IAAUA,MAAA,CAAA,OAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,IAClC,KAAK,GAAA;AACH,MAAA,OAAO,IAAUA,MAAA,CAAA,OAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA;AAEtC;ACHO,IAAM,WAAA,GAAN,cAAgCC,MAAA,CAAA,QAAA,CAAS;AAAA,EACrC,aAAA,GAAgB,IAAA;AAAA,EAChB,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EAED,MAAA,GAAS,CAAA;AAAA,EAEjB,YAAY,KAAA,EAAyB;AACnC,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,IAAA;AAClB,IAAA,IAAA,CAAK,YAAY,KAAA,CAAM,IAAA;AACvB,IAAA,IAAA,CAAK,YAAY,KAAA,CAAM,IAAA;AACvB,IAAA,IAAA,CAAK,YAAY,KAAA,CAAM,IAAA;AACvB,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA,CAAW,KAAA,CAAM,IAAI,CAAA;AACjC,IAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,KAAA;AACnB,IAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,KAAA;AAAA,EACrB;AAAA,EAEA,IAAI,KAAA,GAAgB;AAClB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,KAAK,SAAA,KAAc,OAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA,CAAS,KAAA,EAAe,aAAA,GAAgB,IAAA,EAAc;AACpD,IAAA,IAAI,CAAC,IAAA,CAAK,WAAA,EAAa,OAAO,IAAA,CAAK,MAAA;AAEnC,IAAA,IAAI,CAAA,GAAI,KAAA;AACR,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,IAAI,KAAK,KAAA,KAAU,MAAA,IAAa,IAAI,IAAA,CAAK,KAAA,MAAW,IAAA,CAAK,KAAA;AACzD,MAAA,IAAI,KAAK,KAAA,KAAU,MAAA,IAAa,IAAI,IAAA,CAAK,KAAA,MAAW,IAAA,CAAK,KAAA;AAAA,IAC3D;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,CAAA;AAEd,IAAA,IAAI,IAAA,CAAK,cAAc,WAAA,EAAa;AAClC,MAAA,IAAA,CAAK,SAAS,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CAAE,eAAe,CAAC,CAAA;AAC9C,MAAA,IAAA,CAAK,WAAW,QAAA,EAAS;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,UAAA,CAAW,gBAAA,CAAiB,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA;AAC7C,MAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,IAC3B;AACA,IAAA,OAAO,CAAA;AAAA,EACT;AACF;ACtDO,IAAM,UAAA,GAAN,cAA+BC,MAAA,CAAA,QAAA,CAAS;AAAA,EACpC,YAAA,GAAe,IAAA;AAAA,EACf,QAAA;AAAA,EACA,QAAA;AAAA,EAET,YAAY,IAAA,EAAuB;AACjC,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,IAAA;AACrB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AAErB,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AAAA,EAC1B;AACF;ACGA,IAAM,aAAA,GAAgB,QAAA;AAiBf,SAAS,kBAAkB,QAAA,EAA6C;AAC7E,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,YAAA,CAAa,QAAQ,EAAE,GAAA,EAAI;AACnD,EAAA,IAAI,CAAC,WAAA,CAAY,MAAM,KAAK,MAAA,CAAO,MAAA,KAAW,GAAG,OAAO,IAAA;AAExD,EAAA,MAAM,QAAA,GAAW,IAAU,MAAA,CAAA,cAAA,EAAe;AAC1C,EAAA,QAAA,CAAS,YAAA,CAAa,YAAY,IAAU,MAAA,CAAA,sBAAA,CAAuB,MAAM,MAAM,CAAA,EAAG,CAAC,CAAC,CAAA;AAEpF,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,YAAA,CAAa,kBAAkB,EAAE,GAAA,EAAI;AAC7D,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,YAAA,CAAa,mBAAmB,EAAE,GAAA,EAAI;AAC/D,EAAA,IAAI,aAAA,CAAc,MAAM,CAAA,IAAK,aAAA,CAAc,OAAO,CAAA,EAAG;AACnD,IAAA,MAAM,OAAA,GAAU,mBAAmB,QAAQ,CAAA;AAC3C,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,MAAA,QAAA,CAAS,SAAS,mBAAA,CAAoB,QAAA,EAAU,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAC,CAAA;AAAA,IAC3E,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,QAAA,CAAS,WAAA,CAAY,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,IAChD;AAAA,EACF,CAAA,MAAA,IAAW,aAAA,CAAc,OAAO,CAAA,EAAG;AACjC,IAAA,QAAA,CAAS,QAAA,CAAS,OAAA,CAAQ,KAAA,EAAO,CAAA;AAAA,EACnC;AAEA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,YAAA,CAAa,SAAS,EAAE,GAAA,EAAI;AACrD,EAAA,IAAI,YAAY,OAAO,CAAA,IAAK,OAAA,CAAQ,MAAA,KAAW,OAAO,MAAA,EAAQ;AAC5D,IAAA,QAAA,CAAS,YAAA,CAAa,UAAU,IAAU,MAAA,CAAA,sBAAA,CAAuB,MAAM,OAAO,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,EACrF,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,oBAAA,EAAqB;AAAA,EAChC;AAEA,EAAA,MAAM,EAAA,GAAK,QAAA,CAAS,YAAA,CAAa,aAAa,EAAE,GAAA,EAAI;AACpD,EAAA,IAAI,YAAY,EAAE,CAAA,IAAK,EAAA,CAAG,MAAA,KAAW,OAAO,MAAA,EAAQ;AAClD,IAAA,QAAA,CAAS,YAAA,CAAa,MAAM,IAAU,MAAA,CAAA,sBAAA,CAAuB,MAAM,EAAE,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,EAC5E;AAEA,EAAA,OAAO,QAAA;AACT;AAUO,SAAS,iBAAA,CACd,QAAA,EACA,KAAA,EACA,QAAA,EAEA,WAAA,EACgB;AAChB,EAAA,MAAM,KAAA,GAAQ,IAAU,MAAA,CAAA,KAAA,CAAM,aAAa,CAAA;AAC3C,EAAA,IAAI,OAAA,GAAU,CAAA;AAEd,EAAA,MAAM,QAAQ,KAAA,GAAQ,oBAAA,CAAqB,KAAA,EAAO,WAAA,IAAe,QAAQ,CAAA,GAAI,MAAA;AAC7E,EAAA,IAAI,OAAO,KAAA,EAAO;AAChB,IAAA,KAAA,CAAM,MAAA,CAAO,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EAC7D,CAAA,MAAO;AACL,IAAA,MAAM,YAAA,GAAe,QAAA,CAAS,YAAA,CAAa,uBAAuB,EAAE,GAAA,EAAI;AACxE,IAAA,IAAI,WAAA,CAAY,YAAY,CAAA,IAAK,YAAA,CAAa,CAAC,CAAA,EAAG;AAChD,MAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,aAAa,CAAC,CAAA;AAChC,MAAA,KAAA,CAAM,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,IACtB;AAAA,EACF;AACA,EAAA,IAAI,KAAA,EAAO,OAAA,KAAY,MAAA,EAAW,OAAA,GAAU,KAAA,CAAM,OAAA;AAKlD,EAAA,MAAM,GAAA,GAAM,CAAC,EAAA,EAAiC,EAAA,KAC5C,MAAM,QAAA,GACF,QAAA,CAAS,GAAG,IAAA,EAAM;AAAA,IAChB,UAAA,EAAY,EAAA;AAAA,IACZ,GAAI,GAAG,KAAA,GAAQ,EAAE,OAAO,EAAA,CAAG,KAAA,KAAU,EAAC;AAAA,IACtC,GAAI,GAAG,KAAA,GAAQ,EAAE,OAAO,EAAA,CAAG,KAAA,KAAU,EAAC;AAAA,IACtC,GAAI,GAAG,SAAA,GAAY,EAAE,WAAW,EAAA,CAAG,SAAA,KAAc;AAAC,GACnD,CAAA,GACD,IAAA;AAEN,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,KAAA,EAAO,YAAA,EAAc,MAAM,CAAA;AAE3C,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,MAAM,CAAA,GAAI,OAAO,YAAA,EAAc,KAAA;AAC/B,IAAA,IAAI,CAAA,EAAG,KAAA,CAAM,MAAA,CAAO,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,SAC/B,KAAA,CAAM,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,EAC3B;AACA,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,KAAA,EAAO,aAAA,EAAe,QAAQ,CAAA;AACpD,EAAA,MAAM,YAAA,GAAe,GAAA,CAAI,KAAA,EAAO,gBAAA,EAAkB,QAAQ,CAAA;AAC1D,EAAA,MAAM,YAAA,GAAe,GAAA,CAAI,KAAA,EAAO,gBAAA,EAAkB,QAAQ,CAAA;AAC1D,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,EAAO,gBAAA,EAAkB,QAAQ,CAAA;AACnD,EAAA,MAAM,WAAA,GAAc,GAAA,CAAI,KAAA,EAAO,eAAA,EAAiB,MAAM,CAAA;AAItD,EAAA,MAAM,SAAA,GACJ,OAAO,SAAA,IAAa,KAAA,EAAO,kBAAkB,KAAA,GAAQ,CAAC,CAAA,KAAM,YAAA,GAAe,CAAA,GAAI,GAAA,CAAA;AACjF,EAAA,MAAM,SAAA,GACJ,OAAO,SAAA,IAAa,KAAA,EAAO,kBAAkB,KAAA,GAAQ,CAAC,CAAA,KAAM,YAAA,GAAe,CAAA,GAAI,GAAA,CAAA;AAEjF,EAAA,MAAM,QAAA,GAAW,IAAU,MAAA,CAAA,KAAA,CAAM,CAAQ,CAAA;AACzC,EAAA,IAAI,OAAO,aAAA,EAAe;AACxB,IAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,aAAA,CAAc,CAAC,CAAA,EAAG,KAAA,CAAM,aAAA,CAAc,CAAC,CAAA,EAAG,KAAA,CAAM,aAAA,CAAc,CAAC,CAAC,CAAA;AAAA,EACxF,WAAW,WAAA,EAAa;AACtB,IAAA,QAAA,CAAS,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,EACzB;AAMA,EAAA,MAAM,aAAa,KAAA,EAAO,cAAA;AAC1B,EAAA,MAAM,iBAAiB,CAAC,EAAE,cAAc,UAAA,CAAW,IAAA,KAAS,OAAO,YAAA,EAAc,IAAA,CAAA;AACjF,EAAA,MAAM,QAAA,GAAW,cAAA,GAAiB,IAAA,GAAO,GAAA,CAAI,YAAY,QAAQ,CAAA;AACjE,EAAA,MAAM,cAAA,GAAiB,OAAA,GAAU,CAAA,IAAK,cAAA,IAAkB,CAAC,CAAC,QAAA;AAC1D,EAAA,MAAM,YAAY,KAAA,EAAO,gBAAA;AACzB,EAAA,MAAM,SAAA,GAAY,SAAA,KAAc,MAAA,IAAa,SAAA,GAAY,IAAI,SAAA,GAAY,CAAA;AAGzE,EAAA,MAAM,WAAA,GAAc,cAAc,CAAA,IAAK,cAAA;AAEvC,EAAA,MAAM,cAAc,QAAA,CAAS,YAAA,CAAa,aAAa,CAAA,CAAE,KAAI,KAAM,IAAA;AACnE,EAAA,MAAM,QAAA,GAAW,IAAU,MAAA,CAAA,oBAAA,CAAqB;AAAA,IAC9C,KAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA;AAAA,IACA,GAAI,SAAA,GAAY,CAAA,GAAI,EAAE,SAAA,KAAc,EAAC;AAAA,IACrC,IAAA,EAAM,cAAoB,MAAA,CAAA,UAAA,GAAmB,MAAA,CAAA,SAAA;AAAA,IAC7C,GAAI,GAAA,GAAM,EAAE,GAAA,KAAQ,EAAC;AAAA,IACrB,GAAI,QAAA,GAAW,EAAE,QAAA,KAAa,EAAC;AAAA,IAC/B,GAAI,SAAA,GAAY,EAAE,SAAA,KAAc,EAAC;AAAA,IACjC,GAAI,YAAA,GAAe,EAAE,YAAA,KAAiB,EAAC;AAAA,IACvC,GAAI,YAAA,GAAe,EAAE,YAAA,KAAiB,EAAC;AAAA,IACvC,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU,EAAC;AAAA,IACzB,GAAI,WAAA,GAAc,EAAE,WAAA,KAAgB;AAAC,GACtC,CAAA;AAED,EAAA,IAAI,KAAA,EAAO,IAAA,EAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,IAAA;AACvC,EAAA,OAAO,QAAA;AACT;AAOO,SAAS,gBACd,KAAA,EACA,OAAA,EACA,IAAA,EACA,OAAA,GAA6B,EAAC,EACxB;AACN,EAAA,MAAM,WAAA,GAAc,QAAQ,WAAA,IAAe,IAAA;AAC3C,EAAA,MAAM,cAAA,GAAiB,QAAQ,cAAA,IAAkB,KAAA;AACjD,EAAA,MAAM,WAAW,OAAA,CAAQ,eAAA;AAEzB,EAAA,KAAA,MAAW,CAAC,KAAK,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG;AACpD,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,aAAA,CAAc,GAAG,CAAA;AACzC,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,aAAA,CAAc,IAAA,CAAK,QAAQ,CAAA;AAClD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,QAAA,EAAU;AAG3B,IAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,IAAA,CAAK,WAAW,CAAA;AAE1C,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,KAAA,MAAW,QAAA,IAAY,KAAK,WAAA,EAAa;AACvC,QAAA,UAAA,CAAW,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,UAAU,QAAQ,CAAA;AAAA,MACnE;AAAA,IACF;AACA,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,cAAA,IAAkB,EAAC,EAAG;AAChD,QAAA,IAAI,WAAA,IAAe,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC5C,QAAA,UAAA,CAAW,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,aAAa,QAAQ,CAAA;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,gBACd,KAAA,EACA,OAAA,EACA,IAAA,EACA,OAAA,GAAiD,EAAC,EAC1C;AACR,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG;AAC5C,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,WAAA,EAAa,KAAA,CAAM,IAAI,IAAI,CAAA;AACnD,IAAA,KAAA,MAAW,QAAQ,IAAA,CAAK,cAAA,IAAkB,EAAC,EAAG,KAAA,CAAM,IAAI,IAAI,CAAA;AAC5D,IAAA,KAAA,CAAM,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,EACzB;AAEA,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,QAAA,EAAS,EAAG;AACnC,IAAA,IAAI,IAAA,CAAK,aAAY,KAAM,MAAA,IAAU,MAAM,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS,CAAA,EAAG;AAChE,IAAA,IAAI,KAAK,MAAA,CAAO,aAAa,CAAA,IAAK,kBAAA,CAAmB,IAAI,CAAA,EAAG;AAE5D,IAAA,IAAI,CAAC,GAAG,KAAK,CAAA,CAAE,KAAK,CAAC,IAAA,KAAS,IAAA,CAAK,OAAA,GAAU,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,CAAA,CAAG,CAAC,CAAA,EAAG;AAEtE,IAAA,MAAM,QAAA,GAAW,kBAAkB,IAAI,CAAA;AACvC,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,MAAM,IAAA,GAAO,IAAU,MAAA,CAAA,IAAA,CAAK,QAAA,EAAU,kBAAkB,IAAA,EAAM,KAAA,EAAO,OAAA,CAAQ,eAAe,CAAC,CAAA;AAC7F,IAAA,IAAA,CAAK,IAAA,GAAO,KAAK,OAAA,EAAQ;AACzB,IAAA,IAAA,CAAK,SAAS,IAAA,GAAO,OAAA;AACrB,IAAA,IAAA,CAAK,QAAA,CAAS,QAAA,GAAW,IAAA,CAAK,OAAA,EAAQ;AACtC,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,IAAA,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,qBAAA,CAAsB,IAAI,CAAC,CAAA;AACjD,IAAA,IAAA,CAAK,sBAAA,GAAyB,IAAA;AAC9B,IAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,IAAA,QAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAOO,SAAS,kBAAA,CACd,QAAA,EACA,KAAA,EACA,QAAA,EACmC;AACnC,EAAA,MAAM,OAAA,GAAU,KAAA,GAAQ,kBAAA,CAAmB,QAAQ,IAAI,EAAC;AACxD,EAAA,IAAI,QAAQ,MAAA,KAAW,CAAA,SAAU,iBAAA,CAAkB,QAAA,EAAU,OAAO,QAAQ,CAAA;AAC5E,EAAA,OAAO;AAAA,IACL,GAAG,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,iBAAA,CAAkB,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC1E,iBAAA,CAAkB,QAAA,EAAU,KAAA,EAAO,QAAQ;AAAA,GAC7C;AACF;AAEA,SAAS,WACP,KAAA,EACA,QAAA,EACA,QAAA,EACA,MAAA,EACA,MACA,QAAA,EACM;AACN,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,aAAA,CAAc,QAAQ,CAAA;AAC7C,EAAA,IAAI,CAAC,QAAA,EAAU;AACf,EAAA,MAAM,QAAA,GAAW,kBAAkB,QAAQ,CAAA;AAC3C,EAAA,IAAI,CAAC,QAAA,EAAU;AAEf,EAAA,MAAM,IAAA,GAAO,IAAU,MAAA,CAAA,IAAA,CAAK,QAAA,EAAU,mBAAmB,QAAA,EAAU,KAAA,EAAO,QAAQ,CAAC,CAAA;AACnF,EAAA,IAAA,CAAK,IAAA,GAAO,SAAS,OAAA,EAAQ;AAC7B,EAAA,IAAA,CAAK,SAAS,IAAA,GAAO,IAAA;AACrB,EAAA,IAAA,CAAK,SAAS,QAAA,GAAW,QAAA;AAEzB,EAAA,IAAI,IAAA,KAAS,WAAA,EAAa,IAAA,CAAK,OAAA,GAAU,KAAA;AACzC,EAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,EAAA,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,iBAAA,CAAkB,QAAA,EAAU,QAAQ,CAAC,CAAA;AAC3D,EAAA,IAAA,CAAK,sBAAA,GAAyB,IAAA;AAC9B,EAAA,MAAA,CAAO,IAAI,IAAI,CAAA;AACjB;AAGA,SAAS,iBAAA,CAAkB,UAAgB,QAAA,EAAsB;AAC/D,EAAA,MAAM,QAAgB,EAAC;AACvB,EAAA,IAAI,CAAA,GAAiB,QAAA;AACrB,EAAA,MAAM,IAAA,GAAO,SAAS,OAAA,EAAQ;AAC9B,EAAA,OAAO,CAAA,IAAK,CAAA,CAAE,OAAA,EAAQ,KAAM,IAAA,EAAM;AAChC,IAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AACZ,IAAA,CAAA,GAAI,EAAE,SAAA,EAAU;AAAA,EAClB;AACA,EAAA,KAAA,CAAM,OAAA,EAAQ;AAEd,EAAA,IAAI,IAAI,SAAA,EAAU;AAClB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,qBAAA,CAAsB,IAAI,EAAE,MAAM,CAAA;AAAA,EACpD;AACA,EAAA,OAAO,CAAA;AACT;AAKA,SAAS,WAAA,CAAY,kBAA4B,iBAAA,EAAuC;AACtF,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,MAAW,SAAS,gBAAA,EAAkB;AACpC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,MAAA,IAAA,CAAK,IAAA;AAAA,QACH,kBAAkB,MAAM,CAAA;AAAA,QACxB,iBAAA,CAAkB,MAAA,GAAS,CAAA,GAAI,CAAC,CAAA;AAAA,QAChC,iBAAA,CAAkB,SAAS,CAAC;AAAA,OAC9B;AAAA,IACF;AACA,IAAA,MAAA,IAAU,KAAA;AAAA,EACZ;AACA,EAAA,OAAO,IAAA;AACT;AAMA,SAAS,mBAAA,CACP,QAAA,EACA,gBAAA,EACA,iBAAA,EACA,OAAA,EACU;AACV,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,MAAW,SAAS,gBAAA,EAAkB;AACpC,IAAA,SAAA,CAAU,KAAK,MAAM,CAAA;AACrB,IAAA,MAAA,IAAU,KAAA;AAAA,EACZ;AAEA,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,MAAM,IAAA,GAAO,CAAC,IAAA,KAAiB;AAC7B,IAAA,MAAM,KAAA,GAAQ,UAAU,IAAI,CAAA;AAC5B,IAAA,MAAM,KAAA,GAAQ,iBAAiB,IAAI,CAAA;AACnC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,MAAA,IAAA,CAAK,IAAA;AAAA,QACH,kBAAkB,KAAK,CAAA;AAAA,QACvB,iBAAA,CAAkB,KAAA,GAAQ,CAAA,GAAI,CAAC,CAAA;AAAA,QAC/B,iBAAA,CAAkB,QAAQ,CAAC;AAAA,OAC7B;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,IAAI,UAAA,CAAW,gBAAA,CAAiB,MAAM,CAAA;AACtD,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,MAAA,EAAQ,KAAA,KAAU;AACjC,IAAA,MAAMC,SAAQ,IAAA,CAAK,MAAA;AACnB,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,MAAA,IAAI,OAAO,CAAA,IAAK,IAAA,IAAQ,iBAAiB,MAAA,IAAU,OAAA,CAAQ,IAAI,CAAA,EAAG;AAClE,MAAA,OAAA,CAAQ,IAAI,CAAA,GAAI,CAAA;AAChB,MAAA,IAAA,CAAK,IAAI,CAAA;AAAA,IACX;AACA,IAAA,IAAI,IAAA,CAAK,SAASA,MAAAA,EAAO,QAAA,CAAS,SAASA,MAAAA,EAAO,IAAA,CAAK,MAAA,GAASA,MAAAA,EAAO,KAAK,CAAA;AAAA,EAC9E,CAAC,CAAA;AAED,EAAA,MAAM,QAAQ,IAAA,CAAK,MAAA;AACnB,EAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,gBAAA,CAAiB,QAAQ,IAAA,EAAA,EAAQ;AACzD,IAAA,IAAI,CAAC,OAAA,CAAQ,IAAI,CAAA,OAAQ,IAAI,CAAA;AAAA,EAC/B;AACA,EAAA,IAAI,IAAA,CAAK,MAAA,GAAS,KAAA,EAAO,QAAA,CAAS,QAAA,CAAS,OAAO,IAAA,CAAK,MAAA,GAAS,KAAA,EAAO,OAAA,CAAQ,MAAM,CAAA;AAErF,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,MAAM,CAAA,EAAqB;AAClC,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAC1C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,GAAA,CAAI,IAAI,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AACpB,IAAA,GAAA,CAAI,IAAI,CAAA,GAAI,CAAC,IAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AACxB,IAAA,GAAA,CAAI,IAAI,CAAA,GAAI,CAAC,IAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,MAAM,CAAA,EAAqB;AAClC,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAC1C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,GAAA,CAAI,IAAI,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AACpB,IAAA,GAAA,CAAI,IAAI,CAAA,GAAI,CAAC,IAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,cAAc,CAAA,EAA2B;AAChD,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,MAAM,CAAC,CAAA,KAAM,OAAO,CAAA,KAAM,QAAQ,CAAA;AACjE;AAEA,SAAS,YAAY,CAAA,EAAyB;AAC5C,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAE,KAAA,CAAM,CAAC,CAAA,KAAM,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,WAAW,CAAC,CAAA;AAC9E;AAEA,SAAS,YAAY,CAAA,EAAyB;AAC5C,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAE,KAAA,CAAM,CAAC,CAAA,KAAM,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,WAAW,CAAC,CAAA;AAC9E;ACnYA,IAAM,OAAA,GAAU,KAAK,EAAA,GAAK,GAAA;AAQnB,SAAS,qBAAA,CAAsB,UAAyB,OAAA,EAAkC;AAC/F,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAqC;AAExD,EAAA,MAAM,QAAA,GAAW,CAAC,GAAA,KAAyC;AACzD,IAAA,IAAI,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AACtB,IAAA,IAAI,CAAC,CAAA,EAAG;AACN,MAAA,CAAA,GAAI,SAAA,CAAU,UAAU,GAAG,CAAA;AAC3B,MAAA,MAAA,CAAO,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,IACnB;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO,CAAC,SAAA,EAAmB,OAAA,GAA0B,EAAC,KAAM;AAC1D,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,IAC3C,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,IAAUC,MAAA,CAAA,OAAA,EAAQ;AAClC,IAAA,OAAA,CAAQ,UAAA,GACN,OAAA,CAAQ,UAAA,KAAe,QAAA,GAAiBA,MAAA,CAAA,YAAA,GAAqBA,MAAA,CAAA,cAAA;AAC/D,IAAA,OAAA,CAAQ,KAAA,GAAQ,WAAA,CAAY,OAAA,CAAQ,KAAK,CAAA;AACzC,IAAA,OAAA,CAAQ,KAAA,GAAQ,WAAA,CAAY,OAAA,CAAQ,KAAK,CAAA;AACzC,IAAA,cAAA,CAAe,OAAA,EAAS,QAAQ,SAAS,CAAA;AAEzC,IAAA,QAAA,CAAS,GAAG,CAAA,CACT,IAAA,CAAK,CAAC,KAAA,KAAU;AACf,MAAA,OAAA,CAAQ,KAAA,GAAQ,KAAA;AAChB,MAAA,OAAA,CAAQ,WAAA,GAAc,IAAA;AAAA,IACxB,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,IAEb,CAAC,CAAA;AACH,IAAA,OAAO,OAAA;AAAA,EACT,CAAA;AACF;AAOA,eAAe,SAAA,CAAU,UAAyB,GAAA,EAAsC;AACtF,EAAA,MAAM,QAAQ,QAAA,CAAS,UAAA,GACnB,MAAM,QAAA,CAAS,WAAW,GAAG,CAAA,GAC7B,IAAI,WAAA,GAAc,MAAA,CAAO,MAAM,QAAA,CAAS,SAAA,CAAU,GAAG,CAAC,CAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,KAAiB,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,GAAG,CAAA,EAAG,CAAA;AAChE,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AAC1C,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,IAAI,OAAA,CAA0B,CAAC,SAAS,MAAA,KAAW;AAC9D,MAAA,MAAM,GAAA,GAAM,IAAI,KAAA,EAAM;AACtB,MAAA,GAAA,CAAI,MAAA,GAAS,MAAM,OAAA,CAAQ,GAAG,CAAA;AAC9B,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,MAAA,CAAO,IAAI,MAAM,CAAA,0BAAA,EAA6B,GAAG,EAAE,CAAC,CAAA;AACxE,MAAA,GAAA,CAAI,GAAA,GAAM,SAAA;AAAA,IACZ,CAAC,CAAA;AAAA,EACH,CAAA,SAAE;AAEA,IAAA,GAAA,CAAI,gBAAgB,SAAS,CAAA;AAAA,EAC/B;AACF;AAEA,SAAS,YAAY,IAAA,EAA+C;AAClE,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,OAAA;AAAA,IACL,KAAK,OAAA;AACH,MAAA,OAAaA,MAAA,CAAA,mBAAA;AAAA,IACf,KAAK,QAAA;AACH,MAAA,OAAaA,MAAA,CAAA,sBAAA;AAAA,IACf;AACE,MAAA,OAAaA,MAAA,CAAA,cAAA;AAAA;AAEnB;AAGA,SAAS,cAAA,CAAe,SAAwB,CAAA,EAAuC;AACrF,EAAA,IAAI,CAAC,CAAA,EAAG;AACR,EAAA,IAAI,CAAA,CAAE,KAAA,EAAO,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA;AACtD,EAAA,IAAI,CAAA,CAAE,WAAA,EAAa,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,WAAA,CAAY,CAAC,CAAA,EAAG,CAAA,CAAE,WAAA,CAAY,CAAC,CAAC,CAAA;AACxE,EAAA,IAAI,CAAA,CAAE,aAAa,MAAA,EAAW;AAC5B,IAAA,OAAA,CAAQ,QAAA,GAAW,EAAE,QAAA,GAAW,OAAA;AAChC,IAAA,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AAAA,EACzB;AACF;AAEA,SAAS,OAAO,GAAA,EAAqB;AACnC,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,YAAA;AAClC,EAAA,IAAI,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,YAAA;AACjC,EAAA,OAAO,WAAA;AACT;AC9FO,IAAM,aAAA,GAAN,cAAkCC,MAAA,CAAA,QAAA,CAAS;AAAA,EACvC,eAAA,GAAkB,IAAA;AAAA,EAClB,KAAA;AAAA,EACA,IAAA;AAAA,EACA,gBAAA;AAAA,EAEQ,WAAA,uBAAkB,GAAA,EAAwB;AAAA,EAC1C,YAAA,uBAAmB,GAAA,EAAyB;AAAA,EACrD,KAAA,GAAQ,IAAA;AAAA,EAEC,UAAA;AAAA,EACT,WAAA,GAAc,IAAA;AAAA,EACd,cAAA,GAAiB,KAAA;AAAA,EACjB,cAAA,GAAiB,KAAA;AAAA,EACjB,eAAA,GAAkB,KAAA;AAAA,EAClB,mBAAuC,EAAC;AAAA,EACxC,mBAAuC,EAAC;AAAA,EAEhD,WAAA,CAAY,KAAA,EAAyB,IAAA,EAAqB,OAAA,GAAgC,EAAC,EAAG;AAC5F,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,IAAA;AAClB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,gBAAA,GAAmB,QAAQ,gBAAA,IAAoB,IAAA;AACpD,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,IAAA;AAGxC,IAAA,KAAA,MAAW,CAAC,KAAK,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AACrD,MAAA,IAAA,CAAK,YAAY,GAAA,CAAI,GAAA,EAAK,IAAI,UAAA,CAAW,IAAI,CAAC,CAAA;AAAA,IAChD;AAEA,IAAA,IAAA,CAAK,UAAA,EAAW;AAChB,IAAA,IAAA,CAAK,eAAA,EAAgB;AACrB,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,IAAA,CAAK,uBAAA,CAAwB,OAAO,OAAO,CAAA;AAC3C,IAAA,IAAI,OAAA,CAAQ,gBAAA,IAAoB,IAAA,EAAM,IAAA,CAAK,iBAAiB,KAAK,CAAA;AAAA,EACnE;AAAA;AAAA,EAGQ,uBAAA,CAAwB,OAAyB,OAAA,EAAqC;AAC5F,IAAA,MAAM,KAAA,GAAA,CAAS,KAAA,CAAM,aAAA,IAAiB,CAAA,KAAM,QAAQ,SAAA,IAAa,CAAA,CAAA;AACjE,IAAA,IAAI,KAAA,KAAU,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,UAAU,KAAK,CAAA;AAE3C,IAAA,MAAM,IAAA,GAAO,QAAQ,gBAAA,IAAoB,MAAA;AACzC,IAAA,MAAM,MAAM,IAAA,KAAS,GAAA,IAAQ,IAAA,KAAS,MAAA,IAAU,MAAM,MAAA,KAAW,GAAA;AACjE,IAAA,IAAI,GAAA,EAAK,IAAA,CAAK,UAAA,CAAW,gBAAA,CAAiB,IAAUA,MAAA,CAAA,OAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA,EACpF;AAAA;AAAA,EAGQ,iBAAiB,KAAA,EAA+B;AACtD,IAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA,EAAG;AACvD,MAAA,IAAI,KAAA,CAAM,iBAAiB,MAAA,EAAW;AACtC,MAAA,IAAA,CAAK,YAAA,CAAa,IAAI,GAAG,CAAA,EAAG,SAAS,KAAA,CAAM,YAAA,EAAc,KAAK,gBAAgB,CAAA;AAAA,IAChF;AACA,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,EACf;AAAA,EAEQ,UAAA,GAAmB;AACzB,IAAA,MAAM,UAAU,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,KAAK,IAAI,CAAA;AACnD,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,YAAA,GAAe,KAAK,IAAA,CAAK,SAAA;AAC/B,IAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,KAAK,IAAI,CAAA;AAChD,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,YAAY,CAAA;AAExC,MAAA,IAAI,CAAA,EAAG,SAAA,CAAU,OAAA,EAAS,QAAA,CAAS,CAAA,CAAE,aAAa,MAAA,CAAO,CAAA,CAAE,WAAW,CAAC,CAAC,CAAA;AAAA,IAC1E,CAAA,MAAA,IAAW,UAAU,cAAA,EAAgB;AAEnC,MAAA,SAAA,CAAU,OAAA,EAAS,SAAS,cAAc,CAAA;AAAA,IAC5C;AACA,IAAA,IAAA,CAAK,IAAI,OAAO,CAAA;AAAA,EAClB;AAAA,EAEQ,eAAA,GAAwB;AAC9B,IAAA,KAAA,MAAW,OAAA,IAAW,IAAA,CAAK,IAAA,CAAK,KAAA,EAAO;AACrC,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACpC,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,WAAW,IAAA,IAAQ,IAAA,CAAK,kBAAkB,IAAA,EAAM;AAElE,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,KAAK,MAAM,CAAA;AAClD,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA;AAC7C,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,KAAK,aAAa,CAAA;AAClD,MAAA,IAAI,CAAC,SAAA,IAAa,CAAC,QAAA,IAAY,CAAC,KAAA,EAAO;AAEvC,MAAA,IAAA,CAAK,gBAAA,CAAiB,SAAA,EAAW,QAAA,EAAU,IAAA,CAAK,eAAe,KAAK,CAAA;AAAA,IACtE;AAAA,EACF;AAAA;AAAA,EAGQ,gBAAA,CACN,MAAA,EACA,KAAA,EACA,QAAA,EACA,KAAA,EACM;AACN,IAAA,MAAM,MAAA,GAAS,IAAUA,MAAA,CAAA,KAAA,EAAM;AAC/B,IAAA,MAAA,CAAO,IAAA,GAAO,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,OAAA,CAAA;AAC3B,IAAA,SAAA,CAAU,MAAA,EAAQ,MAAM,WAAW,CAAA;AAEnC,IAAA,MAAM,MAAA,GAAS,IAAI,WAAA,CAAY,KAAK,CAAA;AAEpC,IAAA,MAAM,SAAA,GAAY,IAAUA,MAAA,CAAA,KAAA,EAAM;AAClC,IAAA,SAAA,CAAU,IAAA,GAAO,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,UAAA,CAAA;AAC9B,IAAA,SAAA,CAAU,SAAA,EAAW,MAAA,CAAO,KAAA,CAAM,WAAW,CAAC,CAAA;AAE9C,IAAA,MAAA,CAAO,IAAI,MAAM,CAAA;AACjB,IAAA,MAAA,CAAO,IAAI,MAAM,CAAA;AACjB,IAAA,MAAA,CAAO,IAAI,SAAS,CAAA;AACpB,IAAA,SAAA,CAAU,IAAI,KAAK,CAAA;AAEnB,IAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,QAAA,EAAU,MAAM,CAAA;AAAA,EACxC;AAAA,EAEQ,mBAAA,GAA4B;AAClC,IAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,IAAA,CAAK,aAAA,EAAe;AACzC,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA;AACpC,MAAA,IAAI,CAAC,GAAA,IAAO,GAAA,CAAI,MAAA,EAAQ;AAGxB,MAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,EAAG,cAAA;AAC9C,MAAA,IAAI,cAAA,EAAgB,SAAA,CAAU,GAAA,EAAK,cAAc,CAAA;AACjD,MAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,aAAA,CAAc,MAAc,KAAA,EAAwB;AAClD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AACxC,IAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,IAAA,KAAA,CAAM,QAAA,CAAS,KAAA,EAAO,IAAA,CAAK,gBAAgB,CAAA;AAC3C,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,eAAe,MAAA,EAAsC;AACnD,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AACxC,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,KAAA,CAAM,QAAA,CAAS,KAAA,EAAO,IAAA,CAAK,gBAAgB,CAAA;AAC3C,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,IAAA,EAAkC;AAC9C,IAAA,OAAO,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA,EAAG,KAAA;AAAA,EACtC;AAAA;AAAA,EAGA,gBAAA,GAAyB;AACvB,IAAA,IAAA,CAAK,kBAAkB,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AAAA,EAEQ,aAAA,GAAsB;AAC5B,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,gBAAA,EAAiB;AAAA,EACxC;AAAA;AAAA,EAIA,mBAAmB,IAAA,EAA6B;AAC9C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAI,CAAA;AACrC,IAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,KAAA,CAAM,CAAA,cAAA,EAAiB,IAAI,CAAA,CAAA,CAAG,CAAA;AAClD,IAAA,IAAA,CAAK,aAAA,EAAc;AACnB,IAAA,OAAO,GAAA,CAAI,YAAY,KAAA,EAAM;AAAA,EAC/B;AAAA,EAEA,qBAAqB,IAAA,EAA6B;AAChD,IAAA,OAAO,IAAUA,MAAA,CAAA,OAAA,EAAQ,CAAE,sBAAsB,IAAA,CAAK,kBAAA,CAAmB,IAAI,CAAC,CAAA;AAAA,EAChF;AAAA,EAEA,cAAc,IAAA,EAAsC;AAClD,IAAA,OAAO,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAI,CAAA;AAAA,EAClC;AAAA,EAEA,eAAe,IAAA,EAAuC;AACpD,IAAA,OAAO,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AAAA,EACnC;AAAA,EAEA,SAAA,GAAgC;AAC9B,IAAA,OAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAAA,EACxC;AAAA,EAEA,QAAA,GAA8B;AAC5B,IAAA,OAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAAA,EACvC;AAAA;AAAA,EAGA,aAAA,GAA0B;AACxB,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,YAAA,CAAa,MAAM,CAAA;AAAA,EACrC;AAAA,EAEA,YAAA,GAAyB;AACvB,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AAAA,EACpC;AAAA,EAEA,gBAAA,GAAkC;AAChC,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AAAA;AAAA;AAAA,EAKA,qBAAA,GAAgC;AAC9B,IAAA,OAAO,IAAA,CAAK,MAAM,kBAAA,IAAsB,EAAA;AAAA,EAC1C;AAAA;AAAA,EAGA,YAAA,GAAwB;AACtB,IAAA,OAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,YAAA,KAAiB,MAAS,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAA,GAAsD;AACpD,IAAA,IAAI,QAAQ,MAAA,CAAO,iBAAA;AACnB,IAAA,IAAI,MAAM,MAAA,CAAO,iBAAA;AACjB,IAAA,KAAA,MAAW,SAAS,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,EAAG;AACpD,MAAA,MAAM,KAAA,GAAQ,MAAM,YAAA,EAAc,KAAA;AAClC,MAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAClC,MAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,KAAA,CAAM,CAAC,CAAE,CAAA;AACjC,MAAA,GAAA,GAAM,KAAK,GAAA,CAAI,GAAA,EAAK,MAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAE,CAAA;AAAA,IAC9C;AACA,IAAA,IAAI,KAAA,IAAS,GAAA,EAAK,OAAO,EAAE,OAAO,GAAA,EAAI;AAEtC,IAAA,MAAM,EAAE,aAAA,EAAe,WAAA,EAAY,GAAI,IAAA,CAAK,KAAA;AAC5C,IAAA,IAAI,aAAA,KAAkB,MAAA,IAAa,WAAA,KAAgB,MAAA,EAAW;AAC5D,MAAA,OAAO,EAAE,KAAA,EAAO,aAAA,EAAe,GAAA,EAAK,WAAA,EAAY;AAAA,IAClD;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,QAAQ,CAAA,EAAiB;AACvB,IAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,EAAG;AAC5D,MAAA,IAAI,KAAA,CAAM,cAAc,IAAA,CAAK,aAAA,CAAc,KAAK,WAAA,CAAY,KAAA,CAAM,YAAA,EAAc,CAAC,CAAC,CAAA;AAAA,IACpF;AAAA,EACF;AAAA;AAAA,EAIA,IAAI,UAAA,GAAsB;AACxB,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EACA,IAAI,WAAW,CAAA,EAAY;AACzB,IAAA,IAAA,CAAK,WAAA,GAAc,CAAA;AACnB,IAAA,IAAA,CAAK,iBAAA,CAAkB,UAAU,CAAC,CAAA;AAAA,EACpC;AAAA,EAEA,IAAI,aAAA,GAAyB;AAC3B,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AAAA,EACA,IAAI,cAAc,CAAA,EAAY;AAC5B,IAAA,IAAA,CAAK,cAAA,GAAiB,CAAA;AACtB,IAAA,IAAA,CAAK,iBAAA,CAAkB,aAAa,CAAC,CAAA;AAAA,EACvC;AAAA,EAEA,IAAI,aAAA,GAAyB;AAC3B,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AAAA,EACA,IAAI,cAAc,CAAA,EAAY;AAC5B,IAAA,IAAA,CAAK,cAAA,GAAiB,CAAA;AACtB,IAAA,IAAI,CAAA,IAAK,IAAA,CAAK,gBAAA,CAAiB,MAAA,KAAW,CAAA,EAAG;AAC3C,MAAA,KAAA,MAAW,KAAA,IAAS,IAAA,CAAK,YAAA,CAAa,MAAA,EAAO,EAAG;AAC9C,QAAA,MAAM,CAAA,GAAI,IAAUA,MAAA,CAAA,UAAA,CAAW,IAAA,CAAK,UAAU,CAAA;AAC9C,QAAA,CAAA,CAAE,IAAA,GAAO,CAAA,EAAG,KAAA,CAAM,SAAS,CAAA,KAAA,CAAA;AAC3B,QAAA,KAAA,CAAM,IAAI,CAAC,CAAA;AACX,QAAA,IAAA,CAAK,gBAAA,CAAiB,KAAK,CAAC,CAAA;AAAA,MAC9B;AAAA,IACF;AACA,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,gBAAA,EAAkB,CAAA,CAAE,OAAA,GAAU,CAAA;AAAA,EACrD;AAAA,EAEA,IAAI,cAAA,GAA0B;AAC5B,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,EACd;AAAA,EACA,IAAI,eAAe,CAAA,EAAY;AAC7B,IAAA,IAAA,CAAK,eAAA,GAAkB,CAAA;AACvB,IAAA,IAAI,CAAA,IAAK,IAAA,CAAK,gBAAA,CAAiB,MAAA,KAAW,CAAA,EAAG;AAC3C,MAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,WAAA,CAAY,MAAA,EAAO,EAAG;AAC5C,QAAA,MAAM,CAAA,GAAI,IAAUA,MAAA,CAAA,UAAA,CAAW,IAAA,CAAK,UAAU,CAAA;AAC9C,QAAA,CAAA,CAAE,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA,MAAA,CAAA;AACzB,QAAA,IAAA,CAAK,IAAI,CAAC,CAAA;AACV,QAAA,IAAA,CAAK,gBAAA,CAAiB,KAAK,CAAC,CAAA;AAAA,MAC9B;AAAA,IACF;AACA,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,gBAAA,EAAkB,CAAA,CAAE,OAAA,GAAU,CAAA;AAAA,EACrD;AAAA,EAEQ,iBAAA,CAAkB,MAAc,OAAA,EAAwB;AAC9D,IAAA,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,KAAM;AACnB,MAAA,IAAK,CAAA,CAAE,QAAA,CAA+B,IAAA,KAAS,IAAA,IAAQ,OAAA,GAAU,OAAA;AAAA,IACnE,CAAC,CAAA;AAAA,EACH;AACF;AAGA,SAAS,SAAA,CAAU,KAAqB,CAAA,EAAe;AACrD,EAAA,GAAA,CAAI,gBAAA,GAAmB,KAAA;AACvB,EAAA,GAAA,CAAI,MAAA,CAAO,UAAU,CAAC,CAAA;AACtB,EAAA,GAAA,CAAI,sBAAA,GAAyB,IAAA;AAC/B;;;ACtSO,IAAM,sBAAN,MAA0B;AAAA,EACtB,OAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAAsC,EAAC,EAAG;AACpD,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,IAAY,QAAA,GAA0B;AACpC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,aAAA,IAAiB,IAAI,oBAAA,EAAqB;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,GAAA,EAAqC;AACnD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA;AAC3C,IAAA,IAAI,WAAW,IAAA,CAAK,GAAG,GAAG,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AACrD,IAAA,IAAI,WAAA,CAAY,QAAQ,KAAK,CAAA,SAAU,IAAA,CAAK,UAAA,CAAW,OAAO,GAAG,CAAA;AACjE,IAAA,OAAO,IAAA,CAAK,MAAM,IAAI,WAAA,GAAc,MAAA,CAAO,KAAK,GAAG,GAAG,CAAA;AAAA,EACxD;AAAA,EAEA,MAAc,eAAe,GAAA,EAAkC;AAC7D,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AACtB,IAAA,IAAI,QAAA,CAAS,UAAA,EAAY,OAAO,QAAA,CAAS,WAAW,GAAG,CAAA;AACvD,IAAA,OAAO,IAAI,aAAY,CAAE,MAAA,CAAO,MAAM,QAAA,CAAS,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,KAAA,CAAM,IAAA,EAAc,OAAA,GAAU,EAAA,EAA4B;AAC9D,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,MACV,MAAM,IAAA,CAAK,YAAA,CAAa,IAAA,EAAM,OAAA,EAAS,KAAK,QAAQ,CAAA;AAAA,MACpD,OAAA;AAAA,MACA,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,UAAU,KAAA,EAA2C;AACzD,IAAA,MAAM,GAAA,GAAM,SAAS,KAAK,CAAA;AAE1B,IAAA,MAAM,YAAY,MAAM,GAAA,CAAI,QAAA,CAAS,UAAA,CAAW,IAAI,SAAS,CAAA;AAC7D,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,qBAAA,CAAsB,WAAW,GAAA,CAAI,SAAA,EAAW,IAAI,QAAQ,CAAA;AACrF,IAAA,OAAO,KAAK,cAAA,CAAe,KAAA,EAAO,GAAA,CAAI,SAAA,EAAW,IAAI,QAAQ,CAAA;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,UAAA,CAAW,KAAA,EAAmB,OAAA,GAAU,EAAA,EAA4B;AACxE,IAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,sBAAsB,KAAA,EAAO,OAAA,EAAS,KAAK,QAAQ,CAAA;AAC5E,IAAA,OAAO,IAAA,CAAK,cAAA,CAAe,KAAA,EAAO,OAAA,EAAS,KAAK,QAAQ,CAAA;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,qBAAA,CAAsB,IAAA,EAAc,OAAA,GAAU,EAAA,EAA+B;AACjF,IAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,aAAa,IAAA,EAAM,OAAA,EAAS,KAAK,QAAQ,CAAA;AAClE,IAAA,OAAO,uBAAA,CAAwB,KAAA,EAAO,IAAA,CAAK,cAAA,EAAgB,CAAA;AAAA,EAC7D;AAAA,EAEQ,cAAA,CAAe,KAAA,EAAc,OAAA,EAAiB,QAAA,EAAwC;AAC5F,IAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,KAAA,EAAO,IAAA,CAAK,gBAAgB,CAAA;AAClE,IAAA,MAAM,IAAA,GAAO,mBAAmB,KAAK,CAAA;AACrC,IAAA,MAAM,UAAU,IAAI,aAAA,CAAc,OAAO,IAAA,EAAM,IAAA,CAAK,cAAc,CAAA;AAElE,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,OAAA,CAAQ,WAAA,IAAe,IAAA;AAChD,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,cAAA,IAAkB,KAAA;AACtD,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,iBAAA,IAAqB,KAAA;AACpD,IAAA,IAAI,WAAA,IAAe,kBAAkB,SAAA,EAAW;AAC9C,MAAA,MAAM,eAAA,GACH,KAAK,OAAA,CAAQ,YAAA,IAAgB,OAAQ,qBAAA,CAAsB,QAAA,EAAU,OAAO,CAAA,GAAI,MAAA;AACnF,MAAA,IAAI,eAAe,cAAA,EAAgB;AACjC,QAAA,eAAA,CAAgB,KAAA,EAAO,SAAS,KAAA,EAAO;AAAA,UACrC,WAAA;AAAA,UACA,cAAA;AAAA,UACA,GAAI,eAAA,GAAkB,EAAE,eAAA,KAAoB;AAAC,SAC9C,CAAA;AAAA,MACH;AACA,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,eAAA,CAAgB,KAAA,EAAO,SAAS,KAAA,EAAO;AAAA,UACrC,GAAI,eAAA,GAAkB,EAAE,eAAA,KAAoB;AAAC,SAC9C,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAc,YAAA,CACZ,IAAA,EACA,OAAA,EACA,QAAA,EACgB;AAChB,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,GAAI,EAAC;AAChF,IAAA,OAAO,KAAA,CAAM,aAAa,MAAM,YAAA,CAAa,MAAM,OAAA,EAAS,QAAA,EAAU,cAAc,CAAC,CAAA;AAAA,EACvF;AAAA;AAAA,EAGA,MAAc,qBAAA,CACZ,KAAA,EACA,OAAA,EACA,QAAA,EACgB;AAChB,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,GAAI,EAAC;AAChF,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,OAAA,CAAQ,KAAK,IACtC,MAAM,WAAA;AAAA,MACJ,eAAA,CAAgB,IAAI,WAAA,CAAY,KAAK,CAAC,CAAA;AAAA,MACtC,OAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF,GACA,MAAM,YAAA,CAAa,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,KAAK,CAAA,EAAG,OAAA,EAAS,QAAA,EAAU,cAAc,CAAA;AACzF,IAAA,OAAO,KAAA,CAAM,aAAa,QAAQ,CAAA;AAAA,EACpC;AAAA,EAEQ,YAAA,GAAqC;AAC3C,IAAA,OAAO;AAAA,MACL,gBAAA,EAAkB,IAAA,CAAK,OAAA,CAAQ,gBAAA,IAAoB,MAAA;AAAA,MACnD,GAAI,IAAA,CAAK,OAAA,CAAQ,gBAAA,KAAqB,MAAA,GAClC,EAAE,gBAAA,EAAkB,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAiB,GAClD,EAAC;AAAA,MACL,GAAI,IAAA,CAAK,OAAA,CAAQ,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAU,GAAI,EAAC;AAAA,MACpF,GAAI,IAAA,CAAK,OAAA,CAAQ,8BAAA,KAAmC,MAAA,GAChD,EAAE,gBAAA,EAAkB,IAAA,CAAK,OAAA,CAAQ,8BAAA,EAA+B,GAChE;AAAC,KACP;AAAA,EACF;AAAA,EAEQ,cAAA,GAA6E;AACnF,IAAA,OAAO;AAAA,MACL,GAAI,IAAA,CAAK,OAAA,CAAQ,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAU,GAAI,EAAC;AAAA,MACpF,GAAI,IAAA,CAAK,OAAA,CAAQ,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,GAAI;AAAC,KAC7E;AAAA,EACF;AACF","file":"chunk-FL554IS5.js","sourcesContent":["import * as THREE from \"three\";\nimport type { Axis } from \"../robot/RobotDescription.js\";\n\n/** Unit vector for a USD joint axis token. Returns a fresh vector each call. */\nexport function axisVector(axis: Axis): THREE.Vector3 {\n switch (axis) {\n case \"X\":\n return new THREE.Vector3(1, 0, 0);\n case \"Y\":\n return new THREE.Vector3(0, 1, 0);\n case \"Z\":\n return new THREE.Vector3(0, 0, 1);\n }\n}\n","import * as THREE from \"three\";\nimport type { Axis, JointDescription, JointType } from \"../robot/RobotDescription.js\";\nimport { axisVector } from \"./axis.js\";\n\n/**\n * The articulated \"motion\" node of a joint, inserted between the joint's two\n * fixed frames (`jointFrame0` and `inverse(jointFrame1)`). {@link setValue}\n * rotates it about the axis (revolute/continuous) or slides it along the axis\n * (prismatic); fixed joints are inert.\n */\nexport class JointObject extends THREE.Object3D {\n readonly isJointObject = true;\n readonly jointName: string;\n readonly jointType: JointType;\n readonly axisToken: Axis;\n readonly axis: THREE.Vector3;\n readonly lower: number | undefined;\n readonly upper: number | undefined;\n\n private _value = 0;\n\n constructor(joint: JointDescription) {\n super();\n this.name = joint.name;\n this.jointName = joint.name;\n this.jointType = joint.type;\n this.axisToken = joint.axis;\n this.axis = axisVector(joint.axis);\n this.lower = joint.lower;\n this.upper = joint.upper;\n }\n\n get value(): number {\n return this._value;\n }\n\n get articulated(): boolean {\n return this.jointType !== \"fixed\";\n }\n\n /**\n * Set the joint value (radians for revolute/continuous, length for prismatic).\n * Optionally clamps to authored limits. Returns the value actually applied.\n */\n setValue(value: number, clampToLimits = true): number {\n if (!this.articulated) return this._value; // fixed joint: inert\n\n let v = value;\n if (clampToLimits) {\n if (this.lower !== undefined && v < this.lower) v = this.lower;\n if (this.upper !== undefined && v > this.upper) v = this.upper;\n }\n this._value = v;\n\n if (this.jointType === \"prismatic\") {\n this.position.copy(this.axis).multiplyScalar(v);\n this.quaternion.identity();\n } else {\n this.quaternion.setFromAxisAngle(this.axis, v);\n this.position.set(0, 0, 0);\n }\n return v;\n }\n}\n","import * as THREE from \"three\";\nimport type { LinkDescription } from \"../robot/RobotDescription.js\";\n\n/**\n * Three.js node for a robot link. Its frame is the USD link prim's frame;\n * visual/collision meshes (M6) attach as children relative to it. Placement\n * relative to the parent is supplied by the joint chain, so a link's own local\n * matrix is identity (except the root, which carries the world-fixed placement).\n */\nexport class LinkObject extends THREE.Object3D {\n readonly isLinkObject = true;\n readonly linkName: string;\n readonly primPath: string;\n\n constructor(link: LinkDescription) {\n super();\n this.name = link.name;\n this.linkName = link.name;\n this.primPath = link.primPath;\n // Placement comes from the parent joint chain; keep the local matrix fixed.\n this.matrixAutoUpdate = false;\n }\n}\n","/**\n * Binds `UsdGeom.Mesh` prims to Three.js geometry and attaches them under the\n * robot's link objects.\n *\n * Triangulates polygons with a simple fan, uses authored per-vertex normals\n * when present (else computes smooth normals), and reads `primvars:st` UVs and\n * `primvars:displayColor`. Geometry is left in stage units; the global\n * `metersPerUnit` scale is applied at the root in M9.\n */\n\nimport * as THREE from \"three\";\nimport { type Mat4, identity4, multiply } from \"../kinematics/transforms.js\";\nimport type { Vec2, Vec3 } from \"../parser/ast.js\";\nimport type { RobotDescription } from \"../robot/RobotDescription.js\";\nimport { type MaterialSubset, getMaterialSubsets, isNonVisualPurpose } from \"../schemas/usdGeom.js\";\nimport { COLLISION_API } from \"../schemas/usdPhysics.js\";\nimport type { Prim } from \"../usd/Prim.js\";\nimport type { Stage } from \"../usd/Stage.js\";\nimport { computeLocalTransform, computeWorldTransform } from \"../usd/xformOps.js\";\nimport { type ResolvedTexture, resolveBoundMaterial } from \"./MaterialBinding.js\";\nimport type { TextureProvider } from \"./TextureBinding.js\";\nimport type { ThreeUsdRobot } from \"./ThreeUsdRobot.js\";\n\nexport type MeshKind = \"visual\" | \"collision\";\n\nconst DEFAULT_COLOR = 0x9a9a9a;\n\nexport type BindMeshesOptions = {\n loadVisuals?: boolean;\n loadCollisions?: boolean;\n /** Resolves diffuse texture asset paths to `THREE.Texture` (M-tex). */\n textureProvider?: TextureProvider;\n};\n\n/**\n * Build a `BufferGeometry` from a Mesh prim, or `null` if it has no points.\n *\n * When the mesh carries `materialBind` face subsets, the triangles are ordered\n * subset by subset and a geometry group is added for each — so the mesh can be\n * drawn with one material per subset (see {@link buildMeshMaterials}). Group\n * order matches {@link getMaterialSubsets}, with any unassigned faces last.\n */\nexport function buildMeshGeometry(meshPrim: Prim): THREE.BufferGeometry | null {\n const points = meshPrim.GetAttribute(\"points\").Get();\n if (!isVec3Array(points) || points.length === 0) return null;\n\n const geometry = new THREE.BufferGeometry();\n geometry.setAttribute(\"position\", new THREE.Float32BufferAttribute(flat3(points), 3));\n\n const counts = meshPrim.GetAttribute(\"faceVertexCounts\").Get();\n const indices = meshPrim.GetAttribute(\"faceVertexIndices\").Get();\n if (isNumberArray(counts) && isNumberArray(indices)) {\n const subsets = getMaterialSubsets(meshPrim);\n if (subsets.length > 0) {\n geometry.setIndex(triangulateBySubset(geometry, counts, indices, subsets));\n } else {\n geometry.setIndex(triangulate(counts, indices));\n }\n } else if (isNumberArray(indices)) {\n geometry.setIndex(indices.slice());\n }\n\n const normals = meshPrim.GetAttribute(\"normals\").Get();\n if (isVec3Array(normals) && normals.length === points.length) {\n geometry.setAttribute(\"normal\", new THREE.Float32BufferAttribute(flat3(normals), 3));\n } else {\n geometry.computeVertexNormals();\n }\n\n const st = meshPrim.GetAttribute(\"primvars:st\").Get();\n if (isVec2Array(st) && st.length === points.length) {\n geometry.setAttribute(\"uv\", new THREE.Float32BufferAttribute(flat2(st), 2));\n }\n\n return geometry;\n}\n\n/**\n * Build a material for a Mesh prim. Color priority: bound `UsdShade` material\n * (when `stage` is given) → `primvars:displayColor` → default gray. Textures\n * (via `textures`) become the matching `MeshStandardMaterial` maps — diffuse →\n * `map` (sRGB), plus `normalMap` / `roughnessMap` / `metalnessMap` / `aoMap`\n * (linear data) and emissive `emissiveMap`. Metalness / roughness / opacity /\n * emissive constants come from the bound material when present.\n */\nexport function buildMeshMaterial(\n meshPrim: Prim,\n stage?: Stage,\n textures?: TextureProvider,\n /** Resolve the material binding from here instead (a `GeomSubset`). */\n bindingPrim?: Prim,\n): THREE.Material {\n const color = new THREE.Color(DEFAULT_COLOR);\n let opacity = 1;\n\n const bound = stage ? resolveBoundMaterial(stage, bindingPrim ?? meshPrim) : undefined;\n if (bound?.color) {\n color.setRGB(bound.color[0], bound.color[1], bound.color[2]);\n } else {\n const displayColor = meshPrim.GetAttribute(\"primvars:displayColor\").Get();\n if (isVec3Array(displayColor) && displayColor[0]) {\n const [r, g, b] = displayColor[0];\n color.setRGB(r, g, b);\n }\n }\n if (bound?.opacity !== undefined) opacity = bound.opacity;\n\n // Resolve a channel's `THREE.Texture`, forwarding its wrap modes and\n // `UsdTransform2d` (the `UsdUVTexture.inputs:scale`/`bias` are folded into the\n // material factors below, not the sampler).\n const tex = (rt: ResolvedTexture | undefined, cs: \"srgb\" | \"linear\") =>\n rt && textures\n ? textures(rt.path, {\n colorSpace: cs,\n ...(rt.wrapS ? { wrapS: rt.wrapS } : {}),\n ...(rt.wrapT ? { wrapT: rt.wrapT } : {}),\n ...(rt.transform ? { transform: rt.transform } : {}),\n })\n : null;\n\n const map = tex(bound?.colorTexture, \"srgb\");\n // `inputs:scale` on the diffuse texture tints the map; otherwise pass through.\n if (map) {\n const s = bound?.colorTexture?.scale;\n if (s) color.setRGB(s[0], s[1], s[2]);\n else color.setRGB(1, 1, 1);\n }\n const normalMap = tex(bound?.normalTexture, \"linear\");\n const roughnessMap = tex(bound?.roughnessTexture, \"linear\");\n const metalnessMap = tex(bound?.metalnessTexture, \"linear\");\n const aoMap = tex(bound?.occlusionTexture, \"linear\");\n const emissiveMap = tex(bound?.emissiveTexture, \"srgb\");\n\n // A scalar map's `inputs:scale[0]` (or an authored constant) becomes three's\n // factor; three multiplies factor × map, so default to 1 to pass it through.\n const metalness =\n bound?.metalness ?? bound?.metalnessTexture?.scale?.[0] ?? (metalnessMap ? 1 : 0.1);\n const roughness =\n bound?.roughness ?? bound?.roughnessTexture?.scale?.[0] ?? (roughnessMap ? 1 : 0.8);\n\n const emissive = new THREE.Color(0x000000);\n if (bound?.emissiveColor) {\n emissive.setRGB(bound.emissiveColor[0], bound.emissiveColor[1], bound.emissiveColor[2]);\n } else if (emissiveMap) {\n emissive.setRGB(1, 1, 1); // let the map drive emission\n }\n\n // Opacity sourcing: a dedicated opacity texture → `alphaMap`; an opacity input\n // wired to the *same* image as the diffuse map → that map's own alpha channel\n // (no separate map needed). `opacityThreshold > 0` means alpha clip (a binary\n // cutout rendered in the opaque pass); otherwise sub-unit alpha blends.\n const opacityTex = bound?.opacityTexture;\n const sharesColorMap = !!(opacityTex && opacityTex.path === bound?.colorTexture?.path);\n const alphaMap = sharesColorMap ? null : tex(opacityTex, \"linear\");\n const hasAlphaSource = opacity < 1 || sharesColorMap || !!alphaMap;\n const threshold = bound?.opacityThreshold;\n const alphaTest = threshold !== undefined && threshold > 0 ? threshold : 0;\n // Alpha-clip masks render opaque (depth-written, discarded below the cutoff);\n // only true translucency uses the transparent/blended pass.\n const transparent = alphaTest === 0 && hasAlphaSource;\n\n const doubleSided = meshPrim.GetAttribute(\"doubleSided\").Get() === true;\n const material = new THREE.MeshStandardMaterial({\n color,\n metalness,\n roughness,\n emissive,\n transparent,\n opacity,\n ...(alphaTest > 0 ? { alphaTest } : {}),\n side: doubleSided ? THREE.DoubleSide : THREE.FrontSide,\n ...(map ? { map } : {}),\n ...(alphaMap ? { alphaMap } : {}),\n ...(normalMap ? { normalMap } : {}),\n ...(roughnessMap ? { roughnessMap } : {}),\n ...(metalnessMap ? { metalnessMap } : {}),\n ...(aoMap ? { aoMap } : {}),\n ...(emissiveMap ? { emissiveMap } : {}),\n });\n // Carry the USD material name so re-exports keep it (and dedupe by it).\n if (bound?.name) material.name = bound.name;\n return material;\n}\n\n/**\n * Attach visual (and optionally collision) meshes to every link of a built\n * {@link ThreeUsdRobot}. Each mesh is positioned by its transform relative to\n * the owning link prim.\n */\nexport function bindRobotMeshes(\n stage: Stage,\n robot3d: ThreeUsdRobot,\n desc: RobotDescription,\n options: BindMeshesOptions = {},\n): void {\n const loadVisuals = options.loadVisuals ?? true;\n const loadCollisions = options.loadCollisions ?? false;\n const textures = options.textureProvider;\n\n for (const [key, link] of Object.entries(desc.links)) {\n const linkObj = robot3d.getLinkObject(key);\n const linkPrim = stage.GetPrimAtPath(link.primPath);\n if (!linkObj || !linkPrim) continue;\n\n // A mesh may be both visual and collision; attach it once, as visual.\n const visualSet = new Set(link.visualPrims);\n\n if (loadVisuals) {\n for (const meshPath of link.visualPrims) {\n attachMesh(stage, linkPrim, meshPath, linkObj, \"visual\", textures);\n }\n }\n if (loadCollisions) {\n for (const meshPath of link.collisionPrims ?? []) {\n if (loadVisuals && visualSet.has(meshPath)) continue;\n attachMesh(stage, linkPrim, meshPath, linkObj, \"collision\", textures);\n }\n }\n }\n}\n\n/**\n * Attach the Mesh prims that belong to no link — the static scenery of a cell\n * that also contains robots. They are placed by their authored stage transform\n * under the robot root, so the loader's up-axis and unit normalization applies\n * to them too. Collision-only and guide/proxy prims are skipped.\n */\nexport function bindSceneMeshes(\n stage: Stage,\n robot3d: ThreeUsdRobot,\n desc: RobotDescription,\n options: { textureProvider?: TextureProvider } = {},\n): number {\n const owned = new Set<string>();\n for (const link of Object.values(desc.links)) {\n for (const path of link.visualPrims) owned.add(path);\n for (const path of link.collisionPrims ?? []) owned.add(path);\n owned.add(link.primPath);\n }\n\n let attached = 0;\n for (const prim of stage.Traverse()) {\n if (prim.GetTypeName() !== \"Mesh\" || owned.has(prim.GetPath())) continue;\n if (prim.HasAPI(COLLISION_API) || isNonVisualPurpose(prim)) continue;\n // Skip meshes under a link (already bound relative to their link).\n if ([...owned].some((path) => prim.GetPath().startsWith(`${path}/`))) continue;\n\n const geometry = buildMeshGeometry(prim);\n if (!geometry) continue;\n const mesh = new THREE.Mesh(geometry, buildMeshMaterial(prim, stage, options.textureProvider));\n mesh.name = prim.GetName();\n mesh.userData.kind = \"scene\";\n mesh.userData.primPath = prim.GetPath();\n mesh.matrixAutoUpdate = false;\n mesh.matrix.fromArray(computeWorldTransform(prim));\n mesh.matrixWorldNeedsUpdate = true;\n robot3d.add(mesh);\n attached++;\n }\n return attached;\n}\n\n/**\n * Materials for a mesh: one per `materialBind` face subset (matching the\n * geometry groups {@link buildMeshGeometry} adds) plus a trailing fallback for\n * faces no subset claims. A mesh without subsets gets a single material.\n */\nexport function buildMeshMaterials(\n meshPrim: Prim,\n stage?: Stage,\n textures?: TextureProvider,\n): THREE.Material | THREE.Material[] {\n const subsets = stage ? getMaterialSubsets(meshPrim) : [];\n if (subsets.length === 0) return buildMeshMaterial(meshPrim, stage, textures);\n return [\n ...subsets.map((s) => buildMeshMaterial(meshPrim, stage, textures, s.prim)),\n buildMeshMaterial(meshPrim, stage, textures),\n ];\n}\n\nfunction attachMesh(\n stage: Stage,\n linkPrim: Prim,\n meshPath: string,\n parent: THREE.Object3D,\n kind: MeshKind,\n textures: TextureProvider | undefined,\n): void {\n const meshPrim = stage.GetPrimAtPath(meshPath);\n if (!meshPrim) return;\n const geometry = buildMeshGeometry(meshPrim);\n if (!geometry) return;\n\n const mesh = new THREE.Mesh(geometry, buildMeshMaterials(meshPrim, stage, textures));\n mesh.name = meshPrim.GetName();\n mesh.userData.kind = kind;\n mesh.userData.primPath = meshPath;\n // Collision meshes are loaded hidden; reveal via `robot.showCollision = true`.\n if (kind === \"collision\") mesh.visible = false;\n mesh.matrixAutoUpdate = false;\n mesh.matrix.fromArray(relativeTransform(linkPrim, meshPrim));\n mesh.matrixWorldNeedsUpdate = true;\n parent.add(mesh);\n}\n\n/** Accumulated local transform from `linkPrim` (exclusive) down to `meshPrim` (inclusive). */\nfunction relativeTransform(linkPrim: Prim, meshPrim: Prim): Mat4 {\n const chain: Prim[] = [];\n let p: Prim | null = meshPrim;\n const stop = linkPrim.GetPath();\n while (p && p.GetPath() !== stop) {\n chain.push(p);\n p = p.GetParent();\n }\n chain.reverse(); // top-most (just under link) → mesh\n\n let m = identity4();\n for (const prim of chain) {\n m = multiply(m, computeLocalTransform(prim).matrix);\n }\n return m;\n}\n\n// --- triangulation & typed-array helpers -----------------------------------\n\n/** Fan-triangulate USD polygon faces into a flat triangle index list. */\nfunction triangulate(faceVertexCounts: number[], faceVertexIndices: number[]): number[] {\n const tris: number[] = [];\n let offset = 0;\n for (const count of faceVertexCounts) {\n for (let k = 2; k < count; k++) {\n tris.push(\n faceVertexIndices[offset]!,\n faceVertexIndices[offset + k - 1]!,\n faceVertexIndices[offset + k]!,\n );\n }\n offset += count;\n }\n return tris;\n}\n\n/**\n * Triangulate subset by subset so each subset owns a contiguous run of the\n * index buffer, and register that run as a geometry group.\n */\nfunction triangulateBySubset(\n geometry: THREE.BufferGeometry,\n faceVertexCounts: number[],\n faceVertexIndices: number[],\n subsets: MaterialSubset[],\n): number[] {\n const faceStart: number[] = [];\n let offset = 0;\n for (const count of faceVertexCounts) {\n faceStart.push(offset);\n offset += count;\n }\n\n const tris: number[] = [];\n const emit = (face: number) => {\n const start = faceStart[face]!;\n const count = faceVertexCounts[face]!;\n for (let k = 2; k < count; k++) {\n tris.push(\n faceVertexIndices[start]!,\n faceVertexIndices[start + k - 1]!,\n faceVertexIndices[start + k]!,\n );\n }\n };\n\n const claimed = new Uint8Array(faceVertexCounts.length);\n subsets.forEach((subset, index) => {\n const begin = tris.length;\n for (const face of subset.faces) {\n if (face < 0 || face >= faceVertexCounts.length || claimed[face]) continue;\n claimed[face] = 1;\n emit(face);\n }\n if (tris.length > begin) geometry.addGroup(begin, tris.length - begin, index);\n });\n\n const begin = tris.length;\n for (let face = 0; face < faceVertexCounts.length; face++) {\n if (!claimed[face]) emit(face);\n }\n if (tris.length > begin) geometry.addGroup(begin, tris.length - begin, subsets.length);\n\n return tris;\n}\n\nfunction flat3(v: Vec3[]): number[] {\n const out = new Array<number>(v.length * 3);\n for (let i = 0; i < v.length; i++) {\n out[i * 3] = v[i]![0];\n out[i * 3 + 1] = v[i]![1];\n out[i * 3 + 2] = v[i]![2];\n }\n return out;\n}\n\nfunction flat2(v: Vec2[]): number[] {\n const out = new Array<number>(v.length * 2);\n for (let i = 0; i < v.length; i++) {\n out[i * 2] = v[i]![0];\n out[i * 2 + 1] = v[i]![1];\n }\n return out;\n}\n\nfunction isNumberArray(v: unknown): v is number[] {\n return Array.isArray(v) && v.every((n) => typeof n === \"number\");\n}\n\nfunction isVec3Array(v: unknown): v is Vec3[] {\n return Array.isArray(v) && v.every((e) => Array.isArray(e) && e.length === 3);\n}\n\nfunction isVec2Array(v: unknown): v is Vec2[] {\n return Array.isArray(v) && v.every((e) => Array.isArray(e) && e.length === 2);\n}\n","/**\n * Loads texture image assets referenced by `UsdShade` materials.\n *\n * A {@link TextureProvider} maps an authored asset path (plus sampler/transform\n * options) to a `THREE.Texture`. The default provider fetches the image **bytes**\n * through the {@link AssetResolver} and decodes them via a blob URL — so it works\n * uniformly for textures served over HTTP and for images embedded inside a\n * `.usdz` package (whose resolver serves zip entries, not real URLs). Decoded\n * images are cached per resolved URL and shared across every texture that uses\n * them; each `THREE.Texture` carries its own color space / wrap / transform.\n */\n\nimport * as THREE from \"three\";\nimport type { AssetResolver } from \"../usd/AssetResolver.js\";\nimport type { TextureTransform, TextureWrap } from \"./MaterialBinding.js\";\n\n/**\n * Color space to interpret a texture in. Color/albedo and emissive maps are\n * `\"srgb\"`; data maps (normal, roughness, metalness, occlusion) are `\"linear\"`.\n */\nexport type TextureColorSpace = \"srgb\" | \"linear\";\n\n/** Per-use sampler state applied to the returned `THREE.Texture`. */\nexport type TextureOptions = {\n /** Defaults to `\"srgb\"`. */\n colorSpace?: TextureColorSpace;\n wrapS?: TextureWrap;\n wrapT?: TextureWrap;\n transform?: TextureTransform;\n};\n\n/** Resolve an authored texture asset path to a `THREE.Texture` (or `null`). */\nexport type TextureProvider = (assetPath: string, options?: TextureOptions) => THREE.Texture | null;\n\nconst DEG2RAD = Math.PI / 180;\n\n/**\n * A {@link TextureProvider} backed by the {@link AssetResolver}, resolving paths\n * against `baseUrl`. Image bytes are fetched once per URL (works for HTTP and\n * `.usdz` entries alike) and the decoded image is shared; each call returns a\n * distinct `THREE.Texture` carrying the requested color space / wrap / transform.\n */\nexport function createTextureProvider(resolver: AssetResolver, baseUrl: string): TextureProvider {\n const images = new Map<string, Promise<TexImageSource>>();\n\n const imageFor = (url: string): Promise<TexImageSource> => {\n let p = images.get(url);\n if (!p) {\n p = loadImage(resolver, url);\n images.set(url, p);\n }\n return p;\n };\n\n return (assetPath: string, options: TextureOptions = {}) => {\n let url: string;\n try {\n url = resolver.resolve(assetPath, baseUrl);\n } catch {\n return null;\n }\n\n const texture = new THREE.Texture();\n texture.colorSpace =\n options.colorSpace === \"linear\" ? THREE.NoColorSpace : THREE.SRGBColorSpace;\n texture.wrapS = toThreeWrap(options.wrapS);\n texture.wrapT = toThreeWrap(options.wrapT);\n applyTransform(texture, options.transform);\n\n imageFor(url)\n .then((image) => {\n texture.image = image;\n texture.needsUpdate = true;\n })\n .catch(() => {\n /* leave the texture blank if the image can't be decoded */\n });\n return texture;\n };\n}\n\n/**\n * Fetch image bytes through the resolver and decode them via a blob URL into an\n * `HTMLImageElement` (so three's default `flipY = true` orients USD's bottom-left\n * `st` origin correctly, matching the prior `TextureLoader` HTTP path).\n */\nasync function loadImage(resolver: AssetResolver, url: string): Promise<TexImageSource> {\n const bytes = resolver.fetchBytes\n ? await resolver.fetchBytes(url)\n : new TextEncoder().encode(await resolver.fetchText(url));\n const blob = new Blob([bytes as BlobPart], { type: mimeOf(url) });\n const objectUrl = URL.createObjectURL(blob);\n try {\n return await new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(`failed to decode texture: ${url}`));\n img.src = objectUrl;\n });\n } finally {\n // The decoded image keeps its pixels; the blob URL can be released.\n URL.revokeObjectURL(objectUrl);\n }\n}\n\nfunction toThreeWrap(wrap: TextureWrap | undefined): THREE.Wrapping {\n switch (wrap) {\n case \"clamp\":\n case \"black\": // three has no border color; clamp is the closest mode\n return THREE.ClampToEdgeWrapping;\n case \"mirror\":\n return THREE.MirroredRepeatWrapping;\n default:\n return THREE.RepeatWrapping;\n }\n}\n\n/** Map a `UsdTransform2d` onto a texture's offset / repeat / rotation. */\nfunction applyTransform(texture: THREE.Texture, t: TextureTransform | undefined): void {\n if (!t) return;\n if (t.scale) texture.repeat.set(t.scale[0], t.scale[1]);\n if (t.translation) texture.offset.set(t.translation[0], t.translation[1]);\n if (t.rotation !== undefined) {\n texture.rotation = t.rotation * DEG2RAD;\n texture.center.set(0, 0); // UsdTransform2d rotates about the origin\n }\n}\n\nfunction mimeOf(url: string): string {\n if (/\\.jpe?g$/i.test(url)) return \"image/jpeg\";\n if (/\\.webp$/i.test(url)) return \"image/webp\";\n return \"image/png\";\n}\n","import * as THREE from \"three\";\nimport { interpolate } from \"../kinematics/sampling.js\";\nimport { type Mat4, invert, multiply } from \"../kinematics/transforms.js\";\nimport type {\n JointDescription,\n LinkDescription,\n RobotDescription,\n} from \"../robot/RobotDescription.js\";\nimport type { KinematicTree } from \"../robot/buildKinematicTree.js\";\nimport { JointObject } from \"./JointObject.js\";\nimport { LinkObject } from \"./LinkObject.js\";\n\nexport type ThreeUsdRobotOptions = {\n /** Clamp `setJointValue` to authored limits (default `true`). */\n clampJointLimits?: boolean;\n /** Size of the built-in joint-axis / link-frame helpers (stage units, default `0.15`). */\n helperSize?: number;\n /**\n * Up-axis correction applied at the robot root. `\"auto\"` rotates Z-up assets\n * into the Three.js Y-up scene; `\"Z\"` forces it, `\"Y\"`/`\"none\"` leave the\n * orientation as authored. Default `\"none\"` (the loader defaults to `\"auto\"`).\n */\n upAxisConversion?: \"auto\" | \"Y\" | \"Z\" | \"none\";\n /** Extra uniform scale multiplied with the stage `metersPerUnit` (default `1`). */\n unitScale?: number;\n /** Seed joints from their authored initial value (drive target / joint state). Default `true`. */\n applyInitialPose?: boolean;\n};\n\n/**\n * A Three.js `Object3D` that realizes a {@link RobotDescription} as a kinematic\n * hierarchy and drives forward kinematics via {@link setJointValue}.\n *\n * Per joint the hierarchy is\n * `parentLink → jointFrame0 → jointMotion → jointFrame1⁻¹ → childLink`,\n * where only `jointMotion` (a {@link JointObject}) changes with the joint value;\n * world poses then fall out of Three.js's `updateMatrixWorld`.\n */\nexport class ThreeUsdRobot extends THREE.Object3D {\n readonly isThreeUsdRobot = true;\n readonly robot: RobotDescription;\n readonly tree: KinematicTree;\n readonly clampJointLimits: boolean;\n\n private readonly linkObjects = new Map<string, LinkObject>();\n private readonly jointObjects = new Map<string, JointObject>();\n private dirty = true;\n\n private readonly helperSize: number;\n private _showVisual = true;\n private _showCollision = false;\n private _showJointAxes = false;\n private _showLinkFrames = false;\n private jointAxesHelpers: THREE.AxesHelper[] = [];\n private linkFrameHelpers: THREE.AxesHelper[] = [];\n\n constructor(robot: RobotDescription, tree: KinematicTree, options: ThreeUsdRobotOptions = {}) {\n super();\n this.name = robot.name;\n this.robot = robot;\n this.tree = tree;\n this.clampJointLimits = options.clampJointLimits ?? true;\n this.helperSize = options.helperSize ?? 0.15;\n\n // Create a node for every link up front.\n for (const [key, link] of Object.entries(robot.links)) {\n this.linkObjects.set(key, new LinkObject(link));\n }\n\n this.attachRoot();\n this.attachTreeEdges();\n this.attachIsolatedLinks();\n this.applyStageNormalization(robot, options);\n if (options.applyInitialPose ?? true) this.applyInitialPose(robot);\n }\n\n /** Orient (Z-up → Y-up) and scale (metersPerUnit × unitScale) the robot root. */\n private applyStageNormalization(robot: RobotDescription, options: ThreeUsdRobotOptions): void {\n const scale = (robot.metersPerUnit || 1) * (options.unitScale ?? 1);\n if (scale !== 1) this.scale.setScalar(scale);\n\n const conv = options.upAxisConversion ?? \"none\";\n const toY = conv === \"Z\" || (conv === \"auto\" && robot.upAxis === \"Z\");\n if (toY) this.quaternion.setFromAxisAngle(new THREE.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n /** Apply each joint's authored initial value, if any. */\n private applyInitialPose(robot: RobotDescription): void {\n for (const [key, joint] of Object.entries(robot.joints)) {\n if (joint.initialValue === undefined) continue;\n this.jointObjects.get(key)?.setValue(joint.initialValue, this.clampJointLimits);\n }\n this.dirty = true;\n }\n\n private attachRoot(): void {\n const rootObj = this.linkObjects.get(this.tree.root);\n if (!rootObj) return; // empty robot\n const rootJointKey = this.tree.rootJoint;\n const rootLink = this.robot.links[this.tree.root];\n if (rootJointKey) {\n const j = this.robot.joints[rootJointKey];\n // World-fixed placement: jointFrame0 (in world) · inverse(jointFrame1).\n if (j) setMatrix(rootObj, multiply(j.jointFrame0, invert(j.jointFrame1)));\n } else if (rootLink?.worldTransform) {\n // Floating base: keep the authored stage placement.\n setMatrix(rootObj, rootLink.worldTransform);\n }\n this.add(rootObj);\n }\n\n private attachTreeEdges(): void {\n for (const linkKey of this.tree.order) {\n const node = this.tree.nodes[linkKey];\n if (!node || node.parent === null || node.jointToParent === null) continue;\n\n const parentObj = this.linkObjects.get(node.parent);\n const childObj = this.linkObjects.get(linkKey);\n const joint = this.robot.joints[node.jointToParent];\n if (!parentObj || !childObj || !joint) continue;\n\n this.attachJointChain(parentObj, childObj, node.jointToParent, joint);\n }\n }\n\n /** Build `parent → frame0 → motion → frame1⁻¹ → child` for one joint. */\n private attachJointChain(\n parent: LinkObject,\n child: LinkObject,\n jointKey: string,\n joint: JointDescription,\n ): void {\n const frame0 = new THREE.Group();\n frame0.name = `${joint.name}:frame0`;\n setMatrix(frame0, joint.jointFrame0);\n\n const motion = new JointObject(joint);\n\n const frame1Inv = new THREE.Group();\n frame1Inv.name = `${joint.name}:frame1Inv`;\n setMatrix(frame1Inv, invert(joint.jointFrame1));\n\n parent.add(frame0);\n frame0.add(motion);\n motion.add(frame1Inv);\n frame1Inv.add(child);\n\n this.jointObjects.set(jointKey, motion);\n }\n\n private attachIsolatedLinks(): void {\n for (const key of this.tree.isolatedLinks) {\n const obj = this.linkObjects.get(key);\n if (!obj || obj.parent) continue;\n // Not placeable by any joint chain — keep the authored stage placement\n // (other machines / free bodies on a multi-articulation stage).\n const worldTransform = this.robot.links[key]?.worldTransform;\n if (worldTransform) setMatrix(obj, worldTransform);\n this.add(obj);\n }\n }\n\n // -- Joint control -------------------------------------------------------\n\n /** Set one joint value. Unknown joints are ignored. Returns whether it applied. */\n setJointValue(name: string, value: number): boolean {\n const joint = this.jointObjects.get(name);\n if (!joint) return false;\n joint.setValue(value, this.clampJointLimits);\n this.dirty = true;\n return true;\n }\n\n /** Set several joint values at once (matrix update is coalesced). */\n setJointValues(values: Record<string, number>): void {\n for (const [name, value] of Object.entries(values)) {\n const joint = this.jointObjects.get(name);\n if (joint) {\n joint.setValue(value, this.clampJointLimits);\n this.dirty = true;\n }\n }\n }\n\n getJointValue(name: string): number | undefined {\n return this.jointObjects.get(name)?.value;\n }\n\n /** Recompute world matrices. Called lazily by the getters; safe to call directly. */\n updateKinematics(): void {\n this.updateMatrixWorld(true);\n this.dirty = false;\n }\n\n private ensureUpdated(): void {\n if (this.dirty) this.updateKinematics();\n }\n\n // -- Queries -------------------------------------------------------------\n\n getLinkWorldMatrix(name: string): THREE.Matrix4 {\n const obj = this.linkObjects.get(name);\n if (!obj) throw new Error(`unknown link \"${name}\"`);\n this.ensureUpdated();\n return obj.matrixWorld.clone();\n }\n\n getLinkWorldPosition(name: string): THREE.Vector3 {\n return new THREE.Vector3().setFromMatrixPosition(this.getLinkWorldMatrix(name));\n }\n\n getLinkObject(name: string): LinkObject | undefined {\n return this.linkObjects.get(name);\n }\n\n getJointObject(name: string): JointObject | undefined {\n return this.jointObjects.get(name);\n }\n\n getJoints(): JointDescription[] {\n return Object.values(this.robot.joints);\n }\n\n getLinks(): LinkDescription[] {\n return Object.values(this.robot.links);\n }\n\n /** Names of the articulated (controllable) joints. */\n getJointNames(): string[] {\n return [...this.jointObjects.keys()];\n }\n\n getLinkNames(): string[] {\n return [...this.linkObjects.keys()];\n }\n\n getKinematicTree(): KinematicTree {\n return this.tree;\n }\n\n // -- Animation playback --------------------------------------------------\n\n /** Playback rate in time codes per second (from the stage; default 24). */\n getTimeCodesPerSecond(): number {\n return this.robot.timeCodesPerSecond ?? 24;\n }\n\n /** Whether any joint has a time-sampled trajectory. */\n hasAnimation(): boolean {\n return Object.values(this.robot.joints).some((j) => j.valueSamples !== undefined);\n }\n\n /**\n * Animation range in time codes: the union of authored joint sample ranges,\n * falling back to the stage `startTimeCode`/`endTimeCode`. `null` if neither.\n */\n getTimeRange(): { start: number; end: number } | null {\n let start = Number.POSITIVE_INFINITY;\n let end = Number.NEGATIVE_INFINITY;\n for (const joint of Object.values(this.robot.joints)) {\n const times = joint.valueSamples?.times;\n if (!times || times.length === 0) continue;\n start = Math.min(start, times[0]!);\n end = Math.max(end, times[times.length - 1]!);\n }\n if (start <= end) return { start, end };\n\n const { startTimeCode, endTimeCode } = this.robot;\n if (startTimeCode !== undefined && endTimeCode !== undefined) {\n return { start: startTimeCode, end: endTimeCode };\n }\n return null;\n }\n\n /** Sample every animated joint at time code `t` and apply the values. */\n setTime(t: number): void {\n for (const [key, joint] of Object.entries(this.robot.joints)) {\n if (joint.valueSamples) this.setJointValue(key, interpolate(joint.valueSamples, t));\n }\n }\n\n // -- Display toggles -----------------------------------------------------\n\n get showVisual(): boolean {\n return this._showVisual;\n }\n set showVisual(v: boolean) {\n this._showVisual = v;\n this.setKindVisibility(\"visual\", v);\n }\n\n get showCollision(): boolean {\n return this._showCollision;\n }\n set showCollision(v: boolean) {\n this._showCollision = v;\n this.setKindVisibility(\"collision\", v);\n }\n\n get showJointAxes(): boolean {\n return this._showJointAxes;\n }\n set showJointAxes(v: boolean) {\n this._showJointAxes = v;\n if (v && this.jointAxesHelpers.length === 0) {\n for (const joint of this.jointObjects.values()) {\n const h = new THREE.AxesHelper(this.helperSize);\n h.name = `${joint.jointName}:axes`;\n joint.add(h);\n this.jointAxesHelpers.push(h);\n }\n }\n for (const h of this.jointAxesHelpers) h.visible = v;\n }\n\n get showLinkFrames(): boolean {\n return this._showLinkFrames;\n }\n set showLinkFrames(v: boolean) {\n this._showLinkFrames = v;\n if (v && this.linkFrameHelpers.length === 0) {\n for (const link of this.linkObjects.values()) {\n const h = new THREE.AxesHelper(this.helperSize);\n h.name = `${link.linkName}:frame`;\n link.add(h);\n this.linkFrameHelpers.push(h);\n }\n }\n for (const h of this.linkFrameHelpers) h.visible = v;\n }\n\n private setKindVisibility(kind: string, visible: boolean): void {\n this.traverse((o) => {\n if ((o.userData as { kind?: string }).kind === kind) o.visible = visible;\n });\n }\n}\n\n/** Assign a fixed local matrix to an object (disables Three.js auto-update). */\nfunction setMatrix(obj: THREE.Object3D, m: Mat4): void {\n obj.matrixAutoUpdate = false;\n obj.matrix.fromArray(m);\n obj.matrixWorldNeedsUpdate = true;\n}\n","import type { RobotDescription } from \"../robot/RobotDescription.js\";\nimport { extractRobotDescription } from \"../robot/RobotExtractor.js\";\nimport { buildKinematicTree } from \"../robot/buildKinematicTree.js\";\nimport { type AssetResolver, DefaultAssetResolver } from \"../usd/AssetResolver.js\";\nimport { Stage } from \"../usd/Stage.js\";\nimport { composeFile, composeLayer } from \"../usd/composition.js\";\nimport { CrateReader } from \"../usd/crate/CrateReader.js\";\nimport { crateToUsdaFile } from \"../usd/crate/toUsdaFile.js\";\nimport { openUsdz } from \"../usd/usdz.js\";\nimport { bindRobotMeshes, bindSceneMeshes } from \"./MeshBinding.js\";\nimport { createTextureProvider } from \"./TextureBinding.js\";\nimport { ThreeUsdRobot, type ThreeUsdRobotOptions } from \"./ThreeUsdRobot.js\";\n\nexport type ThreeUsdRobotLoaderOptions = {\n /** Resolver for references / payloads / sublayers (default {@link DefaultAssetResolver}). */\n assetResolver?: AssetResolver;\n /** Render visual meshes (M6). */\n loadVisuals?: boolean;\n /** Render collision meshes (M6). */\n loadCollisions?: boolean;\n /**\n * Also render Mesh prims that belong to no link — the static scenery of a\n * cell that contains robots (floor, guarding, racking, …). Placed by their\n * authored stage transform. Default `false`.\n */\n loadSceneGeometry?: boolean;\n /** Load diffuse textures referenced by materials (default `true`). */\n loadTextures?: boolean;\n /** Up-axis correction strategy (M9). */\n upAxisConversion?: \"auto\" | \"Y\" | \"Z\" | \"none\";\n /** Extra uniform scale multiplied with `metersPerUnit` (M9). */\n unitScale?: number;\n /** Clamp `setJointValue` to authored limits (default `true`). */\n clampJointLimits?: boolean;\n /** Seed joints from drive targets / joint state (M9). */\n applyDriveTargetsAsInitialPose?: boolean;\n /** Override the robot name. */\n robotName?: string;\n /** Receives non-fatal load diagnostics. */\n onWarn?: (message: string) => void;\n};\n\n/**\n * Loads Isaac Sim / OpenUSD robot assets into a controllable {@link ThreeUsdRobot}.\n *\n * Composition (references / payloads / sublayers, M8) is resolved through an\n * {@link AssetResolver}. Mesh rendering is M6; unit / up-axis / initial-pose\n * handling is M9; USDC and variants are M10.\n */\nexport class ThreeUsdRobotLoader {\n readonly options: ThreeUsdRobotLoaderOptions;\n\n constructor(options: ThreeUsdRobotLoaderOptions = {}) {\n this.options = options;\n }\n\n private get resolver(): AssetResolver {\n return this.options.assetResolver ?? new DefaultAssetResolver();\n }\n\n /**\n * Fetch an asset by URL and build the robot. `.usdz` packages are unzipped and\n * composed from their entries; everything else is sniffed for the crate magic\n * and parsed as binary USDC or USDA text.\n */\n async loadAsync(url: string): Promise<ThreeUsdRobot> {\n const bytes = await this.fetchRootBytes(url);\n if (/\\.usdz$/i.test(url)) return this.parseUsdz(bytes);\n if (CrateReader.isCrate(bytes)) return this.parseCrate(bytes, url);\n return this.parse(new TextDecoder().decode(bytes), url);\n }\n\n private async fetchRootBytes(url: string): Promise<Uint8Array> {\n const resolver = this.resolver;\n if (resolver.fetchBytes) return resolver.fetchBytes(url);\n return new TextEncoder().encode(await resolver.fetchText(url));\n }\n\n /** Build a robot (composed, with meshes) from USDA source text. */\n async parse(text: string, baseUrl = \"\"): Promise<ThreeUsdRobot> {\n return this.buildFromStage(\n await this.composeStage(text, baseUrl, this.resolver),\n baseUrl,\n this.resolver,\n );\n }\n\n /** Build a robot from the bytes of a `.usdz` package. */\n async parseUsdz(bytes: Uint8Array): Promise<ThreeUsdRobot> {\n const pkg = openUsdz(bytes);\n // The root layer of a usdz is typically binary USDC — sniff, don't assume text.\n const rootBytes = await pkg.resolver.fetchBytes(pkg.rootEntry);\n const stage = await this.composeStageFromBytes(rootBytes, pkg.rootEntry, pkg.resolver);\n return this.buildFromStage(stage, pkg.rootEntry, pkg.resolver);\n }\n\n /** Build a robot from the bytes of a binary crate (`.usdc` / binary `.usd`). */\n async parseCrate(bytes: Uint8Array, baseUrl = \"\"): Promise<ThreeUsdRobot> {\n const stage = await this.composeStageFromBytes(bytes, baseUrl, this.resolver);\n return this.buildFromStage(stage, baseUrl, this.resolver);\n }\n\n /** Parse + compose USDA source into the Three.js-independent robot IR. */\n async parseRobotDescription(text: string, baseUrl = \"\"): Promise<RobotDescription> {\n const stage = await this.composeStage(text, baseUrl, this.resolver);\n return extractRobotDescription(stage, this.extractOptions());\n }\n\n private buildFromStage(stage: Stage, baseUrl: string, resolver: AssetResolver): ThreeUsdRobot {\n const robot = extractRobotDescription(stage, this.extractOptions());\n const tree = buildKinematicTree(robot);\n const robot3d = new ThreeUsdRobot(robot, tree, this.robotOptions());\n\n const loadVisuals = this.options.loadVisuals ?? true;\n const loadCollisions = this.options.loadCollisions ?? false;\n const loadScene = this.options.loadSceneGeometry ?? false;\n if (loadVisuals || loadCollisions || loadScene) {\n const textureProvider =\n (this.options.loadTextures ?? true) ? createTextureProvider(resolver, baseUrl) : undefined;\n if (loadVisuals || loadCollisions) {\n bindRobotMeshes(stage, robot3d, robot, {\n loadVisuals,\n loadCollisions,\n ...(textureProvider ? { textureProvider } : {}),\n });\n }\n if (loadScene) {\n bindSceneMeshes(stage, robot3d, robot, {\n ...(textureProvider ? { textureProvider } : {}),\n });\n }\n }\n return robot3d;\n }\n\n private async composeStage(\n text: string,\n baseUrl: string,\n resolver: AssetResolver,\n ): Promise<Stage> {\n const composeOptions = this.options.onWarn ? { onWarn: this.options.onWarn } : {};\n return Stage.OpenFromFile(await composeLayer(text, baseUrl, resolver, composeOptions));\n }\n\n /** Compose a layer from raw bytes, sniffing binary crate vs USDA text. */\n private async composeStageFromBytes(\n bytes: Uint8Array,\n baseUrl: string,\n resolver: AssetResolver,\n ): Promise<Stage> {\n const composeOptions = this.options.onWarn ? { onWarn: this.options.onWarn } : {};\n const composed = CrateReader.isCrate(bytes)\n ? await composeFile(\n crateToUsdaFile(new CrateReader(bytes)),\n baseUrl,\n resolver,\n composeOptions,\n )\n : await composeLayer(new TextDecoder().decode(bytes), baseUrl, resolver, composeOptions);\n return Stage.OpenFromFile(composed);\n }\n\n private robotOptions(): ThreeUsdRobotOptions {\n return {\n upAxisConversion: this.options.upAxisConversion ?? \"auto\",\n ...(this.options.clampJointLimits !== undefined\n ? { clampJointLimits: this.options.clampJointLimits }\n : {}),\n ...(this.options.unitScale !== undefined ? { unitScale: this.options.unitScale } : {}),\n ...(this.options.applyDriveTargetsAsInitialPose !== undefined\n ? { applyInitialPose: this.options.applyDriveTargetsAsInitialPose }\n : {}),\n };\n }\n\n private extractOptions(): { robotName?: string; onWarn?: (message: string) => void } {\n return {\n ...(this.options.robotName !== undefined ? { robotName: this.options.robotName } : {}),\n ...(this.options.onWarn !== undefined ? { onWarn: this.options.onWarn } : {}),\n };\n }\n}\n"]}