import {
  AmbientLight,
  AnimationClip,
  Bone,
  BufferGeometry,
  ClampToEdgeWrapping,
  Color,
  ColorManagement,
  DataTextureLoader,
  DirectionalLight,
  DoubleSide,
  FileLoader,
  Float32BufferAttribute,
  FrontSide,
  Group,
  Line,
  LineBasicMaterial,
  LineSegments,
  LinearMipmapLinearFilter,
  Loader,
  LoaderUtils,
  MathUtils,
  Matrix4,
  Mesh,
  MeshBasicMaterial,
  MeshLambertMaterial,
  MeshPhongMaterial,
  OrthographicCamera,
  PerspectiveCamera,
  PointLight,
  Quaternion,
  QuaternionKeyframeTrack,
  RepeatWrapping,
  SRGBColorSpace,
  Scene,
  Skeleton,
  SkinnedMesh,
  SpotLight,
  TextureLoader,
  Vector2,
  Vector3,
  VectorKeyframeTrack
} from "./chunk-4JECOO4M.js";

// node_modules/three/examples/jsm/loaders/TGALoader.js
var TGALoader = class extends DataTextureLoader {
  /**
   * Constructs a new TGA loader.
   *
   * @param {LoadingManager} [manager] - The loading manager.
   */
  constructor(manager) {
    super(manager);
  }
  /**
   * Parses the given TGA texture data.
   *
   * @param {ArrayBuffer} buffer - The raw texture data.
   * @return {DataTextureLoader~TexData} An object representing the parsed texture data.
   */
  parse(buffer) {
    function tgaCheckHeader(header2) {
      switch (header2.image_type) {
        // check indexed type
        case TGA_TYPE_INDEXED:
        case TGA_TYPE_RLE_INDEXED:
          if (header2.colormap_length > 256 || header2.colormap_size !== 24 || header2.colormap_type !== 1) {
            throw new Error("THREE.TGALoader: Invalid type colormap data for indexed type.");
          }
          break;
        // check colormap type
        case TGA_TYPE_RGB:
        case TGA_TYPE_GREY:
        case TGA_TYPE_RLE_RGB:
        case TGA_TYPE_RLE_GREY:
          if (header2.colormap_type) {
            throw new Error("THREE.TGALoader: Invalid type colormap data for colormap type.");
          }
          break;
        // What the need of a file without data ?
        case TGA_TYPE_NO_DATA:
          throw new Error("THREE.TGALoader: No data.");
        // Invalid type ?
        default:
          throw new Error("THREE.TGALoader: Invalid type " + header2.image_type);
      }
      if (header2.width <= 0 || header2.height <= 0) {
        throw new Error("THREE.TGALoader: Invalid image size.");
      }
      if (header2.pixel_size !== 8 && header2.pixel_size !== 16 && header2.pixel_size !== 24 && header2.pixel_size !== 32) {
        throw new Error("THREE.TGALoader: Invalid pixel size " + header2.pixel_size);
      }
    }
    function tgaParse(use_rle2, use_pal2, header2, offset2, data) {
      let pixel_data, palettes;
      const pixel_size = header2.pixel_size >> 3;
      const pixel_total = header2.width * header2.height * pixel_size;
      if (use_pal2) {
        palettes = data.subarray(offset2, offset2 += header2.colormap_length * (header2.colormap_size >> 3));
      }
      if (use_rle2) {
        pixel_data = new Uint8Array(pixel_total);
        let c, count, i;
        let shift = 0;
        const pixels = new Uint8Array(pixel_size);
        while (shift < pixel_total) {
          c = data[offset2++];
          count = (c & 127) + 1;
          if (c & 128) {
            for (i = 0; i < pixel_size; ++i) {
              pixels[i] = data[offset2++];
            }
            for (i = 0; i < count; ++i) {
              pixel_data.set(pixels, shift + i * pixel_size);
            }
            shift += pixel_size * count;
          } else {
            count *= pixel_size;
            for (i = 0; i < count; ++i) {
              pixel_data[shift + i] = data[offset2++];
            }
            shift += count;
          }
        }
      } else {
        pixel_data = data.subarray(
          offset2,
          offset2 += use_pal2 ? header2.width * header2.height : pixel_total
        );
      }
      return {
        pixel_data,
        palettes
      };
    }
    function tgaGetImageData8bits(imageData2, y_start, y_step, y_end, x_start, x_step, x_end, image, palettes) {
      const colormap = palettes;
      let color, i = 0, x, y;
      const width = header.width;
      for (y = y_start; y !== y_end; y += y_step) {
        for (x = x_start; x !== x_end; x += x_step, i++) {
          color = image[i];
          imageData2[(x + width * y) * 4 + 3] = 255;
          imageData2[(x + width * y) * 4 + 2] = colormap[color * 3 + 0];
          imageData2[(x + width * y) * 4 + 1] = colormap[color * 3 + 1];
          imageData2[(x + width * y) * 4 + 0] = colormap[color * 3 + 2];
        }
      }
      return imageData2;
    }
    function tgaGetImageData16bits(imageData2, y_start, y_step, y_end, x_start, x_step, x_end, image) {
      let color, i = 0, x, y;
      const width = header.width;
      for (y = y_start; y !== y_end; y += y_step) {
        for (x = x_start; x !== x_end; x += x_step, i += 2) {
          color = image[i + 0] + (image[i + 1] << 8);
          imageData2[(x + width * y) * 4 + 0] = (color & 31744) >> 7;
          imageData2[(x + width * y) * 4 + 1] = (color & 992) >> 2;
          imageData2[(x + width * y) * 4 + 2] = (color & 31) << 3;
          imageData2[(x + width * y) * 4 + 3] = color & 32768 ? 0 : 255;
        }
      }
      return imageData2;
    }
    function tgaGetImageData24bits(imageData2, y_start, y_step, y_end, x_start, x_step, x_end, image) {
      let i = 0, x, y;
      const width = header.width;
      for (y = y_start; y !== y_end; y += y_step) {
        for (x = x_start; x !== x_end; x += x_step, i += 3) {
          imageData2[(x + width * y) * 4 + 3] = 255;
          imageData2[(x + width * y) * 4 + 2] = image[i + 0];
          imageData2[(x + width * y) * 4 + 1] = image[i + 1];
          imageData2[(x + width * y) * 4 + 0] = image[i + 2];
        }
      }
      return imageData2;
    }
    function tgaGetImageData32bits(imageData2, y_start, y_step, y_end, x_start, x_step, x_end, image) {
      let i = 0, x, y;
      const width = header.width;
      for (y = y_start; y !== y_end; y += y_step) {
        for (x = x_start; x !== x_end; x += x_step, i += 4) {
          imageData2[(x + width * y) * 4 + 2] = image[i + 0];
          imageData2[(x + width * y) * 4 + 1] = image[i + 1];
          imageData2[(x + width * y) * 4 + 0] = image[i + 2];
          imageData2[(x + width * y) * 4 + 3] = image[i + 3];
        }
      }
      return imageData2;
    }
    function tgaGetImageDataGrey8bits(imageData2, y_start, y_step, y_end, x_start, x_step, x_end, image) {
      let color, i = 0, x, y;
      const width = header.width;
      for (y = y_start; y !== y_end; y += y_step) {
        for (x = x_start; x !== x_end; x += x_step, i++) {
          color = image[i];
          imageData2[(x + width * y) * 4 + 0] = color;
          imageData2[(x + width * y) * 4 + 1] = color;
          imageData2[(x + width * y) * 4 + 2] = color;
          imageData2[(x + width * y) * 4 + 3] = 255;
        }
      }
      return imageData2;
    }
    function tgaGetImageDataGrey16bits(imageData2, y_start, y_step, y_end, x_start, x_step, x_end, image) {
      let i = 0, x, y;
      const width = header.width;
      for (y = y_start; y !== y_end; y += y_step) {
        for (x = x_start; x !== x_end; x += x_step, i += 2) {
          imageData2[(x + width * y) * 4 + 0] = image[i + 0];
          imageData2[(x + width * y) * 4 + 1] = image[i + 0];
          imageData2[(x + width * y) * 4 + 2] = image[i + 0];
          imageData2[(x + width * y) * 4 + 3] = image[i + 1];
        }
      }
      return imageData2;
    }
    function getTgaRGBA(data, width, height, image, palette) {
      let x_start, y_start, x_step, y_step, x_end, y_end;
      switch ((header.flags & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT) {
        default:
        case TGA_ORIGIN_UL:
          x_start = 0;
          x_step = 1;
          x_end = width;
          y_start = 0;
          y_step = 1;
          y_end = height;
          break;
        case TGA_ORIGIN_BL:
          x_start = 0;
          x_step = 1;
          x_end = width;
          y_start = height - 1;
          y_step = -1;
          y_end = -1;
          break;
        case TGA_ORIGIN_UR:
          x_start = width - 1;
          x_step = -1;
          x_end = -1;
          y_start = 0;
          y_step = 1;
          y_end = height;
          break;
        case TGA_ORIGIN_BR:
          x_start = width - 1;
          x_step = -1;
          x_end = -1;
          y_start = height - 1;
          y_step = -1;
          y_end = -1;
          break;
      }
      if (use_grey) {
        switch (header.pixel_size) {
          case 8:
            tgaGetImageDataGrey8bits(data, y_start, y_step, y_end, x_start, x_step, x_end, image);
            break;
          case 16:
            tgaGetImageDataGrey16bits(data, y_start, y_step, y_end, x_start, x_step, x_end, image);
            break;
          default:
            throw new Error("THREE.TGALoader: Format not supported.");
            break;
        }
      } else {
        switch (header.pixel_size) {
          case 8:
            tgaGetImageData8bits(data, y_start, y_step, y_end, x_start, x_step, x_end, image, palette);
            break;
          case 16:
            tgaGetImageData16bits(data, y_start, y_step, y_end, x_start, x_step, x_end, image);
            break;
          case 24:
            tgaGetImageData24bits(data, y_start, y_step, y_end, x_start, x_step, x_end, image);
            break;
          case 32:
            tgaGetImageData32bits(data, y_start, y_step, y_end, x_start, x_step, x_end, image);
            break;
          default:
            throw new Error("THREE.TGALoader: Format not supported.");
            break;
        }
      }
      return data;
    }
    const TGA_TYPE_NO_DATA = 0, TGA_TYPE_INDEXED = 1, TGA_TYPE_RGB = 2, TGA_TYPE_GREY = 3, TGA_TYPE_RLE_INDEXED = 9, TGA_TYPE_RLE_RGB = 10, TGA_TYPE_RLE_GREY = 11, TGA_ORIGIN_MASK = 48, TGA_ORIGIN_SHIFT = 4, TGA_ORIGIN_BL = 0, TGA_ORIGIN_BR = 1, TGA_ORIGIN_UL = 2, TGA_ORIGIN_UR = 3;
    if (buffer.length < 19) throw new Error("THREE.TGALoader: Not enough data to contain header.");
    let offset = 0;
    const content = new Uint8Array(buffer), header = {
      id_length: content[offset++],
      colormap_type: content[offset++],
      image_type: content[offset++],
      colormap_index: content[offset++] | content[offset++] << 8,
      colormap_length: content[offset++] | content[offset++] << 8,
      colormap_size: content[offset++],
      origin: [
        content[offset++] | content[offset++] << 8,
        content[offset++] | content[offset++] << 8
      ],
      width: content[offset++] | content[offset++] << 8,
      height: content[offset++] | content[offset++] << 8,
      pixel_size: content[offset++],
      flags: content[offset++]
    };
    tgaCheckHeader(header);
    if (header.id_length + offset > buffer.length) {
      throw new Error("THREE.TGALoader: No data.");
    }
    offset += header.id_length;
    let use_rle = false, use_pal = false, use_grey = false;
    switch (header.image_type) {
      case TGA_TYPE_RLE_INDEXED:
        use_rle = true;
        use_pal = true;
        break;
      case TGA_TYPE_INDEXED:
        use_pal = true;
        break;
      case TGA_TYPE_RLE_RGB:
        use_rle = true;
        break;
      case TGA_TYPE_RGB:
        break;
      case TGA_TYPE_RLE_GREY:
        use_rle = true;
        use_grey = true;
        break;
      case TGA_TYPE_GREY:
        use_grey = true;
        break;
    }
    const imageData = new Uint8Array(header.width * header.height * 4);
    const result = tgaParse(use_rle, use_pal, header, offset, content);
    getTgaRGBA(imageData, header.width, header.height, result.pixel_data, result.palettes);
    return {
      data: imageData,
      width: header.width,
      height: header.height,
      flipY: true,
      generateMipmaps: true,
      minFilter: LinearMipmapLinearFilter
    };
  }
};

// node_modules/three/examples/jsm/loaders/ColladaLoader.js
var ColladaLoader = class extends Loader {
  /**
   * Starts loading from the given URL and passes the loaded Collada asset
   * to the `onLoad()` callback.
   *
   * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
   * @param {function({scene:Group,animations:Array<AnimationClip>,kinematics:Object})} onLoad - Executed when the loading process has been finished.
   * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
   * @param {onErrorCallback} onError - Executed when errors occur.
   */
  load(url, onLoad, onProgress, onError) {
    const scope = this;
    const path = scope.path === "" ? LoaderUtils.extractUrlBase(url) : scope.path;
    const loader = new FileLoader(scope.manager);
    loader.setPath(scope.path);
    loader.setRequestHeader(scope.requestHeader);
    loader.setWithCredentials(scope.withCredentials);
    loader.load(url, function(text) {
      try {
        onLoad(scope.parse(text, path));
      } catch (e) {
        if (onError) {
          onError(e);
        } else {
          console.error(e);
        }
        scope.manager.itemError(url);
      }
    }, onProgress, onError);
  }
  /**
   * Parses the given Collada data and returns a result object holding the parsed scene,
   * an array of animation clips and kinematics.
   *
   * @param {string} text - The raw Collada data as a string.
   * @param {string} [path] - The asset path.
   * @return {?{scene:Group,animations:Array<AnimationClip>,kinematics:Object}} An object representing the parsed asset.
   */
  parse(text, path) {
    function getElementsByTagName(xml2, name) {
      const array = [];
      const childNodes = xml2.childNodes;
      for (let i = 0, l = childNodes.length; i < l; i++) {
        const child = childNodes[i];
        if (child.nodeName === name) {
          array.push(child);
        }
      }
      return array;
    }
    function parseStrings(text2) {
      if (text2.length === 0) return [];
      const parts = text2.trim().split(/\s+/);
      const array = new Array(parts.length);
      for (let i = 0, l = parts.length; i < l; i++) {
        array[i] = parts[i];
      }
      return array;
    }
    function parseFloats(text2) {
      if (text2.length === 0) return [];
      const parts = text2.trim().split(/\s+/);
      const array = new Array(parts.length);
      for (let i = 0, l = parts.length; i < l; i++) {
        array[i] = parseFloat(parts[i]);
      }
      return array;
    }
    function parseInts(text2) {
      if (text2.length === 0) return [];
      const parts = text2.trim().split(/\s+/);
      const array = new Array(parts.length);
      for (let i = 0, l = parts.length; i < l; i++) {
        array[i] = parseInt(parts[i]);
      }
      return array;
    }
    function parseId(text2) {
      return text2.substring(1);
    }
    function generateId() {
      return "three_default_" + count++;
    }
    function isEmpty(object) {
      return Object.keys(object).length === 0;
    }
    function parseAsset(xml2) {
      return {
        unit: parseAssetUnit(getElementsByTagName(xml2, "unit")[0]),
        upAxis: parseAssetUpAxis(getElementsByTagName(xml2, "up_axis")[0])
      };
    }
    function parseAssetUnit(xml2) {
      if (xml2 !== void 0 && xml2.hasAttribute("meter") === true) {
        return parseFloat(xml2.getAttribute("meter"));
      } else {
        return 1;
      }
    }
    function parseAssetUpAxis(xml2) {
      return xml2 !== void 0 ? xml2.textContent : "Y_UP";
    }
    function parseLibrary(xml2, libraryName, nodeName, parser) {
      const library2 = getElementsByTagName(xml2, libraryName)[0];
      if (library2 !== void 0) {
        const elements = getElementsByTagName(library2, nodeName);
        for (let i = 0; i < elements.length; i++) {
          parser(elements[i]);
        }
      }
    }
    function buildLibrary(data, builder) {
      for (const name in data) {
        const object = data[name];
        object.build = builder(data[name]);
      }
    }
    function getBuild(data, builder) {
      if (data.build !== void 0) return data.build;
      data.build = builder(data);
      return data.build;
    }
    function parseAnimation(xml2) {
      const data = {
        sources: {},
        samplers: {},
        channels: {}
      };
      let hasChildren = false;
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        let id;
        switch (child.nodeName) {
          case "source":
            id = child.getAttribute("id");
            data.sources[id] = parseSource(child);
            break;
          case "sampler":
            id = child.getAttribute("id");
            data.samplers[id] = parseAnimationSampler(child);
            break;
          case "channel":
            id = child.getAttribute("target");
            data.channels[id] = parseAnimationChannel(child);
            break;
          case "animation":
            parseAnimation(child);
            hasChildren = true;
            break;
          default:
            console.log(child);
        }
      }
      if (hasChildren === false) {
        library.animations[xml2.getAttribute("id") || MathUtils.generateUUID()] = data;
      }
    }
    function parseAnimationSampler(xml2) {
      const data = {
        inputs: {}
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "input":
            const id = parseId(child.getAttribute("source"));
            const semantic = child.getAttribute("semantic");
            data.inputs[semantic] = id;
            break;
        }
      }
      return data;
    }
    function parseAnimationChannel(xml2) {
      const data = {};
      const target = xml2.getAttribute("target");
      let parts = target.split("/");
      const id = parts.shift();
      let sid = parts.shift();
      const arraySyntax = sid.indexOf("(") !== -1;
      const memberSyntax = sid.indexOf(".") !== -1;
      if (memberSyntax) {
        parts = sid.split(".");
        sid = parts.shift();
        data.member = parts.shift();
      } else if (arraySyntax) {
        const indices = sid.split("(");
        sid = indices.shift();
        for (let i = 0; i < indices.length; i++) {
          indices[i] = parseInt(indices[i].replace(/\)/, ""));
        }
        data.indices = indices;
      }
      data.id = id;
      data.sid = sid;
      data.arraySyntax = arraySyntax;
      data.memberSyntax = memberSyntax;
      data.sampler = parseId(xml2.getAttribute("source"));
      return data;
    }
    function buildAnimation(data) {
      const tracks = [];
      const channels = data.channels;
      const samplers = data.samplers;
      const sources = data.sources;
      for (const target in channels) {
        if (channels.hasOwnProperty(target)) {
          const channel = channels[target];
          const sampler = samplers[channel.sampler];
          const inputId = sampler.inputs.INPUT;
          const outputId = sampler.inputs.OUTPUT;
          const inputSource = sources[inputId];
          const outputSource = sources[outputId];
          const animation = buildAnimationChannel(channel, inputSource, outputSource);
          createKeyframeTracks(animation, tracks);
        }
      }
      return tracks;
    }
    function getAnimation(id) {
      return getBuild(library.animations[id], buildAnimation);
    }
    function buildAnimationChannel(channel, inputSource, outputSource) {
      const node = library.nodes[channel.id];
      const object3D = getNode(node.id);
      const transform = node.transforms[channel.sid];
      const defaultMatrix = node.matrix.clone().transpose();
      let time, stride;
      let i, il, j, jl;
      const data = {};
      switch (transform) {
        case "matrix":
          for (i = 0, il = inputSource.array.length; i < il; i++) {
            time = inputSource.array[i];
            stride = i * outputSource.stride;
            if (data[time] === void 0) data[time] = {};
            if (channel.arraySyntax === true) {
              const value = outputSource.array[stride];
              const index = channel.indices[0] + 4 * channel.indices[1];
              data[time][index] = value;
            } else {
              for (j = 0, jl = outputSource.stride; j < jl; j++) {
                data[time][j] = outputSource.array[stride + j];
              }
            }
          }
          break;
        case "translate":
          console.warn('THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform);
          break;
        case "rotate":
          console.warn('THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform);
          break;
        case "scale":
          console.warn('THREE.ColladaLoader: Animation transform type "%s" not yet implemented.', transform);
          break;
      }
      const keyframes = prepareAnimationData(data, defaultMatrix);
      const animation = {
        name: object3D.uuid,
        keyframes
      };
      return animation;
    }
    function prepareAnimationData(data, defaultMatrix) {
      const keyframes = [];
      for (const time in data) {
        keyframes.push({ time: parseFloat(time), value: data[time] });
      }
      keyframes.sort(ascending);
      for (let i = 0; i < 16; i++) {
        transformAnimationData(keyframes, i, defaultMatrix.elements[i]);
      }
      return keyframes;
      function ascending(a, b) {
        return a.time - b.time;
      }
    }
    const position = new Vector3();
    const scale = new Vector3();
    const quaternion = new Quaternion();
    function createKeyframeTracks(animation, tracks) {
      const keyframes = animation.keyframes;
      const name = animation.name;
      const times = [];
      const positionData = [];
      const quaternionData = [];
      const scaleData = [];
      for (let i = 0, l = keyframes.length; i < l; i++) {
        const keyframe = keyframes[i];
        const time = keyframe.time;
        const value = keyframe.value;
        matrix.fromArray(value).transpose();
        matrix.decompose(position, quaternion, scale);
        times.push(time);
        positionData.push(position.x, position.y, position.z);
        quaternionData.push(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
        scaleData.push(scale.x, scale.y, scale.z);
      }
      if (positionData.length > 0) tracks.push(new VectorKeyframeTrack(name + ".position", times, positionData));
      if (quaternionData.length > 0) tracks.push(new QuaternionKeyframeTrack(name + ".quaternion", times, quaternionData));
      if (scaleData.length > 0) tracks.push(new VectorKeyframeTrack(name + ".scale", times, scaleData));
      return tracks;
    }
    function transformAnimationData(keyframes, property, defaultValue) {
      let keyframe;
      let empty = true;
      let i, l;
      for (i = 0, l = keyframes.length; i < l; i++) {
        keyframe = keyframes[i];
        if (keyframe.value[property] === void 0) {
          keyframe.value[property] = null;
        } else {
          empty = false;
        }
      }
      if (empty === true) {
        for (i = 0, l = keyframes.length; i < l; i++) {
          keyframe = keyframes[i];
          keyframe.value[property] = defaultValue;
        }
      } else {
        createMissingKeyframes(keyframes, property);
      }
    }
    function createMissingKeyframes(keyframes, property) {
      let prev, next;
      for (let i = 0, l = keyframes.length; i < l; i++) {
        const keyframe = keyframes[i];
        if (keyframe.value[property] === null) {
          prev = getPrev(keyframes, i, property);
          next = getNext(keyframes, i, property);
          if (prev === null) {
            keyframe.value[property] = next.value[property];
            continue;
          }
          if (next === null) {
            keyframe.value[property] = prev.value[property];
            continue;
          }
          interpolate(keyframe, prev, next, property);
        }
      }
    }
    function getPrev(keyframes, i, property) {
      while (i >= 0) {
        const keyframe = keyframes[i];
        if (keyframe.value[property] !== null) return keyframe;
        i--;
      }
      return null;
    }
    function getNext(keyframes, i, property) {
      while (i < keyframes.length) {
        const keyframe = keyframes[i];
        if (keyframe.value[property] !== null) return keyframe;
        i++;
      }
      return null;
    }
    function interpolate(key, prev, next, property) {
      if (next.time - prev.time === 0) {
        key.value[property] = prev.value[property];
        return;
      }
      key.value[property] = (key.time - prev.time) * (next.value[property] - prev.value[property]) / (next.time - prev.time) + prev.value[property];
    }
    function parseAnimationClip(xml2) {
      const data = {
        name: xml2.getAttribute("id") || "default",
        start: parseFloat(xml2.getAttribute("start") || 0),
        end: parseFloat(xml2.getAttribute("end") || 0),
        animations: []
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "instance_animation":
            data.animations.push(parseId(child.getAttribute("url")));
            break;
        }
      }
      library.clips[xml2.getAttribute("id")] = data;
    }
    function buildAnimationClip(data) {
      const tracks = [];
      const name = data.name;
      const duration = data.end - data.start || -1;
      const animations2 = data.animations;
      for (let i = 0, il = animations2.length; i < il; i++) {
        const animationTracks = getAnimation(animations2[i]);
        for (let j = 0, jl = animationTracks.length; j < jl; j++) {
          tracks.push(animationTracks[j]);
        }
      }
      return new AnimationClip(name, duration, tracks);
    }
    function getAnimationClip(id) {
      return getBuild(library.clips[id], buildAnimationClip);
    }
    function parseController(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "skin":
            data.id = parseId(child.getAttribute("source"));
            data.skin = parseSkin(child);
            break;
          case "morph":
            data.id = parseId(child.getAttribute("source"));
            console.warn("THREE.ColladaLoader: Morph target animation not supported yet.");
            break;
        }
      }
      library.controllers[xml2.getAttribute("id")] = data;
    }
    function parseSkin(xml2) {
      const data = {
        sources: {}
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "bind_shape_matrix":
            data.bindShapeMatrix = parseFloats(child.textContent);
            break;
          case "source":
            const id = child.getAttribute("id");
            data.sources[id] = parseSource(child);
            break;
          case "joints":
            data.joints = parseJoints(child);
            break;
          case "vertex_weights":
            data.vertexWeights = parseVertexWeights(child);
            break;
        }
      }
      return data;
    }
    function parseJoints(xml2) {
      const data = {
        inputs: {}
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "input":
            const semantic = child.getAttribute("semantic");
            const id = parseId(child.getAttribute("source"));
            data.inputs[semantic] = id;
            break;
        }
      }
      return data;
    }
    function parseVertexWeights(xml2) {
      const data = {
        inputs: {}
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "input":
            const semantic = child.getAttribute("semantic");
            const id = parseId(child.getAttribute("source"));
            const offset = parseInt(child.getAttribute("offset"));
            data.inputs[semantic] = { id, offset };
            break;
          case "vcount":
            data.vcount = parseInts(child.textContent);
            break;
          case "v":
            data.v = parseInts(child.textContent);
            break;
        }
      }
      return data;
    }
    function buildController(data) {
      const build = {
        id: data.id
      };
      const geometry = library.geometries[build.id];
      if (data.skin !== void 0) {
        build.skin = buildSkin(data.skin);
        geometry.sources.skinIndices = build.skin.indices;
        geometry.sources.skinWeights = build.skin.weights;
      }
      return build;
    }
    function buildSkin(data) {
      const BONE_LIMIT = 4;
      const build = {
        joints: [],
        // this must be an array to preserve the joint order
        indices: {
          array: [],
          stride: BONE_LIMIT
        },
        weights: {
          array: [],
          stride: BONE_LIMIT
        }
      };
      const sources = data.sources;
      const vertexWeights = data.vertexWeights;
      const vcount = vertexWeights.vcount;
      const v = vertexWeights.v;
      const jointOffset = vertexWeights.inputs.JOINT.offset;
      const weightOffset = vertexWeights.inputs.WEIGHT.offset;
      const jointSource = data.sources[data.joints.inputs.JOINT];
      const inverseSource = data.sources[data.joints.inputs.INV_BIND_MATRIX];
      const weights = sources[vertexWeights.inputs.WEIGHT.id].array;
      let stride = 0;
      let i, j, l;
      for (i = 0, l = vcount.length; i < l; i++) {
        const jointCount = vcount[i];
        const vertexSkinData = [];
        for (j = 0; j < jointCount; j++) {
          const skinIndex = v[stride + jointOffset];
          const weightId = v[stride + weightOffset];
          const skinWeight = weights[weightId];
          vertexSkinData.push({ index: skinIndex, weight: skinWeight });
          stride += 2;
        }
        vertexSkinData.sort(descending);
        for (j = 0; j < BONE_LIMIT; j++) {
          const d = vertexSkinData[j];
          if (d !== void 0) {
            build.indices.array.push(d.index);
            build.weights.array.push(d.weight);
          } else {
            build.indices.array.push(0);
            build.weights.array.push(0);
          }
        }
      }
      if (data.bindShapeMatrix) {
        build.bindMatrix = new Matrix4().fromArray(data.bindShapeMatrix).transpose();
      } else {
        build.bindMatrix = new Matrix4().identity();
      }
      for (i = 0, l = jointSource.array.length; i < l; i++) {
        const name = jointSource.array[i];
        const boneInverse = new Matrix4().fromArray(inverseSource.array, i * inverseSource.stride).transpose();
        build.joints.push({ name, boneInverse });
      }
      return build;
      function descending(a, b) {
        return b.weight - a.weight;
      }
    }
    function getController(id) {
      return getBuild(library.controllers[id], buildController);
    }
    function parseImage(xml2) {
      const data = {
        init_from: getElementsByTagName(xml2, "init_from")[0].textContent
      };
      library.images[xml2.getAttribute("id")] = data;
    }
    function buildImage(data) {
      if (data.build !== void 0) return data.build;
      return data.init_from;
    }
    function getImage(id) {
      const data = library.images[id];
      if (data !== void 0) {
        return getBuild(data, buildImage);
      }
      console.warn("THREE.ColladaLoader: Couldn't find image with ID:", id);
      return null;
    }
    function parseEffect(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "profile_COMMON":
            data.profile = parseEffectProfileCOMMON(child);
            break;
        }
      }
      library.effects[xml2.getAttribute("id")] = data;
    }
    function parseEffectProfileCOMMON(xml2) {
      const data = {
        surfaces: {},
        samplers: {}
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "newparam":
            parseEffectNewparam(child, data);
            break;
          case "technique":
            data.technique = parseEffectTechnique(child);
            break;
          case "extra":
            data.extra = parseEffectExtra(child);
            break;
        }
      }
      return data;
    }
    function parseEffectNewparam(xml2, data) {
      const sid = xml2.getAttribute("sid");
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "surface":
            data.surfaces[sid] = parseEffectSurface(child);
            break;
          case "sampler2D":
            data.samplers[sid] = parseEffectSampler(child);
            break;
        }
      }
    }
    function parseEffectSurface(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "init_from":
            data.init_from = child.textContent;
            break;
        }
      }
      return data;
    }
    function parseEffectSampler(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "source":
            data.source = child.textContent;
            break;
        }
      }
      return data;
    }
    function parseEffectTechnique(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "constant":
          case "lambert":
          case "blinn":
          case "phong":
            data.type = child.nodeName;
            data.parameters = parseEffectParameters(child);
            break;
          case "extra":
            data.extra = parseEffectExtra(child);
            break;
        }
      }
      return data;
    }
    function parseEffectParameters(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "emission":
          case "diffuse":
          case "specular":
          case "bump":
          case "ambient":
          case "shininess":
          case "transparency":
            data[child.nodeName] = parseEffectParameter(child);
            break;
          case "transparent":
            data[child.nodeName] = {
              opaque: child.hasAttribute("opaque") ? child.getAttribute("opaque") : "A_ONE",
              data: parseEffectParameter(child)
            };
            break;
        }
      }
      return data;
    }
    function parseEffectParameter(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "color":
            data[child.nodeName] = parseFloats(child.textContent);
            break;
          case "float":
            data[child.nodeName] = parseFloat(child.textContent);
            break;
          case "texture":
            data[child.nodeName] = { id: child.getAttribute("texture"), extra: parseEffectParameterTexture(child) };
            break;
        }
      }
      return data;
    }
    function parseEffectParameterTexture(xml2) {
      const data = {
        technique: {}
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "extra":
            parseEffectParameterTextureExtra(child, data);
            break;
        }
      }
      return data;
    }
    function parseEffectParameterTextureExtra(xml2, data) {
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "technique":
            parseEffectParameterTextureExtraTechnique(child, data);
            break;
        }
      }
    }
    function parseEffectParameterTextureExtraTechnique(xml2, data) {
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "repeatU":
          case "repeatV":
          case "offsetU":
          case "offsetV":
            data.technique[child.nodeName] = parseFloat(child.textContent);
            break;
          case "wrapU":
          case "wrapV":
            if (child.textContent.toUpperCase() === "TRUE") {
              data.technique[child.nodeName] = 1;
            } else if (child.textContent.toUpperCase() === "FALSE") {
              data.technique[child.nodeName] = 0;
            } else {
              data.technique[child.nodeName] = parseInt(child.textContent);
            }
            break;
          case "bump":
            data[child.nodeName] = parseEffectExtraTechniqueBump(child);
            break;
        }
      }
    }
    function parseEffectExtra(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "technique":
            data.technique = parseEffectExtraTechnique(child);
            break;
        }
      }
      return data;
    }
    function parseEffectExtraTechnique(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "double_sided":
            data[child.nodeName] = parseInt(child.textContent);
            break;
          case "bump":
            data[child.nodeName] = parseEffectExtraTechniqueBump(child);
            break;
        }
      }
      return data;
    }
    function parseEffectExtraTechniqueBump(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "texture":
            data[child.nodeName] = { id: child.getAttribute("texture"), texcoord: child.getAttribute("texcoord"), extra: parseEffectParameterTexture(child) };
            break;
        }
      }
      return data;
    }
    function buildEffect(data) {
      return data;
    }
    function getEffect(id) {
      return getBuild(library.effects[id], buildEffect);
    }
    function parseMaterial(xml2) {
      const data = {
        name: xml2.getAttribute("name")
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "instance_effect":
            data.url = parseId(child.getAttribute("url"));
            break;
        }
      }
      library.materials[xml2.getAttribute("id")] = data;
    }
    function getTextureLoader(image) {
      let loader;
      let extension = image.slice((image.lastIndexOf(".") - 1 >>> 0) + 2);
      extension = extension.toLowerCase();
      switch (extension) {
        case "tga":
          loader = tgaLoader;
          break;
        default:
          loader = textureLoader;
      }
      return loader;
    }
    function buildMaterial(data) {
      const effect = getEffect(data.url);
      const technique = effect.profile.technique;
      let material;
      switch (technique.type) {
        case "phong":
        case "blinn":
          material = new MeshPhongMaterial();
          break;
        case "lambert":
          material = new MeshLambertMaterial();
          break;
        default:
          material = new MeshBasicMaterial();
          break;
      }
      material.name = data.name || "";
      function getTexture(textureObject, colorSpace = null) {
        const sampler = effect.profile.samplers[textureObject.id];
        let image = null;
        if (sampler !== void 0) {
          const surface = effect.profile.surfaces[sampler.source];
          image = getImage(surface.init_from);
        } else {
          console.warn("THREE.ColladaLoader: Undefined sampler. Access image directly (see #12530).");
          image = getImage(textureObject.id);
        }
        if (image !== null) {
          const loader = getTextureLoader(image);
          if (loader !== void 0) {
            const texture = loader.load(image);
            const extra = textureObject.extra;
            if (extra !== void 0 && extra.technique !== void 0 && isEmpty(extra.technique) === false) {
              const technique2 = extra.technique;
              texture.wrapS = technique2.wrapU ? RepeatWrapping : ClampToEdgeWrapping;
              texture.wrapT = technique2.wrapV ? RepeatWrapping : ClampToEdgeWrapping;
              texture.offset.set(technique2.offsetU || 0, technique2.offsetV || 0);
              texture.repeat.set(technique2.repeatU || 1, technique2.repeatV || 1);
            } else {
              texture.wrapS = RepeatWrapping;
              texture.wrapT = RepeatWrapping;
            }
            if (colorSpace !== null) {
              texture.colorSpace = colorSpace;
            }
            return texture;
          } else {
            console.warn("THREE.ColladaLoader: Loader for texture %s not found.", image);
            return null;
          }
        } else {
          console.warn("THREE.ColladaLoader: Couldn't create texture with ID:", textureObject.id);
          return null;
        }
      }
      const parameters = technique.parameters;
      for (const key in parameters) {
        const parameter = parameters[key];
        switch (key) {
          case "diffuse":
            if (parameter.color) material.color.fromArray(parameter.color);
            if (parameter.texture) material.map = getTexture(parameter.texture, SRGBColorSpace);
            break;
          case "specular":
            if (parameter.color && material.specular) material.specular.fromArray(parameter.color);
            if (parameter.texture) material.specularMap = getTexture(parameter.texture);
            break;
          case "bump":
            if (parameter.texture) material.normalMap = getTexture(parameter.texture);
            break;
          case "ambient":
            if (parameter.texture) material.lightMap = getTexture(parameter.texture, SRGBColorSpace);
            break;
          case "shininess":
            if (parameter.float && material.shininess) material.shininess = parameter.float;
            break;
          case "emission":
            if (parameter.color && material.emissive) material.emissive.fromArray(parameter.color);
            if (parameter.texture) material.emissiveMap = getTexture(parameter.texture, SRGBColorSpace);
            break;
        }
      }
      ColorManagement.colorSpaceToWorking(material.color, SRGBColorSpace);
      if (material.specular) ColorManagement.colorSpaceToWorking(material.specular, SRGBColorSpace);
      if (material.emissive) ColorManagement.colorSpaceToWorking(material.emissive, SRGBColorSpace);
      let transparent = parameters["transparent"];
      let transparency = parameters["transparency"];
      if (transparency === void 0 && transparent) {
        transparency = {
          float: 1
        };
      }
      if (transparent === void 0 && transparency) {
        transparent = {
          opaque: "A_ONE",
          data: {
            color: [1, 1, 1, 1]
          }
        };
      }
      if (transparent && transparency) {
        if (transparent.data.texture) {
          material.transparent = true;
        } else {
          const color = transparent.data.color;
          switch (transparent.opaque) {
            case "A_ONE":
              material.opacity = color[3] * transparency.float;
              break;
            case "RGB_ZERO":
              material.opacity = 1 - color[0] * transparency.float;
              break;
            case "A_ZERO":
              material.opacity = 1 - color[3] * transparency.float;
              break;
            case "RGB_ONE":
              material.opacity = color[0] * transparency.float;
              break;
            default:
              console.warn('THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.', transparent.opaque);
          }
          if (material.opacity < 1) material.transparent = true;
        }
      }
      if (technique.extra !== void 0 && technique.extra.technique !== void 0) {
        const techniques = technique.extra.technique;
        for (const k in techniques) {
          const v = techniques[k];
          switch (k) {
            case "double_sided":
              material.side = v === 1 ? DoubleSide : FrontSide;
              break;
            case "bump":
              material.normalMap = getTexture(v.texture);
              material.normalScale = new Vector2(1, 1);
              break;
          }
        }
      }
      return material;
    }
    function getMaterial(id) {
      return getBuild(library.materials[id], buildMaterial);
    }
    function parseCamera(xml2) {
      const data = {
        name: xml2.getAttribute("name")
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "optics":
            data.optics = parseCameraOptics(child);
            break;
        }
      }
      library.cameras[xml2.getAttribute("id")] = data;
    }
    function parseCameraOptics(xml2) {
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        switch (child.nodeName) {
          case "technique_common":
            return parseCameraTechnique(child);
        }
      }
      return {};
    }
    function parseCameraTechnique(xml2) {
      const data = {};
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        switch (child.nodeName) {
          case "perspective":
          case "orthographic":
            data.technique = child.nodeName;
            data.parameters = parseCameraParameters(child);
            break;
        }
      }
      return data;
    }
    function parseCameraParameters(xml2) {
      const data = {};
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        switch (child.nodeName) {
          case "xfov":
          case "yfov":
          case "xmag":
          case "ymag":
          case "znear":
          case "zfar":
          case "aspect_ratio":
            data[child.nodeName] = parseFloat(child.textContent);
            break;
        }
      }
      return data;
    }
    function buildCamera(data) {
      let camera;
      switch (data.optics.technique) {
        case "perspective":
          camera = new PerspectiveCamera(
            data.optics.parameters.yfov,
            data.optics.parameters.aspect_ratio,
            data.optics.parameters.znear,
            data.optics.parameters.zfar
          );
          break;
        case "orthographic":
          let ymag = data.optics.parameters.ymag;
          let xmag = data.optics.parameters.xmag;
          const aspectRatio = data.optics.parameters.aspect_ratio;
          xmag = xmag === void 0 ? ymag * aspectRatio : xmag;
          ymag = ymag === void 0 ? xmag / aspectRatio : ymag;
          xmag *= 0.5;
          ymag *= 0.5;
          camera = new OrthographicCamera(
            -xmag,
            xmag,
            ymag,
            -ymag,
            // left, right, top, bottom
            data.optics.parameters.znear,
            data.optics.parameters.zfar
          );
          break;
        default:
          camera = new PerspectiveCamera();
          break;
      }
      camera.name = data.name || "";
      return camera;
    }
    function getCamera(id) {
      const data = library.cameras[id];
      if (data !== void 0) {
        return getBuild(data, buildCamera);
      }
      console.warn("THREE.ColladaLoader: Couldn't find camera with ID:", id);
      return null;
    }
    function parseLight(xml2) {
      let data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "technique_common":
            data = parseLightTechnique(child);
            break;
        }
      }
      library.lights[xml2.getAttribute("id")] = data;
    }
    function parseLightTechnique(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "directional":
          case "point":
          case "spot":
          case "ambient":
            data.technique = child.nodeName;
            data.parameters = parseLightParameters(child);
        }
      }
      return data;
    }
    function parseLightParameters(xml2) {
      const data = {};
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "color":
            const array = parseFloats(child.textContent);
            data.color = new Color().fromArray(array);
            ColorManagement.colorSpaceToWorking(data.color, SRGBColorSpace);
            break;
          case "falloff_angle":
            data.falloffAngle = parseFloat(child.textContent);
            break;
          case "quadratic_attenuation":
            const f = parseFloat(child.textContent);
            data.distance = f ? Math.sqrt(1 / f) : 0;
            break;
        }
      }
      return data;
    }
    function buildLight(data) {
      let light;
      switch (data.technique) {
        case "directional":
          light = new DirectionalLight();
          break;
        case "point":
          light = new PointLight();
          break;
        case "spot":
          light = new SpotLight();
          break;
        case "ambient":
          light = new AmbientLight();
          break;
      }
      if (data.parameters.color) light.color.copy(data.parameters.color);
      if (data.parameters.distance) light.distance = data.parameters.distance;
      return light;
    }
    function getLight(id) {
      const data = library.lights[id];
      if (data !== void 0) {
        return getBuild(data, buildLight);
      }
      console.warn("THREE.ColladaLoader: Couldn't find light with ID:", id);
      return null;
    }
    function parseGeometry(xml2) {
      const data = {
        name: xml2.getAttribute("name"),
        sources: {},
        vertices: {},
        primitives: []
      };
      const mesh = getElementsByTagName(xml2, "mesh")[0];
      if (mesh === void 0) return;
      for (let i = 0; i < mesh.childNodes.length; i++) {
        const child = mesh.childNodes[i];
        if (child.nodeType !== 1) continue;
        const id = child.getAttribute("id");
        switch (child.nodeName) {
          case "source":
            data.sources[id] = parseSource(child);
            break;
          case "vertices":
            data.vertices = parseGeometryVertices(child);
            break;
          case "polygons":
            console.warn("THREE.ColladaLoader: Unsupported primitive type: ", child.nodeName);
            break;
          case "lines":
          case "linestrips":
          case "polylist":
          case "triangles":
            data.primitives.push(parseGeometryPrimitive(child));
            break;
          default:
            console.log(child);
        }
      }
      library.geometries[xml2.getAttribute("id")] = data;
    }
    function parseSource(xml2) {
      const data = {
        array: [],
        stride: 3
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "float_array":
            data.array = parseFloats(child.textContent);
            break;
          case "Name_array":
            data.array = parseStrings(child.textContent);
            break;
          case "technique_common":
            const accessor = getElementsByTagName(child, "accessor")[0];
            if (accessor !== void 0) {
              data.stride = parseInt(accessor.getAttribute("stride"));
            }
            break;
        }
      }
      return data;
    }
    function parseGeometryVertices(xml2) {
      const data = {};
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        data[child.getAttribute("semantic")] = parseId(child.getAttribute("source"));
      }
      return data;
    }
    function parseGeometryPrimitive(xml2) {
      const primitive = {
        type: xml2.nodeName,
        material: xml2.getAttribute("material"),
        count: parseInt(xml2.getAttribute("count")),
        inputs: {},
        stride: 0,
        hasUV: false
      };
      for (let i = 0, l = xml2.childNodes.length; i < l; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "input":
            const id = parseId(child.getAttribute("source"));
            const semantic = child.getAttribute("semantic");
            const offset = parseInt(child.getAttribute("offset"));
            const set = parseInt(child.getAttribute("set"));
            const inputname = set > 0 ? semantic + set : semantic;
            primitive.inputs[inputname] = { id, offset };
            primitive.stride = Math.max(primitive.stride, offset + 1);
            if (semantic === "TEXCOORD") primitive.hasUV = true;
            break;
          case "vcount":
            primitive.vcount = parseInts(child.textContent);
            break;
          case "p":
            primitive.p = parseInts(child.textContent);
            break;
        }
      }
      return primitive;
    }
    function groupPrimitives(primitives) {
      const build = {};
      for (let i = 0; i < primitives.length; i++) {
        const primitive = primitives[i];
        if (build[primitive.type] === void 0) build[primitive.type] = [];
        build[primitive.type].push(primitive);
      }
      return build;
    }
    function checkUVCoordinates(primitives) {
      let count2 = 0;
      for (let i = 0, l = primitives.length; i < l; i++) {
        const primitive = primitives[i];
        if (primitive.hasUV === true) {
          count2++;
        }
      }
      if (count2 > 0 && count2 < primitives.length) {
        primitives.uvsNeedsFix = true;
      }
    }
    function buildGeometry(data) {
      const build = {};
      const sources = data.sources;
      const vertices = data.vertices;
      const primitives = data.primitives;
      if (primitives.length === 0) return {};
      const groupedPrimitives = groupPrimitives(primitives);
      for (const type in groupedPrimitives) {
        const primitiveType = groupedPrimitives[type];
        checkUVCoordinates(primitiveType);
        build[type] = buildGeometryType(primitiveType, sources, vertices);
      }
      return build;
    }
    function buildGeometryType(primitives, sources, vertices) {
      const build = {};
      const position2 = { array: [], stride: 0 };
      const normal = { array: [], stride: 0 };
      const uv = { array: [], stride: 0 };
      const uv1 = { array: [], stride: 0 };
      const color = { array: [], stride: 0 };
      const skinIndex = { array: [], stride: 4 };
      const skinWeight = { array: [], stride: 4 };
      const geometry = new BufferGeometry();
      const materialKeys = [];
      let start = 0;
      for (let p = 0; p < primitives.length; p++) {
        const primitive = primitives[p];
        const inputs = primitive.inputs;
        let count2 = 0;
        switch (primitive.type) {
          case "lines":
          case "linestrips":
            count2 = primitive.count * 2;
            break;
          case "triangles":
            count2 = primitive.count * 3;
            break;
          case "polylist":
            for (let g = 0; g < primitive.count; g++) {
              const vc = primitive.vcount[g];
              switch (vc) {
                case 3:
                  count2 += 3;
                  break;
                case 4:
                  count2 += 6;
                  break;
                default:
                  count2 += (vc - 2) * 3;
                  break;
              }
            }
            break;
          default:
            console.warn("THREE.ColladaLoader: Unknown primitive type:", primitive.type);
        }
        geometry.addGroup(start, count2, p);
        start += count2;
        if (primitive.material) {
          materialKeys.push(primitive.material);
        }
        for (const name in inputs) {
          const input = inputs[name];
          switch (name) {
            case "VERTEX":
              for (const key in vertices) {
                const id = vertices[key];
                switch (key) {
                  case "POSITION":
                    const prevLength = position2.array.length;
                    buildGeometryData(primitive, sources[id], input.offset, position2.array);
                    position2.stride = sources[id].stride;
                    if (sources.skinWeights && sources.skinIndices) {
                      buildGeometryData(primitive, sources.skinIndices, input.offset, skinIndex.array);
                      buildGeometryData(primitive, sources.skinWeights, input.offset, skinWeight.array);
                    }
                    if (primitive.hasUV === false && primitives.uvsNeedsFix === true) {
                      const count3 = (position2.array.length - prevLength) / position2.stride;
                      for (let i = 0; i < count3; i++) {
                        uv.array.push(0, 0);
                      }
                    }
                    break;
                  case "NORMAL":
                    buildGeometryData(primitive, sources[id], input.offset, normal.array);
                    normal.stride = sources[id].stride;
                    break;
                  case "COLOR":
                    buildGeometryData(primitive, sources[id], input.offset, color.array);
                    color.stride = sources[id].stride;
                    break;
                  case "TEXCOORD":
                    buildGeometryData(primitive, sources[id], input.offset, uv.array);
                    uv.stride = sources[id].stride;
                    break;
                  case "TEXCOORD1":
                    buildGeometryData(primitive, sources[id], input.offset, uv1.array);
                    uv.stride = sources[id].stride;
                    break;
                  default:
                    console.warn('THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key);
                }
              }
              break;
            case "NORMAL":
              buildGeometryData(primitive, sources[input.id], input.offset, normal.array);
              normal.stride = sources[input.id].stride;
              break;
            case "COLOR":
              buildGeometryData(primitive, sources[input.id], input.offset, color.array, true);
              color.stride = sources[input.id].stride;
              break;
            case "TEXCOORD":
              buildGeometryData(primitive, sources[input.id], input.offset, uv.array);
              uv.stride = sources[input.id].stride;
              break;
            case "TEXCOORD1":
              buildGeometryData(primitive, sources[input.id], input.offset, uv1.array);
              uv1.stride = sources[input.id].stride;
              break;
          }
        }
      }
      if (position2.array.length > 0) geometry.setAttribute("position", new Float32BufferAttribute(position2.array, position2.stride));
      if (normal.array.length > 0) geometry.setAttribute("normal", new Float32BufferAttribute(normal.array, normal.stride));
      if (color.array.length > 0) geometry.setAttribute("color", new Float32BufferAttribute(color.array, color.stride));
      if (uv.array.length > 0) geometry.setAttribute("uv", new Float32BufferAttribute(uv.array, uv.stride));
      if (uv1.array.length > 0) geometry.setAttribute("uv1", new Float32BufferAttribute(uv1.array, uv1.stride));
      if (skinIndex.array.length > 0) geometry.setAttribute("skinIndex", new Float32BufferAttribute(skinIndex.array, skinIndex.stride));
      if (skinWeight.array.length > 0) geometry.setAttribute("skinWeight", new Float32BufferAttribute(skinWeight.array, skinWeight.stride));
      build.data = geometry;
      build.type = primitives[0].type;
      build.materialKeys = materialKeys;
      return build;
    }
    function buildGeometryData(primitive, source, offset, array, isColor = false) {
      const indices = primitive.p;
      const stride = primitive.stride;
      const vcount = primitive.vcount;
      function pushVector(i) {
        let index = indices[i + offset] * sourceStride;
        const length = index + sourceStride;
        for (; index < length; index++) {
          array.push(sourceArray[index]);
        }
        if (isColor) {
          const startIndex = array.length - sourceStride - 1;
          tempColor.setRGB(
            array[startIndex + 0],
            array[startIndex + 1],
            array[startIndex + 2],
            SRGBColorSpace
          );
          array[startIndex + 0] = tempColor.r;
          array[startIndex + 1] = tempColor.g;
          array[startIndex + 2] = tempColor.b;
        }
      }
      const sourceArray = source.array;
      const sourceStride = source.stride;
      if (primitive.vcount !== void 0) {
        let index = 0;
        for (let i = 0, l = vcount.length; i < l; i++) {
          const count2 = vcount[i];
          if (count2 === 4) {
            const a = index + stride * 0;
            const b = index + stride * 1;
            const c = index + stride * 2;
            const d = index + stride * 3;
            pushVector(a);
            pushVector(b);
            pushVector(d);
            pushVector(b);
            pushVector(c);
            pushVector(d);
          } else if (count2 === 3) {
            const a = index + stride * 0;
            const b = index + stride * 1;
            const c = index + stride * 2;
            pushVector(a);
            pushVector(b);
            pushVector(c);
          } else if (count2 > 4) {
            for (let k = 1, kl = count2 - 2; k <= kl; k++) {
              const a = index + stride * 0;
              const b = index + stride * k;
              const c = index + stride * (k + 1);
              pushVector(a);
              pushVector(b);
              pushVector(c);
            }
          }
          index += stride * count2;
        }
      } else {
        for (let i = 0, l = indices.length; i < l; i += stride) {
          pushVector(i);
        }
      }
    }
    function getGeometry(id) {
      return getBuild(library.geometries[id], buildGeometry);
    }
    function parseKinematicsModel(xml2) {
      const data = {
        name: xml2.getAttribute("name") || "",
        joints: {},
        links: []
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "technique_common":
            parseKinematicsTechniqueCommon(child, data);
            break;
        }
      }
      library.kinematicsModels[xml2.getAttribute("id")] = data;
    }
    function buildKinematicsModel(data) {
      if (data.build !== void 0) return data.build;
      return data;
    }
    function getKinematicsModel(id) {
      return getBuild(library.kinematicsModels[id], buildKinematicsModel);
    }
    function parseKinematicsTechniqueCommon(xml2, data) {
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "joint":
            data.joints[child.getAttribute("sid")] = parseKinematicsJoint(child);
            break;
          case "link":
            data.links.push(parseKinematicsLink(child));
            break;
        }
      }
    }
    function parseKinematicsJoint(xml2) {
      let data;
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "prismatic":
          case "revolute":
            data = parseKinematicsJointParameter(child);
            break;
        }
      }
      return data;
    }
    function parseKinematicsJointParameter(xml2) {
      const data = {
        sid: xml2.getAttribute("sid"),
        name: xml2.getAttribute("name") || "",
        axis: new Vector3(),
        limits: {
          min: 0,
          max: 0
        },
        type: xml2.nodeName,
        static: false,
        zeroPosition: 0,
        middlePosition: 0
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "axis":
            const array = parseFloats(child.textContent);
            data.axis.fromArray(array);
            break;
          case "limits":
            const max = child.getElementsByTagName("max")[0];
            const min = child.getElementsByTagName("min")[0];
            data.limits.max = parseFloat(max.textContent);
            data.limits.min = parseFloat(min.textContent);
            break;
        }
      }
      if (data.limits.min >= data.limits.max) {
        data.static = true;
      }
      data.middlePosition = (data.limits.min + data.limits.max) / 2;
      return data;
    }
    function parseKinematicsLink(xml2) {
      const data = {
        sid: xml2.getAttribute("sid"),
        name: xml2.getAttribute("name") || "",
        attachments: [],
        transforms: []
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "attachment_full":
            data.attachments.push(parseKinematicsAttachment(child));
            break;
          case "matrix":
          case "translate":
          case "rotate":
            data.transforms.push(parseKinematicsTransform(child));
            break;
        }
      }
      return data;
    }
    function parseKinematicsAttachment(xml2) {
      const data = {
        joint: xml2.getAttribute("joint").split("/").pop(),
        transforms: [],
        links: []
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "link":
            data.links.push(parseKinematicsLink(child));
            break;
          case "matrix":
          case "translate":
          case "rotate":
            data.transforms.push(parseKinematicsTransform(child));
            break;
        }
      }
      return data;
    }
    function parseKinematicsTransform(xml2) {
      const data = {
        type: xml2.nodeName
      };
      const array = parseFloats(xml2.textContent);
      switch (data.type) {
        case "matrix":
          data.obj = new Matrix4();
          data.obj.fromArray(array).transpose();
          break;
        case "translate":
          data.obj = new Vector3();
          data.obj.fromArray(array);
          break;
        case "rotate":
          data.obj = new Vector3();
          data.obj.fromArray(array);
          data.angle = MathUtils.degToRad(array[3]);
          break;
      }
      return data;
    }
    function parsePhysicsModel(xml2) {
      const data = {
        name: xml2.getAttribute("name") || "",
        rigidBodies: {}
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "rigid_body":
            data.rigidBodies[child.getAttribute("name")] = {};
            parsePhysicsRigidBody(child, data.rigidBodies[child.getAttribute("name")]);
            break;
        }
      }
      library.physicsModels[xml2.getAttribute("id")] = data;
    }
    function parsePhysicsRigidBody(xml2, data) {
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "technique_common":
            parsePhysicsTechniqueCommon(child, data);
            break;
        }
      }
    }
    function parsePhysicsTechniqueCommon(xml2, data) {
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "inertia":
            data.inertia = parseFloats(child.textContent);
            break;
          case "mass":
            data.mass = parseFloats(child.textContent)[0];
            break;
        }
      }
    }
    function parseKinematicsScene(xml2) {
      const data = {
        bindJointAxis: []
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "bind_joint_axis":
            data.bindJointAxis.push(parseKinematicsBindJointAxis(child));
            break;
        }
      }
      library.kinematicsScenes[parseId(xml2.getAttribute("url"))] = data;
    }
    function parseKinematicsBindJointAxis(xml2) {
      const data = {
        target: xml2.getAttribute("target").split("/").pop()
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        switch (child.nodeName) {
          case "axis":
            const param = child.getElementsByTagName("param")[0];
            data.axis = param.textContent;
            const tmpJointIndex = data.axis.split("inst_").pop().split("axis")[0];
            data.jointIndex = tmpJointIndex.substring(0, tmpJointIndex.length - 1);
            break;
        }
      }
      return data;
    }
    function buildKinematicsScene(data) {
      if (data.build !== void 0) return data.build;
      return data;
    }
    function getKinematicsScene(id) {
      return getBuild(library.kinematicsScenes[id], buildKinematicsScene);
    }
    function setupKinematics() {
      const kinematicsModelId = Object.keys(library.kinematicsModels)[0];
      const kinematicsSceneId = Object.keys(library.kinematicsScenes)[0];
      const visualSceneId = Object.keys(library.visualScenes)[0];
      if (kinematicsModelId === void 0 || kinematicsSceneId === void 0) return;
      const kinematicsModel = getKinematicsModel(kinematicsModelId);
      const kinematicsScene = getKinematicsScene(kinematicsSceneId);
      const visualScene = getVisualScene(visualSceneId);
      const bindJointAxis = kinematicsScene.bindJointAxis;
      const jointMap = {};
      for (let i = 0, l = bindJointAxis.length; i < l; i++) {
        const axis = bindJointAxis[i];
        const targetElement = collada.querySelector('[sid="' + axis.target + '"]');
        if (targetElement) {
          const parentVisualElement = targetElement.parentElement;
          connect(axis.jointIndex, parentVisualElement);
        }
      }
      function connect(jointIndex, visualElement) {
        const visualElementName = visualElement.getAttribute("name");
        const joint = kinematicsModel.joints[jointIndex];
        visualScene.traverse(function(object) {
          if (object.name === visualElementName) {
            jointMap[jointIndex] = {
              object,
              transforms: buildTransformList(visualElement),
              joint,
              position: joint.zeroPosition
            };
          }
        });
      }
      const m0 = new Matrix4();
      kinematics = {
        joints: kinematicsModel && kinematicsModel.joints,
        getJointValue: function(jointIndex) {
          const jointData = jointMap[jointIndex];
          if (jointData) {
            return jointData.position;
          } else {
            console.warn("THREE.ColladaLoader: Joint " + jointIndex + " doesn't exist.");
          }
        },
        setJointValue: function(jointIndex, value) {
          const jointData = jointMap[jointIndex];
          if (jointData) {
            const joint = jointData.joint;
            if (value > joint.limits.max || value < joint.limits.min) {
              console.warn("THREE.ColladaLoader: Joint " + jointIndex + " value " + value + " outside of limits (min: " + joint.limits.min + ", max: " + joint.limits.max + ").");
            } else if (joint.static) {
              console.warn("THREE.ColladaLoader: Joint " + jointIndex + " is static.");
            } else {
              const object = jointData.object;
              const axis = joint.axis;
              const transforms = jointData.transforms;
              matrix.identity();
              for (let i = 0; i < transforms.length; i++) {
                const transform = transforms[i];
                if (transform.sid && transform.sid.indexOf(jointIndex) !== -1) {
                  switch (joint.type) {
                    case "revolute":
                      matrix.multiply(m0.makeRotationAxis(axis, MathUtils.degToRad(value)));
                      break;
                    case "prismatic":
                      matrix.multiply(m0.makeTranslation(axis.x * value, axis.y * value, axis.z * value));
                      break;
                    default:
                      console.warn("THREE.ColladaLoader: Unknown joint type: " + joint.type);
                      break;
                  }
                } else {
                  switch (transform.type) {
                    case "matrix":
                      matrix.multiply(transform.obj);
                      break;
                    case "translate":
                      matrix.multiply(m0.makeTranslation(transform.obj.x, transform.obj.y, transform.obj.z));
                      break;
                    case "scale":
                      matrix.scale(transform.obj);
                      break;
                    case "rotate":
                      matrix.multiply(m0.makeRotationAxis(transform.obj, transform.angle));
                      break;
                  }
                }
              }
              object.matrix.copy(matrix);
              object.matrix.decompose(object.position, object.quaternion, object.scale);
              jointMap[jointIndex].position = value;
            }
          } else {
            console.log("THREE.ColladaLoader: " + jointIndex + " does not exist.");
          }
        }
      };
    }
    function buildTransformList(node) {
      const transforms = [];
      const xml2 = collada.querySelector('[id="' + node.id + '"]');
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        let array, vector2;
        switch (child.nodeName) {
          case "matrix":
            array = parseFloats(child.textContent);
            const matrix2 = new Matrix4().fromArray(array).transpose();
            transforms.push({
              sid: child.getAttribute("sid"),
              type: child.nodeName,
              obj: matrix2
            });
            break;
          case "translate":
          case "scale":
            array = parseFloats(child.textContent);
            vector2 = new Vector3().fromArray(array);
            transforms.push({
              sid: child.getAttribute("sid"),
              type: child.nodeName,
              obj: vector2
            });
            break;
          case "rotate":
            array = parseFloats(child.textContent);
            vector2 = new Vector3().fromArray(array);
            const angle = MathUtils.degToRad(array[3]);
            transforms.push({
              sid: child.getAttribute("sid"),
              type: child.nodeName,
              obj: vector2,
              angle
            });
            break;
        }
      }
      return transforms;
    }
    function prepareNodes(xml2) {
      const elements = xml2.getElementsByTagName("node");
      for (let i = 0; i < elements.length; i++) {
        const element = elements[i];
        if (element.hasAttribute("id") === false) {
          element.setAttribute("id", generateId());
        }
      }
    }
    const matrix = new Matrix4();
    const vector = new Vector3();
    function parseNode(xml2) {
      const data = {
        name: xml2.getAttribute("name") || "",
        type: xml2.getAttribute("type"),
        id: xml2.getAttribute("id"),
        sid: xml2.getAttribute("sid"),
        matrix: new Matrix4(),
        nodes: [],
        instanceCameras: [],
        instanceControllers: [],
        instanceLights: [],
        instanceGeometries: [],
        instanceNodes: [],
        transforms: {}
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        if (child.nodeType !== 1) continue;
        let array;
        switch (child.nodeName) {
          case "node":
            data.nodes.push(child.getAttribute("id"));
            parseNode(child);
            break;
          case "instance_camera":
            data.instanceCameras.push(parseId(child.getAttribute("url")));
            break;
          case "instance_controller":
            data.instanceControllers.push(parseNodeInstance(child));
            break;
          case "instance_light":
            data.instanceLights.push(parseId(child.getAttribute("url")));
            break;
          case "instance_geometry":
            data.instanceGeometries.push(parseNodeInstance(child));
            break;
          case "instance_node":
            data.instanceNodes.push(parseId(child.getAttribute("url")));
            break;
          case "matrix":
            array = parseFloats(child.textContent);
            data.matrix.multiply(matrix.fromArray(array).transpose());
            data.transforms[child.getAttribute("sid")] = child.nodeName;
            break;
          case "translate":
            array = parseFloats(child.textContent);
            vector.fromArray(array);
            data.matrix.multiply(matrix.makeTranslation(vector.x, vector.y, vector.z));
            data.transforms[child.getAttribute("sid")] = child.nodeName;
            break;
          case "rotate":
            array = parseFloats(child.textContent);
            const angle = MathUtils.degToRad(array[3]);
            data.matrix.multiply(matrix.makeRotationAxis(vector.fromArray(array), angle));
            data.transforms[child.getAttribute("sid")] = child.nodeName;
            break;
          case "scale":
            array = parseFloats(child.textContent);
            data.matrix.scale(vector.fromArray(array));
            data.transforms[child.getAttribute("sid")] = child.nodeName;
            break;
          case "extra":
            break;
          default:
            console.log(child);
        }
      }
      if (hasNode(data.id)) {
        console.warn("THREE.ColladaLoader: There is already a node with ID %s. Exclude current node from further processing.", data.id);
      } else {
        library.nodes[data.id] = data;
      }
      return data;
    }
    function parseNodeInstance(xml2) {
      const data = {
        id: parseId(xml2.getAttribute("url")),
        materials: {},
        skeletons: []
      };
      for (let i = 0; i < xml2.childNodes.length; i++) {
        const child = xml2.childNodes[i];
        switch (child.nodeName) {
          case "bind_material":
            const instances = child.getElementsByTagName("instance_material");
            for (let j = 0; j < instances.length; j++) {
              const instance = instances[j];
              const symbol = instance.getAttribute("symbol");
              const target = instance.getAttribute("target");
              data.materials[symbol] = parseId(target);
            }
            break;
          case "skeleton":
            data.skeletons.push(parseId(child.textContent));
            break;
          default:
            break;
        }
      }
      return data;
    }
    function buildSkeleton(skeletons, joints) {
      const boneData = [];
      const sortedBoneData = [];
      let i, j, data;
      for (i = 0; i < skeletons.length; i++) {
        const skeleton = skeletons[i];
        let root;
        if (hasNode(skeleton)) {
          root = getNode(skeleton);
          buildBoneHierarchy(root, joints, boneData);
        } else if (hasVisualScene(skeleton)) {
          const visualScene = library.visualScenes[skeleton];
          const children = visualScene.children;
          for (let j2 = 0; j2 < children.length; j2++) {
            const child = children[j2];
            if (child.type === "JOINT") {
              const root2 = getNode(child.id);
              buildBoneHierarchy(root2, joints, boneData);
            }
          }
        } else {
          console.error("THREE.ColladaLoader: Unable to find root bone of skeleton with ID:", skeleton);
        }
      }
      for (i = 0; i < joints.length; i++) {
        for (j = 0; j < boneData.length; j++) {
          data = boneData[j];
          if (data.bone.name === joints[i].name) {
            sortedBoneData[i] = data;
            data.processed = true;
            break;
          }
        }
      }
      for (i = 0; i < boneData.length; i++) {
        data = boneData[i];
        if (data.processed === false) {
          sortedBoneData.push(data);
          data.processed = true;
        }
      }
      const bones = [];
      const boneInverses = [];
      for (i = 0; i < sortedBoneData.length; i++) {
        data = sortedBoneData[i];
        bones.push(data.bone);
        boneInverses.push(data.boneInverse);
      }
      return new Skeleton(bones, boneInverses);
    }
    function buildBoneHierarchy(root, joints, boneData) {
      root.traverse(function(object) {
        if (object.isBone === true) {
          let boneInverse;
          for (let i = 0; i < joints.length; i++) {
            const joint = joints[i];
            if (joint.name === object.name) {
              boneInverse = joint.boneInverse;
              break;
            }
          }
          if (boneInverse === void 0) {
            boneInverse = new Matrix4();
          }
          boneData.push({ bone: object, boneInverse, processed: false });
        }
      });
    }
    function buildNode(data) {
      const objects = [];
      const matrix2 = data.matrix;
      const nodes = data.nodes;
      const type = data.type;
      const instanceCameras = data.instanceCameras;
      const instanceControllers = data.instanceControllers;
      const instanceLights = data.instanceLights;
      const instanceGeometries = data.instanceGeometries;
      const instanceNodes = data.instanceNodes;
      for (let i = 0, l = nodes.length; i < l; i++) {
        objects.push(getNode(nodes[i]));
      }
      for (let i = 0, l = instanceCameras.length; i < l; i++) {
        const instanceCamera = getCamera(instanceCameras[i]);
        if (instanceCamera !== null) {
          objects.push(instanceCamera.clone());
        }
      }
      for (let i = 0, l = instanceControllers.length; i < l; i++) {
        const instance = instanceControllers[i];
        const controller = getController(instance.id);
        const geometries = getGeometry(controller.id);
        const newObjects = buildObjects(geometries, instance.materials);
        const skeletons = instance.skeletons;
        const joints = controller.skin.joints;
        const skeleton = buildSkeleton(skeletons, joints);
        for (let j = 0, jl = newObjects.length; j < jl; j++) {
          const object2 = newObjects[j];
          if (object2.isSkinnedMesh) {
            object2.bind(skeleton, controller.skin.bindMatrix);
            object2.normalizeSkinWeights();
          }
          objects.push(object2);
        }
      }
      for (let i = 0, l = instanceLights.length; i < l; i++) {
        const instanceLight = getLight(instanceLights[i]);
        if (instanceLight !== null) {
          objects.push(instanceLight.clone());
        }
      }
      for (let i = 0, l = instanceGeometries.length; i < l; i++) {
        const instance = instanceGeometries[i];
        const geometries = getGeometry(instance.id);
        const newObjects = buildObjects(geometries, instance.materials);
        for (let j = 0, jl = newObjects.length; j < jl; j++) {
          objects.push(newObjects[j]);
        }
      }
      for (let i = 0, l = instanceNodes.length; i < l; i++) {
        objects.push(getNode(instanceNodes[i]).clone());
      }
      let object;
      if (nodes.length === 0 && objects.length === 1) {
        object = objects[0];
      } else {
        object = type === "JOINT" ? new Bone() : new Group();
        for (let i = 0; i < objects.length; i++) {
          object.add(objects[i]);
        }
      }
      object.name = type === "JOINT" ? data.sid : data.name;
      object.matrix.copy(matrix2);
      object.matrix.decompose(object.position, object.quaternion, object.scale);
      return object;
    }
    const fallbackMaterial = new MeshBasicMaterial({
      name: Loader.DEFAULT_MATERIAL_NAME,
      color: 16711935
    });
    function resolveMaterialBinding(keys, instanceMaterials) {
      const materials = [];
      for (let i = 0, l = keys.length; i < l; i++) {
        const id = instanceMaterials[keys[i]];
        if (id === void 0) {
          console.warn("THREE.ColladaLoader: Material with key %s not found. Apply fallback material.", keys[i]);
          materials.push(fallbackMaterial);
        } else {
          materials.push(getMaterial(id));
        }
      }
      return materials;
    }
    function buildObjects(geometries, instanceMaterials) {
      const objects = [];
      for (const type in geometries) {
        const geometry = geometries[type];
        const materials = resolveMaterialBinding(geometry.materialKeys, instanceMaterials);
        if (materials.length === 0) {
          if (type === "lines" || type === "linestrips") {
            materials.push(new LineBasicMaterial());
          } else {
            materials.push(new MeshPhongMaterial());
          }
        }
        if (type === "lines" || type === "linestrips") {
          for (let i = 0, l = materials.length; i < l; i++) {
            const material2 = materials[i];
            if (material2.isMeshPhongMaterial === true || material2.isMeshLambertMaterial === true) {
              const lineMaterial = new LineBasicMaterial();
              lineMaterial.color.copy(material2.color);
              lineMaterial.opacity = material2.opacity;
              lineMaterial.transparent = material2.transparent;
              materials[i] = lineMaterial;
            }
          }
        }
        const skinning = geometry.data.attributes.skinIndex !== void 0;
        const material = materials.length === 1 ? materials[0] : materials;
        let object;
        switch (type) {
          case "lines":
            object = new LineSegments(geometry.data, material);
            break;
          case "linestrips":
            object = new Line(geometry.data, material);
            break;
          case "triangles":
          case "polylist":
            if (skinning) {
              object = new SkinnedMesh(geometry.data, material);
            } else {
              object = new Mesh(geometry.data, material);
            }
            break;
        }
        objects.push(object);
      }
      return objects;
    }
    function hasNode(id) {
      return library.nodes[id] !== void 0;
    }
    function getNode(id) {
      return getBuild(library.nodes[id], buildNode);
    }
    function parseVisualScene(xml2) {
      const data = {
        name: xml2.getAttribute("name"),
        children: []
      };
      prepareNodes(xml2);
      const elements = getElementsByTagName(xml2, "node");
      for (let i = 0; i < elements.length; i++) {
        data.children.push(parseNode(elements[i]));
      }
      library.visualScenes[xml2.getAttribute("id")] = data;
    }
    function buildVisualScene(data) {
      const group = new Group();
      group.name = data.name;
      const children = data.children;
      for (let i = 0; i < children.length; i++) {
        const child = children[i];
        group.add(getNode(child.id));
      }
      return group;
    }
    function hasVisualScene(id) {
      return library.visualScenes[id] !== void 0;
    }
    function getVisualScene(id) {
      return getBuild(library.visualScenes[id], buildVisualScene);
    }
    function parseScene(xml2) {
      const instance = getElementsByTagName(xml2, "instance_visual_scene")[0];
      return getVisualScene(parseId(instance.getAttribute("url")));
    }
    function setupAnimations() {
      const clips = library.clips;
      if (isEmpty(clips) === true) {
        if (isEmpty(library.animations) === false) {
          const tracks = [];
          for (const id in library.animations) {
            const animationTracks = getAnimation(id);
            for (let i = 0, l = animationTracks.length; i < l; i++) {
              tracks.push(animationTracks[i]);
            }
          }
          animations.push(new AnimationClip("default", -1, tracks));
        }
      } else {
        for (const id in clips) {
          animations.push(getAnimationClip(id));
        }
      }
    }
    function parserErrorToText(parserError2) {
      let result = "";
      const stack = [parserError2];
      while (stack.length) {
        const node = stack.shift();
        if (node.nodeType === Node.TEXT_NODE) {
          result += node.textContent;
        } else {
          result += "\n";
          stack.push(...node.childNodes);
        }
      }
      return result.trim();
    }
    if (text.length === 0) {
      return { scene: new Scene() };
    }
    const xml = new DOMParser().parseFromString(text, "application/xml");
    const collada = getElementsByTagName(xml, "COLLADA")[0];
    const parserError = xml.getElementsByTagName("parsererror")[0];
    if (parserError !== void 0) {
      const errorElement = getElementsByTagName(parserError, "div")[0];
      let errorText;
      if (errorElement) {
        errorText = errorElement.textContent;
      } else {
        errorText = parserErrorToText(parserError);
      }
      console.error("THREE.ColladaLoader: Failed to parse collada file.\n", errorText);
      return null;
    }
    const version = collada.getAttribute("version");
    console.debug("THREE.ColladaLoader: File version", version);
    const asset = parseAsset(getElementsByTagName(collada, "asset")[0]);
    const textureLoader = new TextureLoader(this.manager);
    textureLoader.setPath(this.resourcePath || path).setCrossOrigin(this.crossOrigin);
    let tgaLoader;
    if (TGALoader) {
      tgaLoader = new TGALoader(this.manager);
      tgaLoader.setPath(this.resourcePath || path);
    }
    const tempColor = new Color();
    const animations = [];
    let kinematics = {};
    let count = 0;
    const library = {
      animations: {},
      clips: {},
      controllers: {},
      images: {},
      effects: {},
      materials: {},
      cameras: {},
      lights: {},
      geometries: {},
      nodes: {},
      visualScenes: {},
      kinematicsModels: {},
      physicsModels: {},
      kinematicsScenes: {}
    };
    parseLibrary(collada, "library_animations", "animation", parseAnimation);
    parseLibrary(collada, "library_animation_clips", "animation_clip", parseAnimationClip);
    parseLibrary(collada, "library_controllers", "controller", parseController);
    parseLibrary(collada, "library_images", "image", parseImage);
    parseLibrary(collada, "library_effects", "effect", parseEffect);
    parseLibrary(collada, "library_materials", "material", parseMaterial);
    parseLibrary(collada, "library_cameras", "camera", parseCamera);
    parseLibrary(collada, "library_lights", "light", parseLight);
    parseLibrary(collada, "library_geometries", "geometry", parseGeometry);
    parseLibrary(collada, "library_nodes", "node", parseNode);
    parseLibrary(collada, "library_visual_scenes", "visual_scene", parseVisualScene);
    parseLibrary(collada, "library_kinematics_models", "kinematics_model", parseKinematicsModel);
    parseLibrary(collada, "library_physics_models", "physics_model", parsePhysicsModel);
    parseLibrary(collada, "scene", "instance_kinematics_scene", parseKinematicsScene);
    buildLibrary(library.animations, buildAnimation);
    buildLibrary(library.clips, buildAnimationClip);
    buildLibrary(library.controllers, buildController);
    buildLibrary(library.images, buildImage);
    buildLibrary(library.effects, buildEffect);
    buildLibrary(library.materials, buildMaterial);
    buildLibrary(library.cameras, buildCamera);
    buildLibrary(library.lights, buildLight);
    buildLibrary(library.geometries, buildGeometry);
    buildLibrary(library.visualScenes, buildVisualScene);
    setupAnimations();
    setupKinematics();
    const scene = parseScene(getElementsByTagName(collada, "scene")[0]);
    scene.animations = animations;
    if (asset.upAxis === "Z_UP") {
      console.warn("THREE.ColladaLoader: You are loading an asset with a Z-UP coordinate system. The loader just rotates the asset to transform it into Y-UP. The vertex data are not converted, see #24289.");
      scene.rotation.set(-Math.PI / 2, 0, 0);
    }
    scene.scale.multiplyScalar(asset.unit);
    return {
      get animations() {
        console.warn("THREE.ColladaLoader: Please access animations over scene.animations now.");
        return animations;
      },
      kinematics,
      library,
      scene
    };
  }
};
export {
  ColladaLoader
};
//# sourceMappingURL=three_examples_jsm_loaders_ColladaLoader__js.js.map
