{"version":3,"file":"game.js","sources":["../../../node_modules/bitecs/dist/index.mjs","../../../node_modules/three/build/three.module.js","../../../node_modules/@esotericsoftware/spine-threejs/dist/require-shim.js","../../../node_modules/@esotericsoftware/spine-core/dist/Utils.js","../../../node_modules/@esotericsoftware/spine-core/dist/attachments/Attachment.js","../../../node_modules/@esotericsoftware/spine-core/dist/attachments/Sequence.js","../../../node_modules/@esotericsoftware/spine-core/dist/Animation.js","../../../node_modules/@esotericsoftware/spine-core/dist/AnimationState.js","../../../node_modules/@esotericsoftware/spine-core/dist/AnimationStateData.js","../../../node_modules/@esotericsoftware/spine-core/dist/attachments/BoundingBoxAttachment.js","../../../node_modules/@esotericsoftware/spine-core/dist/attachments/ClippingAttachment.js","../../../node_modules/@esotericsoftware/spine-core/dist/Texture.js","../../../node_modules/@esotericsoftware/spine-core/dist/TextureAtlas.js","../../../node_modules/@esotericsoftware/spine-core/dist/attachments/MeshAttachment.js","../../../node_modules/@esotericsoftware/spine-core/dist/attachments/PathAttachment.js","../../../node_modules/@esotericsoftware/spine-core/dist/attachments/PointAttachment.js","../../../node_modules/@esotericsoftware/spine-core/dist/attachments/RegionAttachment.js","../../../node_modules/@esotericsoftware/spine-core/dist/AtlasAttachmentLoader.js","../../../node_modules/@esotericsoftware/spine-core/dist/BoneData.js","../../../node_modules/@esotericsoftware/spine-core/dist/Bone.js","../../../node_modules/@esotericsoftware/spine-core/dist/ConstraintData.js","../../../node_modules/@esotericsoftware/spine-core/dist/AssetManagerBase.js","../../../node_modules/@esotericsoftware/spine-core/dist/Event.js","../../../node_modules/@esotericsoftware/spine-core/dist/EventData.js","../../../node_modules/@esotericsoftware/spine-core/dist/IkConstraint.js","../../../node_modules/@esotericsoftware/spine-core/dist/IkConstraintData.js","../../../node_modules/@esotericsoftware/spine-core/dist/PathConstraintData.js","../../../node_modules/@esotericsoftware/spine-core/dist/PathConstraint.js","../../../node_modules/@esotericsoftware/spine-core/dist/PhysicsConstraint.js","../../../node_modules/@esotericsoftware/spine-core/dist/Slot.js","../../../node_modules/@esotericsoftware/spine-core/dist/TransformConstraint.js","../../../node_modules/@esotericsoftware/spine-core/dist/Skeleton.js","../../../node_modules/@esotericsoftware/spine-core/dist/PhysicsConstraintData.js","../../../node_modules/@esotericsoftware/spine-core/dist/SkeletonData.js","../../../node_modules/@esotericsoftware/spine-core/dist/Skin.js","../../../node_modules/@esotericsoftware/spine-core/dist/SlotData.js","../../../node_modules/@esotericsoftware/spine-core/dist/TransformConstraintData.js","../../../node_modules/@esotericsoftware/spine-core/dist/SkeletonBinary.js","../../../node_modules/@esotericsoftware/spine-core/dist/Triangulator.js","../../../node_modules/@esotericsoftware/spine-core/dist/SkeletonClipping.js","../../../node_modules/@esotericsoftware/spine-core/dist/SkeletonJson.js","../../../node_modules/@esotericsoftware/spine-core/dist/polyfills.js","../../../node_modules/@esotericsoftware/spine-threejs/dist/ThreeJsTexture.js","../../../node_modules/@esotericsoftware/spine-threejs/dist/AssetManager.js","../../../node_modules/@esotericsoftware/spine-threejs/dist/SkeletonMesh.js","../../../node_modules/@esotericsoftware/spine-threejs/dist/MeshBatcher.js","../constants.ts","../components.ts","../../../node_modules/three/examples/jsm/loaders/GLTFLoader.js","../factory/object.ts","../factory/world.ts","../../../node_modules/systemjs/dist/system.min.js","../../../node_modules/imgui-js/build/bind-imgui.js","../../../node_modules/imgui-js/src/imgui.ts","../../../node_modules/imgui-js/example/src/imgui_impl.ts","../systems/time.ts","../../../node_modules/three/examples/jsm/shaders/CopyShader.js","../../../node_modules/three/examples/jsm/postprocessing/Pass.js","../../../node_modules/three/examples/jsm/postprocessing/ShaderPass.js","../../../node_modules/three/examples/jsm/postprocessing/MaskPass.js","../../../node_modules/three/examples/jsm/postprocessing/EffectComposer.js","../../../node_modules/three/examples/jsm/postprocessing/RenderPass.js","../../../node_modules/three/examples/jsm/postprocessing/OutlinePass.js","../systems/render.ts","../../../node_modules/@yandeu/events/cjs/version.js","../../../node_modules/@yandeu/events/cjs/index.js","../../../node_modules/@geckos.io/common/lib/bridge.js","../../../node_modules/@geckos.io/common/lib/constants.js","../../../node_modules/@geckos.io/common/lib/types.js","../../../node_modules/@geckos.io/common/lib/helpers.js","../../../node_modules/@geckos.io/common/lib/parseMessage.js","../../../node_modules/@geckos.io/common/lib/sendMessage.js","../../../node_modules/@geckos.io/client/lib/wrtc/connectionsManager.js","../../../node_modules/@geckos.io/client/lib/wrtc/peerConnection.js","../../../node_modules/@geckos.io/common/lib/makeRandomId.js","../../../node_modules/@geckos.io/common/lib/runInterval.js","../../../node_modules/@geckos.io/common/lib/reliableMessage.js","../../../node_modules/@geckos.io/client/lib/geckos/channel.js","../systems/animation.ts","../factory/player.ts","../../../node_modules/jsx-dom/index.js","../ui/disconnect.tsx","../ui/nameplate.tsx","../factory/nameplate.ts","../ui/chatmessage.tsx","../factory/chatmessage.ts","../systems/network.ts","../systems/movement.ts","../ui/toolbar.tsx","../systems/ui.ts","../../../node_modules/three/examples/jsm/loaders/SVGLoader.js","../ui/contextmenu.tsx","../ui/playercontextmenu.tsx","../systems/control.ts","../systems/imgui.ts","../../../node_modules/three/examples/jsm/controls/OrbitControls.js","../../../node_modules/three/examples/jsm/controls/TransformControls.js","../systems/editor.ts","../factory/systems.ts","../htmx.ts","../main.ts"],"sourcesContent":["// src/Constants.js\nvar TYPES_ENUM = {\n i8: \"i8\",\n ui8: \"ui8\",\n ui8c: \"ui8c\",\n i16: \"i16\",\n ui16: \"ui16\",\n i32: \"i32\",\n ui32: \"ui32\",\n f32: \"f32\",\n f64: \"f64\",\n eid: \"eid\"\n};\nvar TYPES_NAMES = {\n i8: \"Int8\",\n ui8: \"Uint8\",\n ui8c: \"Uint8Clamped\",\n i16: \"Int16\",\n ui16: \"Uint16\",\n i32: \"Int32\",\n ui32: \"Uint32\",\n eid: \"Uint32\",\n f32: \"Float32\",\n f64: \"Float64\"\n};\nvar TYPES = {\n i8: Int8Array,\n ui8: Uint8Array,\n ui8c: Uint8ClampedArray,\n i16: Int16Array,\n ui16: Uint16Array,\n i32: Int32Array,\n ui32: Uint32Array,\n f32: Float32Array,\n f64: Float64Array,\n eid: Uint32Array\n};\nvar UNSIGNED_MAX = {\n uint8: 2 ** 8,\n uint16: 2 ** 16,\n uint32: 2 ** 32\n};\n\n// src/Storage.js\nvar roundToMultiple = (mul) => (x) => Math.ceil(x / mul) * mul;\nvar roundToMultiple4 = roundToMultiple(4);\nvar $storeRef = Symbol(\"storeRef\");\nvar $storeSize = Symbol(\"storeSize\");\nvar $storeMaps = Symbol(\"storeMaps\");\nvar $storeFlattened = Symbol(\"storeFlattened\");\nvar $storeBase = Symbol(\"storeBase\");\nvar $storeType = Symbol(\"storeType\");\nvar $storeArrayElementCounts = Symbol(\"storeArrayElementCounts\");\nvar $storeSubarrays = Symbol(\"storeSubarrays\");\nvar $subarrayCursors = Symbol(\"subarrayCursors\");\nvar $subarray = Symbol(\"subarray\");\nvar $subarrayFrom = Symbol(\"subarrayFrom\");\nvar $subarrayTo = Symbol(\"subarrayTo\");\nvar $parentArray = Symbol(\"parentArray\");\nvar $tagStore = Symbol(\"tagStore\");\nvar $queryShadow = Symbol(\"queryShadow\");\nvar $serializeShadow = Symbol(\"serializeShadow\");\nvar $indexType = Symbol(\"indexType\");\nvar $indexBytes = Symbol(\"indexBytes\");\nvar $isEidType = Symbol(\"isEidType\");\nvar stores = {};\nvar resize = (ta, size) => {\n const newBuffer = new ArrayBuffer(size * ta.BYTES_PER_ELEMENT);\n const newTa = new ta.constructor(newBuffer);\n newTa.set(ta, 0);\n return newTa;\n};\nvar createShadow = (store, key) => {\n if (!ArrayBuffer.isView(store)) {\n const shadowStore = store[$parentArray].slice(0);\n store[key] = store.map((_, eid) => {\n const { length } = store[eid];\n const start = length * eid;\n const end = start + length;\n return shadowStore.subarray(start, end);\n });\n } else {\n store[key] = store.slice(0);\n }\n};\nvar resetStoreFor = (store, eid) => {\n if (store[$storeFlattened]) {\n store[$storeFlattened].forEach((ta) => {\n if (ArrayBuffer.isView(ta))\n ta[eid] = 0;\n else\n ta[eid].fill(0);\n });\n }\n};\nvar createTypeStore = (type, length) => {\n const totalBytes = length * TYPES[type].BYTES_PER_ELEMENT;\n const buffer = new ArrayBuffer(totalBytes);\n const store = new TYPES[type](buffer);\n store[$isEidType] = type === TYPES_ENUM.eid;\n return store;\n};\nvar parentArray = (store) => store[$parentArray];\nvar createArrayStore = (metadata, type, length) => {\n const storeSize = metadata[$storeSize];\n const store = Array(storeSize).fill(0);\n store[$storeType] = type;\n store[$isEidType] = type === TYPES_ENUM.eid;\n const cursors = metadata[$subarrayCursors];\n const indexType = length <= UNSIGNED_MAX.uint8 ? TYPES_ENUM.ui8 : length <= UNSIGNED_MAX.uint16 ? TYPES_ENUM.ui16 : TYPES_ENUM.ui32;\n if (!length)\n throw new Error(\"bitECS - Must define component array length\");\n if (!TYPES[type])\n throw new Error(`bitECS - Invalid component array property type ${type}`);\n if (!metadata[$storeSubarrays][type]) {\n const arrayElementCount = metadata[$storeArrayElementCounts][type];\n const array = new TYPES[type](roundToMultiple4(arrayElementCount * storeSize));\n array[$indexType] = TYPES_NAMES[indexType];\n array[$indexBytes] = TYPES[indexType].BYTES_PER_ELEMENT;\n metadata[$storeSubarrays][type] = array;\n }\n const start = cursors[type];\n const end = start + storeSize * length;\n cursors[type] = end;\n store[$parentArray] = metadata[$storeSubarrays][type].subarray(start, end);\n for (let eid = 0; eid < storeSize; eid++) {\n const start2 = length * eid;\n const end2 = start2 + length;\n store[eid] = store[$parentArray].subarray(start2, end2);\n store[eid][$indexType] = TYPES_NAMES[indexType];\n store[eid][$indexBytes] = TYPES[indexType].BYTES_PER_ELEMENT;\n store[eid][$subarray] = true;\n }\n return store;\n};\nvar isArrayType = (x) => Array.isArray(x) && typeof x[0] === \"string\" && typeof x[1] === \"number\";\nvar createStore = (schema, size) => {\n const $store = Symbol(\"store\");\n if (!schema || !Object.keys(schema).length) {\n stores[$store] = {\n [$storeSize]: size,\n [$tagStore]: true,\n [$storeBase]: () => stores[$store]\n };\n return stores[$store];\n }\n schema = JSON.parse(JSON.stringify(schema));\n const arrayElementCounts = {};\n const collectArrayElementCounts = (s) => {\n const keys = Object.keys(s);\n for (const k of keys) {\n if (isArrayType(s[k])) {\n if (!arrayElementCounts[s[k][0]])\n arrayElementCounts[s[k][0]] = 0;\n arrayElementCounts[s[k][0]] += s[k][1];\n } else if (s[k] instanceof Object) {\n collectArrayElementCounts(s[k]);\n }\n }\n };\n collectArrayElementCounts(schema);\n const metadata = {\n [$storeSize]: size,\n [$storeMaps]: {},\n [$storeSubarrays]: {},\n [$storeRef]: $store,\n [$subarrayCursors]: Object.keys(TYPES).reduce((a, type) => ({ ...a, [type]: 0 }), {}),\n [$storeFlattened]: [],\n [$storeArrayElementCounts]: arrayElementCounts\n };\n if (schema instanceof Object && Object.keys(schema).length) {\n const recursiveTransform = (a, k) => {\n if (typeof a[k] === \"string\") {\n a[k] = createTypeStore(a[k], size);\n a[k][$storeBase] = () => stores[$store];\n metadata[$storeFlattened].push(a[k]);\n } else if (isArrayType(a[k])) {\n const [type, length] = a[k];\n a[k] = createArrayStore(metadata, type, length);\n a[k][$storeBase] = () => stores[$store];\n metadata[$storeFlattened].push(a[k]);\n } else if (a[k] instanceof Object) {\n a[k] = Object.keys(a[k]).reduce(recursiveTransform, a[k]);\n }\n return a;\n };\n stores[$store] = Object.assign(Object.keys(schema).reduce(recursiveTransform, schema), metadata);\n stores[$store][$storeBase] = () => stores[$store];\n return stores[$store];\n }\n};\n\n// src/Util.js\nvar SparseSet = () => {\n const dense = [];\n const sparse = [];\n dense.sort = function(comparator) {\n const result = Array.prototype.sort.call(this, comparator);\n for (let i = 0; i < dense.length; i++) {\n sparse[dense[i]] = i;\n }\n return result;\n };\n const has = (val) => dense[sparse[val]] === val;\n const add = (val) => {\n if (has(val))\n return;\n sparse[val] = dense.push(val) - 1;\n };\n const remove = (val) => {\n if (!has(val))\n return;\n const index = sparse[val];\n const swapped = dense.pop();\n if (swapped !== val) {\n dense[index] = swapped;\n sparse[swapped] = index;\n }\n };\n const reset = () => {\n dense.length = 0;\n sparse.length = 0;\n };\n return {\n add,\n remove,\n has,\n sparse,\n dense,\n reset\n };\n};\n\n// src/Serialize.js\nvar DESERIALIZE_MODE = {\n REPLACE: 0,\n APPEND: 1,\n MAP: 2\n};\nvar resized = false;\nvar setSerializationResized = (v) => {\n resized = v;\n};\nvar concat = (a, v) => a.concat(v);\nvar not = (fn) => (v) => !fn(v);\nvar storeFlattened = (c) => c[$storeFlattened];\nvar isFullComponent = storeFlattened;\nvar isProperty = not(isFullComponent);\nvar isModifier = (c) => typeof c === \"function\" && c[$modifier];\nvar isNotModifier = not(isModifier);\nvar isChangedModifier = (c) => isModifier(c) && c()[1] === \"changed\";\nvar isWorld = (w) => Object.getOwnPropertySymbols(w).includes($componentMap);\nvar fromModifierToComponent = (c) => c()[0];\nvar canonicalize = (target) => {\n if (isWorld(target))\n return [[], /* @__PURE__ */ new Map()];\n const fullComponentProps = target.filter(isNotModifier).filter(isFullComponent).map(storeFlattened).reduce(concat, []);\n const changedComponentProps = target.filter(isChangedModifier).map(fromModifierToComponent).filter(isFullComponent).map(storeFlattened).reduce(concat, []);\n const props = target.filter(isNotModifier).filter(isProperty);\n const changedProps = target.filter(isChangedModifier).map(fromModifierToComponent).filter(isProperty);\n const componentProps = [...fullComponentProps, ...props, ...changedComponentProps, ...changedProps];\n const allChangedProps = [...changedComponentProps, ...changedProps].reduce((map, prop) => {\n const $ = Symbol();\n createShadow(prop, $);\n map.set(prop, $);\n return map;\n }, /* @__PURE__ */ new Map());\n return [componentProps, allChangedProps];\n};\nvar defineSerializer = (target, maxBytes = 2e7) => {\n const worldSerializer = isWorld(target);\n let [componentProps, changedProps] = canonicalize(target);\n const buffer = new ArrayBuffer(maxBytes);\n const view = new DataView(buffer);\n const entityComponentCache = /* @__PURE__ */ new Map();\n return (ents) => {\n if (resized) {\n [componentProps, changedProps] = canonicalize(target);\n resized = false;\n }\n if (worldSerializer) {\n componentProps = [];\n target[$componentMap].forEach((c, component) => {\n if (component[$storeFlattened])\n componentProps.push(...component[$storeFlattened]);\n else\n componentProps.push(component);\n });\n }\n let world;\n if (Object.getOwnPropertySymbols(ents).includes($componentMap)) {\n world = ents;\n ents = ents[$entityArray];\n } else {\n world = eidToWorld.get(ents[0]);\n }\n let where = 0;\n if (!ents.length)\n return buffer.slice(0, where);\n const cache = /* @__PURE__ */ new Map();\n for (let pid = 0; pid < componentProps.length; pid++) {\n const prop = componentProps[pid];\n const component = prop[$storeBase]();\n const $diff = changedProps.get(prop);\n const shadow = $diff ? prop[$diff] : null;\n if (!cache.has(component))\n cache.set(component, /* @__PURE__ */ new Map());\n view.setUint8(where, pid);\n where += 1;\n const countWhere = where;\n where += 4;\n let writeCount = 0;\n for (let i = 0; i < ents.length; i++) {\n const eid = ents[i];\n let componentCache = entityComponentCache.get(eid);\n if (!componentCache)\n componentCache = entityComponentCache.set(eid, /* @__PURE__ */ new Set()).get(eid);\n componentCache.add(eid);\n const newlyAddedComponent = shadow && cache.get(component).get(eid) || !componentCache.has(component) && hasComponent(world, component, eid);\n cache.get(component).set(eid, newlyAddedComponent);\n if (newlyAddedComponent) {\n componentCache.add(component);\n } else if (!hasComponent(world, component, eid)) {\n componentCache.delete(component);\n continue;\n }\n const rewindWhere = where;\n view.setUint32(where, eid);\n where += 4;\n if (prop[$tagStore]) {\n writeCount++;\n continue;\n }\n if (ArrayBuffer.isView(prop[eid])) {\n const type = prop[eid].constructor.name.replace(\"Array\", \"\");\n const indexType = prop[eid][$indexType];\n const indexBytes = prop[eid][$indexBytes];\n const countWhere2 = where;\n where += indexBytes;\n let arrayWriteCount = 0;\n for (let i2 = 0; i2 < prop[eid].length; i2++) {\n if (shadow) {\n const changed = shadow[eid][i2] !== prop[eid][i2];\n shadow[eid][i2] = prop[eid][i2];\n if (!changed && !newlyAddedComponent) {\n continue;\n }\n }\n view[`set${indexType}`](where, i2);\n where += indexBytes;\n const value = prop[eid][i2];\n view[`set${type}`](where, value);\n where += prop[eid].BYTES_PER_ELEMENT;\n arrayWriteCount++;\n }\n if (arrayWriteCount > 0) {\n view[`set${indexType}`](countWhere2, arrayWriteCount);\n writeCount++;\n } else {\n where = rewindWhere;\n continue;\n }\n } else {\n if (shadow) {\n const changed = shadow[eid] !== prop[eid];\n shadow[eid] = prop[eid];\n if (!changed && !newlyAddedComponent) {\n where = rewindWhere;\n continue;\n }\n }\n const type = prop.constructor.name.replace(\"Array\", \"\");\n view[`set${type}`](where, prop[eid]);\n where += prop.BYTES_PER_ELEMENT;\n writeCount++;\n }\n }\n if (writeCount > 0) {\n view.setUint32(countWhere, writeCount);\n } else {\n where -= 5;\n }\n }\n return buffer.slice(0, where);\n };\n};\nvar newEntities = /* @__PURE__ */ new Map();\nvar defineDeserializer = (target) => {\n const isWorld2 = Object.getOwnPropertySymbols(target).includes($componentMap);\n let [componentProps] = canonicalize(target);\n const deserializedEntities = /* @__PURE__ */ new Set();\n return (world, packet, mode = 0) => {\n newEntities.clear();\n if (resized) {\n [componentProps] = canonicalize(target);\n resized = false;\n }\n if (isWorld2) {\n componentProps = [];\n target[$componentMap].forEach((c, component) => {\n if (component[$storeFlattened])\n componentProps.push(...component[$storeFlattened]);\n else\n componentProps.push(component);\n });\n }\n const localEntities = world[$localEntities];\n const localEntityLookup = world[$localEntityLookup];\n const view = new DataView(packet);\n let where = 0;\n while (where < packet.byteLength) {\n const pid = view.getUint8(where);\n where += 1;\n const entityCount = view.getUint32(where);\n where += 4;\n const prop = componentProps[pid];\n for (let i = 0; i < entityCount; i++) {\n let eid = view.getUint32(where);\n where += 4;\n if (mode === DESERIALIZE_MODE.MAP) {\n if (localEntities.has(eid)) {\n eid = localEntities.get(eid);\n } else if (newEntities.has(eid)) {\n eid = newEntities.get(eid);\n } else {\n const newEid = addEntity(world);\n localEntities.set(eid, newEid);\n localEntityLookup.set(newEid, eid);\n newEntities.set(eid, newEid);\n eid = newEid;\n }\n }\n if (mode === DESERIALIZE_MODE.APPEND || mode === DESERIALIZE_MODE.REPLACE && !world[$entitySparseSet].has(eid)) {\n const newEid = newEntities.get(eid) || addEntity(world);\n newEntities.set(eid, newEid);\n eid = newEid;\n }\n const component = prop[$storeBase]();\n if (!hasComponent(world, component, eid)) {\n addComponent(world, component, eid);\n }\n deserializedEntities.add(eid);\n if (component[$tagStore]) {\n continue;\n }\n if (ArrayBuffer.isView(prop[eid])) {\n const array = prop[eid];\n const count = view[`get${array[$indexType]}`](where);\n where += array[$indexBytes];\n for (let i2 = 0; i2 < count; i2++) {\n const index = view[`get${array[$indexType]}`](where);\n where += array[$indexBytes];\n const value = view[`get${array.constructor.name.replace(\"Array\", \"\")}`](where);\n where += array.BYTES_PER_ELEMENT;\n if (prop[$isEidType]) {\n let localEid;\n if (localEntities.has(value)) {\n localEid = localEntities.get(value);\n } else if (newEntities.has(value)) {\n localEid = newEntities.get(value);\n } else {\n const newEid = addEntity(world);\n localEntities.set(value, newEid);\n localEntityLookup.set(newEid, value);\n newEntities.set(value, newEid);\n localEid = newEid;\n }\n prop[eid][index] = localEid;\n } else\n prop[eid][index] = value;\n }\n } else {\n const value = view[`get${prop.constructor.name.replace(\"Array\", \"\")}`](where);\n where += prop.BYTES_PER_ELEMENT;\n if (prop[$isEidType]) {\n let localEid;\n if (localEntities.has(value)) {\n localEid = localEntities.get(value);\n } else if (newEntities.has(value)) {\n localEid = newEntities.get(value);\n } else {\n const newEid = addEntity(world);\n localEntities.set(value, newEid);\n localEntityLookup.set(newEid, value);\n newEntities.set(value, newEid);\n localEid = newEid;\n }\n prop[eid] = localEid;\n } else\n prop[eid] = value;\n }\n }\n }\n const ents = Array.from(deserializedEntities);\n deserializedEntities.clear();\n return ents;\n };\n};\n\n// src/Entity.js\nvar $entityMasks = Symbol(\"entityMasks\");\nvar $entityComponents = Symbol(\"entityComponents\");\nvar $entitySparseSet = Symbol(\"entitySparseSet\");\nvar $entityArray = Symbol(\"entityArray\");\nvar $entityIndices = Symbol(\"entityIndices\");\nvar $removedEntities = Symbol(\"removedEntities\");\nvar defaultSize = 1e5;\nvar globalEntityCursor = 0;\nvar globalSize = defaultSize;\nvar getGlobalSize = () => globalSize;\nvar removed = [];\nvar recycled = [];\nvar defaultRemovedReuseThreshold = 0.01;\nvar removedReuseThreshold = defaultRemovedReuseThreshold;\nvar resetGlobals = () => {\n globalSize = defaultSize;\n globalEntityCursor = 0;\n removedReuseThreshold = defaultRemovedReuseThreshold;\n removed.length = 0;\n recycled.length = 0;\n};\nvar setDefaultSize = (newSize) => {\n const oldSize = globalSize;\n defaultSize = newSize;\n resetGlobals();\n globalSize = newSize;\n resizeWorlds(newSize);\n setSerializationResized(true);\n};\nvar setRemovedRecycleThreshold = (newThreshold) => {\n removedReuseThreshold = newThreshold;\n};\nvar getEntityCursor = () => globalEntityCursor;\nvar eidToWorld = /* @__PURE__ */ new Map();\nvar flushRemovedEntities = (world) => {\n if (!world[$manualEntityRecycling]) {\n throw new Error(\"bitECS - cannot flush removed entities, enable feature with the enableManualEntityRecycling function\");\n }\n removed.push(...recycled);\n recycled.length = 0;\n};\nvar addEntity = (world) => {\n const eid = world[$manualEntityRecycling] ? removed.length ? removed.shift() : globalEntityCursor++ : removed.length > Math.round(globalSize * removedReuseThreshold) ? removed.shift() : globalEntityCursor++;\n if (eid > world[$size])\n throw new Error(\"bitECS - max entities reached\");\n world[$entitySparseSet].add(eid);\n eidToWorld.set(eid, world);\n world[$notQueries].forEach((q) => {\n const match = queryCheckEntity(world, q, eid);\n if (match)\n queryAddEntity(q, eid);\n });\n world[$entityComponents].set(eid, /* @__PURE__ */ new Set());\n return eid;\n};\nvar removeEntity = (world, eid) => {\n if (!world[$entitySparseSet].has(eid))\n return;\n world[$queries].forEach((q) => {\n queryRemoveEntity(world, q, eid);\n });\n if (world[$manualEntityRecycling])\n recycled.push(eid);\n else\n removed.push(eid);\n world[$entitySparseSet].remove(eid);\n world[$entityComponents].delete(eid);\n world[$localEntities].delete(world[$localEntityLookup].get(eid));\n world[$localEntityLookup].delete(eid);\n for (let i = 0; i < world[$entityMasks].length; i++)\n world[$entityMasks][i][eid] = 0;\n};\nvar getEntityComponents = (world, eid) => {\n if (eid === void 0)\n throw new Error(\"bitECS - entity is undefined.\");\n if (!world[$entitySparseSet].has(eid))\n throw new Error(\"bitECS - entity does not exist in the world.\");\n return Array.from(world[$entityComponents].get(eid));\n};\nvar entityExists = (world, eid) => world[$entitySparseSet].has(eid);\n\n// src/Query.js\nvar $modifier = Symbol(\"$modifier\");\nfunction modifier(c, mod) {\n const inner = () => [c, mod];\n inner[$modifier] = true;\n return inner;\n}\nvar Not = (c) => modifier(c, \"not\");\nvar Changed = (c) => modifier(c, \"changed\");\nfunction Any(...comps) {\n return function QueryAny() {\n return comps;\n };\n}\nfunction All(...comps) {\n return function QueryAll() {\n return comps;\n };\n}\nfunction None(...comps) {\n return function QueryNone() {\n return comps;\n };\n}\nvar $queries = Symbol(\"queries\");\nvar $notQueries = Symbol(\"notQueries\");\nvar $queryAny = Symbol(\"queryAny\");\nvar $queryAll = Symbol(\"queryAll\");\nvar $queryNone = Symbol(\"queryNone\");\nvar $queryMap = Symbol(\"queryMap\");\nvar $dirtyQueries = Symbol(\"$dirtyQueries\");\nvar $queryComponents = Symbol(\"queryComponents\");\nvar $enterQuery = Symbol(\"enterQuery\");\nvar $exitQuery = Symbol(\"exitQuery\");\nvar empty = Object.freeze([]);\nvar enterQuery = (query) => (world) => {\n if (!world[$queryMap].has(query))\n registerQuery(world, query);\n const q = world[$queryMap].get(query);\n if (q.entered.dense.length === 0) {\n return empty;\n } else {\n const results = q.entered.dense.slice();\n q.entered.reset();\n return results;\n }\n};\nvar exitQuery = (query) => (world) => {\n if (!world[$queryMap].has(query))\n registerQuery(world, query);\n const q = world[$queryMap].get(query);\n if (q.exited.dense.length === 0) {\n return empty;\n } else {\n const results = q.exited.dense.slice();\n q.exited.reset();\n return results;\n }\n};\nvar registerQuery = (world, query) => {\n const components2 = [];\n const notComponents = [];\n const changedComponents = [];\n query[$queryComponents].forEach((c) => {\n if (typeof c === \"function\" && c[$modifier]) {\n const [comp, mod] = c();\n if (!world[$componentMap].has(comp))\n registerComponent(world, comp);\n if (mod === \"not\") {\n notComponents.push(comp);\n }\n if (mod === \"changed\") {\n changedComponents.push(comp);\n components2.push(comp);\n }\n } else {\n if (!world[$componentMap].has(c))\n registerComponent(world, c);\n components2.push(c);\n }\n });\n const mapComponents = (c) => world[$componentMap].get(c);\n const allComponents = components2.concat(notComponents).map(mapComponents);\n const sparseSet = SparseSet();\n const archetypes = [];\n const changed = [];\n const toRemove = SparseSet();\n const entered = SparseSet();\n const exited = SparseSet();\n const generations = allComponents.map((c) => c.generationId).reduce((a, v) => {\n if (a.includes(v))\n return a;\n a.push(v);\n return a;\n }, []);\n const reduceBitflags = (a, c) => {\n if (!a[c.generationId])\n a[c.generationId] = 0;\n a[c.generationId] |= c.bitflag;\n return a;\n };\n const masks = components2.map(mapComponents).reduce(reduceBitflags, {});\n const notMasks = notComponents.map(mapComponents).reduce(reduceBitflags, {});\n const hasMasks = allComponents.reduce(reduceBitflags, {});\n const flatProps = components2.filter((c) => !c[$tagStore]).map((c) => Object.getOwnPropertySymbols(c).includes($storeFlattened) ? c[$storeFlattened] : [c]).reduce((a, v) => a.concat(v), []);\n const shadows = [];\n const q = Object.assign(sparseSet, {\n archetypes,\n changed,\n components: components2,\n notComponents,\n changedComponents,\n allComponents,\n masks,\n notMasks,\n hasMasks,\n generations,\n flatProps,\n toRemove,\n entered,\n exited,\n shadows\n });\n world[$queryMap].set(query, q);\n world[$queries].add(q);\n allComponents.forEach((c) => {\n c.queries.add(q);\n });\n if (notComponents.length)\n world[$notQueries].add(q);\n for (let eid = 0; eid < getEntityCursor(); eid++) {\n if (!world[$entitySparseSet].has(eid))\n continue;\n const match = queryCheckEntity(world, q, eid);\n if (match)\n queryAddEntity(q, eid);\n }\n};\nvar generateShadow = (q, pid) => {\n const $ = Symbol();\n const prop = q.flatProps[pid];\n createShadow(prop, $);\n q.shadows[pid] = prop[$];\n return prop[$];\n};\nvar diff = (q, clearDiff) => {\n if (clearDiff)\n q.changed = [];\n const { flatProps, shadows } = q;\n for (let i = 0; i < q.dense.length; i++) {\n const eid = q.dense[i];\n let dirty = false;\n for (let pid = 0; pid < flatProps.length; pid++) {\n const prop = flatProps[pid];\n const shadow = shadows[pid] || generateShadow(q, pid);\n if (ArrayBuffer.isView(prop[eid])) {\n for (let i2 = 0; i2 < prop[eid].length; i2++) {\n if (prop[eid][i2] !== shadow[eid][i2]) {\n dirty = true;\n break;\n }\n }\n shadow[eid].set(prop[eid]);\n } else {\n if (prop[eid] !== shadow[eid]) {\n dirty = true;\n shadow[eid] = prop[eid];\n }\n }\n }\n if (dirty)\n q.changed.push(eid);\n }\n return q.changed;\n};\nvar flatten = (a, v) => a.concat(v);\nvar aggregateComponentsFor = (mod) => (x) => x.filter((f) => f.name === mod().constructor.name).reduce(flatten);\nvar getAnyComponents = aggregateComponentsFor(Any);\nvar getAllComponents = aggregateComponentsFor(All);\nvar getNoneComponents = aggregateComponentsFor(None);\nvar defineQuery = (...args) => {\n let components2;\n let any, all, none;\n if (Array.isArray(args[0])) {\n components2 = args[0];\n } else {\n }\n if (components2 === void 0 || components2[$componentMap] !== void 0) {\n return (world) => world ? world[$entityArray] : components2[$entityArray];\n }\n const query = function(world, clearDiff = true) {\n if (!world[$queryMap].has(query))\n registerQuery(world, query);\n const q = world[$queryMap].get(query);\n commitRemovals(world);\n if (q.changedComponents.length)\n return diff(q, clearDiff);\n return q.dense;\n };\n query[$queryComponents] = components2;\n query[$queryAny] = any;\n query[$queryAll] = all;\n query[$queryNone] = none;\n return query;\n};\nvar queryCheckEntity = (world, q, eid) => {\n const { masks, notMasks, generations } = q;\n let or = 0;\n for (let i = 0; i < generations.length; i++) {\n const generationId = generations[i];\n const qMask = masks[generationId];\n const qNotMask = notMasks[generationId];\n const eMask = world[$entityMasks][generationId][eid];\n if (qNotMask && (eMask & qNotMask) !== 0) {\n return false;\n }\n if (qMask && (eMask & qMask) !== qMask) {\n return false;\n }\n }\n return true;\n};\nvar queryAddEntity = (q, eid) => {\n q.toRemove.remove(eid);\n q.entered.add(eid);\n q.add(eid);\n};\nvar queryCommitRemovals = (q) => {\n for (let i = q.toRemove.dense.length - 1; i >= 0; i--) {\n const eid = q.toRemove.dense[i];\n q.toRemove.remove(eid);\n q.remove(eid);\n }\n};\nvar commitRemovals = (world) => {\n if (!world[$dirtyQueries].size)\n return;\n world[$dirtyQueries].forEach(queryCommitRemovals);\n world[$dirtyQueries].clear();\n};\nvar queryRemoveEntity = (world, q, eid) => {\n if (!q.has(eid) || q.toRemove.has(eid))\n return;\n q.toRemove.add(eid);\n world[$dirtyQueries].add(q);\n q.exited.add(eid);\n};\nvar resetChangedQuery = (world, query) => {\n const q = world[$queryMap].get(query);\n q.changed = [];\n};\nvar removeQuery = (world, query) => {\n const q = world[$queryMap].get(query);\n world[$queries].delete(q);\n world[$queryMap].delete(query);\n};\n\n// src/Component.js\nvar $componentMap = Symbol(\"componentMap\");\nvar components = [];\nvar defineComponent = (schema, size) => {\n const component = createStore(schema, size || getGlobalSize());\n if (schema && Object.keys(schema).length)\n components.push(component);\n return component;\n};\nvar incrementBitflag = (world) => {\n world[$bitflag] *= 2;\n if (world[$bitflag] >= 2 ** 31) {\n world[$bitflag] = 1;\n world[$entityMasks].push(new Uint32Array(world[$size]));\n }\n};\nvar registerComponent = (world, component) => {\n if (!component)\n throw new Error(`bitECS - Cannot register null or undefined component`);\n const queries = /* @__PURE__ */ new Set();\n const notQueries = /* @__PURE__ */ new Set();\n const changedQueries = /* @__PURE__ */ new Set();\n world[$queries].forEach((q) => {\n if (q.allComponents.includes(component)) {\n queries.add(q);\n }\n });\n world[$componentMap].set(component, {\n generationId: world[$entityMasks].length - 1,\n bitflag: world[$bitflag],\n store: component,\n queries,\n notQueries,\n changedQueries\n });\n incrementBitflag(world);\n};\nvar registerComponents = (world, components2) => {\n components2.forEach((c) => registerComponent(world, c));\n};\nvar hasComponent = (world, component, eid) => {\n const registeredComponent = world[$componentMap].get(component);\n if (!registeredComponent)\n return false;\n const { generationId, bitflag } = registeredComponent;\n const mask = world[$entityMasks][generationId][eid];\n return (mask & bitflag) === bitflag;\n};\nvar addComponent = (world, component, eid, reset = false) => {\n if (eid === void 0)\n throw new Error(\"bitECS - entity is undefined.\");\n if (!world[$entitySparseSet].has(eid))\n throw new Error(\"bitECS - entity does not exist in the world.\");\n if (!world[$componentMap].has(component))\n registerComponent(world, component);\n if (hasComponent(world, component, eid))\n return;\n const c = world[$componentMap].get(component);\n const { generationId, bitflag, queries, notQueries } = c;\n world[$entityMasks][generationId][eid] |= bitflag;\n queries.forEach((q) => {\n q.toRemove.remove(eid);\n const match = queryCheckEntity(world, q, eid);\n if (match) {\n q.exited.remove(eid);\n queryAddEntity(q, eid);\n }\n if (!match) {\n q.entered.remove(eid);\n queryRemoveEntity(world, q, eid);\n }\n });\n world[$entityComponents].get(eid).add(component);\n if (reset)\n resetStoreFor(component, eid);\n};\nvar removeComponent = (world, component, eid, reset = true) => {\n if (eid === void 0)\n throw new Error(\"bitECS - entity is undefined.\");\n if (!world[$entitySparseSet].has(eid))\n throw new Error(\"bitECS - entity does not exist in the world.\");\n if (!hasComponent(world, component, eid))\n return;\n const c = world[$componentMap].get(component);\n const { generationId, bitflag, queries } = c;\n world[$entityMasks][generationId][eid] &= ~bitflag;\n queries.forEach((q) => {\n q.toRemove.remove(eid);\n const match = queryCheckEntity(world, q, eid);\n if (match) {\n q.exited.remove(eid);\n queryAddEntity(q, eid);\n }\n if (!match) {\n q.entered.remove(eid);\n queryRemoveEntity(world, q, eid);\n }\n });\n world[$entityComponents].get(eid).delete(component);\n if (reset)\n resetStoreFor(component, eid);\n};\n\n// src/World.js\nvar $size = Symbol(\"size\");\nvar $resizeThreshold = Symbol(\"resizeThreshold\");\nvar $bitflag = Symbol(\"bitflag\");\nvar $archetypes = Symbol(\"archetypes\");\nvar $localEntities = Symbol(\"localEntities\");\nvar $localEntityLookup = Symbol(\"localEntityLookup\");\nvar $manualEntityRecycling = Symbol(\"manualEntityRecycling\");\nvar worlds = [];\nvar resizeWorlds = (size) => {\n worlds.forEach((world) => {\n world[$size] = size;\n for (let i = 0; i < world[$entityMasks].length; i++) {\n const masks = world[$entityMasks][i];\n world[$entityMasks][i] = resize(masks, size);\n }\n world[$resizeThreshold] = world[$size] - world[$size] / 5;\n });\n};\nvar createWorld = (...args) => {\n const world = typeof args[0] === \"object\" ? args[0] : {};\n const size = typeof args[0] === \"number\" ? args[0] : typeof args[1] === \"number\" ? args[1] : getGlobalSize();\n resetWorld(world, size);\n worlds.push(world);\n return world;\n};\nvar enableManualEntityRecycling = (world) => {\n world[$manualEntityRecycling] = true;\n};\nvar resetWorld = (world, size = getGlobalSize()) => {\n world[$size] = size;\n if (world[$entityArray])\n world[$entityArray].forEach((eid) => removeEntity(world, eid));\n world[$entityMasks] = [new Uint32Array(size)];\n world[$entityComponents] = /* @__PURE__ */ new Map();\n world[$archetypes] = [];\n world[$entitySparseSet] = SparseSet();\n world[$entityArray] = world[$entitySparseSet].dense;\n world[$bitflag] = 1;\n world[$componentMap] = /* @__PURE__ */ new Map();\n world[$queryMap] = /* @__PURE__ */ new Map();\n world[$queries] = /* @__PURE__ */ new Set();\n world[$notQueries] = /* @__PURE__ */ new Set();\n world[$dirtyQueries] = /* @__PURE__ */ new Set();\n world[$localEntities] = /* @__PURE__ */ new Map();\n world[$localEntityLookup] = /* @__PURE__ */ new Map();\n world[$manualEntityRecycling] = false;\n return world;\n};\nvar deleteWorld = (world) => {\n Object.getOwnPropertySymbols(world).forEach(($) => {\n delete world[$];\n });\n Object.keys(world).forEach((key) => {\n delete world[key];\n });\n worlds.splice(worlds.indexOf(world), 1);\n};\nvar getWorldComponents = (world) => Array.from(world[$componentMap].keys());\nvar getAllEntities = (world) => world[$entitySparseSet].dense.slice(0);\n\n// src/System.js\nvar defineSystem = (update) => (world, ...args) => {\n update(world, ...args);\n return world;\n};\n\n// src/index.js\nvar pipe = (...fns) => (input) => {\n let tmp = input;\n for (let i = 0; i < fns.length; i++) {\n const fn = fns[i];\n tmp = fn(tmp);\n }\n return tmp;\n};\nvar Types = TYPES_ENUM;\nexport {\n Changed,\n DESERIALIZE_MODE,\n Not,\n Types,\n addComponent,\n addEntity,\n commitRemovals,\n createWorld,\n defineComponent,\n defineDeserializer,\n defineQuery,\n defineSerializer,\n defineSystem,\n deleteWorld,\n enableManualEntityRecycling,\n enterQuery,\n entityExists,\n exitQuery,\n flushRemovedEntities,\n getAllEntities,\n getEntityComponents,\n getWorldComponents,\n hasComponent,\n parentArray,\n pipe,\n registerComponent,\n registerComponents,\n removeComponent,\n removeEntity,\n removeQuery,\n resetChangedQuery,\n resetGlobals,\n resetWorld,\n setDefaultSize,\n setRemovedRecycleThreshold\n};\n//# sourceMappingURL=index.mjs.map\n","/**\n * @license\n * Copyright 2010-2022 Three.js Authors\n * SPDX-License-Identifier: MIT\n */\nconst REVISION = '141';\nconst MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };\nconst TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };\nconst CullFaceNone = 0;\nconst CullFaceBack = 1;\nconst CullFaceFront = 2;\nconst CullFaceFrontBack = 3;\nconst BasicShadowMap = 0;\nconst PCFShadowMap = 1;\nconst PCFSoftShadowMap = 2;\nconst VSMShadowMap = 3;\nconst FrontSide = 0;\nconst BackSide = 1;\nconst DoubleSide = 2;\nconst FlatShading = 1;\nconst SmoothShading = 2;\nconst NoBlending = 0;\nconst NormalBlending = 1;\nconst AdditiveBlending = 2;\nconst SubtractiveBlending = 3;\nconst MultiplyBlending = 4;\nconst CustomBlending = 5;\nconst AddEquation = 100;\nconst SubtractEquation = 101;\nconst ReverseSubtractEquation = 102;\nconst MinEquation = 103;\nconst MaxEquation = 104;\nconst ZeroFactor = 200;\nconst OneFactor = 201;\nconst SrcColorFactor = 202;\nconst OneMinusSrcColorFactor = 203;\nconst SrcAlphaFactor = 204;\nconst OneMinusSrcAlphaFactor = 205;\nconst DstAlphaFactor = 206;\nconst OneMinusDstAlphaFactor = 207;\nconst DstColorFactor = 208;\nconst OneMinusDstColorFactor = 209;\nconst SrcAlphaSaturateFactor = 210;\nconst NeverDepth = 0;\nconst AlwaysDepth = 1;\nconst LessDepth = 2;\nconst LessEqualDepth = 3;\nconst EqualDepth = 4;\nconst GreaterEqualDepth = 5;\nconst GreaterDepth = 6;\nconst NotEqualDepth = 7;\nconst MultiplyOperation = 0;\nconst MixOperation = 1;\nconst AddOperation = 2;\nconst NoToneMapping = 0;\nconst LinearToneMapping = 1;\nconst ReinhardToneMapping = 2;\nconst CineonToneMapping = 3;\nconst ACESFilmicToneMapping = 4;\nconst CustomToneMapping = 5;\n\nconst UVMapping = 300;\nconst CubeReflectionMapping = 301;\nconst CubeRefractionMapping = 302;\nconst EquirectangularReflectionMapping = 303;\nconst EquirectangularRefractionMapping = 304;\nconst CubeUVReflectionMapping = 306;\nconst RepeatWrapping = 1000;\nconst ClampToEdgeWrapping = 1001;\nconst MirroredRepeatWrapping = 1002;\nconst NearestFilter = 1003;\nconst NearestMipmapNearestFilter = 1004;\nconst NearestMipMapNearestFilter = 1004;\nconst NearestMipmapLinearFilter = 1005;\nconst NearestMipMapLinearFilter = 1005;\nconst LinearFilter = 1006;\nconst LinearMipmapNearestFilter = 1007;\nconst LinearMipMapNearestFilter = 1007;\nconst LinearMipmapLinearFilter = 1008;\nconst LinearMipMapLinearFilter = 1008;\nconst UnsignedByteType = 1009;\nconst ByteType = 1010;\nconst ShortType = 1011;\nconst UnsignedShortType = 1012;\nconst IntType = 1013;\nconst UnsignedIntType = 1014;\nconst FloatType = 1015;\nconst HalfFloatType = 1016;\nconst UnsignedShort4444Type = 1017;\nconst UnsignedShort5551Type = 1018;\nconst UnsignedInt248Type = 1020;\nconst AlphaFormat = 1021;\nconst RGBFormat = 1022;\nconst RGBAFormat = 1023;\nconst LuminanceFormat = 1024;\nconst LuminanceAlphaFormat = 1025;\nconst DepthFormat = 1026;\nconst DepthStencilFormat = 1027;\nconst RedFormat = 1028;\nconst RedIntegerFormat = 1029;\nconst RGFormat = 1030;\nconst RGIntegerFormat = 1031;\nconst RGBAIntegerFormat = 1033;\n\nconst RGB_S3TC_DXT1_Format = 33776;\nconst RGBA_S3TC_DXT1_Format = 33777;\nconst RGBA_S3TC_DXT3_Format = 33778;\nconst RGBA_S3TC_DXT5_Format = 33779;\nconst RGB_PVRTC_4BPPV1_Format = 35840;\nconst RGB_PVRTC_2BPPV1_Format = 35841;\nconst RGBA_PVRTC_4BPPV1_Format = 35842;\nconst RGBA_PVRTC_2BPPV1_Format = 35843;\nconst RGB_ETC1_Format = 36196;\nconst RGB_ETC2_Format = 37492;\nconst RGBA_ETC2_EAC_Format = 37496;\nconst RGBA_ASTC_4x4_Format = 37808;\nconst RGBA_ASTC_5x4_Format = 37809;\nconst RGBA_ASTC_5x5_Format = 37810;\nconst RGBA_ASTC_6x5_Format = 37811;\nconst RGBA_ASTC_6x6_Format = 37812;\nconst RGBA_ASTC_8x5_Format = 37813;\nconst RGBA_ASTC_8x6_Format = 37814;\nconst RGBA_ASTC_8x8_Format = 37815;\nconst RGBA_ASTC_10x5_Format = 37816;\nconst RGBA_ASTC_10x6_Format = 37817;\nconst RGBA_ASTC_10x8_Format = 37818;\nconst RGBA_ASTC_10x10_Format = 37819;\nconst RGBA_ASTC_12x10_Format = 37820;\nconst RGBA_ASTC_12x12_Format = 37821;\nconst RGBA_BPTC_Format = 36492;\nconst LoopOnce = 2200;\nconst LoopRepeat = 2201;\nconst LoopPingPong = 2202;\nconst InterpolateDiscrete = 2300;\nconst InterpolateLinear = 2301;\nconst InterpolateSmooth = 2302;\nconst ZeroCurvatureEnding = 2400;\nconst ZeroSlopeEnding = 2401;\nconst WrapAroundEnding = 2402;\nconst NormalAnimationBlendMode = 2500;\nconst AdditiveAnimationBlendMode = 2501;\nconst TrianglesDrawMode = 0;\nconst TriangleStripDrawMode = 1;\nconst TriangleFanDrawMode = 2;\nconst LinearEncoding = 3000;\nconst sRGBEncoding = 3001;\nconst BasicDepthPacking = 3200;\nconst RGBADepthPacking = 3201;\nconst TangentSpaceNormalMap = 0;\nconst ObjectSpaceNormalMap = 1;\n\n// Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available.\nconst NoColorSpace = '';\nconst SRGBColorSpace = 'srgb';\nconst LinearSRGBColorSpace = 'srgb-linear';\n\nconst ZeroStencilOp = 0;\nconst KeepStencilOp = 7680;\nconst ReplaceStencilOp = 7681;\nconst IncrementStencilOp = 7682;\nconst DecrementStencilOp = 7683;\nconst IncrementWrapStencilOp = 34055;\nconst DecrementWrapStencilOp = 34056;\nconst InvertStencilOp = 5386;\n\nconst NeverStencilFunc = 512;\nconst LessStencilFunc = 513;\nconst EqualStencilFunc = 514;\nconst LessEqualStencilFunc = 515;\nconst GreaterStencilFunc = 516;\nconst NotEqualStencilFunc = 517;\nconst GreaterEqualStencilFunc = 518;\nconst AlwaysStencilFunc = 519;\n\nconst StaticDrawUsage = 35044;\nconst DynamicDrawUsage = 35048;\nconst StreamDrawUsage = 35040;\nconst StaticReadUsage = 35045;\nconst DynamicReadUsage = 35049;\nconst StreamReadUsage = 35041;\nconst StaticCopyUsage = 35046;\nconst DynamicCopyUsage = 35050;\nconst StreamCopyUsage = 35042;\n\nconst GLSL1 = '100';\nconst GLSL3 = '300 es';\n\nconst _SRGBAFormat = 1035; // fallback for WebGL 1\n\n/**\n * https://github.com/mrdoob/eventdispatcher.js/\n */\n\nclass EventDispatcher {\n\n\taddEventListener( type, listener ) {\n\n\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\tconst listeners = this._listeners;\n\n\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\tlisteners[ type ] = [];\n\n\t\t}\n\n\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\tlisteners[ type ].push( listener );\n\n\t\t}\n\n\t}\n\n\thasEventListener( type, listener ) {\n\n\t\tif ( this._listeners === undefined ) return false;\n\n\t\tconst listeners = this._listeners;\n\n\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t}\n\n\tremoveEventListener( type, listener ) {\n\n\t\tif ( this._listeners === undefined ) return;\n\n\t\tconst listeners = this._listeners;\n\t\tconst listenerArray = listeners[ type ];\n\n\t\tif ( listenerArray !== undefined ) {\n\n\t\t\tconst index = listenerArray.indexOf( listener );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tdispatchEvent( event ) {\n\n\t\tif ( this._listeners === undefined ) return;\n\n\t\tconst listeners = this._listeners;\n\t\tconst listenerArray = listeners[ event.type ];\n\n\t\tif ( listenerArray !== undefined ) {\n\n\t\t\tevent.target = this;\n\n\t\t\t// Make a copy, in case listeners are removed while iterating.\n\t\t\tconst array = listenerArray.slice( 0 );\n\n\t\t\tfor ( let i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t}\n\n\t\t\tevent.target = null;\n\n\t\t}\n\n\t}\n\n}\n\nconst _lut = [];\n\nfor ( let i = 0; i < 256; i ++ ) {\n\n\t_lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 );\n\n}\n\nlet _seed = 1234567;\n\n\nconst DEG2RAD = Math.PI / 180;\nconst RAD2DEG = 180 / Math.PI;\n\n// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136\nfunction generateUUID() {\n\n\tconst d0 = Math.random() * 0xffffffff | 0;\n\tconst d1 = Math.random() * 0xffffffff | 0;\n\tconst d2 = Math.random() * 0xffffffff | 0;\n\tconst d3 = Math.random() * 0xffffffff | 0;\n\tconst uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' +\n\t\t\t_lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' +\n\t\t\t_lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] +\n\t\t\t_lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ];\n\n\t// .toLowerCase() here flattens concatenated strings to save heap memory space.\n\treturn uuid.toLowerCase();\n\n}\n\nfunction clamp( value, min, max ) {\n\n\treturn Math.max( min, Math.min( max, value ) );\n\n}\n\n// compute euclidean modulo of m % n\n// https://en.wikipedia.org/wiki/Modulo_operation\nfunction euclideanModulo( n, m ) {\n\n\treturn ( ( n % m ) + m ) % m;\n\n}\n\n// Linear mapping from range to range \nfunction mapLinear( x, a1, a2, b1, b2 ) {\n\n\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n}\n\n// https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/\nfunction inverseLerp( x, y, value ) {\n\n\tif ( x !== y ) {\n\n\t\treturn ( value - x ) / ( y - x );\n\n\t} else {\n\n\t\treturn 0;\n\n\t}\n\n}\n\n// https://en.wikipedia.org/wiki/Linear_interpolation\nfunction lerp( x, y, t ) {\n\n\treturn ( 1 - t ) * x + t * y;\n\n}\n\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\nfunction damp( x, y, lambda, dt ) {\n\n\treturn lerp( x, y, 1 - Math.exp( - lambda * dt ) );\n\n}\n\n// https://www.desmos.com/calculator/vcsjnyz7x4\nfunction pingpong( x, length = 1 ) {\n\n\treturn length - Math.abs( euclideanModulo( x, length * 2 ) - length );\n\n}\n\n// http://en.wikipedia.org/wiki/Smoothstep\nfunction smoothstep( x, min, max ) {\n\n\tif ( x <= min ) return 0;\n\tif ( x >= max ) return 1;\n\n\tx = ( x - min ) / ( max - min );\n\n\treturn x * x * ( 3 - 2 * x );\n\n}\n\nfunction smootherstep( x, min, max ) {\n\n\tif ( x <= min ) return 0;\n\tif ( x >= max ) return 1;\n\n\tx = ( x - min ) / ( max - min );\n\n\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n}\n\n// Random integer from interval\nfunction randInt( low, high ) {\n\n\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n}\n\n// Random float from interval\nfunction randFloat( low, high ) {\n\n\treturn low + Math.random() * ( high - low );\n\n}\n\n// Random float from <-range/2, range/2> interval\nfunction randFloatSpread( range ) {\n\n\treturn range * ( 0.5 - Math.random() );\n\n}\n\n// Deterministic pseudo-random float in the interval [ 0, 1 ]\nfunction seededRandom( s ) {\n\n\tif ( s !== undefined ) _seed = s;\n\n\t// Mulberry32 generator\n\n\tlet t = _seed += 0x6D2B79F5;\n\n\tt = Math.imul( t ^ t >>> 15, t | 1 );\n\n\tt ^= t + Math.imul( t ^ t >>> 7, t | 61 );\n\n\treturn ( ( t ^ t >>> 14 ) >>> 0 ) / 4294967296;\n\n}\n\nfunction degToRad( degrees ) {\n\n\treturn degrees * DEG2RAD;\n\n}\n\nfunction radToDeg( radians ) {\n\n\treturn radians * RAD2DEG;\n\n}\n\nfunction isPowerOfTwo( value ) {\n\n\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n}\n\nfunction ceilPowerOfTwo( value ) {\n\n\treturn Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) );\n\n}\n\nfunction floorPowerOfTwo( value ) {\n\n\treturn Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) );\n\n}\n\nfunction setQuaternionFromProperEuler( q, a, b, c, order ) {\n\n\t// Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles\n\n\t// rotations are applied to the axes in the order specified by 'order'\n\t// rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c'\n\t// angles are in radians\n\n\tconst cos = Math.cos;\n\tconst sin = Math.sin;\n\n\tconst c2 = cos( b / 2 );\n\tconst s2 = sin( b / 2 );\n\n\tconst c13 = cos( ( a + c ) / 2 );\n\tconst s13 = sin( ( a + c ) / 2 );\n\n\tconst c1_3 = cos( ( a - c ) / 2 );\n\tconst s1_3 = sin( ( a - c ) / 2 );\n\n\tconst c3_1 = cos( ( c - a ) / 2 );\n\tconst s3_1 = sin( ( c - a ) / 2 );\n\n\tswitch ( order ) {\n\n\t\tcase 'XYX':\n\t\t\tq.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'YZY':\n\t\t\tq.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'ZXZ':\n\t\t\tq.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'XZX':\n\t\t\tq.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'YXY':\n\t\t\tq.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 );\n\t\t\tbreak;\n\n\t\tcase 'ZYZ':\n\t\t\tq.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 );\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tconsole.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order );\n\n\t}\n\n}\n\nfunction denormalize$1( value, array ) {\n\n\tswitch ( array.constructor ) {\n\n\t\tcase Float32Array:\n\n\t\t\treturn value;\n\n\t\tcase Uint16Array:\n\n\t\t\treturn value / 65535.0;\n\n\t\tcase Uint8Array:\n\n\t\t\treturn value / 255.0;\n\n\t\tcase Int16Array:\n\n\t\t\treturn Math.max( value / 32767.0, - 1.0 );\n\n\t\tcase Int8Array:\n\n\t\t\treturn Math.max( value / 127.0, - 1.0 );\n\n\t\tdefault:\n\n\t\t\tthrow new Error( 'Invalid component type.' );\n\n\t}\n\n}\n\nfunction normalize( value, array ) {\n\n\tswitch ( array.constructor ) {\n\n\t\tcase Float32Array:\n\n\t\t\treturn value;\n\n\t\tcase Uint16Array:\n\n\t\t\treturn Math.round( value * 65535.0 );\n\n\t\tcase Uint8Array:\n\n\t\t\treturn Math.round( value * 255.0 );\n\n\t\tcase Int16Array:\n\n\t\t\treturn Math.round( value * 32767.0 );\n\n\t\tcase Int8Array:\n\n\t\t\treturn Math.round( value * 127.0 );\n\n\t\tdefault:\n\n\t\t\tthrow new Error( 'Invalid component type.' );\n\n\t}\n\n}\n\nvar MathUtils = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tDEG2RAD: DEG2RAD,\n\tRAD2DEG: RAD2DEG,\n\tgenerateUUID: generateUUID,\n\tclamp: clamp,\n\teuclideanModulo: euclideanModulo,\n\tmapLinear: mapLinear,\n\tinverseLerp: inverseLerp,\n\tlerp: lerp,\n\tdamp: damp,\n\tpingpong: pingpong,\n\tsmoothstep: smoothstep,\n\tsmootherstep: smootherstep,\n\trandInt: randInt,\n\trandFloat: randFloat,\n\trandFloatSpread: randFloatSpread,\n\tseededRandom: seededRandom,\n\tdegToRad: degToRad,\n\tradToDeg: radToDeg,\n\tisPowerOfTwo: isPowerOfTwo,\n\tceilPowerOfTwo: ceilPowerOfTwo,\n\tfloorPowerOfTwo: floorPowerOfTwo,\n\tsetQuaternionFromProperEuler: setQuaternionFromProperEuler,\n\tnormalize: normalize,\n\tdenormalize: denormalize$1\n});\n\nclass Vector2 {\n\n\tconstructor( x = 0, y = 0 ) {\n\n\t\tthis.isVector2 = true;\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\n\t}\n\n\tget width() {\n\n\t\treturn this.x;\n\n\t}\n\n\tset width( value ) {\n\n\t\tthis.x = value;\n\n\t}\n\n\tget height() {\n\n\t\treturn this.y;\n\n\t}\n\n\tset height( value ) {\n\n\t\tthis.y = value;\n\n\t}\n\n\tset( x, y ) {\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetScalar( scalar ) {\n\n\t\tthis.x = scalar;\n\t\tthis.y = scalar;\n\n\t\treturn this;\n\n\t}\n\n\tsetX( x ) {\n\n\t\tthis.x = x;\n\n\t\treturn this;\n\n\t}\n\n\tsetY( y ) {\n\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetComponent( index, value ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: this.x = value; break;\n\t\t\tcase 1: this.y = value; break;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetComponent( index ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: return this.x;\n\t\t\tcase 1: return this.y;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.x, this.y );\n\n\t}\n\n\tcopy( v ) {\n\n\t\tthis.x = v.x;\n\t\tthis.y = v.y;\n\n\t\treturn this;\n\n\t}\n\n\tadd( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\treturn this.addVectors( v, w );\n\n\t\t}\n\n\t\tthis.x += v.x;\n\t\tthis.y += v.y;\n\n\t\treturn this;\n\n\t}\n\n\taddScalar( s ) {\n\n\t\tthis.x += s;\n\t\tthis.y += s;\n\n\t\treturn this;\n\n\t}\n\n\taddVectors( a, b ) {\n\n\t\tthis.x = a.x + b.x;\n\t\tthis.y = a.y + b.y;\n\n\t\treturn this;\n\n\t}\n\n\taddScaledVector( v, s ) {\n\n\t\tthis.x += v.x * s;\n\t\tthis.y += v.y * s;\n\n\t\treturn this;\n\n\t}\n\n\tsub( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\treturn this.subVectors( v, w );\n\n\t\t}\n\n\t\tthis.x -= v.x;\n\t\tthis.y -= v.y;\n\n\t\treturn this;\n\n\t}\n\n\tsubScalar( s ) {\n\n\t\tthis.x -= s;\n\t\tthis.y -= s;\n\n\t\treturn this;\n\n\t}\n\n\tsubVectors( a, b ) {\n\n\t\tthis.x = a.x - b.x;\n\t\tthis.y = a.y - b.y;\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( v ) {\n\n\t\tthis.x *= v.x;\n\t\tthis.y *= v.y;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( scalar ) {\n\n\t\tthis.x *= scalar;\n\t\tthis.y *= scalar;\n\n\t\treturn this;\n\n\t}\n\n\tdivide( v ) {\n\n\t\tthis.x /= v.x;\n\t\tthis.y /= v.y;\n\n\t\treturn this;\n\n\t}\n\n\tdivideScalar( scalar ) {\n\n\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t}\n\n\tapplyMatrix3( m ) {\n\n\t\tconst x = this.x, y = this.y;\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ];\n\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ];\n\n\t\treturn this;\n\n\t}\n\n\tmin( v ) {\n\n\t\tthis.x = Math.min( this.x, v.x );\n\t\tthis.y = Math.min( this.y, v.y );\n\n\t\treturn this;\n\n\t}\n\n\tmax( v ) {\n\n\t\tthis.x = Math.max( this.x, v.x );\n\t\tthis.y = Math.max( this.y, v.y );\n\n\t\treturn this;\n\n\t}\n\n\tclamp( min, max ) {\n\n\t\t// assumes min < max, componentwise\n\n\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampScalar( minVal, maxVal ) {\n\n\t\tthis.x = Math.max( minVal, Math.min( maxVal, this.x ) );\n\t\tthis.y = Math.max( minVal, Math.min( maxVal, this.y ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampLength( min, max ) {\n\n\t\tconst length = this.length();\n\n\t\treturn this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );\n\n\t}\n\n\tfloor() {\n\n\t\tthis.x = Math.floor( this.x );\n\t\tthis.y = Math.floor( this.y );\n\n\t\treturn this;\n\n\t}\n\n\tceil() {\n\n\t\tthis.x = Math.ceil( this.x );\n\t\tthis.y = Math.ceil( this.y );\n\n\t\treturn this;\n\n\t}\n\n\tround() {\n\n\t\tthis.x = Math.round( this.x );\n\t\tthis.y = Math.round( this.y );\n\n\t\treturn this;\n\n\t}\n\n\troundToZero() {\n\n\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\treturn this;\n\n\t}\n\n\tnegate() {\n\n\t\tthis.x = - this.x;\n\t\tthis.y = - this.y;\n\n\t\treturn this;\n\n\t}\n\n\tdot( v ) {\n\n\t\treturn this.x * v.x + this.y * v.y;\n\n\t}\n\n\tcross( v ) {\n\n\t\treturn this.x * v.y - this.y * v.x;\n\n\t}\n\n\tlengthSq() {\n\n\t\treturn this.x * this.x + this.y * this.y;\n\n\t}\n\n\tlength() {\n\n\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t}\n\n\tmanhattanLength() {\n\n\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t}\n\n\tnormalize() {\n\n\t\treturn this.divideScalar( this.length() || 1 );\n\n\t}\n\n\tangle() {\n\n\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\tconst angle = Math.atan2( - this.y, - this.x ) + Math.PI;\n\n\t\treturn angle;\n\n\t}\n\n\tdistanceTo( v ) {\n\n\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t}\n\n\tdistanceToSquared( v ) {\n\n\t\tconst dx = this.x - v.x, dy = this.y - v.y;\n\t\treturn dx * dx + dy * dy;\n\n\t}\n\n\tmanhattanDistanceTo( v ) {\n\n\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t}\n\n\tsetLength( length ) {\n\n\t\treturn this.normalize().multiplyScalar( length );\n\n\t}\n\n\tlerp( v, alpha ) {\n\n\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpVectors( v1, v2, alpha ) {\n\n\t\tthis.x = v1.x + ( v2.x - v1.x ) * alpha;\n\t\tthis.y = v1.y + ( v2.y - v1.y ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tequals( v ) {\n\n\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis.x = array[ offset ];\n\t\tthis.y = array[ offset + 1 ];\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this.x;\n\t\tarray[ offset + 1 ] = this.y;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index, offset ) {\n\n\t\tif ( offset !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t}\n\n\t\tthis.x = attribute.getX( index );\n\t\tthis.y = attribute.getY( index );\n\n\t\treturn this;\n\n\t}\n\n\trotateAround( center, angle ) {\n\n\t\tconst c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\tconst x = this.x - center.x;\n\t\tconst y = this.y - center.y;\n\n\t\tthis.x = x * c - y * s + center.x;\n\t\tthis.y = x * s + y * c + center.y;\n\n\t\treturn this;\n\n\t}\n\n\trandom() {\n\n\t\tthis.x = Math.random();\n\t\tthis.y = Math.random();\n\n\t\treturn this;\n\n\t}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this.x;\n\t\tyield this.y;\n\n\t}\n\n}\n\nclass Matrix3 {\n\n\tconstructor() {\n\n\t\tthis.isMatrix3 = true;\n\n\t\tthis.elements = [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t];\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tset( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\treturn this;\n\n\t}\n\n\tidentity() {\n\n\t\tthis.set(\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tcopy( m ) {\n\n\t\tconst te = this.elements;\n\t\tconst me = m.elements;\n\n\t\tte[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];\n\t\tte[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];\n\t\tte[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];\n\n\t\treturn this;\n\n\t}\n\n\textractBasis( xAxis, yAxis, zAxis ) {\n\n\t\txAxis.setFromMatrix3Column( this, 0 );\n\t\tyAxis.setFromMatrix3Column( this, 1 );\n\t\tzAxis.setFromMatrix3Column( this, 2 );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrix4( m ) {\n\n\t\tconst me = m.elements;\n\n\t\tthis.set(\n\n\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( m ) {\n\n\t\treturn this.multiplyMatrices( this, m );\n\n\t}\n\n\tpremultiply( m ) {\n\n\t\treturn this.multiplyMatrices( m, this );\n\n\t}\n\n\tmultiplyMatrices( a, b ) {\n\n\t\tconst ae = a.elements;\n\t\tconst be = b.elements;\n\t\tconst te = this.elements;\n\n\t\tconst a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];\n\t\tconst a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];\n\t\tconst a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];\n\n\t\tconst b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];\n\t\tconst b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];\n\t\tconst b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];\n\n\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;\n\t\tte[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;\n\t\tte[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;\n\n\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;\n\t\tte[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;\n\t\tte[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;\n\n\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;\n\t\tte[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;\n\t\tte[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( s ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\treturn this;\n\n\t}\n\n\tdeterminant() {\n\n\t\tconst te = this.elements;\n\n\t\tconst a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t}\n\n\tinvert() {\n\n\t\tconst te = this.elements,\n\n\t\t\tn11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ],\n\t\t\tn12 = te[ 3 ], n22 = te[ 4 ], n32 = te[ 5 ],\n\t\t\tn13 = te[ 6 ], n23 = te[ 7 ], n33 = te[ 8 ],\n\n\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\tif ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 );\n\n\t\tconst detInv = 1 / det;\n\n\t\tte[ 0 ] = t11 * detInv;\n\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\tte[ 3 ] = t12 * detInv;\n\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\tte[ 6 ] = t13 * detInv;\n\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\treturn this;\n\n\t}\n\n\ttranspose() {\n\n\t\tlet tmp;\n\t\tconst m = this.elements;\n\n\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\treturn this;\n\n\t}\n\n\tgetNormalMatrix( matrix4 ) {\n\n\t\treturn this.setFromMatrix4( matrix4 ).invert().transpose();\n\n\t}\n\n\ttransposeIntoArray( r ) {\n\n\t\tconst m = this.elements;\n\n\t\tr[ 0 ] = m[ 0 ];\n\t\tr[ 1 ] = m[ 3 ];\n\t\tr[ 2 ] = m[ 6 ];\n\t\tr[ 3 ] = m[ 1 ];\n\t\tr[ 4 ] = m[ 4 ];\n\t\tr[ 5 ] = m[ 7 ];\n\t\tr[ 6 ] = m[ 2 ];\n\t\tr[ 7 ] = m[ 5 ];\n\t\tr[ 8 ] = m[ 8 ];\n\n\t\treturn this;\n\n\t}\n\n\tsetUvTransform( tx, ty, sx, sy, rotation, cx, cy ) {\n\n\t\tconst c = Math.cos( rotation );\n\t\tconst s = Math.sin( rotation );\n\n\t\tthis.set(\n\t\t\tsx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx,\n\t\t\t- sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty,\n\t\t\t0, 0, 1\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tscale( sx, sy ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx;\n\t\tte[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy;\n\n\t\treturn this;\n\n\t}\n\n\trotate( theta ) {\n\n\t\tconst c = Math.cos( theta );\n\t\tconst s = Math.sin( theta );\n\n\t\tconst te = this.elements;\n\n\t\tconst a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ];\n\t\tconst a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ];\n\n\t\tte[ 0 ] = c * a11 + s * a21;\n\t\tte[ 3 ] = c * a12 + s * a22;\n\t\tte[ 6 ] = c * a13 + s * a23;\n\n\t\tte[ 1 ] = - s * a11 + c * a21;\n\t\tte[ 4 ] = - s * a12 + c * a22;\n\t\tte[ 7 ] = - s * a13 + c * a23;\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( tx, ty ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ];\n\t\tte[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ];\n\n\t\treturn this;\n\n\t}\n\n\tequals( matrix ) {\n\n\t\tconst te = this.elements;\n\t\tconst me = matrix.elements;\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tconst te = this.elements;\n\n\t\tarray[ offset ] = te[ 0 ];\n\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\treturn array;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().fromArray( this.elements );\n\n\t}\n\n}\n\nfunction arrayNeedsUint32( array ) {\n\n\t// assumes larger values usually on last\n\n\tfor ( let i = array.length - 1; i >= 0; -- i ) {\n\n\t\tif ( array[ i ] > 65535 ) return true;\n\n\t}\n\n\treturn false;\n\n}\n\nconst TYPED_ARRAYS = {\n\tInt8Array: Int8Array,\n\tUint8Array: Uint8Array,\n\tUint8ClampedArray: Uint8ClampedArray,\n\tInt16Array: Int16Array,\n\tUint16Array: Uint16Array,\n\tInt32Array: Int32Array,\n\tUint32Array: Uint32Array,\n\tFloat32Array: Float32Array,\n\tFloat64Array: Float64Array\n};\n\nfunction getTypedArray( type, buffer ) {\n\n\treturn new TYPED_ARRAYS[ type ]( buffer );\n\n}\n\nfunction createElementNS( name ) {\n\n\treturn document.createElementNS( 'http://www.w3.org/1999/xhtml', name );\n\n}\n\nfunction SRGBToLinear( c ) {\n\n\treturn ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );\n\n}\n\nfunction LinearToSRGB( c ) {\n\n\treturn ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;\n\n}\n\n// JavaScript RGB-to-RGB transforms, defined as\n// FN[InputColorSpace][OutputColorSpace] callback functions.\nconst FN = {\n\t[ SRGBColorSpace ]: { [ LinearSRGBColorSpace ]: SRGBToLinear },\n\t[ LinearSRGBColorSpace ]: { [ SRGBColorSpace ]: LinearToSRGB },\n};\n\nconst ColorManagement = {\n\n\tlegacyMode: true,\n\n\tget workingColorSpace() {\n\n\t\treturn LinearSRGBColorSpace;\n\n\t},\n\n\tset workingColorSpace( colorSpace ) {\n\n\t\tconsole.warn( 'THREE.ColorManagement: .workingColorSpace is readonly.' );\n\n\t},\n\n\tconvert: function ( color, sourceColorSpace, targetColorSpace ) {\n\n\t\tif ( this.legacyMode || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) {\n\n\t\t\treturn color;\n\n\t\t}\n\n\t\tif ( FN[ sourceColorSpace ] && FN[ sourceColorSpace ][ targetColorSpace ] !== undefined ) {\n\n\t\t\tconst fn = FN[ sourceColorSpace ][ targetColorSpace ];\n\n\t\t\tcolor.r = fn( color.r );\n\t\t\tcolor.g = fn( color.g );\n\t\t\tcolor.b = fn( color.b );\n\n\t\t\treturn color;\n\n\t\t}\n\n\t\tthrow new Error( 'Unsupported color space conversion.' );\n\n\t},\n\n\tfromWorkingColorSpace: function ( color, targetColorSpace ) {\n\n\t\treturn this.convert( color, this.workingColorSpace, targetColorSpace );\n\n\t},\n\n\ttoWorkingColorSpace: function ( color, sourceColorSpace ) {\n\n\t\treturn this.convert( color, sourceColorSpace, this.workingColorSpace );\n\n\t},\n\n};\n\nconst _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\nconst _rgb = { r: 0, g: 0, b: 0 };\nconst _hslA = { h: 0, s: 0, l: 0 };\nconst _hslB = { h: 0, s: 0, l: 0 };\n\nfunction hue2rgb( p, q, t ) {\n\n\tif ( t < 0 ) t += 1;\n\tif ( t > 1 ) t -= 1;\n\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\tif ( t < 1 / 2 ) return q;\n\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\treturn p;\n\n}\n\nfunction toComponents( source, target ) {\n\n\ttarget.r = source.r;\n\ttarget.g = source.g;\n\ttarget.b = source.b;\n\n\treturn target;\n\n}\n\nclass Color {\n\n\tconstructor( r, g, b ) {\n\n\t\tthis.isColor = true;\n\n\t\tthis.r = 1;\n\t\tthis.g = 1;\n\t\tthis.b = 1;\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tset( value ) {\n\n\t\tif ( value && value.isColor ) {\n\n\t\t\tthis.copy( value );\n\n\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\tthis.setHex( value );\n\n\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\tthis.setStyle( value );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetScalar( scalar ) {\n\n\t\tthis.r = scalar;\n\t\tthis.g = scalar;\n\t\tthis.b = scalar;\n\n\t\treturn this;\n\n\t}\n\n\tsetHex( hex, colorSpace = SRGBColorSpace ) {\n\n\t\thex = Math.floor( hex );\n\n\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\treturn this;\n\n\t}\n\n\tsetRGB( r, g, b, colorSpace = LinearSRGBColorSpace ) {\n\n\t\tthis.r = r;\n\t\tthis.g = g;\n\t\tthis.b = b;\n\n\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\treturn this;\n\n\t}\n\n\tsetHSL( h, s, l, colorSpace = LinearSRGBColorSpace ) {\n\n\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\th = euclideanModulo( h, 1 );\n\t\ts = clamp( s, 0, 1 );\n\t\tl = clamp( l, 0, 1 );\n\n\t\tif ( s === 0 ) {\n\n\t\t\tthis.r = this.g = this.b = l;\n\n\t\t} else {\n\n\t\t\tconst p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\tconst q = ( 2 * l ) - p;\n\n\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t}\n\n\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\treturn this;\n\n\t}\n\n\tsetStyle( style, colorSpace = SRGBColorSpace ) {\n\n\t\tfunction handleAlpha( string ) {\n\n\t\t\tif ( string === undefined ) return;\n\n\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tlet m;\n\n\t\tif ( m = /^((?:rgb|hsl)a?)\\(([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t// rgb / hsl\n\n\t\t\tlet color;\n\t\t\tconst name = m[ 1 ];\n\t\t\tconst components = m[ 2 ];\n\n\t\t\tswitch ( name ) {\n\n\t\t\t\tcase 'rgb':\n\t\t\t\tcase 'rgba':\n\n\t\t\t\t\tif ( color = /^\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\t\t\t\t\thandleAlpha( color[ 4 ] );\n\n\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( color = /^\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\t\t\t\t\thandleAlpha( color[ 4 ] );\n\n\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'hsl':\n\t\t\t\tcase 'hsla':\n\n\t\t\t\t\tif ( color = /^\\s*(\\d*\\.?\\d+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(?:,\\s*(\\d*\\.?\\d+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\tconst h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\tconst s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\tconst l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\thandleAlpha( color[ 4 ] );\n\n\t\t\t\t\t\treturn this.setHSL( h, s, l, colorSpace );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t} else if ( m = /^\\#([A-Fa-f\\d]+)$/.exec( style ) ) {\n\n\t\t\t// hex color\n\n\t\t\tconst hex = m[ 1 ];\n\t\t\tconst size = hex.length;\n\n\t\t\tif ( size === 3 ) {\n\n\t\t\t\t// #ff0\n\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\t\t\treturn this;\n\n\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t// #ff0000\n\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\tColorManagement.toWorkingColorSpace( this, colorSpace );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( style && style.length > 0 ) {\n\n\t\t\treturn this.setColorName( style, colorSpace );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetColorName( style, colorSpace = SRGBColorSpace ) {\n\n\t\t// color keywords\n\t\tconst hex = _colorKeywords[ style.toLowerCase() ];\n\n\t\tif ( hex !== undefined ) {\n\n\t\t\t// red\n\t\t\tthis.setHex( hex, colorSpace );\n\n\t\t} else {\n\n\t\t\t// unknown color\n\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t}\n\n\tcopy( color ) {\n\n\t\tthis.r = color.r;\n\t\tthis.g = color.g;\n\t\tthis.b = color.b;\n\n\t\treturn this;\n\n\t}\n\n\tcopySRGBToLinear( color ) {\n\n\t\tthis.r = SRGBToLinear( color.r );\n\t\tthis.g = SRGBToLinear( color.g );\n\t\tthis.b = SRGBToLinear( color.b );\n\n\t\treturn this;\n\n\t}\n\n\tcopyLinearToSRGB( color ) {\n\n\t\tthis.r = LinearToSRGB( color.r );\n\t\tthis.g = LinearToSRGB( color.g );\n\t\tthis.b = LinearToSRGB( color.b );\n\n\t\treturn this;\n\n\t}\n\n\tconvertSRGBToLinear() {\n\n\t\tthis.copySRGBToLinear( this );\n\n\t\treturn this;\n\n\t}\n\n\tconvertLinearToSRGB() {\n\n\t\tthis.copyLinearToSRGB( this );\n\n\t\treturn this;\n\n\t}\n\n\tgetHex( colorSpace = SRGBColorSpace ) {\n\n\t\tColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );\n\n\t\treturn clamp( _rgb.r * 255, 0, 255 ) << 16 ^ clamp( _rgb.g * 255, 0, 255 ) << 8 ^ clamp( _rgb.b * 255, 0, 255 ) << 0;\n\n\t}\n\n\tgetHexString( colorSpace = SRGBColorSpace ) {\n\n\t\treturn ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( - 6 );\n\n\t}\n\n\tgetHSL( target, colorSpace = LinearSRGBColorSpace ) {\n\n\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\tColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );\n\n\t\tconst r = _rgb.r, g = _rgb.g, b = _rgb.b;\n\n\t\tconst max = Math.max( r, g, b );\n\t\tconst min = Math.min( r, g, b );\n\n\t\tlet hue, saturation;\n\t\tconst lightness = ( min + max ) / 2.0;\n\n\t\tif ( min === max ) {\n\n\t\t\thue = 0;\n\t\t\tsaturation = 0;\n\n\t\t} else {\n\n\t\t\tconst delta = max - min;\n\n\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\tswitch ( max ) {\n\n\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t}\n\n\t\t\thue /= 6;\n\n\t\t}\n\n\t\ttarget.h = hue;\n\t\ttarget.s = saturation;\n\t\ttarget.l = lightness;\n\n\t\treturn target;\n\n\t}\n\n\tgetRGB( target, colorSpace = LinearSRGBColorSpace ) {\n\n\t\tColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );\n\n\t\ttarget.r = _rgb.r;\n\t\ttarget.g = _rgb.g;\n\t\ttarget.b = _rgb.b;\n\n\t\treturn target;\n\n\t}\n\n\tgetStyle( colorSpace = SRGBColorSpace ) {\n\n\t\tColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );\n\n\t\tif ( colorSpace !== SRGBColorSpace ) {\n\n\t\t\t// Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).\n\t\t\treturn `color(${ colorSpace } ${ _rgb.r } ${ _rgb.g } ${ _rgb.b })`;\n\n\t\t}\n\n\t\treturn `rgb(${( _rgb.r * 255 ) | 0},${( _rgb.g * 255 ) | 0},${( _rgb.b * 255 ) | 0})`;\n\n\t}\n\n\toffsetHSL( h, s, l ) {\n\n\t\tthis.getHSL( _hslA );\n\n\t\t_hslA.h += h; _hslA.s += s; _hslA.l += l;\n\n\t\tthis.setHSL( _hslA.h, _hslA.s, _hslA.l );\n\n\t\treturn this;\n\n\t}\n\n\tadd( color ) {\n\n\t\tthis.r += color.r;\n\t\tthis.g += color.g;\n\t\tthis.b += color.b;\n\n\t\treturn this;\n\n\t}\n\n\taddColors( color1, color2 ) {\n\n\t\tthis.r = color1.r + color2.r;\n\t\tthis.g = color1.g + color2.g;\n\t\tthis.b = color1.b + color2.b;\n\n\t\treturn this;\n\n\t}\n\n\taddScalar( s ) {\n\n\t\tthis.r += s;\n\t\tthis.g += s;\n\t\tthis.b += s;\n\n\t\treturn this;\n\n\t}\n\n\tsub( color ) {\n\n\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( color ) {\n\n\t\tthis.r *= color.r;\n\t\tthis.g *= color.g;\n\t\tthis.b *= color.b;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( s ) {\n\n\t\tthis.r *= s;\n\t\tthis.g *= s;\n\t\tthis.b *= s;\n\n\t\treturn this;\n\n\t}\n\n\tlerp( color, alpha ) {\n\n\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpColors( color1, color2, alpha ) {\n\n\t\tthis.r = color1.r + ( color2.r - color1.r ) * alpha;\n\t\tthis.g = color1.g + ( color2.g - color1.g ) * alpha;\n\t\tthis.b = color1.b + ( color2.b - color1.b ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpHSL( color, alpha ) {\n\n\t\tthis.getHSL( _hslA );\n\t\tcolor.getHSL( _hslB );\n\n\t\tconst h = lerp( _hslA.h, _hslB.h, alpha );\n\t\tconst s = lerp( _hslA.s, _hslB.s, alpha );\n\t\tconst l = lerp( _hslA.l, _hslB.l, alpha );\n\n\t\tthis.setHSL( h, s, l );\n\n\t\treturn this;\n\n\t}\n\n\tequals( c ) {\n\n\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis.r = array[ offset ];\n\t\tthis.g = array[ offset + 1 ];\n\t\tthis.b = array[ offset + 2 ];\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this.r;\n\t\tarray[ offset + 1 ] = this.g;\n\t\tarray[ offset + 2 ] = this.b;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index ) {\n\n\t\tthis.r = attribute.getX( index );\n\t\tthis.g = attribute.getY( index );\n\t\tthis.b = attribute.getZ( index );\n\n\t\tif ( attribute.normalized === true ) {\n\n\t\t\t// assuming Uint8Array\n\n\t\t\tthis.r /= 255;\n\t\t\tthis.g /= 255;\n\t\t\tthis.b /= 255;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\treturn this.getHex();\n\n\t}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this.r;\n\t\tyield this.g;\n\t\tyield this.b;\n\n\t}\n\n}\n\nColor.NAMES = _colorKeywords;\n\nlet _canvas;\n\nclass ImageUtils {\n\n\tstatic getDataURL( image ) {\n\n\t\tif ( /^data:/i.test( image.src ) ) {\n\n\t\t\treturn image.src;\n\n\t\t}\n\n\t\tif ( typeof HTMLCanvasElement == 'undefined' ) {\n\n\t\t\treturn image.src;\n\n\t\t}\n\n\t\tlet canvas;\n\n\t\tif ( image instanceof HTMLCanvasElement ) {\n\n\t\t\tcanvas = image;\n\n\t\t} else {\n\n\t\t\tif ( _canvas === undefined ) _canvas = createElementNS( 'canvas' );\n\n\t\t\t_canvas.width = image.width;\n\t\t\t_canvas.height = image.height;\n\n\t\t\tconst context = _canvas.getContext( '2d' );\n\n\t\t\tif ( image instanceof ImageData ) {\n\n\t\t\t\tcontext.putImageData( image, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t}\n\n\t\t\tcanvas = _canvas;\n\n\t\t}\n\n\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons', image );\n\n\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t} else {\n\n\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t}\n\n\t}\n\n\tstatic sRGBToLinear( image ) {\n\n\t\tif ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||\n\t\t\t( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||\n\t\t\t( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {\n\n\t\t\tconst canvas = createElementNS( 'canvas' );\n\n\t\t\tcanvas.width = image.width;\n\t\t\tcanvas.height = image.height;\n\n\t\t\tconst context = canvas.getContext( '2d' );\n\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\tconst imageData = context.getImageData( 0, 0, image.width, image.height );\n\t\t\tconst data = imageData.data;\n\n\t\t\tfor ( let i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tdata[ i ] = SRGBToLinear( data[ i ] / 255 ) * 255;\n\n\t\t\t}\n\n\t\t\tcontext.putImageData( imageData, 0, 0 );\n\n\t\t\treturn canvas;\n\n\t\t} else if ( image.data ) {\n\n\t\t\tconst data = image.data.slice( 0 );\n\n\t\t\tfor ( let i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tif ( data instanceof Uint8Array || data instanceof Uint8ClampedArray ) {\n\n\t\t\t\t\tdata[ i ] = Math.floor( SRGBToLinear( data[ i ] / 255 ) * 255 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assuming float\n\n\t\t\t\t\tdata[ i ] = SRGBToLinear( data[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tdata: data,\n\t\t\t\twidth: image.width,\n\t\t\t\theight: image.height\n\t\t\t};\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.' );\n\t\t\treturn image;\n\n\t\t}\n\n\t}\n\n}\n\nclass Source {\n\n\tconstructor( data = null ) {\n\n\t\tthis.isSource = true;\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.data = data;\n\n\t\tthis.version = 0;\n\n\t}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) this.version ++;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst isRootObject = ( meta === undefined || typeof meta === 'string' );\n\n\t\tif ( ! isRootObject && meta.images[ this.uuid ] !== undefined ) {\n\n\t\t\treturn meta.images[ this.uuid ];\n\n\t\t}\n\n\t\tconst output = {\n\t\t\tuuid: this.uuid,\n\t\t\turl: ''\n\t\t};\n\n\t\tconst data = this.data;\n\n\t\tif ( data !== null ) {\n\n\t\t\tlet url;\n\n\t\t\tif ( Array.isArray( data ) ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\turl = [];\n\n\t\t\t\tfor ( let i = 0, l = data.length; i < l; i ++ ) {\n\n\t\t\t\t\tif ( data[ i ].isDataTexture ) {\n\n\t\t\t\t\t\turl.push( serializeImage( data[ i ].image ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\turl.push( serializeImage( data[ i ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// texture\n\n\t\t\t\turl = serializeImage( data );\n\n\t\t\t}\n\n\t\t\toutput.url = url;\n\n\t\t}\n\n\t\tif ( ! isRootObject ) {\n\n\t\t\tmeta.images[ this.uuid ] = output;\n\n\t\t}\n\n\t\treturn output;\n\n\t}\n\n}\n\nfunction serializeImage( image ) {\n\n\tif ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||\n\t\t( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||\n\t\t( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {\n\n\t\t// default images\n\n\t\treturn ImageUtils.getDataURL( image );\n\n\t} else {\n\n\t\tif ( image.data ) {\n\n\t\t\t// images of DataTexture\n\n\t\t\treturn {\n\t\t\t\tdata: Array.prototype.slice.call( image.data ),\n\t\t\t\twidth: image.width,\n\t\t\t\theight: image.height,\n\t\t\t\ttype: image.data.constructor.name\n\t\t\t};\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.Texture: Unable to serialize Texture.' );\n\t\t\treturn {};\n\n\t\t}\n\n\t}\n\n}\n\nlet textureId = 0;\n\nclass Texture extends EventDispatcher {\n\n\tconstructor( image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding ) {\n\n\t\tsuper();\n\n\t\tthis.isTexture = true;\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.source = new Source( image );\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping;\n\n\t\tthis.wrapS = wrapS;\n\t\tthis.wrapT = wrapT;\n\n\t\tthis.magFilter = magFilter;\n\t\tthis.minFilter = minFilter;\n\n\t\tthis.anisotropy = anisotropy;\n\n\t\tthis.format = format;\n\t\tthis.internalFormat = null;\n\t\tthis.type = type;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\t\tthis.center = new Vector2( 0, 0 );\n\t\tthis.rotation = 0;\n\n\t\tthis.matrixAutoUpdate = true;\n\t\tthis.matrix = new Matrix3();\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding;\n\n\t\tthis.userData = {};\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t\tthis.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not\n\t\tthis.needsPMREMUpdate = false; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures)\n\n\t}\n\n\tget image() {\n\n\t\treturn this.source.data;\n\n\t}\n\n\tset image( value ) {\n\n\t\tthis.source.data = value;\n\n\t}\n\n\tupdateMatrix() {\n\n\t\tthis.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.name = source.name;\n\n\t\tthis.source = source.source;\n\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\tthis.mapping = source.mapping;\n\n\t\tthis.wrapS = source.wrapS;\n\t\tthis.wrapT = source.wrapT;\n\n\t\tthis.magFilter = source.magFilter;\n\t\tthis.minFilter = source.minFilter;\n\n\t\tthis.anisotropy = source.anisotropy;\n\n\t\tthis.format = source.format;\n\t\tthis.internalFormat = source.internalFormat;\n\t\tthis.type = source.type;\n\n\t\tthis.offset.copy( source.offset );\n\t\tthis.repeat.copy( source.repeat );\n\t\tthis.center.copy( source.center );\n\t\tthis.rotation = source.rotation;\n\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\tthis.matrix.copy( source.matrix );\n\n\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\tthis.flipY = source.flipY;\n\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\tthis.encoding = source.encoding;\n\n\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\tthis.needsUpdate = true;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst isRootObject = ( meta === undefined || typeof meta === 'string' );\n\n\t\tif ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t}\n\n\t\tconst output = {\n\n\t\t\tmetadata: {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'Texture',\n\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t},\n\n\t\t\tuuid: this.uuid,\n\t\t\tname: this.name,\n\n\t\t\timage: this.source.toJSON( meta ).uuid,\n\n\t\t\tmapping: this.mapping,\n\n\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\tcenter: [ this.center.x, this.center.y ],\n\t\t\trotation: this.rotation,\n\n\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\tformat: this.format,\n\t\t\ttype: this.type,\n\t\t\tencoding: this.encoding,\n\n\t\t\tminFilter: this.minFilter,\n\t\t\tmagFilter: this.magFilter,\n\t\t\tanisotropy: this.anisotropy,\n\n\t\t\tflipY: this.flipY,\n\n\t\t\tpremultiplyAlpha: this.premultiplyAlpha,\n\t\t\tunpackAlignment: this.unpackAlignment\n\n\t\t};\n\n\t\tif ( JSON.stringify( this.userData ) !== '{}' ) output.userData = this.userData;\n\n\t\tif ( ! isRootObject ) {\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t}\n\n\t\treturn output;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n\ttransformUv( uv ) {\n\n\t\tif ( this.mapping !== UVMapping ) return uv;\n\n\t\tuv.applyMatrix3( this.matrix );\n\n\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.flipY ) {\n\n\t\t\tuv.y = 1 - uv.y;\n\n\t\t}\n\n\t\treturn uv;\n\n\t}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) {\n\n\t\t\tthis.version ++;\n\t\t\tthis.source.needsUpdate = true;\n\n\t\t}\n\n\t}\n\n}\n\nTexture.DEFAULT_IMAGE = null;\nTexture.DEFAULT_MAPPING = UVMapping;\n\nclass Vector4 {\n\n\tconstructor( x = 0, y = 0, z = 0, w = 1 ) {\n\n\t\tthis.isVector4 = true;\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.z = z;\n\t\tthis.w = w;\n\n\t}\n\n\tget width() {\n\n\t\treturn this.z;\n\n\t}\n\n\tset width( value ) {\n\n\t\tthis.z = value;\n\n\t}\n\n\tget height() {\n\n\t\treturn this.w;\n\n\t}\n\n\tset height( value ) {\n\n\t\tthis.w = value;\n\n\t}\n\n\tset( x, y, z, w ) {\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.z = z;\n\t\tthis.w = w;\n\n\t\treturn this;\n\n\t}\n\n\tsetScalar( scalar ) {\n\n\t\tthis.x = scalar;\n\t\tthis.y = scalar;\n\t\tthis.z = scalar;\n\t\tthis.w = scalar;\n\n\t\treturn this;\n\n\t}\n\n\tsetX( x ) {\n\n\t\tthis.x = x;\n\n\t\treturn this;\n\n\t}\n\n\tsetY( y ) {\n\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetZ( z ) {\n\n\t\tthis.z = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetW( w ) {\n\n\t\tthis.w = w;\n\n\t\treturn this;\n\n\t}\n\n\tsetComponent( index, value ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: this.x = value; break;\n\t\t\tcase 1: this.y = value; break;\n\t\t\tcase 2: this.z = value; break;\n\t\t\tcase 3: this.w = value; break;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetComponent( index ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: return this.x;\n\t\t\tcase 1: return this.y;\n\t\t\tcase 2: return this.z;\n\t\t\tcase 3: return this.w;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t}\n\n\tcopy( v ) {\n\n\t\tthis.x = v.x;\n\t\tthis.y = v.y;\n\t\tthis.z = v.z;\n\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\treturn this;\n\n\t}\n\n\tadd( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\treturn this.addVectors( v, w );\n\n\t\t}\n\n\t\tthis.x += v.x;\n\t\tthis.y += v.y;\n\t\tthis.z += v.z;\n\t\tthis.w += v.w;\n\n\t\treturn this;\n\n\t}\n\n\taddScalar( s ) {\n\n\t\tthis.x += s;\n\t\tthis.y += s;\n\t\tthis.z += s;\n\t\tthis.w += s;\n\n\t\treturn this;\n\n\t}\n\n\taddVectors( a, b ) {\n\n\t\tthis.x = a.x + b.x;\n\t\tthis.y = a.y + b.y;\n\t\tthis.z = a.z + b.z;\n\t\tthis.w = a.w + b.w;\n\n\t\treturn this;\n\n\t}\n\n\taddScaledVector( v, s ) {\n\n\t\tthis.x += v.x * s;\n\t\tthis.y += v.y * s;\n\t\tthis.z += v.z * s;\n\t\tthis.w += v.w * s;\n\n\t\treturn this;\n\n\t}\n\n\tsub( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\treturn this.subVectors( v, w );\n\n\t\t}\n\n\t\tthis.x -= v.x;\n\t\tthis.y -= v.y;\n\t\tthis.z -= v.z;\n\t\tthis.w -= v.w;\n\n\t\treturn this;\n\n\t}\n\n\tsubScalar( s ) {\n\n\t\tthis.x -= s;\n\t\tthis.y -= s;\n\t\tthis.z -= s;\n\t\tthis.w -= s;\n\n\t\treturn this;\n\n\t}\n\n\tsubVectors( a, b ) {\n\n\t\tthis.x = a.x - b.x;\n\t\tthis.y = a.y - b.y;\n\t\tthis.z = a.z - b.z;\n\t\tthis.w = a.w - b.w;\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( v ) {\n\n\t\tthis.x *= v.x;\n\t\tthis.y *= v.y;\n\t\tthis.z *= v.z;\n\t\tthis.w *= v.w;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( scalar ) {\n\n\t\tthis.x *= scalar;\n\t\tthis.y *= scalar;\n\t\tthis.z *= scalar;\n\t\tthis.w *= scalar;\n\n\t\treturn this;\n\n\t}\n\n\tapplyMatrix4( m ) {\n\n\t\tconst x = this.x, y = this.y, z = this.z, w = this.w;\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\treturn this;\n\n\t}\n\n\tdivideScalar( scalar ) {\n\n\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t}\n\n\tsetAxisAngleFromQuaternion( q ) {\n\n\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t// q is assumed to be normalized\n\n\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\tconst s = Math.sqrt( 1 - q.w * q.w );\n\n\t\tif ( s < 0.0001 ) {\n\n\t\t\tthis.x = 1;\n\t\t\tthis.y = 0;\n\t\t\tthis.z = 0;\n\n\t\t} else {\n\n\t\t\tthis.x = q.x / s;\n\t\t\tthis.y = q.y / s;\n\t\t\tthis.z = q.z / s;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetAxisAngleFromRotationMatrix( m ) {\n\n\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\tlet angle, x, y, z; // variables for result\n\t\tconst epsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\tte = m.elements,\n\n\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t// singularity found\n\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t}\n\n\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\tangle = Math.PI;\n\n\t\t\tconst xx = ( m11 + 1 ) / 2;\n\t\t\tconst yy = ( m22 + 1 ) / 2;\n\t\t\tconst zz = ( m33 + 1 ) / 2;\n\t\t\tconst xy = ( m12 + m21 ) / 4;\n\t\t\tconst xz = ( m13 + m31 ) / 4;\n\t\t\tconst yz = ( m23 + m32 ) / 4;\n\n\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\tx = 0;\n\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\ty = xy / x;\n\t\t\t\t\tz = xz / x;\n\n\t\t\t\t}\n\n\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\ty = 0;\n\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t} else {\n\n\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\tx = xy / y;\n\t\t\t\t\tz = yz / y;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\tz = 0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\tx = xz / z;\n\t\t\t\t\ty = yz / z;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.set( x, y, z, angle );\n\n\t\t\treturn this; // return 180 deg rotation\n\n\t\t}\n\n\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\tlet s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\tthis.x = ( m32 - m23 ) / s;\n\t\tthis.y = ( m13 - m31 ) / s;\n\t\tthis.z = ( m21 - m12 ) / s;\n\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\treturn this;\n\n\t}\n\n\tmin( v ) {\n\n\t\tthis.x = Math.min( this.x, v.x );\n\t\tthis.y = Math.min( this.y, v.y );\n\t\tthis.z = Math.min( this.z, v.z );\n\t\tthis.w = Math.min( this.w, v.w );\n\n\t\treturn this;\n\n\t}\n\n\tmax( v ) {\n\n\t\tthis.x = Math.max( this.x, v.x );\n\t\tthis.y = Math.max( this.y, v.y );\n\t\tthis.z = Math.max( this.z, v.z );\n\t\tthis.w = Math.max( this.w, v.w );\n\n\t\treturn this;\n\n\t}\n\n\tclamp( min, max ) {\n\n\t\t// assumes min < max, componentwise\n\n\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampScalar( minVal, maxVal ) {\n\n\t\tthis.x = Math.max( minVal, Math.min( maxVal, this.x ) );\n\t\tthis.y = Math.max( minVal, Math.min( maxVal, this.y ) );\n\t\tthis.z = Math.max( minVal, Math.min( maxVal, this.z ) );\n\t\tthis.w = Math.max( minVal, Math.min( maxVal, this.w ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampLength( min, max ) {\n\n\t\tconst length = this.length();\n\n\t\treturn this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );\n\n\t}\n\n\tfloor() {\n\n\t\tthis.x = Math.floor( this.x );\n\t\tthis.y = Math.floor( this.y );\n\t\tthis.z = Math.floor( this.z );\n\t\tthis.w = Math.floor( this.w );\n\n\t\treturn this;\n\n\t}\n\n\tceil() {\n\n\t\tthis.x = Math.ceil( this.x );\n\t\tthis.y = Math.ceil( this.y );\n\t\tthis.z = Math.ceil( this.z );\n\t\tthis.w = Math.ceil( this.w );\n\n\t\treturn this;\n\n\t}\n\n\tround() {\n\n\t\tthis.x = Math.round( this.x );\n\t\tthis.y = Math.round( this.y );\n\t\tthis.z = Math.round( this.z );\n\t\tthis.w = Math.round( this.w );\n\n\t\treturn this;\n\n\t}\n\n\troundToZero() {\n\n\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\treturn this;\n\n\t}\n\n\tnegate() {\n\n\t\tthis.x = - this.x;\n\t\tthis.y = - this.y;\n\t\tthis.z = - this.z;\n\t\tthis.w = - this.w;\n\n\t\treturn this;\n\n\t}\n\n\tdot( v ) {\n\n\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t}\n\n\tlengthSq() {\n\n\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t}\n\n\tlength() {\n\n\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t}\n\n\tmanhattanLength() {\n\n\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t}\n\n\tnormalize() {\n\n\t\treturn this.divideScalar( this.length() || 1 );\n\n\t}\n\n\tsetLength( length ) {\n\n\t\treturn this.normalize().multiplyScalar( length );\n\n\t}\n\n\tlerp( v, alpha ) {\n\n\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpVectors( v1, v2, alpha ) {\n\n\t\tthis.x = v1.x + ( v2.x - v1.x ) * alpha;\n\t\tthis.y = v1.y + ( v2.y - v1.y ) * alpha;\n\t\tthis.z = v1.z + ( v2.z - v1.z ) * alpha;\n\t\tthis.w = v1.w + ( v2.w - v1.w ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tequals( v ) {\n\n\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis.x = array[ offset ];\n\t\tthis.y = array[ offset + 1 ];\n\t\tthis.z = array[ offset + 2 ];\n\t\tthis.w = array[ offset + 3 ];\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this.x;\n\t\tarray[ offset + 1 ] = this.y;\n\t\tarray[ offset + 2 ] = this.z;\n\t\tarray[ offset + 3 ] = this.w;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index, offset ) {\n\n\t\tif ( offset !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t}\n\n\t\tthis.x = attribute.getX( index );\n\t\tthis.y = attribute.getY( index );\n\t\tthis.z = attribute.getZ( index );\n\t\tthis.w = attribute.getW( index );\n\n\t\treturn this;\n\n\t}\n\n\trandom() {\n\n\t\tthis.x = Math.random();\n\t\tthis.y = Math.random();\n\t\tthis.z = Math.random();\n\t\tthis.w = Math.random();\n\n\t\treturn this;\n\n\t}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this.x;\n\t\tyield this.y;\n\t\tyield this.z;\n\t\tyield this.w;\n\n\t}\n\n}\n\n/*\n In options, we can specify:\n * Texture parameters for an auto-generated target texture\n * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n*/\nclass WebGLRenderTarget extends EventDispatcher {\n\n\tconstructor( width, height, options = {} ) {\n\n\t\tsuper();\n\n\t\tthis.isWebGLRenderTarget = true;\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\t\tthis.depth = 1;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\tconst image = { width: width, height: height, depth: 1 };\n\n\t\tthis.texture = new Texture( image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t\tthis.texture.flipY = false;\n\t\tthis.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;\n\t\tthis.texture.internalFormat = options.internalFormat !== undefined ? options.internalFormat : null;\n\t\tthis.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;\n\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t\tthis.samples = options.samples !== undefined ? options.samples : 0;\n\n\t}\n\n\tsetSize( width, height, depth = 1 ) {\n\n\t\tif ( this.width !== width || this.height !== height || this.depth !== depth ) {\n\n\t\t\tthis.width = width;\n\t\t\tthis.height = height;\n\t\t\tthis.depth = depth;\n\n\t\t\tthis.texture.image.width = width;\n\t\t\tthis.texture.image.height = height;\n\t\t\tthis.texture.image.depth = depth;\n\n\t\t\tthis.dispose();\n\n\t\t}\n\n\t\tthis.viewport.set( 0, 0, width, height );\n\t\tthis.scissor.set( 0, 0, width, height );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.width = source.width;\n\t\tthis.height = source.height;\n\t\tthis.depth = source.depth;\n\n\t\tthis.viewport.copy( source.viewport );\n\n\t\tthis.texture = source.texture.clone();\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t\t// ensure image object is not shared, see #20328\n\n\t\tconst image = Object.assign( {}, source.texture.image );\n\t\tthis.texture.source = new Source( image );\n\n\t\tthis.depthBuffer = source.depthBuffer;\n\t\tthis.stencilBuffer = source.stencilBuffer;\n\n\t\tif ( source.depthTexture !== null ) this.depthTexture = source.depthTexture.clone();\n\n\t\tthis.samples = source.samples;\n\n\t\treturn this;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n}\n\nclass DataArrayTexture extends Texture {\n\n\tconstructor( data = null, width = 1, height = 1, depth = 1 ) {\n\n\t\tsuper( null );\n\n\t\tthis.isDataArrayTexture = true;\n\n\t\tthis.image = { data, width, height, depth };\n\n\t\tthis.magFilter = NearestFilter;\n\t\tthis.minFilter = NearestFilter;\n\n\t\tthis.wrapR = ClampToEdgeWrapping;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n}\n\nclass WebGLArrayRenderTarget extends WebGLRenderTarget {\n\n\tconstructor( width, height, depth ) {\n\n\t\tsuper( width, height );\n\n\t\tthis.isWebGLArrayRenderTarget = true;\n\n\t\tthis.depth = depth;\n\n\t\tthis.texture = new DataArrayTexture( null, width, height, depth );\n\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t}\n\n}\n\nclass Data3DTexture extends Texture {\n\n\tconstructor( data = null, width = 1, height = 1, depth = 1 ) {\n\n\t\t// We're going to add .setXXX() methods for setting properties later.\n\t\t// Users can still set in DataTexture3D directly.\n\t\t//\n\t\t//\tconst texture = new THREE.DataTexture3D( data, width, height, depth );\n\t\t// \ttexture.anisotropy = 16;\n\t\t//\n\t\t// See #14839\n\n\t\tsuper( null );\n\n\t\tthis.isData3DTexture = true;\n\n\t\tthis.image = { data, width, height, depth };\n\n\t\tthis.magFilter = NearestFilter;\n\t\tthis.minFilter = NearestFilter;\n\n\t\tthis.wrapR = ClampToEdgeWrapping;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n}\n\nclass WebGL3DRenderTarget extends WebGLRenderTarget {\n\n\tconstructor( width, height, depth ) {\n\n\t\tsuper( width, height );\n\n\t\tthis.isWebGL3DRenderTarget = true;\n\n\t\tthis.depth = depth;\n\n\t\tthis.texture = new Data3DTexture( null, width, height, depth );\n\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t}\n\n}\n\nclass WebGLMultipleRenderTargets extends WebGLRenderTarget {\n\n\tconstructor( width, height, count, options = {} ) {\n\n\t\tsuper( width, height, options );\n\n\t\tthis.isWebGLMultipleRenderTargets = true;\n\n\t\tconst texture = this.texture;\n\n\t\tthis.texture = [];\n\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\tthis.texture[ i ] = texture.clone();\n\t\t\tthis.texture[ i ].isRenderTargetTexture = true;\n\n\t\t}\n\n\t}\n\n\tsetSize( width, height, depth = 1 ) {\n\n\t\tif ( this.width !== width || this.height !== height || this.depth !== depth ) {\n\n\t\t\tthis.width = width;\n\t\t\tthis.height = height;\n\t\t\tthis.depth = depth;\n\n\t\t\tfor ( let i = 0, il = this.texture.length; i < il; i ++ ) {\n\n\t\t\t\tthis.texture[ i ].image.width = width;\n\t\t\t\tthis.texture[ i ].image.height = height;\n\t\t\t\tthis.texture[ i ].image.depth = depth;\n\n\t\t\t}\n\n\t\t\tthis.dispose();\n\n\t\t}\n\n\t\tthis.viewport.set( 0, 0, width, height );\n\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.dispose();\n\n\t\tthis.width = source.width;\n\t\tthis.height = source.height;\n\t\tthis.depth = source.depth;\n\n\t\tthis.viewport.set( 0, 0, this.width, this.height );\n\t\tthis.scissor.set( 0, 0, this.width, this.height );\n\n\t\tthis.depthBuffer = source.depthBuffer;\n\t\tthis.stencilBuffer = source.stencilBuffer;\n\n\t\tif ( source.depthTexture !== null ) this.depthTexture = source.depthTexture.clone();\n\n\t\tthis.texture.length = 0;\n\n\t\tfor ( let i = 0, il = source.texture.length; i < il; i ++ ) {\n\n\t\t\tthis.texture[ i ] = source.texture[ i ].clone();\n\t\t\tthis.texture[ i ].isRenderTargetTexture = true;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass Quaternion {\n\n\tconstructor( x = 0, y = 0, z = 0, w = 1 ) {\n\n\t\tthis.isQuaternion = true;\n\n\t\tthis._x = x;\n\t\tthis._y = y;\n\t\tthis._z = z;\n\t\tthis._w = w;\n\n\t}\n\n\tstatic slerp( qa, qb, qm, t ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead.' );\n\t\treturn qm.slerpQuaternions( qa, qb, t );\n\n\t}\n\n\tstatic slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\tlet x0 = src0[ srcOffset0 + 0 ],\n\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\tw0 = src0[ srcOffset0 + 3 ];\n\n\t\tconst x1 = src1[ srcOffset1 + 0 ],\n\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\tif ( t === 0 ) {\n\n\t\t\tdst[ dstOffset + 0 ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( t === 1 ) {\n\n\t\t\tdst[ dstOffset + 0 ] = x1;\n\t\t\tdst[ dstOffset + 1 ] = y1;\n\t\t\tdst[ dstOffset + 2 ] = z1;\n\t\t\tdst[ dstOffset + 3 ] = w1;\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\tlet s = 1 - t;\n\t\t\tconst cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\tconst sin = Math.sqrt( sqrSin ),\n\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t}\n\n\t\t\tconst tDir = t * dir;\n\n\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t// Normalize in case we just did a lerp:\n\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\tconst f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\tx0 *= f;\n\t\t\t\ty0 *= f;\n\t\t\t\tz0 *= f;\n\t\t\t\tw0 *= f;\n\n\t\t\t}\n\n\t\t}\n\n\t\tdst[ dstOffset ] = x0;\n\t\tdst[ dstOffset + 1 ] = y0;\n\t\tdst[ dstOffset + 2 ] = z0;\n\t\tdst[ dstOffset + 3 ] = w0;\n\n\t}\n\n\tstatic multiplyQuaternionsFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) {\n\n\t\tconst x0 = src0[ srcOffset0 ];\n\t\tconst y0 = src0[ srcOffset0 + 1 ];\n\t\tconst z0 = src0[ srcOffset0 + 2 ];\n\t\tconst w0 = src0[ srcOffset0 + 3 ];\n\n\t\tconst x1 = src1[ srcOffset1 ];\n\t\tconst y1 = src1[ srcOffset1 + 1 ];\n\t\tconst z1 = src1[ srcOffset1 + 2 ];\n\t\tconst w1 = src1[ srcOffset1 + 3 ];\n\n\t\tdst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;\n\t\tdst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;\n\t\tdst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;\n\t\tdst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;\n\n\t\treturn dst;\n\n\t}\n\n\tget x() {\n\n\t\treturn this._x;\n\n\t}\n\n\tset x( value ) {\n\n\t\tthis._x = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget y() {\n\n\t\treturn this._y;\n\n\t}\n\n\tset y( value ) {\n\n\t\tthis._y = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget z() {\n\n\t\treturn this._z;\n\n\t}\n\n\tset z( value ) {\n\n\t\tthis._z = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget w() {\n\n\t\treturn this._w;\n\n\t}\n\n\tset w( value ) {\n\n\t\tthis._w = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tset( x, y, z, w ) {\n\n\t\tthis._x = x;\n\t\tthis._y = y;\n\t\tthis._z = z;\n\t\tthis._w = w;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t}\n\n\tcopy( quaternion ) {\n\n\t\tthis._x = quaternion.x;\n\t\tthis._y = quaternion.y;\n\t\tthis._z = quaternion.z;\n\t\tthis._w = quaternion.w;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromEuler( euler, update ) {\n\n\t\tif ( ! ( euler && euler.isEuler ) ) {\n\n\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t}\n\n\t\tconst x = euler._x, y = euler._y, z = euler._z, order = euler._order;\n\n\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t//\tcontent/SpinCalc.m\n\n\t\tconst cos = Math.cos;\n\t\tconst sin = Math.sin;\n\n\t\tconst c1 = cos( x / 2 );\n\t\tconst c2 = cos( y / 2 );\n\t\tconst c3 = cos( z / 2 );\n\n\t\tconst s1 = sin( x / 2 );\n\t\tconst s2 = sin( y / 2 );\n\t\tconst s3 = sin( z / 2 );\n\n\t\tswitch ( order ) {\n\n\t\t\tcase 'XYZ':\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'YXZ':\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'ZXY':\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'ZYX':\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'YZX':\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tcase 'XZY':\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order );\n\n\t\t}\n\n\t\tif ( update !== false ) this._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromAxisAngle( axis, angle ) {\n\n\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t// assumes axis is normalized\n\n\t\tconst halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\tthis._x = axis.x * s;\n\t\tthis._y = axis.y * s;\n\t\tthis._z = axis.z * s;\n\t\tthis._w = Math.cos( halfAngle );\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromRotationMatrix( m ) {\n\n\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\tconst te = m.elements,\n\n\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\ttrace = m11 + m22 + m33;\n\n\t\tif ( trace > 0 ) {\n\n\t\t\tconst s = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\tthis._w = 0.25 / s;\n\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\tconst s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\tthis._x = 0.25 * s;\n\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t} else if ( m22 > m33 ) {\n\n\t\t\tconst s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\tthis._y = 0.25 * s;\n\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t} else {\n\n\t\t\tconst s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\tthis._z = 0.25 * s;\n\n\t\t}\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromUnitVectors( vFrom, vTo ) {\n\n\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\tlet r = vFrom.dot( vTo ) + 1;\n\n\t\tif ( r < Number.EPSILON ) {\n\n\t\t\t// vFrom and vTo point in opposite directions\n\n\t\t\tr = 0;\n\n\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\tthis._x = - vFrom.y;\n\t\t\t\tthis._y = vFrom.x;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = r;\n\n\t\t\t} else {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = - vFrom.z;\n\t\t\t\tthis._z = vFrom.y;\n\t\t\t\tthis._w = r;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3\n\n\t\t\tthis._x = vFrom.y * vTo.z - vFrom.z * vTo.y;\n\t\t\tthis._y = vFrom.z * vTo.x - vFrom.x * vTo.z;\n\t\t\tthis._z = vFrom.x * vTo.y - vFrom.y * vTo.x;\n\t\t\tthis._w = r;\n\n\t\t}\n\n\t\treturn this.normalize();\n\n\t}\n\n\tangleTo( q ) {\n\n\t\treturn 2 * Math.acos( Math.abs( clamp( this.dot( q ), - 1, 1 ) ) );\n\n\t}\n\n\trotateTowards( q, step ) {\n\n\t\tconst angle = this.angleTo( q );\n\n\t\tif ( angle === 0 ) return this;\n\n\t\tconst t = Math.min( 1, step / angle );\n\n\t\tthis.slerp( q, t );\n\n\t\treturn this;\n\n\t}\n\n\tidentity() {\n\n\t\treturn this.set( 0, 0, 0, 1 );\n\n\t}\n\n\tinvert() {\n\n\t\t// quaternion is assumed to have unit length\n\n\t\treturn this.conjugate();\n\n\t}\n\n\tconjugate() {\n\n\t\tthis._x *= - 1;\n\t\tthis._y *= - 1;\n\t\tthis._z *= - 1;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tdot( v ) {\n\n\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t}\n\n\tlengthSq() {\n\n\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t}\n\n\tlength() {\n\n\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t}\n\n\tnormalize() {\n\n\t\tlet l = this.length();\n\n\t\tif ( l === 0 ) {\n\n\t\t\tthis._x = 0;\n\t\t\tthis._y = 0;\n\t\t\tthis._z = 0;\n\t\t\tthis._w = 1;\n\n\t\t} else {\n\n\t\t\tl = 1 / l;\n\n\t\t\tthis._x = this._x * l;\n\t\t\tthis._y = this._y * l;\n\t\t\tthis._z = this._z * l;\n\t\t\tthis._w = this._w * l;\n\n\t\t}\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( q, p ) {\n\n\t\tif ( p !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t}\n\n\t\treturn this.multiplyQuaternions( this, q );\n\n\t}\n\n\tpremultiply( q ) {\n\n\t\treturn this.multiplyQuaternions( q, this );\n\n\t}\n\n\tmultiplyQuaternions( a, b ) {\n\n\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\tconst qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\tconst qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tslerp( qb, t ) {\n\n\t\tif ( t === 0 ) return this;\n\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\tconst x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\tlet cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\tthis._w = - qb._w;\n\t\t\tthis._x = - qb._x;\n\t\t\tthis._y = - qb._y;\n\t\t\tthis._z = - qb._z;\n\n\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t} else {\n\n\t\t\tthis.copy( qb );\n\n\t\t}\n\n\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\tthis._w = w;\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tconst sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;\n\n\t\tif ( sqrSinHalfTheta <= Number.EPSILON ) {\n\n\t\t\tconst s = 1 - t;\n\t\t\tthis._w = s * w + t * this._w;\n\t\t\tthis._x = s * x + t * this._x;\n\t\t\tthis._y = s * y + t * this._y;\n\t\t\tthis._z = s * z + t * this._z;\n\n\t\t\tthis.normalize();\n\t\t\tthis._onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tconst sinHalfTheta = Math.sqrt( sqrSinHalfTheta );\n\t\tconst halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\tconst ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tslerpQuaternions( qa, qb, t ) {\n\n\t\treturn this.copy( qa ).slerp( qb, t );\n\n\t}\n\n\trandom() {\n\n\t\t// Derived from http://planning.cs.uiuc.edu/node198.html\n\t\t// Note, this source uses w, x, y, z ordering,\n\t\t// so we swap the order below.\n\n\t\tconst u1 = Math.random();\n\t\tconst sqrt1u1 = Math.sqrt( 1 - u1 );\n\t\tconst sqrtu1 = Math.sqrt( u1 );\n\n\t\tconst u2 = 2 * Math.PI * Math.random();\n\n\t\tconst u3 = 2 * Math.PI * Math.random();\n\n\t\treturn this.set(\n\t\t\tsqrt1u1 * Math.cos( u2 ),\n\t\t\tsqrtu1 * Math.sin( u3 ),\n\t\t\tsqrtu1 * Math.cos( u3 ),\n\t\t\tsqrt1u1 * Math.sin( u2 ),\n\t\t);\n\n\t}\n\n\tequals( quaternion ) {\n\n\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis._x = array[ offset ];\n\t\tthis._y = array[ offset + 1 ];\n\t\tthis._z = array[ offset + 2 ];\n\t\tthis._w = array[ offset + 3 ];\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this._x;\n\t\tarray[ offset + 1 ] = this._y;\n\t\tarray[ offset + 2 ] = this._z;\n\t\tarray[ offset + 3 ] = this._w;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index ) {\n\n\t\tthis._x = attribute.getX( index );\n\t\tthis._y = attribute.getY( index );\n\t\tthis._z = attribute.getZ( index );\n\t\tthis._w = attribute.getW( index );\n\n\t\treturn this;\n\n\t}\n\n\t_onChange( callback ) {\n\n\t\tthis._onChangeCallback = callback;\n\n\t\treturn this;\n\n\t}\n\n\t_onChangeCallback() {}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this._x;\n\t\tyield this._y;\n\t\tyield this._z;\n\t\tyield this._w;\n\n\t}\n\n}\n\nclass Vector3 {\n\n\tconstructor( x = 0, y = 0, z = 0 ) {\n\n\t\tthis.isVector3 = true;\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.z = z;\n\n\t}\n\n\tset( x, y, z ) {\n\n\t\tif ( z === undefined ) z = this.z; // sprite.scale.set(x,y)\n\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.z = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetScalar( scalar ) {\n\n\t\tthis.x = scalar;\n\t\tthis.y = scalar;\n\t\tthis.z = scalar;\n\n\t\treturn this;\n\n\t}\n\n\tsetX( x ) {\n\n\t\tthis.x = x;\n\n\t\treturn this;\n\n\t}\n\n\tsetY( y ) {\n\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetZ( z ) {\n\n\t\tthis.z = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetComponent( index, value ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: this.x = value; break;\n\t\t\tcase 1: this.y = value; break;\n\t\t\tcase 2: this.z = value; break;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetComponent( index ) {\n\n\t\tswitch ( index ) {\n\n\t\t\tcase 0: return this.x;\n\t\t\tcase 1: return this.y;\n\t\t\tcase 2: return this.z;\n\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t}\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t}\n\n\tcopy( v ) {\n\n\t\tthis.x = v.x;\n\t\tthis.y = v.y;\n\t\tthis.z = v.z;\n\n\t\treturn this;\n\n\t}\n\n\tadd( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\treturn this.addVectors( v, w );\n\n\t\t}\n\n\t\tthis.x += v.x;\n\t\tthis.y += v.y;\n\t\tthis.z += v.z;\n\n\t\treturn this;\n\n\t}\n\n\taddScalar( s ) {\n\n\t\tthis.x += s;\n\t\tthis.y += s;\n\t\tthis.z += s;\n\n\t\treturn this;\n\n\t}\n\n\taddVectors( a, b ) {\n\n\t\tthis.x = a.x + b.x;\n\t\tthis.y = a.y + b.y;\n\t\tthis.z = a.z + b.z;\n\n\t\treturn this;\n\n\t}\n\n\taddScaledVector( v, s ) {\n\n\t\tthis.x += v.x * s;\n\t\tthis.y += v.y * s;\n\t\tthis.z += v.z * s;\n\n\t\treturn this;\n\n\t}\n\n\tsub( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\treturn this.subVectors( v, w );\n\n\t\t}\n\n\t\tthis.x -= v.x;\n\t\tthis.y -= v.y;\n\t\tthis.z -= v.z;\n\n\t\treturn this;\n\n\t}\n\n\tsubScalar( s ) {\n\n\t\tthis.x -= s;\n\t\tthis.y -= s;\n\t\tthis.z -= s;\n\n\t\treturn this;\n\n\t}\n\n\tsubVectors( a, b ) {\n\n\t\tthis.x = a.x - b.x;\n\t\tthis.y = a.y - b.y;\n\t\tthis.z = a.z - b.z;\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t}\n\n\t\tthis.x *= v.x;\n\t\tthis.y *= v.y;\n\t\tthis.z *= v.z;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( scalar ) {\n\n\t\tthis.x *= scalar;\n\t\tthis.y *= scalar;\n\t\tthis.z *= scalar;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyVectors( a, b ) {\n\n\t\tthis.x = a.x * b.x;\n\t\tthis.y = a.y * b.y;\n\t\tthis.z = a.z * b.z;\n\n\t\treturn this;\n\n\t}\n\n\tapplyEuler( euler ) {\n\n\t\tif ( ! ( euler && euler.isEuler ) ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t}\n\n\t\treturn this.applyQuaternion( _quaternion$4.setFromEuler( euler ) );\n\n\t}\n\n\tapplyAxisAngle( axis, angle ) {\n\n\t\treturn this.applyQuaternion( _quaternion$4.setFromAxisAngle( axis, angle ) );\n\n\t}\n\n\tapplyMatrix3( m ) {\n\n\t\tconst x = this.x, y = this.y, z = this.z;\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\treturn this;\n\n\t}\n\n\tapplyNormalMatrix( m ) {\n\n\t\treturn this.applyMatrix3( m ).normalize();\n\n\t}\n\n\tapplyMatrix4( m ) {\n\n\t\tconst x = this.x, y = this.y, z = this.z;\n\t\tconst e = m.elements;\n\n\t\tconst w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );\n\n\t\tthis.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;\n\t\tthis.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;\n\t\tthis.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;\n\n\t\treturn this;\n\n\t}\n\n\tapplyQuaternion( q ) {\n\n\t\tconst x = this.x, y = this.y, z = this.z;\n\t\tconst qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t// calculate quat * vector\n\n\t\tconst ix = qw * x + qy * z - qz * y;\n\t\tconst iy = qw * y + qz * x - qx * z;\n\t\tconst iz = qw * z + qx * y - qy * x;\n\t\tconst iw = - qx * x - qy * y - qz * z;\n\n\t\t// calculate result * inverse quat\n\n\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\treturn this;\n\n\t}\n\n\tproject( camera ) {\n\n\t\treturn this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix );\n\n\t}\n\n\tunproject( camera ) {\n\n\t\treturn this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld );\n\n\t}\n\n\ttransformDirection( m ) {\n\n\t\t// input: THREE.Matrix4 affine matrix\n\t\t// vector interpreted as a direction\n\n\t\tconst x = this.x, y = this.y, z = this.z;\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\treturn this.normalize();\n\n\t}\n\n\tdivide( v ) {\n\n\t\tthis.x /= v.x;\n\t\tthis.y /= v.y;\n\t\tthis.z /= v.z;\n\n\t\treturn this;\n\n\t}\n\n\tdivideScalar( scalar ) {\n\n\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t}\n\n\tmin( v ) {\n\n\t\tthis.x = Math.min( this.x, v.x );\n\t\tthis.y = Math.min( this.y, v.y );\n\t\tthis.z = Math.min( this.z, v.z );\n\n\t\treturn this;\n\n\t}\n\n\tmax( v ) {\n\n\t\tthis.x = Math.max( this.x, v.x );\n\t\tthis.y = Math.max( this.y, v.y );\n\t\tthis.z = Math.max( this.z, v.z );\n\n\t\treturn this;\n\n\t}\n\n\tclamp( min, max ) {\n\n\t\t// assumes min < max, componentwise\n\n\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampScalar( minVal, maxVal ) {\n\n\t\tthis.x = Math.max( minVal, Math.min( maxVal, this.x ) );\n\t\tthis.y = Math.max( minVal, Math.min( maxVal, this.y ) );\n\t\tthis.z = Math.max( minVal, Math.min( maxVal, this.z ) );\n\n\t\treturn this;\n\n\t}\n\n\tclampLength( min, max ) {\n\n\t\tconst length = this.length();\n\n\t\treturn this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );\n\n\t}\n\n\tfloor() {\n\n\t\tthis.x = Math.floor( this.x );\n\t\tthis.y = Math.floor( this.y );\n\t\tthis.z = Math.floor( this.z );\n\n\t\treturn this;\n\n\t}\n\n\tceil() {\n\n\t\tthis.x = Math.ceil( this.x );\n\t\tthis.y = Math.ceil( this.y );\n\t\tthis.z = Math.ceil( this.z );\n\n\t\treturn this;\n\n\t}\n\n\tround() {\n\n\t\tthis.x = Math.round( this.x );\n\t\tthis.y = Math.round( this.y );\n\t\tthis.z = Math.round( this.z );\n\n\t\treturn this;\n\n\t}\n\n\troundToZero() {\n\n\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\treturn this;\n\n\t}\n\n\tnegate() {\n\n\t\tthis.x = - this.x;\n\t\tthis.y = - this.y;\n\t\tthis.z = - this.z;\n\n\t\treturn this;\n\n\t}\n\n\tdot( v ) {\n\n\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t}\n\n\t// TODO lengthSquared?\n\n\tlengthSq() {\n\n\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t}\n\n\tlength() {\n\n\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t}\n\n\tmanhattanLength() {\n\n\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t}\n\n\tnormalize() {\n\n\t\treturn this.divideScalar( this.length() || 1 );\n\n\t}\n\n\tsetLength( length ) {\n\n\t\treturn this.normalize().multiplyScalar( length );\n\n\t}\n\n\tlerp( v, alpha ) {\n\n\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tlerpVectors( v1, v2, alpha ) {\n\n\t\tthis.x = v1.x + ( v2.x - v1.x ) * alpha;\n\t\tthis.y = v1.y + ( v2.y - v1.y ) * alpha;\n\t\tthis.z = v1.z + ( v2.z - v1.z ) * alpha;\n\n\t\treturn this;\n\n\t}\n\n\tcross( v, w ) {\n\n\t\tif ( w !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\treturn this.crossVectors( v, w );\n\n\t\t}\n\n\t\treturn this.crossVectors( this, v );\n\n\t}\n\n\tcrossVectors( a, b ) {\n\n\t\tconst ax = a.x, ay = a.y, az = a.z;\n\t\tconst bx = b.x, by = b.y, bz = b.z;\n\n\t\tthis.x = ay * bz - az * by;\n\t\tthis.y = az * bx - ax * bz;\n\t\tthis.z = ax * by - ay * bx;\n\n\t\treturn this;\n\n\t}\n\n\tprojectOnVector( v ) {\n\n\t\tconst denominator = v.lengthSq();\n\n\t\tif ( denominator === 0 ) return this.set( 0, 0, 0 );\n\n\t\tconst scalar = v.dot( this ) / denominator;\n\n\t\treturn this.copy( v ).multiplyScalar( scalar );\n\n\t}\n\n\tprojectOnPlane( planeNormal ) {\n\n\t\t_vector$c.copy( this ).projectOnVector( planeNormal );\n\n\t\treturn this.sub( _vector$c );\n\n\t}\n\n\treflect( normal ) {\n\n\t\t// reflect incident vector off plane orthogonal to normal\n\t\t// normal is assumed to have unit length\n\n\t\treturn this.sub( _vector$c.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t}\n\n\tangleTo( v ) {\n\n\t\tconst denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );\n\n\t\tif ( denominator === 0 ) return Math.PI / 2;\n\n\t\tconst theta = this.dot( v ) / denominator;\n\n\t\t// clamp, to handle numerical problems\n\n\t\treturn Math.acos( clamp( theta, - 1, 1 ) );\n\n\t}\n\n\tdistanceTo( v ) {\n\n\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t}\n\n\tdistanceToSquared( v ) {\n\n\t\tconst dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t}\n\n\tmanhattanDistanceTo( v ) {\n\n\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t}\n\n\tsetFromSpherical( s ) {\n\n\t\treturn this.setFromSphericalCoords( s.radius, s.phi, s.theta );\n\n\t}\n\n\tsetFromSphericalCoords( radius, phi, theta ) {\n\n\t\tconst sinPhiRadius = Math.sin( phi ) * radius;\n\n\t\tthis.x = sinPhiRadius * Math.sin( theta );\n\t\tthis.y = Math.cos( phi ) * radius;\n\t\tthis.z = sinPhiRadius * Math.cos( theta );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromCylindrical( c ) {\n\n\t\treturn this.setFromCylindricalCoords( c.radius, c.theta, c.y );\n\n\t}\n\n\tsetFromCylindricalCoords( radius, theta, y ) {\n\n\t\tthis.x = radius * Math.sin( theta );\n\t\tthis.y = y;\n\t\tthis.z = radius * Math.cos( theta );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrixPosition( m ) {\n\n\t\tconst e = m.elements;\n\n\t\tthis.x = e[ 12 ];\n\t\tthis.y = e[ 13 ];\n\t\tthis.z = e[ 14 ];\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrixScale( m ) {\n\n\t\tconst sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\tconst sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\tconst sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\tthis.x = sx;\n\t\tthis.y = sy;\n\t\tthis.z = sz;\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrixColumn( m, index ) {\n\n\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t}\n\n\tsetFromMatrix3Column( m, index ) {\n\n\t\treturn this.fromArray( m.elements, index * 3 );\n\n\t}\n\n\tsetFromEuler( e ) {\n\n\t\tthis.x = e._x;\n\t\tthis.y = e._y;\n\t\tthis.z = e._z;\n\n\t\treturn this;\n\n\t}\n\n\tequals( v ) {\n\n\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tthis.x = array[ offset ];\n\t\tthis.y = array[ offset + 1 ];\n\t\tthis.z = array[ offset + 2 ];\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this.x;\n\t\tarray[ offset + 1 ] = this.y;\n\t\tarray[ offset + 2 ] = this.z;\n\n\t\treturn array;\n\n\t}\n\n\tfromBufferAttribute( attribute, index, offset ) {\n\n\t\tif ( offset !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t}\n\n\t\tthis.x = attribute.getX( index );\n\t\tthis.y = attribute.getY( index );\n\t\tthis.z = attribute.getZ( index );\n\n\t\treturn this;\n\n\t}\n\n\trandom() {\n\n\t\tthis.x = Math.random();\n\t\tthis.y = Math.random();\n\t\tthis.z = Math.random();\n\n\t\treturn this;\n\n\t}\n\n\trandomDirection() {\n\n\t\t// Derived from https://mathworld.wolfram.com/SpherePointPicking.html\n\n\t\tconst u = ( Math.random() - 0.5 ) * 2;\n\t\tconst t = Math.random() * Math.PI * 2;\n\t\tconst f = Math.sqrt( 1 - u ** 2 );\n\n\t\tthis.x = f * Math.cos( t );\n\t\tthis.y = f * Math.sin( t );\n\t\tthis.z = u;\n\n\t\treturn this;\n\n\t}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this.x;\n\t\tyield this.y;\n\t\tyield this.z;\n\n\t}\n\n}\n\nconst _vector$c = /*@__PURE__*/ new Vector3();\nconst _quaternion$4 = /*@__PURE__*/ new Quaternion();\n\nclass Box3 {\n\n\tconstructor( min = new Vector3( + Infinity, + Infinity, + Infinity ), max = new Vector3( - Infinity, - Infinity, - Infinity ) ) {\n\n\t\tthis.isBox3 = true;\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tset( min, max ) {\n\n\t\tthis.min.copy( min );\n\t\tthis.max.copy( max );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromArray( array ) {\n\n\t\tlet minX = + Infinity;\n\t\tlet minY = + Infinity;\n\t\tlet minZ = + Infinity;\n\n\t\tlet maxX = - Infinity;\n\t\tlet maxY = - Infinity;\n\t\tlet maxZ = - Infinity;\n\n\t\tfor ( let i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\tconst x = array[ i ];\n\t\t\tconst y = array[ i + 1 ];\n\t\t\tconst z = array[ i + 2 ];\n\n\t\t\tif ( x < minX ) minX = x;\n\t\t\tif ( y < minY ) minY = y;\n\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\tif ( x > maxX ) maxX = x;\n\t\t\tif ( y > maxY ) maxY = y;\n\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t}\n\n\t\tthis.min.set( minX, minY, minZ );\n\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromBufferAttribute( attribute ) {\n\n\t\tlet minX = + Infinity;\n\t\tlet minY = + Infinity;\n\t\tlet minZ = + Infinity;\n\n\t\tlet maxX = - Infinity;\n\t\tlet maxY = - Infinity;\n\t\tlet maxZ = - Infinity;\n\n\t\tfor ( let i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\tconst x = attribute.getX( i );\n\t\t\tconst y = attribute.getY( i );\n\t\t\tconst z = attribute.getZ( i );\n\n\t\t\tif ( x < minX ) minX = x;\n\t\t\tif ( y < minY ) minY = y;\n\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\tif ( x > maxX ) maxX = x;\n\t\t\tif ( y > maxY ) maxY = y;\n\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t}\n\n\t\tthis.min.set( minX, minY, minZ );\n\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPoints( points ) {\n\n\t\tthis.makeEmpty();\n\n\t\tfor ( let i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetFromCenterAndSize( center, size ) {\n\n\t\tconst halfSize = _vector$b.copy( size ).multiplyScalar( 0.5 );\n\n\t\tthis.min.copy( center ).sub( halfSize );\n\t\tthis.max.copy( center ).add( halfSize );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromObject( object, precise = false ) {\n\n\t\tthis.makeEmpty();\n\n\t\treturn this.expandByObject( object, precise );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( box ) {\n\n\t\tthis.min.copy( box.min );\n\t\tthis.max.copy( box.max );\n\n\t\treturn this;\n\n\t}\n\n\tmakeEmpty() {\n\n\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\treturn this;\n\n\t}\n\n\tisEmpty() {\n\n\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t}\n\n\tgetCenter( target ) {\n\n\t\treturn this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t}\n\n\tgetSize( target ) {\n\n\t\treturn this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min );\n\n\t}\n\n\texpandByPoint( point ) {\n\n\t\tthis.min.min( point );\n\t\tthis.max.max( point );\n\n\t\treturn this;\n\n\t}\n\n\texpandByVector( vector ) {\n\n\t\tthis.min.sub( vector );\n\t\tthis.max.add( vector );\n\n\t\treturn this;\n\n\t}\n\n\texpandByScalar( scalar ) {\n\n\t\tthis.min.addScalar( - scalar );\n\t\tthis.max.addScalar( scalar );\n\n\t\treturn this;\n\n\t}\n\n\texpandByObject( object, precise = false ) {\n\n\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t// accounting for both the object's, and children's, world transforms\n\n\t\tobject.updateWorldMatrix( false, false );\n\n\t\tconst geometry = object.geometry;\n\n\t\tif ( geometry !== undefined ) {\n\n\t\t\tif ( precise && geometry.attributes != undefined && geometry.attributes.position !== undefined ) {\n\n\t\t\t\tconst position = geometry.attributes.position;\n\t\t\t\tfor ( let i = 0, l = position.count; i < l; i ++ ) {\n\n\t\t\t\t\t_vector$b.fromBufferAttribute( position, i ).applyMatrix4( object.matrixWorld );\n\t\t\t\t\tthis.expandByPoint( _vector$b );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( geometry.boundingBox === null ) {\n\n\t\t\t\t\tgeometry.computeBoundingBox();\n\n\t\t\t\t}\n\n\t\t\t\t_box$3.copy( geometry.boundingBox );\n\t\t\t\t_box$3.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tthis.union( _box$3 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst children = object.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tthis.expandByObject( children[ i ], precise );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t}\n\n\tcontainsBox( box ) {\n\n\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t}\n\n\tgetParameter( point, target ) {\n\n\t\t// This can potentially have a divide by zero if the box\n\t\t// has a size dimension of 0.\n\n\t\treturn target.set(\n\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t);\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\t// using 6 splitting planes to rule out intersections.\n\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\t// Find the point on the AABB closest to the sphere center.\n\t\tthis.clampPoint( sphere.center, _vector$b );\n\n\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\treturn _vector$b.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t}\n\n\tintersectsPlane( plane ) {\n\n\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\tlet min, max;\n\n\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t} else {\n\n\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t}\n\n\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t} else {\n\n\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t}\n\n\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t} else {\n\n\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t}\n\n\t\treturn ( min <= - plane.constant && max >= - plane.constant );\n\n\t}\n\n\tintersectsTriangle( triangle ) {\n\n\t\tif ( this.isEmpty() ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// compute box center and extents\n\t\tthis.getCenter( _center );\n\t\t_extents.subVectors( this.max, _center );\n\n\t\t// translate triangle to aabb origin\n\t\t_v0$2.subVectors( triangle.a, _center );\n\t\t_v1$7.subVectors( triangle.b, _center );\n\t\t_v2$3.subVectors( triangle.c, _center );\n\n\t\t// compute edge vectors for triangle\n\t\t_f0.subVectors( _v1$7, _v0$2 );\n\t\t_f1.subVectors( _v2$3, _v1$7 );\n\t\t_f2.subVectors( _v0$2, _v2$3 );\n\n\t\t// test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb\n\t\t// make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation\n\t\t// axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned)\n\t\tlet axes = [\n\t\t\t0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y,\n\t\t\t_f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x,\n\t\t\t- _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0\n\t\t];\n\t\tif ( ! satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents ) ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// test 3 face normals from the aabb\n\t\taxes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];\n\t\tif ( ! satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents ) ) {\n\n\t\t\treturn false;\n\n\t\t}\n\n\t\t// finally testing the face normal of the triangle\n\t\t// use already existing triangle edge vectors here\n\t\t_triangleNormal.crossVectors( _f0, _f1 );\n\t\taxes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ];\n\n\t\treturn satForAxes( axes, _v0$2, _v1$7, _v2$3, _extents );\n\n\t}\n\n\tclampPoint( point, target ) {\n\n\t\treturn target.copy( point ).clamp( this.min, this.max );\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\tconst clampedPoint = _vector$b.copy( point ).clamp( this.min, this.max );\n\n\t\treturn clampedPoint.sub( point ).length();\n\n\t}\n\n\tgetBoundingSphere( target ) {\n\n\t\tthis.getCenter( target.center );\n\n\t\ttarget.radius = this.getSize( _vector$b ).length() * 0.5;\n\n\t\treturn target;\n\n\t}\n\n\tintersect( box ) {\n\n\t\tthis.min.max( box.min );\n\t\tthis.max.min( box.max );\n\n\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\tif ( this.isEmpty() ) this.makeEmpty();\n\n\t\treturn this;\n\n\t}\n\n\tunion( box ) {\n\n\t\tthis.min.min( box.min );\n\t\tthis.max.max( box.max );\n\n\t\treturn this;\n\n\t}\n\n\tapplyMatrix4( matrix ) {\n\n\t\t// transform of empty box is an empty box.\n\t\tif ( this.isEmpty() ) return this;\n\n\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t_points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t_points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t_points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t_points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t_points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t_points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t_points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t_points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111\n\n\t\tthis.setFromPoints( _points );\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( offset ) {\n\n\t\tthis.min.add( offset );\n\t\tthis.max.add( offset );\n\n\t\treturn this;\n\n\t}\n\n\tequals( box ) {\n\n\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t}\n\n}\n\nconst _points = [\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3(),\n\t/*@__PURE__*/ new Vector3()\n];\n\nconst _vector$b = /*@__PURE__*/ new Vector3();\n\nconst _box$3 = /*@__PURE__*/ new Box3();\n\n// triangle centered vertices\n\nconst _v0$2 = /*@__PURE__*/ new Vector3();\nconst _v1$7 = /*@__PURE__*/ new Vector3();\nconst _v2$3 = /*@__PURE__*/ new Vector3();\n\n// triangle edge vectors\n\nconst _f0 = /*@__PURE__*/ new Vector3();\nconst _f1 = /*@__PURE__*/ new Vector3();\nconst _f2 = /*@__PURE__*/ new Vector3();\n\nconst _center = /*@__PURE__*/ new Vector3();\nconst _extents = /*@__PURE__*/ new Vector3();\nconst _triangleNormal = /*@__PURE__*/ new Vector3();\nconst _testAxis = /*@__PURE__*/ new Vector3();\n\nfunction satForAxes( axes, v0, v1, v2, extents ) {\n\n\tfor ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) {\n\n\t\t_testAxis.fromArray( axes, i );\n\t\t// project the aabb onto the separating axis\n\t\tconst r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z );\n\t\t// project all 3 vertices of the triangle onto the separating axis\n\t\tconst p0 = v0.dot( _testAxis );\n\t\tconst p1 = v1.dot( _testAxis );\n\t\tconst p2 = v2.dot( _testAxis );\n\t\t// actual test, basically see if either of the most extreme of the triangle points intersects r\n\t\tif ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) {\n\n\t\t\t// points of the projected triangle are outside the projected half-length of the aabb\n\t\t\t// the axis is separating and we can exit\n\t\t\treturn false;\n\n\t\t}\n\n\t}\n\n\treturn true;\n\n}\n\nconst _box$2 = /*@__PURE__*/ new Box3();\nconst _v1$6 = /*@__PURE__*/ new Vector3();\nconst _toFarthestPoint = /*@__PURE__*/ new Vector3();\nconst _toPoint = /*@__PURE__*/ new Vector3();\n\nclass Sphere {\n\n\tconstructor( center = new Vector3(), radius = - 1 ) {\n\n\t\tthis.center = center;\n\t\tthis.radius = radius;\n\n\t}\n\n\tset( center, radius ) {\n\n\t\tthis.center.copy( center );\n\t\tthis.radius = radius;\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPoints( points, optionalCenter ) {\n\n\t\tconst center = this.center;\n\n\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\tcenter.copy( optionalCenter );\n\n\t\t} else {\n\n\t\t\t_box$2.setFromPoints( points ).getCenter( center );\n\n\t\t}\n\n\t\tlet maxRadiusSq = 0;\n\n\t\tfor ( let i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t}\n\n\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( sphere ) {\n\n\t\tthis.center.copy( sphere.center );\n\t\tthis.radius = sphere.radius;\n\n\t\treturn this;\n\n\t}\n\n\tisEmpty() {\n\n\t\treturn ( this.radius < 0 );\n\n\t}\n\n\tmakeEmpty() {\n\n\t\tthis.center.set( 0, 0, 0 );\n\t\tthis.radius = - 1;\n\n\t\treturn this;\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\tconst radiusSum = this.radius + sphere.radius;\n\n\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\treturn box.intersectsSphere( this );\n\n\t}\n\n\tintersectsPlane( plane ) {\n\n\t\treturn Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius;\n\n\t}\n\n\tclampPoint( point, target ) {\n\n\t\tconst deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\ttarget.copy( point );\n\n\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\ttarget.sub( this.center ).normalize();\n\t\t\ttarget.multiplyScalar( this.radius ).add( this.center );\n\n\t\t}\n\n\t\treturn target;\n\n\t}\n\n\tgetBoundingBox( target ) {\n\n\t\tif ( this.isEmpty() ) {\n\n\t\t\t// Empty sphere produces empty bounding box\n\t\t\ttarget.makeEmpty();\n\t\t\treturn target;\n\n\t\t}\n\n\t\ttarget.set( this.center, this.center );\n\t\ttarget.expandByScalar( this.radius );\n\n\t\treturn target;\n\n\t}\n\n\tapplyMatrix4( matrix ) {\n\n\t\tthis.center.applyMatrix4( matrix );\n\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( offset ) {\n\n\t\tthis.center.add( offset );\n\n\t\treturn this;\n\n\t}\n\n\texpandByPoint( point ) {\n\n\t\t// from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671\n\n\t\t_toPoint.subVectors( point, this.center );\n\n\t\tconst lengthSq = _toPoint.lengthSq();\n\n\t\tif ( lengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\tconst length = Math.sqrt( lengthSq );\n\t\t\tconst missingRadiusHalf = ( length - this.radius ) * 0.5;\n\n\t\t\t// Nudge this sphere towards the target point. Add half the missing distance to radius,\n\t\t\t// and the other half to position. This gives a tighter enclosure, instead of if\n\t\t\t// the whole missing distance were just added to radius.\n\n\t\t\tthis.center.add( _toPoint.multiplyScalar( missingRadiusHalf / length ) );\n\t\t\tthis.radius += missingRadiusHalf;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tunion( sphere ) {\n\n\t\t// from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769\n\n\t\t// To enclose another sphere into this sphere, we only need to enclose two points:\n\t\t// 1) Enclose the farthest point on the other sphere into this sphere.\n\t\t// 2) Enclose the opposite point of the farthest point into this sphere.\n\n\t\t if ( this.center.equals( sphere.center ) === true ) {\n\n\t\t\t _toFarthestPoint.set( 0, 0, 1 ).multiplyScalar( sphere.radius );\n\n\n\t\t} else {\n\n\t\t\t_toFarthestPoint.subVectors( sphere.center, this.center ).normalize().multiplyScalar( sphere.radius );\n\n\t\t}\n\n\t\tthis.expandByPoint( _v1$6.copy( sphere.center ).add( _toFarthestPoint ) );\n\t\tthis.expandByPoint( _v1$6.copy( sphere.center ).sub( _toFarthestPoint ) );\n\n\t\treturn this;\n\n\t}\n\n\tequals( sphere ) {\n\n\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nconst _vector$a = /*@__PURE__*/ new Vector3();\nconst _segCenter = /*@__PURE__*/ new Vector3();\nconst _segDir = /*@__PURE__*/ new Vector3();\nconst _diff = /*@__PURE__*/ new Vector3();\n\nconst _edge1 = /*@__PURE__*/ new Vector3();\nconst _edge2 = /*@__PURE__*/ new Vector3();\nconst _normal$1 = /*@__PURE__*/ new Vector3();\n\nclass Ray {\n\n\tconstructor( origin = new Vector3(), direction = new Vector3( 0, 0, - 1 ) ) {\n\n\t\tthis.origin = origin;\n\t\tthis.direction = direction;\n\n\t}\n\n\tset( origin, direction ) {\n\n\t\tthis.origin.copy( origin );\n\t\tthis.direction.copy( direction );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( ray ) {\n\n\t\tthis.origin.copy( ray.origin );\n\t\tthis.direction.copy( ray.direction );\n\n\t\treturn this;\n\n\t}\n\n\tat( t, target ) {\n\n\t\treturn target.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t}\n\n\tlookAt( v ) {\n\n\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\treturn this;\n\n\t}\n\n\trecast( t ) {\n\n\t\tthis.origin.copy( this.at( t, _vector$a ) );\n\n\t\treturn this;\n\n\t}\n\n\tclosestPointToPoint( point, target ) {\n\n\t\ttarget.subVectors( point, this.origin );\n\n\t\tconst directionDistance = target.dot( this.direction );\n\n\t\tif ( directionDistance < 0 ) {\n\n\t\t\treturn target.copy( this.origin );\n\n\t\t}\n\n\t\treturn target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t}\n\n\tdistanceSqToPoint( point ) {\n\n\t\tconst directionDistance = _vector$a.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t// point behind the ray\n\n\t\tif ( directionDistance < 0 ) {\n\n\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t}\n\n\t\t_vector$a.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\treturn _vector$a.distanceToSquared( point );\n\n\t}\n\n\tdistanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t// from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t// It returns the min distance between the ray and the segment\n\t\t// defined by v0 and v1\n\t\t// It can also set two optional targets :\n\t\t// - The closest point on the ray\n\t\t// - The closest point on the segment\n\n\t\t_segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t_segDir.copy( v1 ).sub( v0 ).normalize();\n\t\t_diff.copy( this.origin ).sub( _segCenter );\n\n\t\tconst segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\tconst a01 = - this.direction.dot( _segDir );\n\t\tconst b0 = _diff.dot( this.direction );\n\t\tconst b1 = - _diff.dot( _segDir );\n\t\tconst c = _diff.lengthSq();\n\t\tconst det = Math.abs( 1 - a01 * a01 );\n\t\tlet s0, s1, sqrDist, extDet;\n\n\t\tif ( det > 0 ) {\n\n\t\t\t// The ray and segment are not parallel.\n\n\t\t\ts0 = a01 * b1 - b0;\n\t\t\ts1 = a01 * b0 - b1;\n\t\t\textDet = segExtent * det;\n\n\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\tconst invDet = 1 / det;\n\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// region 5\n\n\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t// region 4\n\n\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t// region 3\n\n\t\t\t\t\ts0 = 0;\n\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// region 2\n\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// Ray and segment are parallel.\n\n\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t}\n\n\t\tif ( optionalPointOnRay ) {\n\n\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t}\n\n\t\tif ( optionalPointOnSegment ) {\n\n\t\t\toptionalPointOnSegment.copy( _segDir ).multiplyScalar( s1 ).add( _segCenter );\n\n\t\t}\n\n\t\treturn sqrDist;\n\n\t}\n\n\tintersectSphere( sphere, target ) {\n\n\t\t_vector$a.subVectors( sphere.center, this.origin );\n\t\tconst tca = _vector$a.dot( this.direction );\n\t\tconst d2 = _vector$a.dot( _vector$a ) - tca * tca;\n\t\tconst radius2 = sphere.radius * sphere.radius;\n\n\t\tif ( d2 > radius2 ) return null;\n\n\t\tconst thc = Math.sqrt( radius2 - d2 );\n\n\t\t// t0 = first intersect point - entrance on front of sphere\n\t\tconst t0 = tca - thc;\n\n\t\t// t1 = second intersect point - exit point on back of sphere\n\t\tconst t1 = tca + thc;\n\n\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t// test to see if t0 is behind the ray:\n\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t// in order to always return an intersect point that is in front of the ray.\n\t\tif ( t0 < 0 ) return this.at( t1, target );\n\n\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\treturn this.at( t0, target );\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\treturn this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t}\n\n\tdistanceToPlane( plane ) {\n\n\t\tconst denominator = plane.normal.dot( this.direction );\n\n\t\tif ( denominator === 0 ) {\n\n\t\t\t// line is coplanar, return origin\n\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\treturn 0;\n\n\t\t\t}\n\n\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t// Return if the ray never intersects the plane\n\n\t\treturn t >= 0 ? t : null;\n\n\t}\n\n\tintersectPlane( plane, target ) {\n\n\t\tconst t = this.distanceToPlane( plane );\n\n\t\tif ( t === null ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\treturn this.at( t, target );\n\n\t}\n\n\tintersectsPlane( plane ) {\n\n\t\t// check if the ray lies on the plane first\n\n\t\tconst distToPoint = plane.distanceToPoint( this.origin );\n\n\t\tif ( distToPoint === 0 ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tconst denominator = plane.normal.dot( this.direction );\n\n\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\treturn false;\n\n\t}\n\n\tintersectBox( box, target ) {\n\n\t\tlet tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\tconst invdirx = 1 / this.direction.x,\n\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\tconst origin = this.origin;\n\n\t\tif ( invdirx >= 0 ) {\n\n\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t} else {\n\n\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t}\n\n\t\tif ( invdiry >= 0 ) {\n\n\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t} else {\n\n\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t}\n\n\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\tif ( invdirz >= 0 ) {\n\n\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t} else {\n\n\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t}\n\n\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t//return point closest to the ray (positive side)\n\n\t\tif ( tmax < 0 ) return null;\n\n\t\treturn this.at( tmin >= 0 ? tmin : tmax, target );\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\treturn this.intersectBox( box, _vector$a ) !== null;\n\n\t}\n\n\tintersectTriangle( a, b, c, backfaceCulling, target ) {\n\n\t\t// Compute the offset origin, edges, and normal.\n\n\t\t// from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t_edge1.subVectors( b, a );\n\t\t_edge2.subVectors( c, a );\n\t\t_normal$1.crossVectors( _edge1, _edge2 );\n\n\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\tlet DdN = this.direction.dot( _normal$1 );\n\t\tlet sign;\n\n\t\tif ( DdN > 0 ) {\n\n\t\t\tif ( backfaceCulling ) return null;\n\t\t\tsign = 1;\n\n\t\t} else if ( DdN < 0 ) {\n\n\t\t\tsign = - 1;\n\t\t\tDdN = - DdN;\n\n\t\t} else {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\t_diff.subVectors( this.origin, a );\n\t\tconst DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) );\n\n\t\t// b1 < 0, no intersection\n\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) );\n\n\t\t// b2 < 0, no intersection\n\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// b1+b2 > 1, no intersection\n\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// Line intersects triangle, check if ray does.\n\t\tconst QdN = - sign * _diff.dot( _normal$1 );\n\n\t\t// t < 0, no intersection\n\t\tif ( QdN < 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\t// Ray intersects triangle.\n\t\treturn this.at( QdN / DdN, target );\n\n\t}\n\n\tapplyMatrix4( matrix4 ) {\n\n\t\tthis.origin.applyMatrix4( matrix4 );\n\t\tthis.direction.transformDirection( matrix4 );\n\n\t\treturn this;\n\n\t}\n\n\tequals( ray ) {\n\n\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nclass Matrix4 {\n\n\tconstructor() {\n\n\t\tthis.isMatrix4 = true;\n\n\t\tthis.elements = [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t];\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tset( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\treturn this;\n\n\t}\n\n\tidentity() {\n\n\t\tthis.set(\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new Matrix4().fromArray( this.elements );\n\n\t}\n\n\tcopy( m ) {\n\n\t\tconst te = this.elements;\n\t\tconst me = m.elements;\n\n\t\tte[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ];\n\t\tte[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ];\n\t\tte[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ];\n\t\tte[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ];\n\n\t\treturn this;\n\n\t}\n\n\tcopyPosition( m ) {\n\n\t\tconst te = this.elements, me = m.elements;\n\n\t\tte[ 12 ] = me[ 12 ];\n\t\tte[ 13 ] = me[ 13 ];\n\t\tte[ 14 ] = me[ 14 ];\n\n\t\treturn this;\n\n\t}\n\n\tsetFromMatrix3( m ) {\n\n\t\tconst me = m.elements;\n\n\t\tthis.set(\n\n\t\t\tme[ 0 ], me[ 3 ], me[ 6 ], 0,\n\t\t\tme[ 1 ], me[ 4 ], me[ 7 ], 0,\n\t\t\tme[ 2 ], me[ 5 ], me[ 8 ], 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\textractBasis( xAxis, yAxis, zAxis ) {\n\n\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\treturn this;\n\n\t}\n\n\tmakeBasis( xAxis, yAxis, zAxis ) {\n\n\t\tthis.set(\n\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t0, 0, 0, 1\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\textractRotation( m ) {\n\n\t\t// this method does not support reflection matrices\n\n\t\tconst te = this.elements;\n\t\tconst me = m.elements;\n\n\t\tconst scaleX = 1 / _v1$5.setFromMatrixColumn( m, 0 ).length();\n\t\tconst scaleY = 1 / _v1$5.setFromMatrixColumn( m, 1 ).length();\n\t\tconst scaleZ = 1 / _v1$5.setFromMatrixColumn( m, 2 ).length();\n\n\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\t\tte[ 3 ] = 0;\n\n\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\t\tte[ 7 ] = 0;\n\n\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\t\tte[ 11 ] = 0;\n\n\t\tte[ 12 ] = 0;\n\t\tte[ 13 ] = 0;\n\t\tte[ 14 ] = 0;\n\t\tte[ 15 ] = 1;\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationFromEuler( euler ) {\n\n\t\tif ( ! ( euler && euler.isEuler ) ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t}\n\n\t\tconst te = this.elements;\n\n\t\tconst x = euler.x, y = euler.y, z = euler.z;\n\t\tconst a = Math.cos( x ), b = Math.sin( x );\n\t\tconst c = Math.cos( y ), d = Math.sin( y );\n\t\tconst e = Math.cos( z ), f = Math.sin( z );\n\n\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\tconst ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\tte[ 0 ] = c * e;\n\t\t\tte[ 4 ] = - c * f;\n\t\t\tte[ 8 ] = d;\n\n\t\t\tte[ 1 ] = af + be * d;\n\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\tte[ 9 ] = - b * c;\n\n\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\tte[ 6 ] = be + af * d;\n\t\t\tte[ 10 ] = a * c;\n\n\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\tconst ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\tte[ 0 ] = ce + df * b;\n\t\t\tte[ 4 ] = de * b - cf;\n\t\t\tte[ 8 ] = a * d;\n\n\t\t\tte[ 1 ] = a * f;\n\t\t\tte[ 5 ] = a * e;\n\t\t\tte[ 9 ] = - b;\n\n\t\t\tte[ 2 ] = cf * b - de;\n\t\t\tte[ 6 ] = df + ce * b;\n\t\t\tte[ 10 ] = a * c;\n\n\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\tconst ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\tte[ 0 ] = ce - df * b;\n\t\t\tte[ 4 ] = - a * f;\n\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\tte[ 1 ] = cf + de * b;\n\t\t\tte[ 5 ] = a * e;\n\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\tte[ 2 ] = - a * d;\n\t\t\tte[ 6 ] = b;\n\t\t\tte[ 10 ] = a * c;\n\n\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\tconst ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\tte[ 0 ] = c * e;\n\t\t\tte[ 4 ] = be * d - af;\n\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\tte[ 1 ] = c * f;\n\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\tte[ 2 ] = - d;\n\t\t\tte[ 6 ] = b * c;\n\t\t\tte[ 10 ] = a * c;\n\n\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\tconst ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\tte[ 0 ] = c * e;\n\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\tte[ 1 ] = f;\n\t\t\tte[ 5 ] = a * e;\n\t\t\tte[ 9 ] = - b * e;\n\n\t\t\tte[ 2 ] = - d * e;\n\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\tconst ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\tte[ 0 ] = c * e;\n\t\t\tte[ 4 ] = - f;\n\t\t\tte[ 8 ] = d * e;\n\n\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\tte[ 5 ] = a * e;\n\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\tte[ 6 ] = b * e;\n\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t}\n\n\t\t// bottom row\n\t\tte[ 3 ] = 0;\n\t\tte[ 7 ] = 0;\n\t\tte[ 11 ] = 0;\n\n\t\t// last column\n\t\tte[ 12 ] = 0;\n\t\tte[ 13 ] = 0;\n\t\tte[ 14 ] = 0;\n\t\tte[ 15 ] = 1;\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationFromQuaternion( q ) {\n\n\t\treturn this.compose( _zero, q, _one );\n\n\t}\n\n\tlookAt( eye, target, up ) {\n\n\t\tconst te = this.elements;\n\n\t\t_z.subVectors( eye, target );\n\n\t\tif ( _z.lengthSq() === 0 ) {\n\n\t\t\t// eye and target are in the same position\n\n\t\t\t_z.z = 1;\n\n\t\t}\n\n\t\t_z.normalize();\n\t\t_x.crossVectors( up, _z );\n\n\t\tif ( _x.lengthSq() === 0 ) {\n\n\t\t\t// up and z are parallel\n\n\t\t\tif ( Math.abs( up.z ) === 1 ) {\n\n\t\t\t\t_z.x += 0.0001;\n\n\t\t\t} else {\n\n\t\t\t\t_z.z += 0.0001;\n\n\t\t\t}\n\n\t\t\t_z.normalize();\n\t\t\t_x.crossVectors( up, _z );\n\n\t\t}\n\n\t\t_x.normalize();\n\t\t_y.crossVectors( _z, _x );\n\n\t\tte[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x;\n\t\tte[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y;\n\t\tte[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z;\n\n\t\treturn this;\n\n\t}\n\n\tmultiply( m, n ) {\n\n\t\tif ( n !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t}\n\n\t\treturn this.multiplyMatrices( this, m );\n\n\t}\n\n\tpremultiply( m ) {\n\n\t\treturn this.multiplyMatrices( m, this );\n\n\t}\n\n\tmultiplyMatrices( a, b ) {\n\n\t\tconst ae = a.elements;\n\t\tconst be = b.elements;\n\t\tconst te = this.elements;\n\n\t\tconst a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\tconst a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\tconst a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\tconst a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\tconst b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\tconst b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\tconst b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\tconst b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\treturn this;\n\n\t}\n\n\tmultiplyScalar( s ) {\n\n\t\tconst te = this.elements;\n\n\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\treturn this;\n\n\t}\n\n\tdeterminant() {\n\n\t\tconst te = this.elements;\n\n\t\tconst n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\tconst n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\tconst n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\tconst n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t//TODO: make this more efficient\n\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\treturn (\n\t\t\tn41 * (\n\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t - n13 * n24 * n32\n\t\t\t\t - n14 * n22 * n33\n\t\t\t\t + n12 * n24 * n33\n\t\t\t\t + n13 * n22 * n34\n\t\t\t\t - n12 * n23 * n34\n\t\t\t) +\n\t\t\tn42 * (\n\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t - n11 * n24 * n33\n\t\t\t\t + n14 * n21 * n33\n\t\t\t\t - n13 * n21 * n34\n\t\t\t\t + n13 * n24 * n31\n\t\t\t\t - n14 * n23 * n31\n\t\t\t) +\n\t\t\tn43 * (\n\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t - n11 * n22 * n34\n\t\t\t\t - n14 * n21 * n32\n\t\t\t\t + n12 * n21 * n34\n\t\t\t\t + n14 * n22 * n31\n\t\t\t\t - n12 * n24 * n31\n\t\t\t) +\n\t\t\tn44 * (\n\t\t\t\t- n13 * n22 * n31\n\t\t\t\t - n11 * n23 * n32\n\t\t\t\t + n11 * n22 * n33\n\t\t\t\t + n13 * n21 * n32\n\t\t\t\t - n12 * n21 * n33\n\t\t\t\t + n12 * n23 * n31\n\t\t\t)\n\n\t\t);\n\n\t}\n\n\ttranspose() {\n\n\t\tconst te = this.elements;\n\t\tlet tmp;\n\n\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\treturn this;\n\n\t}\n\n\tsetPosition( x, y, z ) {\n\n\t\tconst te = this.elements;\n\n\t\tif ( x.isVector3 ) {\n\n\t\t\tte[ 12 ] = x.x;\n\t\t\tte[ 13 ] = x.y;\n\t\t\tte[ 14 ] = x.z;\n\n\t\t} else {\n\n\t\t\tte[ 12 ] = x;\n\t\t\tte[ 13 ] = y;\n\t\t\tte[ 14 ] = z;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tinvert() {\n\n\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\tconst te = this.elements,\n\n\t\t\tn11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n41 = te[ 3 ],\n\t\t\tn12 = te[ 4 ], n22 = te[ 5 ], n32 = te[ 6 ], n42 = te[ 7 ],\n\t\t\tn13 = te[ 8 ], n23 = te[ 9 ], n33 = te[ 10 ], n43 = te[ 11 ],\n\t\t\tn14 = te[ 12 ], n24 = te[ 13 ], n34 = te[ 14 ], n44 = te[ 15 ],\n\n\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\tconst det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\tif ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );\n\n\t\tconst detInv = 1 / det;\n\n\t\tte[ 0 ] = t11 * detInv;\n\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\tte[ 4 ] = t12 * detInv;\n\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\tte[ 8 ] = t13 * detInv;\n\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\tte[ 12 ] = t14 * detInv;\n\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\treturn this;\n\n\t}\n\n\tscale( v ) {\n\n\t\tconst te = this.elements;\n\t\tconst x = v.x, y = v.y, z = v.z;\n\n\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\treturn this;\n\n\t}\n\n\tgetMaxScaleOnAxis() {\n\n\t\tconst te = this.elements;\n\n\t\tconst scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\tconst scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\tconst scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t}\n\n\tmakeTranslation( x, y, z ) {\n\n\t\tthis.set(\n\n\t\t\t1, 0, 0, x,\n\t\t\t0, 1, 0, y,\n\t\t\t0, 0, 1, z,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationX( theta ) {\n\n\t\tconst c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\tthis.set(\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, c, - s, 0,\n\t\t\t0, s, c, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationY( theta ) {\n\n\t\tconst c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\tthis.set(\n\n\t\t\t c, 0, s, 0,\n\t\t\t 0, 1, 0, 0,\n\t\t\t- s, 0, c, 0,\n\t\t\t 0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationZ( theta ) {\n\n\t\tconst c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\tthis.set(\n\n\t\t\tc, - s, 0, 0,\n\t\t\ts, c, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeRotationAxis( axis, angle ) {\n\n\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\tconst c = Math.cos( angle );\n\t\tconst s = Math.sin( angle );\n\t\tconst t = 1 - c;\n\t\tconst x = axis.x, y = axis.y, z = axis.z;\n\t\tconst tx = t * x, ty = t * y;\n\n\t\tthis.set(\n\n\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeScale( x, y, z ) {\n\n\t\tthis.set(\n\n\t\t\tx, 0, 0, 0,\n\t\t\t0, y, 0, 0,\n\t\t\t0, 0, z, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tmakeShear( xy, xz, yx, yz, zx, zy ) {\n\n\t\tthis.set(\n\n\t\t\t1, yx, zx, 0,\n\t\t\txy, 1, zy, 0,\n\t\t\txz, yz, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t);\n\n\t\treturn this;\n\n\t}\n\n\tcompose( position, quaternion, scale ) {\n\n\t\tconst te = this.elements;\n\n\t\tconst x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;\n\t\tconst x2 = x + x,\ty2 = y + y, z2 = z + z;\n\t\tconst xx = x * x2, xy = x * y2, xz = x * z2;\n\t\tconst yy = y * y2, yz = y * z2, zz = z * z2;\n\t\tconst wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\tconst sx = scale.x, sy = scale.y, sz = scale.z;\n\n\t\tte[ 0 ] = ( 1 - ( yy + zz ) ) * sx;\n\t\tte[ 1 ] = ( xy + wz ) * sx;\n\t\tte[ 2 ] = ( xz - wy ) * sx;\n\t\tte[ 3 ] = 0;\n\n\t\tte[ 4 ] = ( xy - wz ) * sy;\n\t\tte[ 5 ] = ( 1 - ( xx + zz ) ) * sy;\n\t\tte[ 6 ] = ( yz + wx ) * sy;\n\t\tte[ 7 ] = 0;\n\n\t\tte[ 8 ] = ( xz + wy ) * sz;\n\t\tte[ 9 ] = ( yz - wx ) * sz;\n\t\tte[ 10 ] = ( 1 - ( xx + yy ) ) * sz;\n\t\tte[ 11 ] = 0;\n\n\t\tte[ 12 ] = position.x;\n\t\tte[ 13 ] = position.y;\n\t\tte[ 14 ] = position.z;\n\t\tte[ 15 ] = 1;\n\n\t\treturn this;\n\n\t}\n\n\tdecompose( position, quaternion, scale ) {\n\n\t\tconst te = this.elements;\n\n\t\tlet sx = _v1$5.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\tconst sy = _v1$5.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\tconst sz = _v1$5.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t// if determine is negative, we need to invert one scale\n\t\tconst det = this.determinant();\n\t\tif ( det < 0 ) sx = - sx;\n\n\t\tposition.x = te[ 12 ];\n\t\tposition.y = te[ 13 ];\n\t\tposition.z = te[ 14 ];\n\n\t\t// scale the rotation part\n\t\t_m1$2.copy( this );\n\n\t\tconst invSX = 1 / sx;\n\t\tconst invSY = 1 / sy;\n\t\tconst invSZ = 1 / sz;\n\n\t\t_m1$2.elements[ 0 ] *= invSX;\n\t\t_m1$2.elements[ 1 ] *= invSX;\n\t\t_m1$2.elements[ 2 ] *= invSX;\n\n\t\t_m1$2.elements[ 4 ] *= invSY;\n\t\t_m1$2.elements[ 5 ] *= invSY;\n\t\t_m1$2.elements[ 6 ] *= invSY;\n\n\t\t_m1$2.elements[ 8 ] *= invSZ;\n\t\t_m1$2.elements[ 9 ] *= invSZ;\n\t\t_m1$2.elements[ 10 ] *= invSZ;\n\n\t\tquaternion.setFromRotationMatrix( _m1$2 );\n\n\t\tscale.x = sx;\n\t\tscale.y = sy;\n\t\tscale.z = sz;\n\n\t\treturn this;\n\n\t}\n\n\tmakePerspective( left, right, top, bottom, near, far ) {\n\n\t\tif ( far === undefined ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t}\n\n\t\tconst te = this.elements;\n\t\tconst x = 2 * near / ( right - left );\n\t\tconst y = 2 * near / ( top - bottom );\n\n\t\tconst a = ( right + left ) / ( right - left );\n\t\tconst b = ( top + bottom ) / ( top - bottom );\n\t\tconst c = - ( far + near ) / ( far - near );\n\t\tconst d = - 2 * far * near / ( far - near );\n\n\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\treturn this;\n\n\t}\n\n\tmakeOrthographic( left, right, top, bottom, near, far ) {\n\n\t\tconst te = this.elements;\n\t\tconst w = 1.0 / ( right - left );\n\t\tconst h = 1.0 / ( top - bottom );\n\t\tconst p = 1.0 / ( far - near );\n\n\t\tconst x = ( right + left ) * w;\n\t\tconst y = ( top + bottom ) * h;\n\t\tconst z = ( far + near ) * p;\n\n\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\treturn this;\n\n\t}\n\n\tequals( matrix ) {\n\n\t\tconst te = this.elements;\n\t\tconst me = matrix.elements;\n\n\t\tfor ( let i = 0; i < 16; i ++ ) {\n\n\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tfor ( let i = 0; i < 16; i ++ ) {\n\n\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tconst te = this.elements;\n\n\t\tarray[ offset ] = te[ 0 ];\n\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\treturn array;\n\n\t}\n\n}\n\nconst _v1$5 = /*@__PURE__*/ new Vector3();\nconst _m1$2 = /*@__PURE__*/ new Matrix4();\nconst _zero = /*@__PURE__*/ new Vector3( 0, 0, 0 );\nconst _one = /*@__PURE__*/ new Vector3( 1, 1, 1 );\nconst _x = /*@__PURE__*/ new Vector3();\nconst _y = /*@__PURE__*/ new Vector3();\nconst _z = /*@__PURE__*/ new Vector3();\n\nconst _matrix$1 = /*@__PURE__*/ new Matrix4();\nconst _quaternion$3 = /*@__PURE__*/ new Quaternion();\n\nclass Euler {\n\n\tconstructor( x = 0, y = 0, z = 0, order = Euler.DefaultOrder ) {\n\n\t\tthis.isEuler = true;\n\n\t\tthis._x = x;\n\t\tthis._y = y;\n\t\tthis._z = z;\n\t\tthis._order = order;\n\n\t}\n\n\tget x() {\n\n\t\treturn this._x;\n\n\t}\n\n\tset x( value ) {\n\n\t\tthis._x = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget y() {\n\n\t\treturn this._y;\n\n\t}\n\n\tset y( value ) {\n\n\t\tthis._y = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget z() {\n\n\t\treturn this._z;\n\n\t}\n\n\tset z( value ) {\n\n\t\tthis._z = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tget order() {\n\n\t\treturn this._order;\n\n\t}\n\n\tset order( value ) {\n\n\t\tthis._order = value;\n\t\tthis._onChangeCallback();\n\n\t}\n\n\tset( x, y, z, order = this._order ) {\n\n\t\tthis._x = x;\n\t\tthis._y = y;\n\t\tthis._z = z;\n\t\tthis._order = order;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t}\n\n\tcopy( euler ) {\n\n\t\tthis._x = euler._x;\n\t\tthis._y = euler._y;\n\t\tthis._z = euler._z;\n\t\tthis._order = euler._order;\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromRotationMatrix( m, order = this._order, update = true ) {\n\n\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\tconst te = m.elements;\n\t\tconst m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\tconst m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\tconst m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\tswitch ( order ) {\n\n\t\t\tcase 'XYZ':\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'YXZ':\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'ZXY':\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'ZYX':\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'YZX':\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'XZY':\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.9999999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );\n\n\t\t}\n\n\t\tthis._order = order;\n\n\t\tif ( update === true ) this._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\tsetFromQuaternion( q, order, update ) {\n\n\t\t_matrix$1.makeRotationFromQuaternion( q );\n\n\t\treturn this.setFromRotationMatrix( _matrix$1, order, update );\n\n\t}\n\n\tsetFromVector3( v, order = this._order ) {\n\n\t\treturn this.set( v.x, v.y, v.z, order );\n\n\t}\n\n\treorder( newOrder ) {\n\n\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t_quaternion$3.setFromEuler( this );\n\n\t\treturn this.setFromQuaternion( _quaternion$3, newOrder );\n\n\t}\n\n\tequals( euler ) {\n\n\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t}\n\n\tfromArray( array ) {\n\n\t\tthis._x = array[ 0 ];\n\t\tthis._y = array[ 1 ];\n\t\tthis._z = array[ 2 ];\n\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\tthis._onChangeCallback();\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tarray[ offset ] = this._x;\n\t\tarray[ offset + 1 ] = this._y;\n\t\tarray[ offset + 2 ] = this._z;\n\t\tarray[ offset + 3 ] = this._order;\n\n\t\treturn array;\n\n\t}\n\n\t_onChange( callback ) {\n\n\t\tthis._onChangeCallback = callback;\n\n\t\treturn this;\n\n\t}\n\n\t_onChangeCallback() {}\n\n\t*[ Symbol.iterator ]() {\n\n\t\tyield this._x;\n\t\tyield this._y;\n\t\tyield this._z;\n\t\tyield this._order;\n\n\t}\n\n\t// @deprecated since r138, 02cf0df1cb4575d5842fef9c85bb5a89fe020d53\n\n\ttoVector3() {\n\n\t\tconsole.error( 'THREE.Euler: .toVector3() has been removed. Use Vector3.setFromEuler() instead' );\n\n\t}\n\n}\n\nEuler.DefaultOrder = 'XYZ';\nEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\nclass Layers {\n\n\tconstructor() {\n\n\t\tthis.mask = 1 | 0;\n\n\t}\n\n\tset( channel ) {\n\n\t\tthis.mask = ( 1 << channel | 0 ) >>> 0;\n\n\t}\n\n\tenable( channel ) {\n\n\t\tthis.mask |= 1 << channel | 0;\n\n\t}\n\n\tenableAll() {\n\n\t\tthis.mask = 0xffffffff | 0;\n\n\t}\n\n\ttoggle( channel ) {\n\n\t\tthis.mask ^= 1 << channel | 0;\n\n\t}\n\n\tdisable( channel ) {\n\n\t\tthis.mask &= ~ ( 1 << channel | 0 );\n\n\t}\n\n\tdisableAll() {\n\n\t\tthis.mask = 0;\n\n\t}\n\n\ttest( layers ) {\n\n\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t}\n\n\tisEnabled( channel ) {\n\n\t\treturn ( this.mask & ( 1 << channel | 0 ) ) !== 0;\n\n\t}\n\n}\n\nlet _object3DId = 0;\n\nconst _v1$4 = /*@__PURE__*/ new Vector3();\nconst _q1 = /*@__PURE__*/ new Quaternion();\nconst _m1$1 = /*@__PURE__*/ new Matrix4();\nconst _target = /*@__PURE__*/ new Vector3();\n\nconst _position$3 = /*@__PURE__*/ new Vector3();\nconst _scale$2 = /*@__PURE__*/ new Vector3();\nconst _quaternion$2 = /*@__PURE__*/ new Quaternion();\n\nconst _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 );\nconst _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 );\nconst _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 );\n\nconst _addedEvent = { type: 'added' };\nconst _removedEvent = { type: 'removed' };\n\nclass Object3D extends EventDispatcher {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isObject3D = true;\n\n\t\tObject.defineProperty( this, 'id', { value: _object3DId ++ } );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tconst position = new Vector3();\n\t\tconst rotation = new Euler();\n\t\tconst quaternion = new Quaternion();\n\t\tconst scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation._onChange( onRotationChange );\n\t\tquaternion._onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.animations = [];\n\n\t\tthis.userData = {};\n\n\t}\n\n\tonBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {}\n\n\tonAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {}\n\n\tapplyMatrix4( matrix ) {\n\n\t\tif ( this.matrixAutoUpdate ) this.updateMatrix();\n\n\t\tthis.matrix.premultiply( matrix );\n\n\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t}\n\n\tapplyQuaternion( q ) {\n\n\t\tthis.quaternion.premultiply( q );\n\n\t\treturn this;\n\n\t}\n\n\tsetRotationFromAxisAngle( axis, angle ) {\n\n\t\t// assumes axis is normalized\n\n\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t}\n\n\tsetRotationFromEuler( euler ) {\n\n\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t}\n\n\tsetRotationFromMatrix( m ) {\n\n\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t}\n\n\tsetRotationFromQuaternion( q ) {\n\n\t\t// assumes q is normalized\n\n\t\tthis.quaternion.copy( q );\n\n\t}\n\n\trotateOnAxis( axis, angle ) {\n\n\t\t// rotate object on axis in object space\n\t\t// axis is assumed to be normalized\n\n\t\t_q1.setFromAxisAngle( axis, angle );\n\n\t\tthis.quaternion.multiply( _q1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateOnWorldAxis( axis, angle ) {\n\n\t\t// rotate object on axis in world space\n\t\t// axis is assumed to be normalized\n\t\t// method assumes no rotated parent\n\n\t\t_q1.setFromAxisAngle( axis, angle );\n\n\t\tthis.quaternion.premultiply( _q1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateX( angle ) {\n\n\t\treturn this.rotateOnAxis( _xAxis, angle );\n\n\t}\n\n\trotateY( angle ) {\n\n\t\treturn this.rotateOnAxis( _yAxis, angle );\n\n\t}\n\n\trotateZ( angle ) {\n\n\t\treturn this.rotateOnAxis( _zAxis, angle );\n\n\t}\n\n\ttranslateOnAxis( axis, distance ) {\n\n\t\t// translate object by distance along axis in object space\n\t\t// axis is assumed to be normalized\n\n\t\t_v1$4.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\tthis.position.add( _v1$4.multiplyScalar( distance ) );\n\n\t\treturn this;\n\n\t}\n\n\ttranslateX( distance ) {\n\n\t\treturn this.translateOnAxis( _xAxis, distance );\n\n\t}\n\n\ttranslateY( distance ) {\n\n\t\treturn this.translateOnAxis( _yAxis, distance );\n\n\t}\n\n\ttranslateZ( distance ) {\n\n\t\treturn this.translateOnAxis( _zAxis, distance );\n\n\t}\n\n\tlocalToWorld( vector ) {\n\n\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t}\n\n\tworldToLocal( vector ) {\n\n\t\treturn vector.applyMatrix4( _m1$1.copy( this.matrixWorld ).invert() );\n\n\t}\n\n\tlookAt( x, y, z ) {\n\n\t\t// This method does not support objects having non-uniformly-scaled parent(s)\n\n\t\tif ( x.isVector3 ) {\n\n\t\t\t_target.copy( x );\n\n\t\t} else {\n\n\t\t\t_target.set( x, y, z );\n\n\t\t}\n\n\t\tconst parent = this.parent;\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\t_position$3.setFromMatrixPosition( this.matrixWorld );\n\n\t\tif ( this.isCamera || this.isLight ) {\n\n\t\t\t_m1$1.lookAt( _position$3, _target, this.up );\n\n\t\t} else {\n\n\t\t\t_m1$1.lookAt( _target, _position$3, this.up );\n\n\t\t}\n\n\t\tthis.quaternion.setFromRotationMatrix( _m1$1 );\n\n\t\tif ( parent ) {\n\n\t\t\t_m1$1.extractRotation( parent.matrixWorld );\n\t\t\t_q1.setFromRotationMatrix( _m1$1 );\n\t\t\tthis.quaternion.premultiply( _q1.invert() );\n\n\t\t}\n\n\t}\n\n\tadd( object ) {\n\n\t\tif ( arguments.length > 1 ) {\n\n\t\t\tfor ( let i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tif ( object === this ) {\n\n\t\t\tconsole.error( 'THREE.Object3D.add: object can\\'t be added as a child of itself.', object );\n\t\t\treturn this;\n\n\t\t}\n\n\t\tif ( object && object.isObject3D ) {\n\n\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\tobject.parent.remove( object );\n\n\t\t\t}\n\n\t\t\tobject.parent = this;\n\t\t\tthis.children.push( object );\n\n\t\t\tobject.dispatchEvent( _addedEvent );\n\n\t\t} else {\n\n\t\t\tconsole.error( 'THREE.Object3D.add: object not an instance of THREE.Object3D.', object );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tremove( object ) {\n\n\t\tif ( arguments.length > 1 ) {\n\n\t\t\tfor ( let i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tconst index = this.children.indexOf( object );\n\n\t\tif ( index !== - 1 ) {\n\n\t\t\tobject.parent = null;\n\t\t\tthis.children.splice( index, 1 );\n\n\t\t\tobject.dispatchEvent( _removedEvent );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tremoveFromParent() {\n\n\t\tconst parent = this.parent;\n\n\t\tif ( parent !== null ) {\n\n\t\t\tparent.remove( this );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tclear() {\n\n\t\tfor ( let i = 0; i < this.children.length; i ++ ) {\n\n\t\t\tconst object = this.children[ i ];\n\n\t\t\tobject.parent = null;\n\n\t\t\tobject.dispatchEvent( _removedEvent );\n\n\t\t}\n\n\t\tthis.children.length = 0;\n\n\t\treturn this;\n\n\n\t}\n\n\tattach( object ) {\n\n\t\t// adds object as a child of this, while maintaining the object's world transform\n\n\t\t// Note: This method does not support scene graphs having non-uniformly-scaled nodes(s)\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\t_m1$1.copy( this.matrixWorld ).invert();\n\n\t\tif ( object.parent !== null ) {\n\n\t\t\tobject.parent.updateWorldMatrix( true, false );\n\n\t\t\t_m1$1.multiply( object.parent.matrixWorld );\n\n\t\t}\n\n\t\tobject.applyMatrix4( _m1$1 );\n\n\t\tthis.add( object );\n\n\t\tobject.updateWorldMatrix( false, true );\n\n\t\treturn this;\n\n\t}\n\n\tgetObjectById( id ) {\n\n\t\treturn this.getObjectByProperty( 'id', id );\n\n\t}\n\n\tgetObjectByName( name ) {\n\n\t\treturn this.getObjectByProperty( 'name', name );\n\n\t}\n\n\tgetObjectByProperty( name, value ) {\n\n\t\tif ( this[ name ] === value ) return this;\n\n\t\tfor ( let i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\tconst child = this.children[ i ];\n\t\t\tconst object = child.getObjectByProperty( name, value );\n\n\t\t\tif ( object !== undefined ) {\n\n\t\t\t\treturn object;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn undefined;\n\n\t}\n\n\tgetWorldPosition( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\treturn target.setFromMatrixPosition( this.matrixWorld );\n\n\t}\n\n\tgetWorldQuaternion( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\tthis.matrixWorld.decompose( _position$3, target, _scale$2 );\n\n\t\treturn target;\n\n\t}\n\n\tgetWorldScale( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\tthis.matrixWorld.decompose( _position$3, _quaternion$2, target );\n\n\t\treturn target;\n\n\t}\n\n\tgetWorldDirection( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\tconst e = this.matrixWorld.elements;\n\n\t\treturn target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();\n\n\t}\n\n\traycast( /* raycaster, intersects */ ) {}\n\n\ttraverse( callback ) {\n\n\t\tcallback( this );\n\n\t\tconst children = this.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tchildren[ i ].traverse( callback );\n\n\t\t}\n\n\t}\n\n\ttraverseVisible( callback ) {\n\n\t\tif ( this.visible === false ) return;\n\n\t\tcallback( this );\n\n\t\tconst children = this.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t}\n\n\t}\n\n\ttraverseAncestors( callback ) {\n\n\t\tconst parent = this.parent;\n\n\t\tif ( parent !== null ) {\n\n\t\t\tcallback( parent );\n\n\t\t\tparent.traverseAncestors( callback );\n\n\t\t}\n\n\t}\n\n\tupdateMatrix() {\n\n\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tif ( this.matrixAutoUpdate ) this.updateMatrix();\n\n\t\tif ( this.matrixWorldNeedsUpdate || force ) {\n\n\t\t\tif ( this.parent === null ) {\n\n\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t} else {\n\n\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t}\n\n\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\tforce = true;\n\n\t\t}\n\n\t\t// update children\n\n\t\tconst children = this.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t}\n\n\t}\n\n\tupdateWorldMatrix( updateParents, updateChildren ) {\n\n\t\tconst parent = this.parent;\n\n\t\tif ( updateParents === true && parent !== null ) {\n\n\t\t\tparent.updateWorldMatrix( true, false );\n\n\t\t}\n\n\t\tif ( this.matrixAutoUpdate ) this.updateMatrix();\n\n\t\tif ( this.parent === null ) {\n\n\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t} else {\n\n\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t}\n\n\t\t// update children\n\n\t\tif ( updateChildren === true ) {\n\n\t\t\tconst children = this.children;\n\n\t\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateWorldMatrix( false, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\t// meta is a string when called from JSON.stringify\n\t\tconst isRootObject = ( meta === undefined || typeof meta === 'string' );\n\n\t\tconst output = {};\n\n\t\t// meta is a hash used to collect geometries, materials.\n\t\t// not providing it implies that this is the root object\n\t\t// being serialized.\n\t\tif ( isRootObject ) {\n\n\t\t\t// initialize meta obj\n\t\t\tmeta = {\n\t\t\t\tgeometries: {},\n\t\t\t\tmaterials: {},\n\t\t\t\ttextures: {},\n\t\t\t\timages: {},\n\t\t\t\tshapes: {},\n\t\t\t\tskeletons: {},\n\t\t\t\tanimations: {},\n\t\t\t\tnodes: {}\n\t\t\t};\n\n\t\t\toutput.metadata = {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'Object',\n\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t};\n\n\t\t}\n\n\t\t// standard Object3D serialization\n\n\t\tconst object = {};\n\n\t\tobject.uuid = this.uuid;\n\t\tobject.type = this.type;\n\n\t\tif ( this.name !== '' ) object.name = this.name;\n\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\tif ( this.visible === false ) object.visible = false;\n\t\tif ( this.frustumCulled === false ) object.frustumCulled = false;\n\t\tif ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;\n\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\n\t\tobject.layers = this.layers.mask;\n\t\tobject.matrix = this.matrix.toArray();\n\n\t\tif ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;\n\n\t\t// object specific properties\n\n\t\tif ( this.isInstancedMesh ) {\n\n\t\t\tobject.type = 'InstancedMesh';\n\t\t\tobject.count = this.count;\n\t\t\tobject.instanceMatrix = this.instanceMatrix.toJSON();\n\t\t\tif ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON();\n\n\t\t}\n\n\t\t//\n\n\t\tfunction serialize( library, element ) {\n\n\t\t\tif ( library[ element.uuid ] === undefined ) {\n\n\t\t\t\tlibrary[ element.uuid ] = element.toJSON( meta );\n\n\t\t\t}\n\n\t\t\treturn element.uuid;\n\n\t\t}\n\n\t\tif ( this.isScene ) {\n\n\t\t\tif ( this.background ) {\n\n\t\t\t\tif ( this.background.isColor ) {\n\n\t\t\t\t\tobject.background = this.background.toJSON();\n\n\t\t\t\t} else if ( this.background.isTexture ) {\n\n\t\t\t\t\tobject.background = this.background.toJSON( meta ).uuid;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.environment && this.environment.isTexture ) {\n\n\t\t\t\tobject.environment = this.environment.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t} else if ( this.isMesh || this.isLine || this.isPoints ) {\n\n\t\t\tobject.geometry = serialize( meta.geometries, this.geometry );\n\n\t\t\tconst parameters = this.geometry.parameters;\n\n\t\t\tif ( parameters !== undefined && parameters.shapes !== undefined ) {\n\n\t\t\t\tconst shapes = parameters.shapes;\n\n\t\t\t\tif ( Array.isArray( shapes ) ) {\n\n\t\t\t\t\tfor ( let i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tconst shape = shapes[ i ];\n\n\t\t\t\t\t\tserialize( meta.shapes, shape );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tserialize( meta.shapes, shapes );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.isSkinnedMesh ) {\n\n\t\t\tobject.bindMode = this.bindMode;\n\t\t\tobject.bindMatrix = this.bindMatrix.toArray();\n\n\t\t\tif ( this.skeleton !== undefined ) {\n\n\t\t\t\tserialize( meta.skeletons, this.skeleton );\n\n\t\t\t\tobject.skeleton = this.skeleton.uuid;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.material !== undefined ) {\n\n\t\t\tif ( Array.isArray( this.material ) ) {\n\n\t\t\t\tconst uuids = [];\n\n\t\t\t\tfor ( let i = 0, l = this.material.length; i < l; i ++ ) {\n\n\t\t\t\t\tuuids.push( serialize( meta.materials, this.material[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = uuids;\n\n\t\t\t} else {\n\n\t\t\t\tobject.material = serialize( meta.materials, this.material );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tif ( this.children.length > 0 ) {\n\n\t\t\tobject.children = [];\n\n\t\t\tfor ( let i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tif ( this.animations.length > 0 ) {\n\n\t\t\tobject.animations = [];\n\n\t\t\tfor ( let i = 0; i < this.animations.length; i ++ ) {\n\n\t\t\t\tconst animation = this.animations[ i ];\n\n\t\t\t\tobject.animations.push( serialize( meta.animations, animation ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( isRootObject ) {\n\n\t\t\tconst geometries = extractFromCache( meta.geometries );\n\t\t\tconst materials = extractFromCache( meta.materials );\n\t\t\tconst textures = extractFromCache( meta.textures );\n\t\t\tconst images = extractFromCache( meta.images );\n\t\t\tconst shapes = extractFromCache( meta.shapes );\n\t\t\tconst skeletons = extractFromCache( meta.skeletons );\n\t\t\tconst animations = extractFromCache( meta.animations );\n\t\t\tconst nodes = extractFromCache( meta.nodes );\n\n\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\tif ( images.length > 0 ) output.images = images;\n\t\t\tif ( shapes.length > 0 ) output.shapes = shapes;\n\t\t\tif ( skeletons.length > 0 ) output.skeletons = skeletons;\n\t\t\tif ( animations.length > 0 ) output.animations = animations;\n\t\t\tif ( nodes.length > 0 ) output.nodes = nodes;\n\n\t\t}\n\n\t\toutput.object = object;\n\n\t\treturn output;\n\n\t\t// extract data from the cache hash\n\t\t// remove metadata on each item\n\t\t// and return as array\n\t\tfunction extractFromCache( cache ) {\n\n\t\t\tconst values = [];\n\t\t\tfor ( const key in cache ) {\n\n\t\t\t\tconst data = cache[ key ];\n\t\t\t\tdelete data.metadata;\n\t\t\t\tvalues.push( data );\n\n\t\t\t}\n\n\t\t\treturn values;\n\n\t\t}\n\n\t}\n\n\tclone( recursive ) {\n\n\t\treturn new this.constructor().copy( this, recursive );\n\n\t}\n\n\tcopy( source, recursive = true ) {\n\n\t\tthis.name = source.name;\n\n\t\tthis.up.copy( source.up );\n\n\t\tthis.position.copy( source.position );\n\t\tthis.rotation.order = source.rotation.order;\n\t\tthis.quaternion.copy( source.quaternion );\n\t\tthis.scale.copy( source.scale );\n\n\t\tthis.matrix.copy( source.matrix );\n\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\tthis.layers.mask = source.layers.mask;\n\t\tthis.visible = source.visible;\n\n\t\tthis.castShadow = source.castShadow;\n\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\tthis.frustumCulled = source.frustumCulled;\n\t\tthis.renderOrder = source.renderOrder;\n\n\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tfor ( let i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\tconst child = source.children[ i ];\n\t\t\t\tthis.add( child.clone() );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nObject3D.DefaultUp = new Vector3( 0, 1, 0 );\nObject3D.DefaultMatrixAutoUpdate = true;\n\nconst _v0$1 = /*@__PURE__*/ new Vector3();\nconst _v1$3 = /*@__PURE__*/ new Vector3();\nconst _v2$2 = /*@__PURE__*/ new Vector3();\nconst _v3$1 = /*@__PURE__*/ new Vector3();\n\nconst _vab = /*@__PURE__*/ new Vector3();\nconst _vac = /*@__PURE__*/ new Vector3();\nconst _vbc = /*@__PURE__*/ new Vector3();\nconst _vap = /*@__PURE__*/ new Vector3();\nconst _vbp = /*@__PURE__*/ new Vector3();\nconst _vcp = /*@__PURE__*/ new Vector3();\n\nclass Triangle {\n\n\tconstructor( a = new Vector3(), b = new Vector3(), c = new Vector3() ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t}\n\n\tstatic getNormal( a, b, c, target ) {\n\n\t\ttarget.subVectors( c, b );\n\t\t_v0$1.subVectors( a, b );\n\t\ttarget.cross( _v0$1 );\n\n\t\tconst targetLengthSq = target.lengthSq();\n\t\tif ( targetLengthSq > 0 ) {\n\n\t\t\treturn target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) );\n\n\t\t}\n\n\t\treturn target.set( 0, 0, 0 );\n\n\t}\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tstatic getBarycoord( point, a, b, c, target ) {\n\n\t\t_v0$1.subVectors( c, a );\n\t\t_v1$3.subVectors( b, a );\n\t\t_v2$2.subVectors( point, a );\n\n\t\tconst dot00 = _v0$1.dot( _v0$1 );\n\t\tconst dot01 = _v0$1.dot( _v1$3 );\n\t\tconst dot02 = _v0$1.dot( _v2$2 );\n\t\tconst dot11 = _v1$3.dot( _v1$3 );\n\t\tconst dot12 = _v1$3.dot( _v2$2 );\n\n\t\tconst denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t// collinear or singular triangle\n\t\tif ( denom === 0 ) {\n\n\t\t\t// arbitrary location outside of triangle?\n\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\treturn target.set( - 2, - 1, - 1 );\n\n\t\t}\n\n\t\tconst invDenom = 1 / denom;\n\t\tconst u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\tconst v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t// barycentric coordinates must always sum to 1\n\t\treturn target.set( 1 - u - v, v, u );\n\n\t}\n\n\tstatic containsPoint( point, a, b, c ) {\n\n\t\tthis.getBarycoord( point, a, b, c, _v3$1 );\n\n\t\treturn ( _v3$1.x >= 0 ) && ( _v3$1.y >= 0 ) && ( ( _v3$1.x + _v3$1.y ) <= 1 );\n\n\t}\n\n\tstatic getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) {\n\n\t\tthis.getBarycoord( point, p1, p2, p3, _v3$1 );\n\n\t\ttarget.set( 0, 0 );\n\t\ttarget.addScaledVector( uv1, _v3$1.x );\n\t\ttarget.addScaledVector( uv2, _v3$1.y );\n\t\ttarget.addScaledVector( uv3, _v3$1.z );\n\n\t\treturn target;\n\n\t}\n\n\tstatic isFrontFacing( a, b, c, direction ) {\n\n\t\t_v0$1.subVectors( c, b );\n\t\t_v1$3.subVectors( a, b );\n\n\t\t// strictly front facing\n\t\treturn ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false;\n\n\t}\n\n\tset( a, b, c ) {\n\n\t\tthis.a.copy( a );\n\t\tthis.b.copy( b );\n\t\tthis.c.copy( c );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPointsAndIndices( points, i0, i1, i2 ) {\n\n\t\tthis.a.copy( points[ i0 ] );\n\t\tthis.b.copy( points[ i1 ] );\n\t\tthis.c.copy( points[ i2 ] );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromAttributeAndIndices( attribute, i0, i1, i2 ) {\n\n\t\tthis.a.fromBufferAttribute( attribute, i0 );\n\t\tthis.b.fromBufferAttribute( attribute, i1 );\n\t\tthis.c.fromBufferAttribute( attribute, i2 );\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( triangle ) {\n\n\t\tthis.a.copy( triangle.a );\n\t\tthis.b.copy( triangle.b );\n\t\tthis.c.copy( triangle.c );\n\n\t\treturn this;\n\n\t}\n\n\tgetArea() {\n\n\t\t_v0$1.subVectors( this.c, this.b );\n\t\t_v1$3.subVectors( this.a, this.b );\n\n\t\treturn _v0$1.cross( _v1$3 ).length() * 0.5;\n\n\t}\n\n\tgetMidpoint( target ) {\n\n\t\treturn target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t}\n\n\tgetNormal( target ) {\n\n\t\treturn Triangle.getNormal( this.a, this.b, this.c, target );\n\n\t}\n\n\tgetPlane( target ) {\n\n\t\treturn target.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t}\n\n\tgetBarycoord( point, target ) {\n\n\t\treturn Triangle.getBarycoord( point, this.a, this.b, this.c, target );\n\n\t}\n\n\tgetUV( point, uv1, uv2, uv3, target ) {\n\n\t\treturn Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target );\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t}\n\n\tisFrontFacing( direction ) {\n\n\t\treturn Triangle.isFrontFacing( this.a, this.b, this.c, direction );\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\treturn box.intersectsTriangle( this );\n\n\t}\n\n\tclosestPointToPoint( p, target ) {\n\n\t\tconst a = this.a, b = this.b, c = this.c;\n\t\tlet v, w;\n\n\t\t// algorithm thanks to Real-Time Collision Detection by Christer Ericson,\n\t\t// published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc.,\n\t\t// under the accompanying license; see chapter 5.1.5 for detailed explanation.\n\t\t// basically, we're distinguishing which of the voronoi regions of the triangle\n\t\t// the point lies in with the minimum amount of redundant computation.\n\n\t\t_vab.subVectors( b, a );\n\t\t_vac.subVectors( c, a );\n\t\t_vap.subVectors( p, a );\n\t\tconst d1 = _vab.dot( _vap );\n\t\tconst d2 = _vac.dot( _vap );\n\t\tif ( d1 <= 0 && d2 <= 0 ) {\n\n\t\t\t// vertex region of A; barycentric coords (1, 0, 0)\n\t\t\treturn target.copy( a );\n\n\t\t}\n\n\t\t_vbp.subVectors( p, b );\n\t\tconst d3 = _vab.dot( _vbp );\n\t\tconst d4 = _vac.dot( _vbp );\n\t\tif ( d3 >= 0 && d4 <= d3 ) {\n\n\t\t\t// vertex region of B; barycentric coords (0, 1, 0)\n\t\t\treturn target.copy( b );\n\n\t\t}\n\n\t\tconst vc = d1 * d4 - d3 * d2;\n\t\tif ( vc <= 0 && d1 >= 0 && d3 <= 0 ) {\n\n\t\t\tv = d1 / ( d1 - d3 );\n\t\t\t// edge region of AB; barycentric coords (1-v, v, 0)\n\t\t\treturn target.copy( a ).addScaledVector( _vab, v );\n\n\t\t}\n\n\t\t_vcp.subVectors( p, c );\n\t\tconst d5 = _vab.dot( _vcp );\n\t\tconst d6 = _vac.dot( _vcp );\n\t\tif ( d6 >= 0 && d5 <= d6 ) {\n\n\t\t\t// vertex region of C; barycentric coords (0, 0, 1)\n\t\t\treturn target.copy( c );\n\n\t\t}\n\n\t\tconst vb = d5 * d2 - d1 * d6;\n\t\tif ( vb <= 0 && d2 >= 0 && d6 <= 0 ) {\n\n\t\t\tw = d2 / ( d2 - d6 );\n\t\t\t// edge region of AC; barycentric coords (1-w, 0, w)\n\t\t\treturn target.copy( a ).addScaledVector( _vac, w );\n\n\t\t}\n\n\t\tconst va = d3 * d6 - d5 * d4;\n\t\tif ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) {\n\n\t\t\t_vbc.subVectors( c, b );\n\t\t\tw = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) );\n\t\t\t// edge region of BC; barycentric coords (0, 1-w, w)\n\t\t\treturn target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC\n\n\t\t}\n\n\t\t// face region\n\t\tconst denom = 1 / ( va + vb + vc );\n\t\t// u = va * denom\n\t\tv = vb * denom;\n\t\tw = vc * denom;\n\n\t\treturn target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w );\n\n\t}\n\n\tequals( triangle ) {\n\n\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t}\n\n}\n\nlet materialId = 0;\n\nclass Material extends EventDispatcher {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isMaterial = true;\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.vertexColors = false;\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.stencilWriteMask = 0xff;\n\t\tthis.stencilFunc = AlwaysStencilFunc;\n\t\tthis.stencilRef = 0;\n\t\tthis.stencilFuncMask = 0xff;\n\t\tthis.stencilFail = KeepStencilOp;\n\t\tthis.stencilZFail = KeepStencilOp;\n\t\tthis.stencilZPass = KeepStencilOp;\n\t\tthis.stencilWrite = false;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.shadowSide = null;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.dithering = false;\n\n\t\tthis.alphaToCoverage = false;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.visible = true;\n\n\t\tthis.toneMapped = true;\n\n\t\tthis.userData = {};\n\n\t\tthis.version = 0;\n\n\t\tthis._alphaTest = 0;\n\n\t}\n\n\tget alphaTest() {\n\n\t\treturn this._alphaTest;\n\n\t}\n\n\tset alphaTest( value ) {\n\n\t\tif ( this._alphaTest > 0 !== value > 0 ) {\n\n\t\t\tthis.version ++;\n\n\t\t}\n\n\t\tthis._alphaTest = value;\n\n\t}\n\n\tonBuild( /* shaderobject, renderer */ ) {}\n\n\tonBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {}\n\n\tonBeforeCompile( /* shaderobject, renderer */ ) {}\n\n\tcustomProgramCacheKey() {\n\n\t\treturn this.onBeforeCompile.toString();\n\n\t}\n\n\tsetValues( values ) {\n\n\t\tif ( values === undefined ) return;\n\n\t\tfor ( const key in values ) {\n\n\t\t\tconst newValue = values[ key ];\n\n\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Material: \\'' + key + '\\' parameter is undefined.' );\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\t// for backward compatibility if shading is set in the constructor\n\t\t\tif ( key === 'shading' ) {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );\n\t\t\t\tthis.flatShading = ( newValue === FlatShading ) ? true : false;\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\tconst currentValue = this[ key ];\n\n\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': \\'' + key + '\\' is not a property of this material.' );\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t} else {\n\n\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst isRootObject = ( meta === undefined || typeof meta === 'string' );\n\n\t\tif ( isRootObject ) {\n\n\t\t\tmeta = {\n\t\t\t\ttextures: {},\n\t\t\t\timages: {}\n\t\t\t};\n\n\t\t}\n\n\t\tconst data = {\n\t\t\tmetadata: {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'Material',\n\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t}\n\t\t};\n\n\t\t// standard Material serialization\n\t\tdata.uuid = this.uuid;\n\t\tdata.type = this.type;\n\n\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\tif ( this.sheen !== undefined ) data.sheen = this.sheen;\n\t\tif ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex();\n\t\tif ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness;\n\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\tif ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;\n\n\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\tif ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity;\n\t\tif ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex();\n\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\tif ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat;\n\t\tif ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness;\n\n\t\tif ( this.clearcoatMap && this.clearcoatMap.isTexture ) {\n\n\t\t\tdata.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;\n\n\t\t}\n\n\t\tif ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {\n\n\t\t\tdata.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;\n\n\t\t}\n\n\t\tif ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {\n\n\t\t\tdata.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;\n\t\t\tdata.clearcoatNormalScale = this.clearcoatNormalScale.toArray();\n\n\t\t}\n\n\t\tif ( this.iridescence !== undefined ) data.iridescence = this.iridescence;\n\t\tif ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR;\n\t\tif ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange;\n\n\t\tif ( this.iridescenceMap && this.iridescenceMap.isTexture ) {\n\n\t\t\tdata.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid;\n\n\t\t}\n\n\t\tif ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) {\n\n\t\t\tdata.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid;\n\n\t\t}\n\n\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\tif ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid;\n\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\n\t\tif ( this.lightMap && this.lightMap.isTexture ) {\n\n\t\t\tdata.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tdata.lightMapIntensity = this.lightMapIntensity;\n\n\t\t}\n\n\t\tif ( this.aoMap && this.aoMap.isTexture ) {\n\n\t\t\tdata.aoMap = this.aoMap.toJSON( meta ).uuid;\n\t\t\tdata.aoMapIntensity = this.aoMapIntensity;\n\n\t\t}\n\n\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t}\n\n\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\tdata.normalMapType = this.normalMapType;\n\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t}\n\n\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t}\n\n\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\t\tif ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid;\n\t\tif ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid;\n\n\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.combine !== undefined ) data.combine = this.combine;\n\n\t\t}\n\n\t\tif ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity;\n\t\tif ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity;\n\t\tif ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio;\n\n\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t}\n\n\t\tif ( this.transmission !== undefined ) data.transmission = this.transmission;\n\t\tif ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid;\n\t\tif ( this.thickness !== undefined ) data.thickness = this.thickness;\n\t\tif ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid;\n\t\tif ( this.attenuationDistance !== undefined ) data.attenuationDistance = this.attenuationDistance;\n\t\tif ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex();\n\n\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\tif ( this.shadowSide !== null ) data.shadowSide = this.shadowSide;\n\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\tif ( this.vertexColors ) data.vertexColors = true;\n\n\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\tdata.depthFunc = this.depthFunc;\n\t\tdata.depthTest = this.depthTest;\n\t\tdata.depthWrite = this.depthWrite;\n\t\tdata.colorWrite = this.colorWrite;\n\n\t\tdata.stencilWrite = this.stencilWrite;\n\t\tdata.stencilWriteMask = this.stencilWriteMask;\n\t\tdata.stencilFunc = this.stencilFunc;\n\t\tdata.stencilRef = this.stencilRef;\n\t\tdata.stencilFuncMask = this.stencilFuncMask;\n\t\tdata.stencilFail = this.stencilFail;\n\t\tdata.stencilZFail = this.stencilZFail;\n\t\tdata.stencilZPass = this.stencilZPass;\n\n\t\t// rotation (SpriteMaterial)\n\t\tif ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation;\n\n\t\tif ( this.polygonOffset === true ) data.polygonOffset = true;\n\t\tif ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor;\n\t\tif ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits;\n\n\t\tif ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth;\n\t\tif ( this.dashSize !== undefined ) data.dashSize = this.dashSize;\n\t\tif ( this.gapSize !== undefined ) data.gapSize = this.gapSize;\n\t\tif ( this.scale !== undefined ) data.scale = this.scale;\n\n\t\tif ( this.dithering === true ) data.dithering = true;\n\n\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\tif ( this.alphaToCoverage === true ) data.alphaToCoverage = this.alphaToCoverage;\n\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\n\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\tif ( this.flatShading === true ) data.flatShading = this.flatShading;\n\n\t\tif ( this.visible === false ) data.visible = false;\n\n\t\tif ( this.toneMapped === false ) data.toneMapped = false;\n\n\t\tif ( this.fog === false ) data.fog = false;\n\n\t\tif ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;\n\n\t\t// TODO: Copied from Object3D.toJSON\n\n\t\tfunction extractFromCache( cache ) {\n\n\t\t\tconst values = [];\n\n\t\t\tfor ( const key in cache ) {\n\n\t\t\t\tconst data = cache[ key ];\n\t\t\t\tdelete data.metadata;\n\t\t\t\tvalues.push( data );\n\n\t\t\t}\n\n\t\t\treturn values;\n\n\t\t}\n\n\t\tif ( isRootObject ) {\n\n\t\t\tconst textures = extractFromCache( meta.textures );\n\t\t\tconst images = extractFromCache( meta.images );\n\n\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.name = source.name;\n\n\t\tthis.blending = source.blending;\n\t\tthis.side = source.side;\n\t\tthis.vertexColors = source.vertexColors;\n\n\t\tthis.opacity = source.opacity;\n\t\tthis.transparent = source.transparent;\n\n\t\tthis.blendSrc = source.blendSrc;\n\t\tthis.blendDst = source.blendDst;\n\t\tthis.blendEquation = source.blendEquation;\n\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\tthis.depthFunc = source.depthFunc;\n\t\tthis.depthTest = source.depthTest;\n\t\tthis.depthWrite = source.depthWrite;\n\n\t\tthis.stencilWriteMask = source.stencilWriteMask;\n\t\tthis.stencilFunc = source.stencilFunc;\n\t\tthis.stencilRef = source.stencilRef;\n\t\tthis.stencilFuncMask = source.stencilFuncMask;\n\t\tthis.stencilFail = source.stencilFail;\n\t\tthis.stencilZFail = source.stencilZFail;\n\t\tthis.stencilZPass = source.stencilZPass;\n\t\tthis.stencilWrite = source.stencilWrite;\n\n\t\tconst srcPlanes = source.clippingPlanes;\n\t\tlet dstPlanes = null;\n\n\t\tif ( srcPlanes !== null ) {\n\n\t\t\tconst n = srcPlanes.length;\n\t\t\tdstPlanes = new Array( n );\n\n\t\t\tfor ( let i = 0; i !== n; ++ i ) {\n\n\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.clippingPlanes = dstPlanes;\n\t\tthis.clipIntersection = source.clipIntersection;\n\t\tthis.clipShadows = source.clipShadows;\n\n\t\tthis.shadowSide = source.shadowSide;\n\n\t\tthis.colorWrite = source.colorWrite;\n\n\t\tthis.precision = source.precision;\n\n\t\tthis.polygonOffset = source.polygonOffset;\n\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\tthis.dithering = source.dithering;\n\n\t\tthis.alphaTest = source.alphaTest;\n\t\tthis.alphaToCoverage = source.alphaToCoverage;\n\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\tthis.visible = source.visible;\n\n\t\tthis.toneMapped = source.toneMapped;\n\n\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\treturn this;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) this.version ++;\n\n\t}\n\n\t// @deprecated since r131, f5803c62cc4a29d90744e9dc7811d086e354c1d8\n\n\tget vertexTangents() {\n\n\t\tconsole.warn( 'THREE.' + this.type + ': .vertexTangents has been removed.' );\n\t\treturn false;\n\n\t}\n\n\tset vertexTangents( value ) {\n\n\t\tconsole.warn( 'THREE.' + this.type + ': .vertexTangents has been removed.' );\n\n\t}\n\n}\n\nMaterial.fromType = function ( /*type*/ ) {\n\n\t// TODO: Behavior added in Materials.js\n\n\treturn null;\n\n};\n\nclass MeshBasicMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshBasicMaterial = true;\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst _vector$9 = /*@__PURE__*/ new Vector3();\nconst _vector2$1 = /*@__PURE__*/ new Vector2();\n\nclass BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.isBufferAttribute = true;\n\n\t\tthis.name = '';\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.usage = StaticDrawUsage;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t}\n\n\tonUploadCallback() {}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) this.version ++;\n\n\t}\n\n\tsetUsage( value ) {\n\n\t\tthis.usage = value;\n\n\t\treturn this;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.name = source.name;\n\t\tthis.array = new source.array.constructor( source.array );\n\t\tthis.itemSize = source.itemSize;\n\t\tthis.count = source.count;\n\t\tthis.normalized = source.normalized;\n\n\t\tthis.usage = source.usage;\n\n\t\treturn this;\n\n\t}\n\n\tcopyAt( index1, attribute, index2 ) {\n\n\t\tindex1 *= this.itemSize;\n\t\tindex2 *= attribute.itemSize;\n\n\t\tfor ( let i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcopyArray( array ) {\n\n\t\tthis.array.set( array );\n\n\t\treturn this;\n\n\t}\n\n\tcopyColorsArray( colors ) {\n\n\t\tconst array = this.array;\n\t\tlet offset = 0;\n\n\t\tfor ( let i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\tlet color = colors[ i ];\n\n\t\t\tif ( color === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\tcolor = new Color();\n\n\t\t\t}\n\n\t\t\tarray[ offset ++ ] = color.r;\n\t\t\tarray[ offset ++ ] = color.g;\n\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcopyVector2sArray( vectors ) {\n\n\t\tconst array = this.array;\n\t\tlet offset = 0;\n\n\t\tfor ( let i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\tlet vector = vectors[ i ];\n\n\t\t\tif ( vector === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\tvector = new Vector2();\n\n\t\t\t}\n\n\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcopyVector3sArray( vectors ) {\n\n\t\tconst array = this.array;\n\t\tlet offset = 0;\n\n\t\tfor ( let i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\tlet vector = vectors[ i ];\n\n\t\t\tif ( vector === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\tvector = new Vector3();\n\n\t\t\t}\n\n\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcopyVector4sArray( vectors ) {\n\n\t\tconst array = this.array;\n\t\tlet offset = 0;\n\n\t\tfor ( let i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\tlet vector = vectors[ i ];\n\n\t\t\tif ( vector === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\tvector = new Vector4();\n\n\t\t\t}\n\n\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyMatrix3( m ) {\n\n\t\tif ( this.itemSize === 2 ) {\n\n\t\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t\t_vector2$1.fromBufferAttribute( this, i );\n\t\t\t\t_vector2$1.applyMatrix3( m );\n\n\t\t\t\tthis.setXY( i, _vector2$1.x, _vector2$1.y );\n\n\t\t\t}\n\n\t\t} else if ( this.itemSize === 3 ) {\n\n\t\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t\t_vector$9.fromBufferAttribute( this, i );\n\t\t\t\t_vector$9.applyMatrix3( m );\n\n\t\t\t\tthis.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyMatrix4( m ) {\n\n\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t_vector$9.fromBufferAttribute( this, i );\n\n\t\t\t_vector$9.applyMatrix4( m );\n\n\t\t\tthis.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyNormalMatrix( m ) {\n\n\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t_vector$9.fromBufferAttribute( this, i );\n\n\t\t\t_vector$9.applyNormalMatrix( m );\n\n\t\t\tthis.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttransformDirection( m ) {\n\n\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t_vector$9.fromBufferAttribute( this, i );\n\n\t\t\t_vector$9.transformDirection( m );\n\n\t\t\tthis.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tset( value, offset = 0 ) {\n\n\t\tthis.array.set( value, offset );\n\n\t\treturn this;\n\n\t}\n\n\tgetX( index ) {\n\n\t\treturn this.array[ index * this.itemSize ];\n\n\t}\n\n\tsetX( index, x ) {\n\n\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\treturn this;\n\n\t}\n\n\tgetY( index ) {\n\n\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t}\n\n\tsetY( index, y ) {\n\n\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\treturn this;\n\n\t}\n\n\tgetZ( index ) {\n\n\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t}\n\n\tsetZ( index, z ) {\n\n\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\treturn this;\n\n\t}\n\n\tgetW( index ) {\n\n\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t}\n\n\tsetW( index, w ) {\n\n\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\treturn this;\n\n\t}\n\n\tsetXY( index, x, y ) {\n\n\t\tindex *= this.itemSize;\n\n\t\tthis.array[ index + 0 ] = x;\n\t\tthis.array[ index + 1 ] = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetXYZ( index, x, y, z ) {\n\n\t\tindex *= this.itemSize;\n\n\t\tthis.array[ index + 0 ] = x;\n\t\tthis.array[ index + 1 ] = y;\n\t\tthis.array[ index + 2 ] = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetXYZW( index, x, y, z, w ) {\n\n\t\tindex *= this.itemSize;\n\n\t\tthis.array[ index + 0 ] = x;\n\t\tthis.array[ index + 1 ] = y;\n\t\tthis.array[ index + 2 ] = z;\n\t\tthis.array[ index + 3 ] = w;\n\n\t\treturn this;\n\n\t}\n\n\tonUpload( callback ) {\n\n\t\tthis.onUploadCallback = callback;\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = {\n\t\t\titemSize: this.itemSize,\n\t\t\ttype: this.array.constructor.name,\n\t\t\tarray: Array.prototype.slice.call( this.array ),\n\t\t\tnormalized: this.normalized\n\t\t};\n\n\t\tif ( this.name !== '' ) data.name = this.name;\n\t\tif ( this.usage !== StaticDrawUsage ) data.usage = this.usage;\n\t\tif ( this.updateRange.offset !== 0 || this.updateRange.count !== - 1 ) data.updateRange = this.updateRange;\n\n\t\treturn data;\n\n\t}\n\n}\n\n//\n\nclass Int8BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Int8Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Uint8BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint8Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Uint8ClampedBufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint8ClampedArray( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Int16BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Int16Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Uint16BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint16Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Int32BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Int32Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Uint32BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint32Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Float16BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Uint16Array( array ), itemSize, normalized );\n\n\t\tthis.isFloat16BufferAttribute = true;\n\n\t}\n\n}\n\n\nclass Float32BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Float32Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nclass Float64BufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized ) {\n\n\t\tsuper( new Float64Array( array ), itemSize, normalized );\n\n\t}\n\n}\n\nlet _id$1 = 0;\n\nconst _m1 = /*@__PURE__*/ new Matrix4();\nconst _obj = /*@__PURE__*/ new Object3D();\nconst _offset = /*@__PURE__*/ new Vector3();\nconst _box$1 = /*@__PURE__*/ new Box3();\nconst _boxMorphTargets = /*@__PURE__*/ new Box3();\nconst _vector$8 = /*@__PURE__*/ new Vector3();\n\nclass BufferGeometry extends EventDispatcher {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isBufferGeometry = true;\n\n\t\tObject.defineProperty( this, 'id', { value: _id$1 ++ } );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\t\tthis.morphTargetsRelative = false;\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t\tthis.userData = {};\n\n\t}\n\n\tgetIndex() {\n\n\t\treturn this.index;\n\n\t}\n\n\tsetIndex( index ) {\n\n\t\tif ( Array.isArray( index ) ) {\n\n\t\t\tthis.index = new ( arrayNeedsUint32( index ) ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t} else {\n\n\t\t\tthis.index = index;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetAttribute( name ) {\n\n\t\treturn this.attributes[ name ];\n\n\t}\n\n\tsetAttribute( name, attribute ) {\n\n\t\tthis.attributes[ name ] = attribute;\n\n\t\treturn this;\n\n\t}\n\n\tdeleteAttribute( name ) {\n\n\t\tdelete this.attributes[ name ];\n\n\t\treturn this;\n\n\t}\n\n\thasAttribute( name ) {\n\n\t\treturn this.attributes[ name ] !== undefined;\n\n\t}\n\n\taddGroup( start, count, materialIndex = 0 ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t}\n\n\tclearGroups() {\n\n\t\tthis.groups = [];\n\n\t}\n\n\tsetDrawRange( start, count ) {\n\n\t\tthis.drawRange.start = start;\n\t\tthis.drawRange.count = count;\n\n\t}\n\n\tapplyMatrix4( matrix ) {\n\n\t\tconst position = this.attributes.position;\n\n\t\tif ( position !== undefined ) {\n\n\t\t\tposition.applyMatrix4( matrix );\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t}\n\n\t\tconst normal = this.attributes.normal;\n\n\t\tif ( normal !== undefined ) {\n\n\t\t\tconst normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tnormal.applyNormalMatrix( normalMatrix );\n\n\t\t\tnormal.needsUpdate = true;\n\n\t\t}\n\n\t\tconst tangent = this.attributes.tangent;\n\n\t\tif ( tangent !== undefined ) {\n\n\t\t\ttangent.transformDirection( matrix );\n\n\t\t\ttangent.needsUpdate = true;\n\n\t\t}\n\n\t\tif ( this.boundingBox !== null ) {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t}\n\n\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyQuaternion( q ) {\n\n\t\t_m1.makeRotationFromQuaternion( q );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateX( angle ) {\n\n\t\t// rotate geometry around world x-axis\n\n\t\t_m1.makeRotationX( angle );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateY( angle ) {\n\n\t\t// rotate geometry around world y-axis\n\n\t\t_m1.makeRotationY( angle );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\trotateZ( angle ) {\n\n\t\t// rotate geometry around world z-axis\n\n\t\t_m1.makeRotationZ( angle );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( x, y, z ) {\n\n\t\t// translate geometry\n\n\t\t_m1.makeTranslation( x, y, z );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\tscale( x, y, z ) {\n\n\t\t// scale geometry\n\n\t\t_m1.makeScale( x, y, z );\n\n\t\tthis.applyMatrix4( _m1 );\n\n\t\treturn this;\n\n\t}\n\n\tlookAt( vector ) {\n\n\t\t_obj.lookAt( vector );\n\n\t\t_obj.updateMatrix();\n\n\t\tthis.applyMatrix4( _obj.matrix );\n\n\t\treturn this;\n\n\t}\n\n\tcenter() {\n\n\t\tthis.computeBoundingBox();\n\n\t\tthis.boundingBox.getCenter( _offset ).negate();\n\n\t\tthis.translate( _offset.x, _offset.y, _offset.z );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPoints( points ) {\n\n\t\tconst position = [];\n\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tconst point = points[ i ];\n\t\t\tposition.push( point.x, point.y, point.z || 0 );\n\n\t\t}\n\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) );\n\n\t\treturn this;\n\n\t}\n\n\tcomputeBoundingBox() {\n\n\t\tif ( this.boundingBox === null ) {\n\n\t\t\tthis.boundingBox = new Box3();\n\n\t\t}\n\n\t\tconst position = this.attributes.position;\n\t\tconst morphAttributesPosition = this.morphAttributes.position;\n\n\t\tif ( position && position.isGLBufferAttribute ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set \"mesh.frustumCulled\" to \"false\".', this );\n\n\t\t\tthis.boundingBox.set(\n\t\t\t\tnew Vector3( - Infinity, - Infinity, - Infinity ),\n\t\t\t\tnew Vector3( + Infinity, + Infinity, + Infinity )\n\t\t\t);\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( position !== undefined ) {\n\n\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t// process morph attributes if present\n\n\t\t\tif ( morphAttributesPosition ) {\n\n\t\t\t\tfor ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst morphAttribute = morphAttributesPosition[ i ];\n\t\t\t\t\t_box$1.setFromBufferAttribute( morphAttribute );\n\n\t\t\t\t\tif ( this.morphTargetsRelative ) {\n\n\t\t\t\t\t\t_vector$8.addVectors( this.boundingBox.min, _box$1.min );\n\t\t\t\t\t\tthis.boundingBox.expandByPoint( _vector$8 );\n\n\t\t\t\t\t\t_vector$8.addVectors( this.boundingBox.max, _box$1.max );\n\t\t\t\t\t\tthis.boundingBox.expandByPoint( _vector$8 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthis.boundingBox.expandByPoint( _box$1.min );\n\t\t\t\t\t\tthis.boundingBox.expandByPoint( _box$1.max );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t}\n\n\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t}\n\n\t}\n\n\tcomputeBoundingSphere() {\n\n\t\tif ( this.boundingSphere === null ) {\n\n\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t}\n\n\t\tconst position = this.attributes.position;\n\t\tconst morphAttributesPosition = this.morphAttributes.position;\n\n\t\tif ( position && position.isGLBufferAttribute ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set \"mesh.frustumCulled\" to \"false\".', this );\n\n\t\t\tthis.boundingSphere.set( new Vector3(), Infinity );\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( position ) {\n\n\t\t\t// first, find the center of the bounding sphere\n\n\t\t\tconst center = this.boundingSphere.center;\n\n\t\t\t_box$1.setFromBufferAttribute( position );\n\n\t\t\t// process morph attributes if present\n\n\t\t\tif ( morphAttributesPosition ) {\n\n\t\t\t\tfor ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst morphAttribute = morphAttributesPosition[ i ];\n\t\t\t\t\t_boxMorphTargets.setFromBufferAttribute( morphAttribute );\n\n\t\t\t\t\tif ( this.morphTargetsRelative ) {\n\n\t\t\t\t\t\t_vector$8.addVectors( _box$1.min, _boxMorphTargets.min );\n\t\t\t\t\t\t_box$1.expandByPoint( _vector$8 );\n\n\t\t\t\t\t\t_vector$8.addVectors( _box$1.max, _boxMorphTargets.max );\n\t\t\t\t\t\t_box$1.expandByPoint( _vector$8 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_box$1.expandByPoint( _boxMorphTargets.min );\n\t\t\t\t\t\t_box$1.expandByPoint( _boxMorphTargets.max );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_box$1.getCenter( center );\n\n\t\t\t// second, try to find a boundingSphere with a radius smaller than the\n\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\tlet maxRadiusSq = 0;\n\n\t\t\tfor ( let i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t_vector$8.fromBufferAttribute( position, i );\n\n\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) );\n\n\t\t\t}\n\n\t\t\t// process morph attributes if present\n\n\t\t\tif ( morphAttributesPosition ) {\n\n\t\t\t\tfor ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst morphAttribute = morphAttributesPosition[ i ];\n\t\t\t\t\tconst morphTargetsRelative = this.morphTargetsRelative;\n\n\t\t\t\t\tfor ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) {\n\n\t\t\t\t\t\t_vector$8.fromBufferAttribute( morphAttribute, j );\n\n\t\t\t\t\t\tif ( morphTargetsRelative ) {\n\n\t\t\t\t\t\t\t_offset.fromBufferAttribute( position, j );\n\t\t\t\t\t\t\t_vector$8.add( _offset );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tcomputeTangents() {\n\n\t\tconst index = this.index;\n\t\tconst attributes = this.attributes;\n\n\t\t// based on http://www.terathon.com/code/tangent.html\n\t\t// (per vertex tangents)\n\n\t\tif ( index === null ||\n\t\t\t attributes.position === undefined ||\n\t\t\t attributes.normal === undefined ||\n\t\t\t attributes.uv === undefined ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst indices = index.array;\n\t\tconst positions = attributes.position.array;\n\t\tconst normals = attributes.normal.array;\n\t\tconst uvs = attributes.uv.array;\n\n\t\tconst nVertices = positions.length / 3;\n\n\t\tif ( this.hasAttribute( 'tangent' ) === false ) {\n\n\t\t\tthis.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );\n\n\t\t}\n\n\t\tconst tangents = this.getAttribute( 'tangent' ).array;\n\n\t\tconst tan1 = [], tan2 = [];\n\n\t\tfor ( let i = 0; i < nVertices; i ++ ) {\n\n\t\t\ttan1[ i ] = new Vector3();\n\t\t\ttan2[ i ] = new Vector3();\n\n\t\t}\n\n\t\tconst vA = new Vector3(),\n\t\t\tvB = new Vector3(),\n\t\t\tvC = new Vector3(),\n\n\t\t\tuvA = new Vector2(),\n\t\t\tuvB = new Vector2(),\n\t\t\tuvC = new Vector2(),\n\n\t\t\tsdir = new Vector3(),\n\t\t\ttdir = new Vector3();\n\n\t\tfunction handleTriangle( a, b, c ) {\n\n\t\t\tvA.fromArray( positions, a * 3 );\n\t\t\tvB.fromArray( positions, b * 3 );\n\t\t\tvC.fromArray( positions, c * 3 );\n\n\t\t\tuvA.fromArray( uvs, a * 2 );\n\t\t\tuvB.fromArray( uvs, b * 2 );\n\t\t\tuvC.fromArray( uvs, c * 2 );\n\n\t\t\tvB.sub( vA );\n\t\t\tvC.sub( vA );\n\n\t\t\tuvB.sub( uvA );\n\t\t\tuvC.sub( uvA );\n\n\t\t\tconst r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y );\n\n\t\t\t// silently ignore degenerate uv triangles having coincident or colinear vertices\n\n\t\t\tif ( ! isFinite( r ) ) return;\n\n\t\t\tsdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r );\n\t\t\ttdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r );\n\n\t\t\ttan1[ a ].add( sdir );\n\t\t\ttan1[ b ].add( sdir );\n\t\t\ttan1[ c ].add( sdir );\n\n\t\t\ttan2[ a ].add( tdir );\n\t\t\ttan2[ b ].add( tdir );\n\t\t\ttan2[ c ].add( tdir );\n\n\t\t}\n\n\t\tlet groups = this.groups;\n\n\t\tif ( groups.length === 0 ) {\n\n\t\t\tgroups = [ {\n\t\t\t\tstart: 0,\n\t\t\t\tcount: indices.length\n\t\t\t} ];\n\n\t\t}\n\n\t\tfor ( let i = 0, il = groups.length; i < il; ++ i ) {\n\n\t\t\tconst group = groups[ i ];\n\n\t\t\tconst start = group.start;\n\t\t\tconst count = group.count;\n\n\t\t\tfor ( let j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\thandleTriangle(\n\t\t\t\t\tindices[ j + 0 ],\n\t\t\t\t\tindices[ j + 1 ],\n\t\t\t\t\tindices[ j + 2 ]\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst tmp = new Vector3(), tmp2 = new Vector3();\n\t\tconst n = new Vector3(), n2 = new Vector3();\n\n\t\tfunction handleVertex( v ) {\n\n\t\t\tn.fromArray( normals, v * 3 );\n\t\t\tn2.copy( n );\n\n\t\t\tconst t = tan1[ v ];\n\n\t\t\t// Gram-Schmidt orthogonalize\n\n\t\t\ttmp.copy( t );\n\t\t\ttmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();\n\n\t\t\t// Calculate handedness\n\n\t\t\ttmp2.crossVectors( n2, t );\n\t\t\tconst test = tmp2.dot( tan2[ v ] );\n\t\t\tconst w = ( test < 0.0 ) ? - 1.0 : 1.0;\n\n\t\t\ttangents[ v * 4 ] = tmp.x;\n\t\t\ttangents[ v * 4 + 1 ] = tmp.y;\n\t\t\ttangents[ v * 4 + 2 ] = tmp.z;\n\t\t\ttangents[ v * 4 + 3 ] = w;\n\n\t\t}\n\n\t\tfor ( let i = 0, il = groups.length; i < il; ++ i ) {\n\n\t\t\tconst group = groups[ i ];\n\n\t\t\tconst start = group.start;\n\t\t\tconst count = group.count;\n\n\t\t\tfor ( let j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\thandleVertex( indices[ j + 0 ] );\n\t\t\t\thandleVertex( indices[ j + 1 ] );\n\t\t\t\thandleVertex( indices[ j + 2 ] );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tcomputeVertexNormals() {\n\n\t\tconst index = this.index;\n\t\tconst positionAttribute = this.getAttribute( 'position' );\n\n\t\tif ( positionAttribute !== undefined ) {\n\n\t\t\tlet normalAttribute = this.getAttribute( 'normal' );\n\n\t\t\tif ( normalAttribute === undefined ) {\n\n\t\t\t\tnormalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 );\n\t\t\t\tthis.setAttribute( 'normal', normalAttribute );\n\n\t\t\t} else {\n\n\t\t\t\t// reset existing normals to zero\n\n\t\t\t\tfor ( let i = 0, il = normalAttribute.count; i < il; i ++ ) {\n\n\t\t\t\t\tnormalAttribute.setXYZ( i, 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\tconst nA = new Vector3(), nB = new Vector3(), nC = new Vector3();\n\t\t\tconst cb = new Vector3(), ab = new Vector3();\n\n\t\t\t// indexed elements\n\n\t\t\tif ( index ) {\n\n\t\t\t\tfor ( let i = 0, il = index.count; i < il; i += 3 ) {\n\n\t\t\t\t\tconst vA = index.getX( i + 0 );\n\t\t\t\t\tconst vB = index.getX( i + 1 );\n\t\t\t\t\tconst vC = index.getX( i + 2 );\n\n\t\t\t\t\tpA.fromBufferAttribute( positionAttribute, vA );\n\t\t\t\t\tpB.fromBufferAttribute( positionAttribute, vB );\n\t\t\t\t\tpC.fromBufferAttribute( positionAttribute, vC );\n\n\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tnA.fromBufferAttribute( normalAttribute, vA );\n\t\t\t\t\tnB.fromBufferAttribute( normalAttribute, vB );\n\t\t\t\t\tnC.fromBufferAttribute( normalAttribute, vC );\n\n\t\t\t\t\tnA.add( cb );\n\t\t\t\t\tnB.add( cb );\n\t\t\t\t\tnC.add( cb );\n\n\t\t\t\t\tnormalAttribute.setXYZ( vA, nA.x, nA.y, nA.z );\n\t\t\t\t\tnormalAttribute.setXYZ( vB, nB.x, nB.y, nB.z );\n\t\t\t\t\tnormalAttribute.setXYZ( vC, nC.x, nC.y, nC.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\tfor ( let i = 0, il = positionAttribute.count; i < il; i += 3 ) {\n\n\t\t\t\t\tpA.fromBufferAttribute( positionAttribute, i + 0 );\n\t\t\t\t\tpB.fromBufferAttribute( positionAttribute, i + 1 );\n\t\t\t\t\tpC.fromBufferAttribute( positionAttribute, i + 2 );\n\n\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tnormalAttribute.setXYZ( i + 0, cb.x, cb.y, cb.z );\n\t\t\t\t\tnormalAttribute.setXYZ( i + 1, cb.x, cb.y, cb.z );\n\t\t\t\t\tnormalAttribute.setXYZ( i + 2, cb.x, cb.y, cb.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.normalizeNormals();\n\n\t\t\tnormalAttribute.needsUpdate = true;\n\n\t\t}\n\n\t}\n\n\tmerge( geometry, offset ) {\n\n\t\tif ( ! ( geometry && geometry.isBufferGeometry ) ) {\n\n\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( offset === undefined ) {\n\n\t\t\toffset = 0;\n\n\t\t\tconsole.warn(\n\t\t\t\t'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. '\n\t\t\t\t+ 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'\n\t\t\t);\n\n\t\t}\n\n\t\tconst attributes = this.attributes;\n\n\t\tfor ( const key in attributes ) {\n\n\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\tconst attribute1 = attributes[ key ];\n\t\t\tconst attributeArray1 = attribute1.array;\n\n\t\t\tconst attribute2 = geometry.attributes[ key ];\n\t\t\tconst attributeArray2 = attribute2.array;\n\n\t\t\tconst attributeOffset = attribute2.itemSize * offset;\n\t\t\tconst length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset );\n\n\t\t\tfor ( let i = 0, j = attributeOffset; i < length; i ++, j ++ ) {\n\n\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tnormalizeNormals() {\n\n\t\tconst normals = this.attributes.normal;\n\n\t\tfor ( let i = 0, il = normals.count; i < il; i ++ ) {\n\n\t\t\t_vector$8.fromBufferAttribute( normals, i );\n\n\t\t\t_vector$8.normalize();\n\n\t\t\tnormals.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );\n\n\t\t}\n\n\t}\n\n\ttoNonIndexed() {\n\n\t\tfunction convertBufferAttribute( attribute, indices ) {\n\n\t\t\tconst array = attribute.array;\n\t\t\tconst itemSize = attribute.itemSize;\n\t\t\tconst normalized = attribute.normalized;\n\n\t\t\tconst array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\tlet index = 0, index2 = 0;\n\n\t\t\tfor ( let i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\tindex = indices[ i ] * attribute.data.stride + attribute.offset;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn new BufferAttribute( array2, itemSize, normalized );\n\n\t\t}\n\n\t\t//\n\n\t\tif ( this.index === null ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.' );\n\t\t\treturn this;\n\n\t\t}\n\n\t\tconst geometry2 = new BufferGeometry();\n\n\t\tconst indices = this.index.array;\n\t\tconst attributes = this.attributes;\n\n\t\t// attributes\n\n\t\tfor ( const name in attributes ) {\n\n\t\t\tconst attribute = attributes[ name ];\n\n\t\t\tconst newAttribute = convertBufferAttribute( attribute, indices );\n\n\t\t\tgeometry2.setAttribute( name, newAttribute );\n\n\t\t}\n\n\t\t// morph attributes\n\n\t\tconst morphAttributes = this.morphAttributes;\n\n\t\tfor ( const name in morphAttributes ) {\n\n\t\t\tconst morphArray = [];\n\t\t\tconst morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\tfor ( let i = 0, il = morphAttribute.length; i < il; i ++ ) {\n\n\t\t\t\tconst attribute = morphAttribute[ i ];\n\n\t\t\t\tconst newAttribute = convertBufferAttribute( attribute, indices );\n\n\t\t\t\tmorphArray.push( newAttribute );\n\n\t\t\t}\n\n\t\t\tgeometry2.morphAttributes[ name ] = morphArray;\n\n\t\t}\n\n\t\tgeometry2.morphTargetsRelative = this.morphTargetsRelative;\n\n\t\t// groups\n\n\t\tconst groups = this.groups;\n\n\t\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tconst group = groups[ i ];\n\t\t\tgeometry2.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn geometry2;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = {\n\t\t\tmetadata: {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t}\n\t\t};\n\n\t\t// standard BufferGeometry serialization\n\n\t\tdata.uuid = this.uuid;\n\t\tdata.type = this.type;\n\t\tif ( this.name !== '' ) data.name = this.name;\n\t\tif ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData;\n\n\t\tif ( this.parameters !== undefined ) {\n\n\t\t\tconst parameters = this.parameters;\n\n\t\t\tfor ( const key in parameters ) {\n\n\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t\t// for simplicity the code assumes attributes are not shared across geometries, see #15811\n\n\t\tdata.data = { attributes: {} };\n\n\t\tconst index = this.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tdata.data.index = {\n\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\tarray: Array.prototype.slice.call( index.array )\n\t\t\t};\n\n\t\t}\n\n\t\tconst attributes = this.attributes;\n\n\t\tfor ( const key in attributes ) {\n\n\t\t\tconst attribute = attributes[ key ];\n\n\t\t\tdata.data.attributes[ key ] = attribute.toJSON( data.data );\n\n\t\t}\n\n\t\tconst morphAttributes = {};\n\t\tlet hasMorphAttributes = false;\n\n\t\tfor ( const key in this.morphAttributes ) {\n\n\t\t\tconst attributeArray = this.morphAttributes[ key ];\n\n\t\t\tconst array = [];\n\n\t\t\tfor ( let i = 0, il = attributeArray.length; i < il; i ++ ) {\n\n\t\t\t\tconst attribute = attributeArray[ i ];\n\n\t\t\t\tarray.push( attribute.toJSON( data.data ) );\n\n\t\t\t}\n\n\t\t\tif ( array.length > 0 ) {\n\n\t\t\t\tmorphAttributes[ key ] = array;\n\n\t\t\t\thasMorphAttributes = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( hasMorphAttributes ) {\n\n\t\t\tdata.data.morphAttributes = morphAttributes;\n\t\t\tdata.data.morphTargetsRelative = this.morphTargetsRelative;\n\n\t\t}\n\n\t\tconst groups = this.groups;\n\n\t\tif ( groups.length > 0 ) {\n\n\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t}\n\n\t\tconst boundingSphere = this.boundingSphere;\n\n\t\tif ( boundingSphere !== null ) {\n\n\t\t\tdata.data.boundingSphere = {\n\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\tradius: boundingSphere.radius\n\t\t\t};\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n\tclone() {\n\n\t\t return new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\t// reset\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\t\tthis.morphAttributes = {};\n\t\tthis.groups = [];\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// used for storing cloned, shared data\n\n\t\tconst data = {};\n\n\t\t// name\n\n\t\tthis.name = source.name;\n\n\t\t// index\n\n\t\tconst index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone( data ) );\n\n\t\t}\n\n\t\t// attributes\n\n\t\tconst attributes = source.attributes;\n\n\t\tfor ( const name in attributes ) {\n\n\t\t\tconst attribute = attributes[ name ];\n\t\t\tthis.setAttribute( name, attribute.clone( data ) );\n\n\t\t}\n\n\t\t// morph attributes\n\n\t\tconst morphAttributes = source.morphAttributes;\n\n\t\tfor ( const name in morphAttributes ) {\n\n\t\t\tconst array = [];\n\t\t\tconst morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\tfor ( let i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\tarray.push( morphAttribute[ i ].clone( data ) );\n\n\t\t\t}\n\n\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t}\n\n\t\tthis.morphTargetsRelative = source.morphTargetsRelative;\n\n\t\t// groups\n\n\t\tconst groups = source.groups;\n\n\t\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tconst group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\t// bounding box\n\n\t\tconst boundingBox = source.boundingBox;\n\n\t\tif ( boundingBox !== null ) {\n\n\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t}\n\n\t\t// bounding sphere\n\n\t\tconst boundingSphere = source.boundingSphere;\n\n\t\tif ( boundingSphere !== null ) {\n\n\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t}\n\n\t\t// draw range\n\n\t\tthis.drawRange.start = source.drawRange.start;\n\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t// user data\n\n\t\tthis.userData = source.userData;\n\n\t\t// geometry generator parameters\n\n\t\tif ( source.parameters !== undefined ) this.parameters = Object.assign( {}, source.parameters );\n\n\t\treturn this;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n}\n\nconst _inverseMatrix$2 = /*@__PURE__*/ new Matrix4();\nconst _ray$2 = /*@__PURE__*/ new Ray();\nconst _sphere$3 = /*@__PURE__*/ new Sphere();\n\nconst _vA$1 = /*@__PURE__*/ new Vector3();\nconst _vB$1 = /*@__PURE__*/ new Vector3();\nconst _vC$1 = /*@__PURE__*/ new Vector3();\n\nconst _tempA = /*@__PURE__*/ new Vector3();\nconst _tempB = /*@__PURE__*/ new Vector3();\nconst _tempC = /*@__PURE__*/ new Vector3();\n\nconst _morphA = /*@__PURE__*/ new Vector3();\nconst _morphB = /*@__PURE__*/ new Vector3();\nconst _morphC = /*@__PURE__*/ new Vector3();\n\nconst _uvA$1 = /*@__PURE__*/ new Vector2();\nconst _uvB$1 = /*@__PURE__*/ new Vector2();\nconst _uvC$1 = /*@__PURE__*/ new Vector2();\n\nconst _intersectionPoint = /*@__PURE__*/ new Vector3();\nconst _intersectionPointWorld = /*@__PURE__*/ new Vector3();\n\nclass Mesh extends Object3D {\n\n\tconstructor( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) {\n\n\t\tsuper();\n\n\t\tthis.isMesh = true;\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry;\n\t\tthis.material = material;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tif ( source.morphTargetInfluences !== undefined ) {\n\n\t\t\tthis.morphTargetInfluences = source.morphTargetInfluences.slice();\n\n\t\t}\n\n\t\tif ( source.morphTargetDictionary !== undefined ) {\n\n\t\t\tthis.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary );\n\n\t\t}\n\n\t\tthis.material = source.material;\n\t\tthis.geometry = source.geometry;\n\n\t\treturn this;\n\n\t}\n\n\tupdateMorphTargets() {\n\n\t\tconst geometry = this.geometry;\n\n\t\tconst morphAttributes = geometry.morphAttributes;\n\t\tconst keys = Object.keys( morphAttributes );\n\n\t\tif ( keys.length > 0 ) {\n\n\t\t\tconst morphAttribute = morphAttributes[ keys[ 0 ] ];\n\n\t\t\tif ( morphAttribute !== undefined ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {\n\n\t\t\t\t\tconst name = morphAttribute[ m ].name || String( m );\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\traycast( raycaster, intersects ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst material = this.material;\n\t\tconst matrixWorld = this.matrixWorld;\n\n\t\tif ( material === undefined ) return;\n\n\t\t// Checking boundingSphere distance to ray\n\n\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t_sphere$3.copy( geometry.boundingSphere );\n\t\t_sphere$3.applyMatrix4( matrixWorld );\n\n\t\tif ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;\n\n\t\t//\n\n\t\t_inverseMatrix$2.copy( matrixWorld ).invert();\n\t\t_ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );\n\n\t\t// Check boundingBox before continuing\n\n\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\tif ( _ray$2.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t}\n\n\t\tlet intersection;\n\n\t\tconst index = geometry.index;\n\t\tconst position = geometry.attributes.position;\n\t\tconst morphPosition = geometry.morphAttributes.position;\n\t\tconst morphTargetsRelative = geometry.morphTargetsRelative;\n\t\tconst uv = geometry.attributes.uv;\n\t\tconst uv2 = geometry.attributes.uv2;\n\t\tconst groups = geometry.groups;\n\t\tconst drawRange = geometry.drawRange;\n\n\t\tif ( index !== null ) {\n\n\t\t\t// indexed buffer geometry\n\n\t\t\tif ( Array.isArray( material ) ) {\n\n\t\t\t\tfor ( let i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst group = groups[ i ];\n\t\t\t\t\tconst groupMaterial = material[ group.materialIndex ];\n\n\t\t\t\t\tconst start = Math.max( group.start, drawRange.start );\n\t\t\t\t\tconst end = Math.min( index.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) );\n\n\t\t\t\t\tfor ( let j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\t\tconst a = index.getX( j );\n\t\t\t\t\t\tconst b = index.getX( j + 1 );\n\t\t\t\t\t\tconst c = index.getX( j + 2 );\n\n\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics\n\t\t\t\t\t\t\tintersection.face.materialIndex = group.materialIndex;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconst start = Math.max( 0, drawRange.start );\n\t\t\t\tconst end = Math.min( index.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\t\tfor ( let i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\t\tconst a = index.getX( i );\n\t\t\t\t\tconst b = index.getX( i + 1 );\n\t\t\t\t\tconst c = index.getX( i + 2 );\n\n\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );\n\n\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics\n\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else if ( position !== undefined ) {\n\n\t\t\t// non-indexed buffer geometry\n\n\t\t\tif ( Array.isArray( material ) ) {\n\n\t\t\t\tfor ( let i = 0, il = groups.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst group = groups[ i ];\n\t\t\t\t\tconst groupMaterial = material[ group.materialIndex ];\n\n\t\t\t\t\tconst start = Math.max( group.start, drawRange.start );\n\t\t\t\t\tconst end = Math.min( position.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) );\n\n\t\t\t\t\tfor ( let j = start, jl = end; j < jl; j += 3 ) {\n\n\t\t\t\t\t\tconst a = j;\n\t\t\t\t\t\tconst b = j + 1;\n\t\t\t\t\t\tconst c = j + 2;\n\n\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics\n\t\t\t\t\t\t\tintersection.face.materialIndex = group.materialIndex;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconst start = Math.max( 0, drawRange.start );\n\t\t\t\tconst end = Math.min( position.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\t\tfor ( let i = start, il = end; i < il; i += 3 ) {\n\n\t\t\t\t\tconst a = i;\n\t\t\t\t\tconst b = i + 1;\n\t\t\t\t\tconst c = i + 2;\n\n\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );\n\n\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics\n\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n}\n\nfunction checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) {\n\n\tlet intersect;\n\n\tif ( material.side === BackSide ) {\n\n\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t} else {\n\n\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t}\n\n\tif ( intersect === null ) return null;\n\n\t_intersectionPointWorld.copy( point );\n\t_intersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\tconst distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );\n\n\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\treturn {\n\t\tdistance: distance,\n\t\tpoint: _intersectionPointWorld.clone(),\n\t\tobject: object\n\t};\n\n}\n\nfunction checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) {\n\n\t_vA$1.fromBufferAttribute( position, a );\n\t_vB$1.fromBufferAttribute( position, b );\n\t_vC$1.fromBufferAttribute( position, c );\n\n\tconst morphInfluences = object.morphTargetInfluences;\n\n\tif ( morphPosition && morphInfluences ) {\n\n\t\t_morphA.set( 0, 0, 0 );\n\t\t_morphB.set( 0, 0, 0 );\n\t\t_morphC.set( 0, 0, 0 );\n\n\t\tfor ( let i = 0, il = morphPosition.length; i < il; i ++ ) {\n\n\t\t\tconst influence = morphInfluences[ i ];\n\t\t\tconst morphAttribute = morphPosition[ i ];\n\n\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t_tempA.fromBufferAttribute( morphAttribute, a );\n\t\t\t_tempB.fromBufferAttribute( morphAttribute, b );\n\t\t\t_tempC.fromBufferAttribute( morphAttribute, c );\n\n\t\t\tif ( morphTargetsRelative ) {\n\n\t\t\t\t_morphA.addScaledVector( _tempA, influence );\n\t\t\t\t_morphB.addScaledVector( _tempB, influence );\n\t\t\t\t_morphC.addScaledVector( _tempC, influence );\n\n\t\t\t} else {\n\n\t\t\t\t_morphA.addScaledVector( _tempA.sub( _vA$1 ), influence );\n\t\t\t\t_morphB.addScaledVector( _tempB.sub( _vB$1 ), influence );\n\t\t\t\t_morphC.addScaledVector( _tempC.sub( _vC$1 ), influence );\n\n\t\t\t}\n\n\t\t}\n\n\t\t_vA$1.add( _morphA );\n\t\t_vB$1.add( _morphB );\n\t\t_vC$1.add( _morphC );\n\n\t}\n\n\tif ( object.isSkinnedMesh ) {\n\n\t\tobject.boneTransform( a, _vA$1 );\n\t\tobject.boneTransform( b, _vB$1 );\n\t\tobject.boneTransform( c, _vC$1 );\n\n\t}\n\n\tconst intersection = checkIntersection( object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint );\n\n\tif ( intersection ) {\n\n\t\tif ( uv ) {\n\n\t\t\t_uvA$1.fromBufferAttribute( uv, a );\n\t\t\t_uvB$1.fromBufferAttribute( uv, b );\n\t\t\t_uvC$1.fromBufferAttribute( uv, c );\n\n\t\t\tintersection.uv = Triangle.getUV( _intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() );\n\n\t\t}\n\n\t\tif ( uv2 ) {\n\n\t\t\t_uvA$1.fromBufferAttribute( uv2, a );\n\t\t\t_uvB$1.fromBufferAttribute( uv2, b );\n\t\t\t_uvC$1.fromBufferAttribute( uv2, c );\n\n\t\t\tintersection.uv2 = Triangle.getUV( _intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() );\n\n\t\t}\n\n\t\tconst face = {\n\t\t\ta: a,\n\t\t\tb: b,\n\t\t\tc: c,\n\t\t\tnormal: new Vector3(),\n\t\t\tmaterialIndex: 0\n\t\t};\n\n\t\tTriangle.getNormal( _vA$1, _vB$1, _vC$1, face.normal );\n\n\t\tintersection.face = face;\n\n\t}\n\n\treturn intersection;\n\n}\n\nclass BoxGeometry extends BufferGeometry {\n\n\tconstructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tconst scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments );\n\t\theightSegments = Math.floor( heightSegments );\n\t\tdepthSegments = Math.floor( depthSegments );\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// helper variables\n\n\t\tlet numberOfVertices = 0;\n\t\tlet groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tconst segmentWidth = width / gridX;\n\t\t\tconst segmentHeight = height / gridY;\n\n\t\t\tconst widthHalf = width / 2;\n\t\t\tconst heightHalf = height / 2;\n\t\t\tconst depthHalf = depth / 2;\n\n\t\t\tconst gridX1 = gridX + 1;\n\t\t\tconst gridY1 = gridY + 1;\n\n\t\t\tlet vertexCounter = 0;\n\t\t\tlet groupCount = 0;\n\n\t\t\tconst vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( let iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tconst y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( let ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tconst x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( let iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( let ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tconst a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tconst b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tconst c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tconst d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments );\n\n\t}\n\n}\n\n/**\n * Uniform Utilities\n */\n\nfunction cloneUniforms( src ) {\n\n\tconst dst = {};\n\n\tfor ( const u in src ) {\n\n\t\tdst[ u ] = {};\n\n\t\tfor ( const p in src[ u ] ) {\n\n\t\t\tconst property = src[ u ][ p ];\n\n\t\t\tif ( property && ( property.isColor ||\n\t\t\t\tproperty.isMatrix3 || property.isMatrix4 ||\n\t\t\t\tproperty.isVector2 || property.isVector3 || property.isVector4 ||\n\t\t\t\tproperty.isTexture || property.isQuaternion ) ) {\n\n\t\t\t\tdst[ u ][ p ] = property.clone();\n\n\t\t\t} else if ( Array.isArray( property ) ) {\n\n\t\t\t\tdst[ u ][ p ] = property.slice();\n\n\t\t\t} else {\n\n\t\t\t\tdst[ u ][ p ] = property;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn dst;\n\n}\n\nfunction mergeUniforms( uniforms ) {\n\n\tconst merged = {};\n\n\tfor ( let u = 0; u < uniforms.length; u ++ ) {\n\n\t\tconst tmp = cloneUniforms( uniforms[ u ] );\n\n\t\tfor ( const p in tmp ) {\n\n\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t}\n\n\t}\n\n\treturn merged;\n\n}\n\n// Legacy\n\nconst UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms };\n\nvar default_vertex = \"void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}\";\n\nvar default_fragment = \"void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}\";\n\nclass ShaderMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isShaderMaterial = true;\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = default_vertex;\n\t\tthis.fragmentShader = default_fragment;\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\t\tthis.uniformsNeedUpdate = false;\n\n\t\tthis.glslVersion = null;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = cloneUniforms( source.uniforms );\n\n\t\tthis.defines = Object.assign( {}, source.defines );\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.fog = source.fog;\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.extensions = Object.assign( {}, source.extensions );\n\n\t\tthis.glslVersion = source.glslVersion;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tdata.glslVersion = this.glslVersion;\n\t\tdata.uniforms = {};\n\n\t\tfor ( const name in this.uniforms ) {\n\n\t\t\tconst uniform = this.uniforms[ name ];\n\t\t\tconst value = uniform.value;\n\n\t\t\tif ( value && value.isTexture ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 't',\n\t\t\t\t\tvalue: value.toJSON( meta ).uuid\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isColor ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'c',\n\t\t\t\t\tvalue: value.getHex()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isVector2 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'v2',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isVector3 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'v3',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isVector4 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'v4',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isMatrix3 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'm3',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else if ( value && value.isMatrix4 ) {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\ttype: 'm4',\n\t\t\t\t\tvalue: value.toArray()\n\t\t\t\t};\n\n\t\t\t} else {\n\n\t\t\t\tdata.uniforms[ name ] = {\n\t\t\t\t\tvalue: value\n\t\t\t\t};\n\n\t\t\t\t// note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines;\n\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\tconst extensions = {};\n\n\t\tfor ( const key in this.extensions ) {\n\n\t\t\tif ( this.extensions[ key ] === true ) extensions[ key ] = true;\n\n\t\t}\n\n\t\tif ( Object.keys( extensions ).length > 0 ) data.extensions = extensions;\n\n\t\treturn data;\n\n\t}\n\n}\n\nclass Camera extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isCamera = true;\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\n\t\tthis.projectionMatrix = new Matrix4();\n\t\tthis.projectionMatrixInverse = new Matrix4();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\t\tthis.projectionMatrixInverse.copy( source.projectionMatrixInverse );\n\n\t\treturn this;\n\n\t}\n\n\tgetWorldDirection( target ) {\n\n\t\tthis.updateWorldMatrix( true, false );\n\n\t\tconst e = this.matrixWorld.elements;\n\n\t\treturn target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize();\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t\tthis.matrixWorldInverse.copy( this.matrixWorld ).invert();\n\n\t}\n\n\tupdateWorldMatrix( updateParents, updateChildren ) {\n\n\t\tsuper.updateWorldMatrix( updateParents, updateChildren );\n\n\t\tthis.matrixWorldInverse.copy( this.matrixWorld ).invert();\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nclass PerspectiveCamera extends Camera {\n\n\tconstructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) {\n\n\t\tsuper();\n\n\t\tthis.isPerspectiveCamera = true;\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near;\n\t\tthis.far = far;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.fov = source.fov;\n\t\tthis.zoom = source.zoom;\n\n\t\tthis.near = source.near;\n\t\tthis.far = source.far;\n\t\tthis.focus = source.focus;\n\n\t\tthis.aspect = source.aspect;\n\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\tthis.filmGauge = source.filmGauge;\n\t\tthis.filmOffset = source.filmOffset;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t *\n\t * The default film gauge is 35, so that the focal length can be specified for\n\t * a 35mm (full frame) camera.\n\t *\n\t * Values for focal length and film gauge must have the same unit.\n\t */\n\tsetFocalLength( focalLength ) {\n\n\t\t/** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */\n\t\tconst vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\tthis.fov = RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\t/**\n\t * Calculates the focal length from the current .fov and .filmGauge.\n\t */\n\tgetFocalLength() {\n\n\t\tconst vExtentSlope = Math.tan( DEG2RAD * 0.5 * this.fov );\n\n\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t}\n\n\tgetEffectiveFOV() {\n\n\t\treturn RAD2DEG * 2 * Math.atan(\n\t\t\tMath.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t}\n\n\tgetFilmWidth() {\n\n\t\t// film not completely covered in portrait format (aspect < 1)\n\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t}\n\n\tgetFilmHeight() {\n\n\t\t// film not completely covered in landscape format (aspect > 1)\n\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t}\n\n\t/**\n\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t * multi-monitor/multi-machine setups.\n\t *\n\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t * the monitors are in grid like this\n\t *\n\t * +---+---+---+\n\t * | A | B | C |\n\t * +---+---+---+\n\t * | D | E | F |\n\t * +---+---+---+\n\t *\n\t * then for each monitor you would call it like this\n\t *\n\t * const w = 1920;\n\t * const h = 1080;\n\t * const fullWidth = w * 3;\n\t * const fullHeight = h * 2;\n\t *\n\t * --A--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t * --B--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t * --C--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t * --D--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t * --E--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t * --F--\n\t * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t *\n\t * Note there is no reason monitors have to be the same size or in a grid.\n\t */\n\tsetViewOffset( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\tif ( this.view === null ) {\n\n\t\t\tthis.view = {\n\t\t\t\tenabled: true,\n\t\t\t\tfullWidth: 1,\n\t\t\t\tfullHeight: 1,\n\t\t\t\toffsetX: 0,\n\t\t\t\toffsetY: 0,\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1\n\t\t\t};\n\n\t\t}\n\n\t\tthis.view.enabled = true;\n\t\tthis.view.fullWidth = fullWidth;\n\t\tthis.view.fullHeight = fullHeight;\n\t\tthis.view.offsetX = x;\n\t\tthis.view.offsetY = y;\n\t\tthis.view.width = width;\n\t\tthis.view.height = height;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tclearViewOffset() {\n\n\t\tif ( this.view !== null ) {\n\n\t\t\tthis.view.enabled = false;\n\n\t\t}\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tupdateProjectionMatrix() {\n\n\t\tconst near = this.near;\n\t\tlet top = near * Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom;\n\t\tlet height = 2 * top;\n\t\tlet width = this.aspect * height;\n\t\tlet left = - 0.5 * width;\n\t\tconst view = this.view;\n\n\t\tif ( this.view !== null && this.view.enabled ) {\n\n\t\t\tconst fullWidth = view.fullWidth,\n\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\twidth *= view.width / fullWidth;\n\t\t\theight *= view.height / fullHeight;\n\n\t\t}\n\n\t\tconst skew = this.filmOffset;\n\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\tthis.projectionMatrixInverse.copy( this.projectionMatrix ).invert();\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tdata.object.fov = this.fov;\n\t\tdata.object.zoom = this.zoom;\n\n\t\tdata.object.near = this.near;\n\t\tdata.object.far = this.far;\n\t\tdata.object.focus = this.focus;\n\n\t\tdata.object.aspect = this.aspect;\n\n\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\tdata.object.filmGauge = this.filmGauge;\n\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\treturn data;\n\n\t}\n\n}\n\nconst fov = 90, aspect = 1;\n\nclass CubeCamera extends Object3D {\n\n\tconstructor( near, far, renderTarget ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tif ( renderTarget.isWebGLCubeRenderTarget !== true ) {\n\n\t\t\tconsole.error( 'THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tthis.renderTarget = renderTarget;\n\n\t\tconst cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.layers = this.layers;\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tconst cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.layers = this.layers;\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tconst cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.layers = this.layers;\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tconst cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.layers = this.layers;\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tconst cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.layers = this.layers;\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tconst cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.layers = this.layers;\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t}\n\n\tupdate( renderer, scene ) {\n\n\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\tconst renderTarget = this.renderTarget;\n\n\t\tconst [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children;\n\n\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\tconst currentToneMapping = renderer.toneMapping;\n\t\tconst currentXrEnabled = renderer.xr.enabled;\n\n\t\trenderer.toneMapping = NoToneMapping;\n\t\trenderer.xr.enabled = false;\n\n\t\tconst generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\trenderer.setRenderTarget( renderTarget, 0 );\n\t\trenderer.render( scene, cameraPX );\n\n\t\trenderer.setRenderTarget( renderTarget, 1 );\n\t\trenderer.render( scene, cameraNX );\n\n\t\trenderer.setRenderTarget( renderTarget, 2 );\n\t\trenderer.render( scene, cameraPY );\n\n\t\trenderer.setRenderTarget( renderTarget, 3 );\n\t\trenderer.render( scene, cameraNY );\n\n\t\trenderer.setRenderTarget( renderTarget, 4 );\n\t\trenderer.render( scene, cameraPZ );\n\n\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\trenderer.setRenderTarget( renderTarget, 5 );\n\t\trenderer.render( scene, cameraNZ );\n\n\t\trenderer.setRenderTarget( currentRenderTarget );\n\n\t\trenderer.toneMapping = currentToneMapping;\n\t\trenderer.xr.enabled = currentXrEnabled;\n\n\t\trenderTarget.texture.needsPMREMUpdate = true;\n\n\t}\n\n}\n\nclass CubeTexture extends Texture {\n\n\tconstructor( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tsuper( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.isCubeTexture = true;\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tget images() {\n\n\t\treturn this.image;\n\n\t}\n\n\tset images( value ) {\n\n\t\tthis.image = value;\n\n\t}\n\n}\n\nclass WebGLCubeRenderTarget extends WebGLRenderTarget {\n\n\tconstructor( size, options = {} ) {\n\n\t\tsuper( size, size, options );\n\n\t\tthis.isWebGLCubeRenderTarget = true;\n\n\t\tconst image = { width: size, height: size, depth: 1 };\n\t\tconst images = [ image, image, image, image, image, image ];\n\n\t\tthis.texture = new CubeTexture( images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\t// By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js)\n\t\t// in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words,\n\t\t// in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly.\n\n\t\t// three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped\n\t\t// and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture\n\t\t// as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures).\n\n\t\tthis.texture.isRenderTargetTexture = true;\n\n\t\tthis.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;\n\t\tthis.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;\n\n\t}\n\n\tfromEquirectangularTexture( renderer, texture ) {\n\n\t\tthis.texture.type = texture.type;\n\t\tthis.texture.encoding = texture.encoding;\n\n\t\tthis.texture.generateMipmaps = texture.generateMipmaps;\n\t\tthis.texture.minFilter = texture.minFilter;\n\t\tthis.texture.magFilter = texture.magFilter;\n\n\t\tconst shader = {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t},\n\n\t\t\tvertexShader: /* glsl */`\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\tfragmentShader: /* glsl */`\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include \n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t`\n\t\t};\n\n\t\tconst geometry = new BoxGeometry( 5, 5, 5 );\n\n\t\tconst material = new ShaderMaterial( {\n\n\t\t\tname: 'CubemapFromEquirect',\n\n\t\t\tuniforms: cloneUniforms( shader.uniforms ),\n\t\t\tvertexShader: shader.vertexShader,\n\t\t\tfragmentShader: shader.fragmentShader,\n\t\t\tside: BackSide,\n\t\t\tblending: NoBlending\n\n\t\t} );\n\n\t\tmaterial.uniforms.tEquirect.value = texture;\n\n\t\tconst mesh = new Mesh( geometry, material );\n\n\t\tconst currentMinFilter = texture.minFilter;\n\n\t\t// Avoid blurred poles\n\t\tif ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter;\n\n\t\tconst camera = new CubeCamera( 1, 10, this );\n\t\tcamera.update( renderer, mesh );\n\n\t\ttexture.minFilter = currentMinFilter;\n\n\t\tmesh.geometry.dispose();\n\t\tmesh.material.dispose();\n\n\t\treturn this;\n\n\t}\n\n\tclear( renderer, color, depth, stencil ) {\n\n\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\trenderer.setRenderTarget( this, i );\n\n\t\t\trenderer.clear( color, depth, stencil );\n\n\t\t}\n\n\t\trenderer.setRenderTarget( currentRenderTarget );\n\n\t}\n\n}\n\nconst _vector1 = /*@__PURE__*/ new Vector3();\nconst _vector2 = /*@__PURE__*/ new Vector3();\nconst _normalMatrix = /*@__PURE__*/ new Matrix3();\n\nclass Plane {\n\n\tconstructor( normal = new Vector3( 1, 0, 0 ), constant = 0 ) {\n\n\t\tthis.isPlane = true;\n\n\t\t// normal is assumed to be normalized\n\n\t\tthis.normal = normal;\n\t\tthis.constant = constant;\n\n\t}\n\n\tset( normal, constant ) {\n\n\t\tthis.normal.copy( normal );\n\t\tthis.constant = constant;\n\n\t\treturn this;\n\n\t}\n\n\tsetComponents( x, y, z, w ) {\n\n\t\tthis.normal.set( x, y, z );\n\t\tthis.constant = w;\n\n\t\treturn this;\n\n\t}\n\n\tsetFromNormalAndCoplanarPoint( normal, point ) {\n\n\t\tthis.normal.copy( normal );\n\t\tthis.constant = - point.dot( this.normal );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromCoplanarPoints( a, b, c ) {\n\n\t\tconst normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize();\n\n\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( plane ) {\n\n\t\tthis.normal.copy( plane.normal );\n\t\tthis.constant = plane.constant;\n\n\t\treturn this;\n\n\t}\n\n\tnormalize() {\n\n\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\tconst inverseNormalLength = 1.0 / this.normal.length();\n\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\tthis.constant *= inverseNormalLength;\n\n\t\treturn this;\n\n\t}\n\n\tnegate() {\n\n\t\tthis.constant *= - 1;\n\t\tthis.normal.negate();\n\n\t\treturn this;\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\treturn this.normal.dot( point ) + this.constant;\n\n\t}\n\n\tdistanceToSphere( sphere ) {\n\n\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t}\n\n\tprojectPoint( point, target ) {\n\n\t\treturn target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point );\n\n\t}\n\n\tintersectLine( line, target ) {\n\n\t\tconst direction = line.delta( _vector1 );\n\n\t\tconst denominator = this.normal.dot( direction );\n\n\t\tif ( denominator === 0 ) {\n\n\t\t\t// line is coplanar, return origin\n\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\treturn target.copy( line.start );\n\n\t\t\t}\n\n\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\treturn target.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t}\n\n\tintersectsLine( line ) {\n\n\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\tconst startSign = this.distanceToPoint( line.start );\n\t\tconst endSign = this.distanceToPoint( line.end );\n\n\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\treturn box.intersectsPlane( this );\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\treturn sphere.intersectsPlane( this );\n\n\t}\n\n\tcoplanarPoint( target ) {\n\n\t\treturn target.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t}\n\n\tapplyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\tconst normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix );\n\n\t\tconst referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix );\n\n\t\tconst normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( offset ) {\n\n\t\tthis.constant -= offset.dot( this.normal );\n\n\t\treturn this;\n\n\t}\n\n\tequals( plane ) {\n\n\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nconst _sphere$2 = /*@__PURE__*/ new Sphere();\nconst _vector$7 = /*@__PURE__*/ new Vector3();\n\nclass Frustum {\n\n\tconstructor( p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane() ) {\n\n\t\tthis.planes = [ p0, p1, p2, p3, p4, p5 ];\n\n\t}\n\n\tset( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tconst planes = this.planes;\n\n\t\tplanes[ 0 ].copy( p0 );\n\t\tplanes[ 1 ].copy( p1 );\n\t\tplanes[ 2 ].copy( p2 );\n\t\tplanes[ 3 ].copy( p3 );\n\t\tplanes[ 4 ].copy( p4 );\n\t\tplanes[ 5 ].copy( p5 );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( frustum ) {\n\n\t\tconst planes = this.planes;\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetFromProjectionMatrix( m ) {\n\n\t\tconst planes = this.planes;\n\t\tconst me = m.elements;\n\t\tconst me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\tconst me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\tconst me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\tconst me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\treturn this;\n\n\t}\n\n\tintersectsObject( object ) {\n\n\t\tconst geometry = object.geometry;\n\n\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t_sphere$2.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );\n\n\t\treturn this.intersectsSphere( _sphere$2 );\n\n\t}\n\n\tintersectsSprite( sprite ) {\n\n\t\t_sphere$2.center.set( 0, 0, 0 );\n\t\t_sphere$2.radius = 0.7071067811865476;\n\t\t_sphere$2.applyMatrix4( sprite.matrixWorld );\n\n\t\treturn this.intersectsSphere( _sphere$2 );\n\n\t}\n\n\tintersectsSphere( sphere ) {\n\n\t\tconst planes = this.planes;\n\t\tconst center = sphere.center;\n\t\tconst negRadius = - sphere.radius;\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tconst distance = planes[ i ].distanceToPoint( center );\n\n\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\tconst planes = this.planes;\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tconst plane = planes[ i ];\n\n\t\t\t// corner at max distance\n\n\t\t\t_vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t_vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t_vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\tif ( plane.distanceToPoint( _vector$7 ) < 0 ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\tconst planes = this.planes;\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nfunction WebGLAnimation() {\n\n\tlet context = null;\n\tlet isAnimating = false;\n\tlet animationLoop = null;\n\tlet requestId = null;\n\n\tfunction onAnimationFrame( time, frame ) {\n\n\t\tanimationLoop( time, frame );\n\n\t\trequestId = context.requestAnimationFrame( onAnimationFrame );\n\n\t}\n\n\treturn {\n\n\t\tstart: function () {\n\n\t\t\tif ( isAnimating === true ) return;\n\t\t\tif ( animationLoop === null ) return;\n\n\t\t\trequestId = context.requestAnimationFrame( onAnimationFrame );\n\n\t\t\tisAnimating = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tcontext.cancelAnimationFrame( requestId );\n\n\t\t\tisAnimating = false;\n\n\t\t},\n\n\t\tsetAnimationLoop: function ( callback ) {\n\n\t\t\tanimationLoop = callback;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n}\n\nfunction WebGLAttributes( gl, capabilities ) {\n\n\tconst isWebGL2 = capabilities.isWebGL2;\n\n\tconst buffers = new WeakMap();\n\n\tfunction createBuffer( attribute, bufferType ) {\n\n\t\tconst array = attribute.array;\n\t\tconst usage = attribute.usage;\n\n\t\tconst buffer = gl.createBuffer();\n\n\t\tgl.bindBuffer( bufferType, buffer );\n\t\tgl.bufferData( bufferType, array, usage );\n\n\t\tattribute.onUploadCallback();\n\n\t\tlet type;\n\n\t\tif ( array instanceof Float32Array ) {\n\n\t\t\ttype = 5126;\n\n\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\tif ( attribute.isFloat16BufferAttribute ) {\n\n\t\t\t\tif ( isWebGL2 ) {\n\n\t\t\t\t\ttype = 5131;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( 'THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.' );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\ttype = 5123;\n\n\t\t\t}\n\n\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\ttype = 5122;\n\n\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\ttype = 5125;\n\n\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\ttype = 5124;\n\n\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\ttype = 5120;\n\n\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\ttype = 5121;\n\n\t\t} else if ( array instanceof Uint8ClampedArray ) {\n\n\t\t\ttype = 5121;\n\n\t\t} else {\n\n\t\t\tthrow new Error( 'THREE.WebGLAttributes: Unsupported buffer data format: ' + array );\n\n\t\t}\n\n\t\treturn {\n\t\t\tbuffer: buffer,\n\t\t\ttype: type,\n\t\t\tbytesPerElement: array.BYTES_PER_ELEMENT,\n\t\t\tversion: attribute.version\n\t\t};\n\n\t}\n\n\tfunction updateBuffer( buffer, attribute, bufferType ) {\n\n\t\tconst array = attribute.array;\n\t\tconst updateRange = attribute.updateRange;\n\n\t\tgl.bindBuffer( bufferType, buffer );\n\n\t\tif ( updateRange.count === - 1 ) {\n\n\t\t\t// Not using update ranges\n\n\t\t\tgl.bufferSubData( bufferType, 0, array );\n\n\t\t} else {\n\n\t\t\tif ( isWebGL2 ) {\n\n\t\t\t\tgl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,\n\t\t\t\t\tarray, updateRange.offset, updateRange.count );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,\n\t\t\t\t\tarray.subarray( updateRange.offset, updateRange.offset + updateRange.count ) );\n\n\t\t\t}\n\n\t\t\tupdateRange.count = - 1; // reset range\n\n\t\t}\n\n\t}\n\n\t//\n\n\tfunction get( attribute ) {\n\n\t\tif ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;\n\n\t\treturn buffers.get( attribute );\n\n\t}\n\n\tfunction remove( attribute ) {\n\n\t\tif ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;\n\n\t\tconst data = buffers.get( attribute );\n\n\t\tif ( data ) {\n\n\t\t\tgl.deleteBuffer( data.buffer );\n\n\t\t\tbuffers.delete( attribute );\n\n\t\t}\n\n\t}\n\n\tfunction update( attribute, bufferType ) {\n\n\t\tif ( attribute.isGLBufferAttribute ) {\n\n\t\t\tconst cached = buffers.get( attribute );\n\n\t\t\tif ( ! cached || cached.version < attribute.version ) {\n\n\t\t\t\tbuffers.set( attribute, {\n\t\t\t\t\tbuffer: attribute.buffer,\n\t\t\t\t\ttype: attribute.type,\n\t\t\t\t\tbytesPerElement: attribute.elementSize,\n\t\t\t\t\tversion: attribute.version\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;\n\n\t\tconst data = buffers.get( attribute );\n\n\t\tif ( data === undefined ) {\n\n\t\t\tbuffers.set( attribute, createBuffer( attribute, bufferType ) );\n\n\t\t} else if ( data.version < attribute.version ) {\n\n\t\t\tupdateBuffer( data.buffer, attribute, bufferType );\n\n\t\t\tdata.version = attribute.version;\n\n\t\t}\n\n\t}\n\n\treturn {\n\n\t\tget: get,\n\t\tremove: remove,\n\t\tupdate: update\n\n\t};\n\n}\n\nclass PlaneGeometry extends BufferGeometry {\n\n\tconstructor( width = 1, height = 1, widthSegments = 1, heightSegments = 1 ) {\n\n\t\tsuper();\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tconst width_half = width / 2;\n\t\tconst height_half = height / 2;\n\n\t\tconst gridX = Math.floor( widthSegments );\n\t\tconst gridY = Math.floor( heightSegments );\n\n\t\tconst gridX1 = gridX + 1;\n\t\tconst gridY1 = gridY + 1;\n\n\t\tconst segment_width = width / gridX;\n\t\tconst segment_height = height / gridY;\n\n\t\t//\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\tfor ( let iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tconst y = iy * segment_height - height_half;\n\n\t\t\tfor ( let ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tconst x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( let ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tconst a = ix + gridX1 * iy;\n\t\t\t\tconst b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tconst c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tconst d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new PlaneGeometry( data.width, data.height, data.widthSegments, data.heightSegments );\n\n\t}\n\n}\n\nvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\";\n\nvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\";\n\nvar alphatest_fragment = \"#ifdef USE_ALPHATEST\\n\\tif ( diffuseColor.a < alphaTest ) discard;\\n#endif\";\n\nvar alphatest_pars_fragment = \"#ifdef USE_ALPHATEST\\n\\tuniform float alphaTest;\\n#endif\";\n\nvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( STANDARD )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\\n\\t#endif\\n#endif\";\n\nvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\nvar begin_vertex = \"vec3 transformed = vec3( position );\";\n\nvar beginnormal_vertex = \"vec3 objectNormal = vec3( normal );\\n#ifdef USE_TANGENT\\n\\tvec3 objectTangent = vec3( tangent.xyz );\\n#endif\";\n\nvar bsdfs = \"vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\\n\\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\\n\\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\\n}\\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\\n\\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\\n\\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\\n}\\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\\n float x2 = x * x;\\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\\n}\\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( lightDir + viewDir );\\n\\tfloat dotNL = saturate( dot( normal, lightDir ) );\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tfloat dotNH = saturate( dot( normal, halfDir ) );\\n\\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\\n\\tvec3 F = F_Schlick( f0, f90, dotVH );\\n\\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( V * D );\\n}\\n#ifdef USE_IRIDESCENCE\\nvec3 BRDF_GGX_Iridescence( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float iridescence, const in vec3 iridescenceFresnel, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( lightDir + viewDir );\\n\\tfloat dotNL = saturate( dot( normal, lightDir ) );\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tfloat dotNH = saturate( dot( normal, halfDir ) );\\n\\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\\n\\tvec3 F = mix(F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence);\\n\\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( V * D );\\n}\\n#endif\\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\\n\\tfloat dotNV = saturate( dot( N, V ) );\\n\\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\\n\\tfloat l = length( f );\\n\\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\\n}\\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\\n\\tfloat x = dot( v1, v2 );\\n\\tfloat y = abs( x );\\n\\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\\n\\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\\n\\tfloat v = a / b;\\n\\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\\n\\treturn cross( v1, v2 ) * theta_sintheta;\\n}\\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\\n\\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\\n\\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\\n\\tvec3 lightNormal = cross( v1, v2 );\\n\\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\\n\\tvec3 T1, T2;\\n\\tT1 = normalize( V - N * dot( V, N ) );\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\\n\\tvec3 coords[ 4 ];\\n\\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\\n\\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\\n\\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\\n\\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\\n\\tcoords[ 0 ] = normalize( coords[ 0 ] );\\n\\tcoords[ 1 ] = normalize( coords[ 1 ] );\\n\\tcoords[ 2 ] = normalize( coords[ 2 ] );\\n\\tcoords[ 3 ] = normalize( coords[ 3 ] );\\n\\tvec3 vectorFormFactor = vec3( 0.0 );\\n\\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\\n\\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\\n\\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\\n\\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\\n\\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\\n\\treturn vec3( result );\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( lightDir + viewDir );\\n\\tfloat dotNH = saturate( dot( normal, halfDir ) );\\n\\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\n#if defined( USE_SHEEN )\\nfloat D_Charlie( float roughness, float dotNH ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tfloat invAlpha = 1.0 / alpha;\\n\\tfloat cos2h = dotNH * dotNH;\\n\\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\\n\\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\\n}\\nfloat V_Neubelt( float dotNV, float dotNL ) {\\n\\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\\n}\\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\\n\\tvec3 halfDir = normalize( lightDir + viewDir );\\n\\tfloat dotNL = saturate( dot( normal, lightDir ) );\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tfloat dotNH = saturate( dot( normal, halfDir ) );\\n\\tfloat D = D_Charlie( sheenRoughness, dotNH );\\n\\tfloat V = V_Neubelt( dotNV, dotNL );\\n\\treturn sheenColor * ( D * V );\\n}\\n#endif\";\n\nvar iridescence_fragment = \"#ifdef USE_IRIDESCENCE\\nconst mat3 XYZ_TO_REC709 = mat3(\\n 3.2404542, -0.9692660, 0.0556434,\\n -1.5371385, 1.8760108, -0.2040259,\\n -0.4985314, 0.0415560, 1.0572252\\n);\\nvec3 Fresnel0ToIor( vec3 fresnel0 ) {\\n vec3 sqrtF0 = sqrt( fresnel0 );\\n return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\\n}\\nvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\\n return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\\n}\\nfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\\n return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\\n}\\nvec3 evalSensitivity( float OPD, vec3 shift ) {\\n float phase = 2.0 * PI * OPD * 1.0e-9;\\n vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\\n vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\\n vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\\n vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( -pow2( phase ) * var );\\n xyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[0] ) * exp( -4.5282e+09 * pow2( phase ) );\\n xyz /= 1.0685e-7;\\n vec3 srgb = XYZ_TO_REC709 * xyz;\\n return srgb;\\n}\\nvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\\n vec3 I;\\n float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\\n float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\\n float cosTheta2Sq = 1.0 - sinTheta2Sq;\\n if ( cosTheta2Sq < 0.0 ) {\\n return vec3( 1.0 );\\n }\\n float cosTheta2 = sqrt( cosTheta2Sq );\\n float R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\\n float R12 = F_Schlick( R0, 1.0, cosTheta1 );\\n float R21 = R12;\\n float T121 = 1.0 - R12;\\n float phi12 = 0.0;\\n if ( iridescenceIOR < outsideIOR ) phi12 = PI;\\n float phi21 = PI - phi12;\\n vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\\n vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\\n vec3 phi23 = vec3( 0.0 );\\n if ( baseIOR[0] < iridescenceIOR ) phi23[0] = PI;\\n if ( baseIOR[1] < iridescenceIOR ) phi23[1] = PI;\\n if ( baseIOR[2] < iridescenceIOR ) phi23[2] = PI;\\n float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\\n vec3 phi = vec3( phi21 ) + phi23;\\n vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\\n vec3 r123 = sqrt( R123 );\\n vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\\n vec3 C0 = R12 + Rs;\\n I = C0;\\n vec3 Cm = Rs - T121;\\n for ( int m = 1; m <= 2; ++m ) {\\n Cm *= r123;\\n vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\\n I += Cm * Sm;\\n }\\n return max( I, vec3( 0.0 ) );\\n}\\n#endif\";\n\nvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\\n\\t\\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\\n\\t\\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 ) * faceDirection;\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\";\n\nvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tvec4 plane;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\\n\\t\\tplane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\t#pragma unroll_loop_start\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\\n\\t\\t\\tplane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\t#pragma unroll_loop_end\\n\\t\\tif ( clipped ) discard;\\n\\t#endif\\n#endif\";\n\nvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tvarying vec3 vClipPosition;\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\";\n\nvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0\\n\\tvarying vec3 vClipPosition;\\n#endif\";\n\nvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0\\n\\tvClipPosition = - mvPosition.xyz;\\n#endif\";\n\nvar color_fragment = \"#if defined( USE_COLOR_ALPHA )\\n\\tdiffuseColor *= vColor;\\n#elif defined( USE_COLOR )\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\nvar color_pars_fragment = \"#if defined( USE_COLOR_ALPHA )\\n\\tvarying vec4 vColor;\\n#elif defined( USE_COLOR )\\n\\tvarying vec3 vColor;\\n#endif\";\n\nvar color_pars_vertex = \"#if defined( USE_COLOR_ALPHA )\\n\\tvarying vec4 vColor;\\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\\n\\tvarying vec3 vColor;\\n#endif\";\n\nvar color_vertex = \"#if defined( USE_COLOR_ALPHA )\\n\\tvColor = vec4( 1.0 );\\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\\n\\tvColor = vec3( 1.0 );\\n#endif\\n#ifdef USE_COLOR\\n\\tvColor *= color;\\n#endif\\n#ifdef USE_INSTANCING_COLOR\\n\\tvColor.xyz *= instanceColor.xyz;\\n#endif\";\n\nvar common = \"#define PI 3.141592653589793\\n#define PI2 6.283185307179586\\n#define PI_HALF 1.5707963267948966\\n#define RECIPROCAL_PI 0.3183098861837907\\n#define RECIPROCAL_PI2 0.15915494309189535\\n#define EPSILON 1e-6\\n#ifndef saturate\\n#define saturate( a ) clamp( a, 0.0, 1.0 )\\n#endif\\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nvec3 pow2( const in vec3 x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract( sin( sn ) * c );\\n}\\n#ifdef HIGH_PRECISION\\n\\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\\n#else\\n\\tfloat precisionSafeLength( vec3 v ) {\\n\\t\\tfloat maxComponent = max3( abs( v ) );\\n\\t\\treturn length( v / maxComponent ) * maxComponent;\\n\\t}\\n#endif\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n#ifdef USE_CLEARCOAT\\n\\tvec3 clearcoatNormal;\\n#endif\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nmat3 transposeMat3( const in mat3 m ) {\\n\\tmat3 tmp;\\n\\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\\n\\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\\n\\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\\n\\treturn tmp;\\n}\\nfloat linearToRelativeLuminance( const in vec3 color ) {\\n\\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\\n\\treturn dot( weights, color.rgb );\\n}\\nbool isPerspectiveMatrix( mat4 m ) {\\n\\treturn m[ 2 ][ 3 ] == - 1.0;\\n}\\nvec2 equirectUv( in vec3 dir ) {\\n\\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\\n\\treturn vec2( u, v );\\n}\";\n\nvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n\\t#define cubeUV_minMipLevel 4.0\\n\\t#define cubeUV_minTileSize 16.0\\n\\tfloat getFace( vec3 direction ) {\\n\\t\\tvec3 absDirection = abs( direction );\\n\\t\\tfloat face = - 1.0;\\n\\t\\tif ( absDirection.x > absDirection.z ) {\\n\\t\\t\\tif ( absDirection.x > absDirection.y )\\n\\t\\t\\t\\tface = direction.x > 0.0 ? 0.0 : 3.0;\\n\\t\\t\\telse\\n\\t\\t\\t\\tface = direction.y > 0.0 ? 1.0 : 4.0;\\n\\t\\t} else {\\n\\t\\t\\tif ( absDirection.z > absDirection.y )\\n\\t\\t\\t\\tface = direction.z > 0.0 ? 2.0 : 5.0;\\n\\t\\t\\telse\\n\\t\\t\\t\\tface = direction.y > 0.0 ? 1.0 : 4.0;\\n\\t\\t}\\n\\t\\treturn face;\\n\\t}\\n\\tvec2 getUV( vec3 direction, float face ) {\\n\\t\\tvec2 uv;\\n\\t\\tif ( face == 0.0 ) {\\n\\t\\t\\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\\n\\t\\t} else if ( face == 1.0 ) {\\n\\t\\t\\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\\n\\t\\t} else if ( face == 2.0 ) {\\n\\t\\t\\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\\n\\t\\t} else if ( face == 3.0 ) {\\n\\t\\t\\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\\n\\t\\t} else if ( face == 4.0 ) {\\n\\t\\t\\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\\n\\t\\t} else {\\n\\t\\t\\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\\n\\t\\t}\\n\\t\\treturn 0.5 * ( uv + 1.0 );\\n\\t}\\n\\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\\n\\t\\tfloat face = getFace( direction );\\n\\t\\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\\n\\t\\tmipInt = max( mipInt, cubeUV_minMipLevel );\\n\\t\\tfloat faceSize = exp2( mipInt );\\n\\t\\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\\n\\t\\tif ( face > 2.0 ) {\\n\\t\\t\\tuv.y += faceSize;\\n\\t\\t\\tface -= 3.0;\\n\\t\\t}\\n\\t\\tuv.x += face * faceSize;\\n\\t\\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\\n\\t\\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\\n\\t\\tuv.x *= CUBEUV_TEXEL_WIDTH;\\n\\t\\tuv.y *= CUBEUV_TEXEL_HEIGHT;\\n\\t\\t#ifdef texture2DGradEXT\\n\\t\\t\\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn texture2D( envMap, uv ).rgb;\\n\\t\\t#endif\\n\\t}\\n\\t#define r0 1.0\\n\\t#define v0 0.339\\n\\t#define m0 - 2.0\\n\\t#define r1 0.8\\n\\t#define v1 0.276\\n\\t#define m1 - 1.0\\n\\t#define r4 0.4\\n\\t#define v4 0.046\\n\\t#define m4 2.0\\n\\t#define r5 0.305\\n\\t#define v5 0.016\\n\\t#define m5 3.0\\n\\t#define r6 0.21\\n\\t#define v6 0.0038\\n\\t#define m6 4.0\\n\\tfloat roughnessToMip( float roughness ) {\\n\\t\\tfloat mip = 0.0;\\n\\t\\tif ( roughness >= r1 ) {\\n\\t\\t\\tmip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;\\n\\t\\t} else if ( roughness >= r4 ) {\\n\\t\\t\\tmip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;\\n\\t\\t} else if ( roughness >= r5 ) {\\n\\t\\t\\tmip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;\\n\\t\\t} else if ( roughness >= r6 ) {\\n\\t\\t\\tmip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;\\n\\t\\t} else {\\n\\t\\t\\tmip = - 2.0 * log2( 1.16 * roughness );\\t\\t}\\n\\t\\treturn mip;\\n\\t}\\n\\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\\n\\t\\tfloat mip = clamp( roughnessToMip( roughness ), m0, CUBEUV_MAX_MIP );\\n\\t\\tfloat mipF = fract( mip );\\n\\t\\tfloat mipInt = floor( mip );\\n\\t\\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\\n\\t\\tif ( mipF == 0.0 ) {\\n\\t\\t\\treturn vec4( color0, 1.0 );\\n\\t\\t} else {\\n\\t\\t\\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\\n\\t\\t\\treturn vec4( mix( color0, color1, mipF ), 1.0 );\\n\\t\\t}\\n\\t}\\n#endif\";\n\nvar defaultnormal_vertex = \"vec3 transformedNormal = objectNormal;\\n#ifdef USE_INSTANCING\\n\\tmat3 m = mat3( instanceMatrix );\\n\\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\\n\\ttransformedNormal = m * transformedNormal;\\n#endif\\ntransformedNormal = normalMatrix * transformedNormal;\\n#ifdef FLIP_SIDED\\n\\ttransformedNormal = - transformedNormal;\\n#endif\\n#ifdef USE_TANGENT\\n\\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\\n\\t#ifdef FLIP_SIDED\\n\\t\\ttransformedTangent = - transformedTangent;\\n\\t#endif\\n#endif\";\n\nvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\";\n\nvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\\n#endif\";\n\nvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\";\n\nvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\";\n\nvar encodings_fragment = \"gl_FragColor = linearToOutputTexel( gl_FragColor );\";\n\nvar encodings_pars_fragment = \"vec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\\n}\";\n\nvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#ifdef ENV_WORLDPOS\\n\\t\\tvec3 cameraToFrag;\\n\\t\\tif ( isOrthographic ) {\\n\\t\\t\\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\\n\\t\\t} else {\\n\\t\\t\\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\\n\\t\\t}\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\";\n\nvar envmap_common_pars_fragment = \"#ifdef USE_ENVMAP\\n\\tuniform float envMapIntensity;\\n\\tuniform float flipEnvMap;\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\t\\n#endif\";\n\nvar envmap_pars_fragment = \"#ifdef USE_ENVMAP\\n\\tuniform float reflectivity;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\t#define ENV_WORLDPOS\\n\\t#endif\\n\\t#ifdef ENV_WORLDPOS\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\";\n\nvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\\n\\t\\t#define ENV_WORLDPOS\\n\\t#endif\\n\\t#ifdef ENV_WORLDPOS\\n\\t\\t\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\";\n\nvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#ifdef ENV_WORLDPOS\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex;\\n\\t\\tif ( isOrthographic ) {\\n\\t\\t\\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\\n\\t\\t} else {\\n\\t\\t\\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\t}\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\";\n\nvar fog_vertex = \"#ifdef USE_FOG\\n\\tvFogDepth = - mvPosition.z;\\n#endif\";\n\nvar fog_pars_vertex = \"#ifdef USE_FOG\\n\\tvarying float vFogDepth;\\n#endif\";\n\nvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\";\n\nvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float vFogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\";\n\nvar gradientmap_pars_fragment = \"#ifdef USE_GRADIENTMAP\\n\\tuniform sampler2D gradientMap;\\n#endif\\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\tfloat dotNL = dot( normal, lightDirection );\\n\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t#ifdef USE_GRADIENTMAP\\n\\t\\treturn vec3( texture2D( gradientMap, coord ).r );\\n\\t#else\\n\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t#endif\\n}\";\n\nvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\\n\\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\\n\\treflectedLight.indirectDiffuse += lightMapIrradiance;\\n#endif\";\n\nvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\nvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\nvIndirectFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n\\tvIndirectBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );\\n#ifdef DOUBLE_SIDED\\n\\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\\n\\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\\n\\t\\t#endif\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\";\n\nvar lights_pars_begin = \"uniform bool receiveShadow;\\nuniform vec3 ambientLightColor;\\nuniform vec3 lightProbe[ 9 ];\\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\\n\\tfloat x = normal.x, y = normal.y, z = normal.z;\\n\\tvec3 result = shCoefficients[ 0 ] * 0.886227;\\n\\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\\n\\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\\n\\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\\n\\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\\n\\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\\n\\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\\n\\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\\n\\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\\n\\treturn result;\\n}\\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\\n\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\\n\\treturn irradiance;\\n}\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\treturn irradiance;\\n}\\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\tif ( cutoffDistance > 0.0 ) {\\n\\t\\t\\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t}\\n\\t\\treturn distanceFalloff;\\n\\t#else\\n\\t\\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\\n\\t\\t\\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t#endif\\n}\\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\\n\\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\\n\\t\\tlight.color = directionalLight.color;\\n\\t\\tlight.direction = directionalLight.direction;\\n\\t\\tlight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tlight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tlight.color = pointLight.color;\\n\\t\\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tlight.visible = ( light.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tlight.direction = normalize( lVector );\\n\\t\\tfloat angleCos = dot( light.direction, spotLight.direction );\\n\\t\\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\tif ( spotAttenuation > 0.0 ) {\\n\\t\\t\\tfloat lightDistance = length( lVector );\\n\\t\\t\\tlight.color = spotLight.color * spotAttenuation;\\n\\t\\t\\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tlight.visible = ( light.color != vec3( 0.0 ) );\\n\\t\\t} else {\\n\\t\\t\\tlight.color = vec3( 0.0 );\\n\\t\\t\\tlight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltc_1;\\tuniform sampler2D ltc_2;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\\n\\t\\tfloat dotNL = dot( normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\";\n\nvar envmap_physical_pars_fragment = \"#if defined( USE_ENVMAP )\\n\\tvec3 getIBLIrradiance( const in vec3 normal ) {\\n\\t\\t#if defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\\n\\t\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t\\t#else\\n\\t\\t\\treturn vec3( 0.0 );\\n\\t\\t#endif\\n\\t}\\n\\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\\n\\t\\t#if defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 reflectVec = reflect( - viewDir, normal );\\n\\t\\t\\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\\n\\t\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\\n\\t\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t\\t#else\\n\\t\\t\\treturn vec3( 0.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\";\n\nvar lights_toon_fragment = \"ToonMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\";\n\nvar lights_toon_pars_fragment = \"varying vec3 vViewPosition;\\nstruct ToonMaterial {\\n\\tvec3 diffuseColor;\\n};\\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Toon\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Toon\\n#define Material_LightProbeLOD( material )\\t(0)\";\n\nvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\";\n\nvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\nstruct BlinnPhongMaterial {\\n\\tvec3 diffuseColor;\\n\\tvec3 specularColor;\\n\\tfloat specularShininess;\\n\\tfloat specularStrength;\\n};\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\";\n\nvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\\nmaterial.roughness = min( material.roughness, 1.0 );\\n#ifdef IOR\\n\\t#ifdef SPECULAR\\n\\t\\tfloat specularIntensityFactor = specularIntensity;\\n\\t\\tvec3 specularColorFactor = specularColor;\\n\\t\\t#ifdef USE_SPECULARINTENSITYMAP\\n\\t\\t\\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\\n\\t\\t#endif\\n\\t\\t#ifdef USE_SPECULARCOLORMAP\\n\\t\\t\\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\\n\\t\\t#endif\\n\\t\\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\\n\\t#else\\n\\t\\tfloat specularIntensityFactor = 1.0;\\n\\t\\tvec3 specularColorFactor = vec3( 1.0 );\\n\\t\\tmaterial.specularF90 = 1.0;\\n\\t#endif\\n\\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.specularF90 = 1.0;\\n#endif\\n#ifdef USE_CLEARCOAT\\n\\tmaterial.clearcoat = clearcoat;\\n\\tmaterial.clearcoatRoughness = clearcoatRoughness;\\n\\tmaterial.clearcoatF0 = vec3( 0.04 );\\n\\tmaterial.clearcoatF90 = 1.0;\\n\\t#ifdef USE_CLEARCOATMAP\\n\\t\\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\\n\\t#endif\\n\\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\\n\\t\\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\\n\\t#endif\\n\\tmaterial.clearcoat = saturate( material.clearcoat );\\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\\n\\tmaterial.clearcoatRoughness += geometryRoughness;\\n\\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\\n#endif\\n#ifdef USE_IRIDESCENCE\\n\\tmaterial.iridescence = iridescence;\\n\\tmaterial.iridescenceIOR = iridescenceIOR;\\n\\t#ifdef USE_IRIDESCENCEMAP\\n\\t\\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\\n\\t#endif\\n\\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\\n\\t\\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\\n\\t#else\\n\\t\\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\\n\\t#endif\\n#endif\\n#ifdef USE_SHEEN\\n\\tmaterial.sheenColor = sheenColor;\\n\\t#ifdef USE_SHEENCOLORMAP\\n\\t\\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\\n\\t#endif\\n\\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\\n\\t#ifdef USE_SHEENROUGHNESSMAP\\n\\t\\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\\n\\t#endif\\n#endif\";\n\nvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3 diffuseColor;\\n\\tfloat roughness;\\n\\tvec3 specularColor;\\n\\tfloat specularF90;\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tfloat clearcoat;\\n\\t\\tfloat clearcoatRoughness;\\n\\t\\tvec3 clearcoatF0;\\n\\t\\tfloat clearcoatF90;\\n\\t#endif\\n\\t#ifdef USE_IRIDESCENCE\\n\\t\\tfloat iridescence;\\n\\t\\tfloat iridescenceIOR;\\n\\t\\tfloat iridescenceThickness;\\n\\t\\tvec3 iridescenceFresnel;\\n\\t\\tvec3 iridescenceF0;\\n\\t#endif\\n\\t#ifdef USE_SHEEN\\n\\t\\tvec3 sheenColor;\\n\\t\\tfloat sheenRoughness;\\n\\t#endif\\n};\\nvec3 clearcoatSpecular = vec3( 0.0 );\\nvec3 sheenSpecular = vec3( 0.0 );\\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tfloat r2 = roughness * roughness;\\n\\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\\n\\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\\n\\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\\n\\treturn saturate( DG * RECIPROCAL_PI );\\n}\\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( normal, viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\\n\\treturn fab;\\n}\\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\\n\\tvec2 fab = DFGApprox( normal, viewDir, roughness );\\n\\treturn specularColor * fab.x + specularF90 * fab.y;\\n}\\n#ifdef USE_IRIDESCENCE\\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\\n#else\\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\\n#endif\\n\\tvec2 fab = DFGApprox( normal, viewDir, roughness );\\n\\t#ifdef USE_IRIDESCENCE\\n\\t\\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\\n\\t#else\\n\\t\\tvec3 Fr = specularColor;\\n\\t#endif\\n\\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\\n\\tfloat Ess = fab.x + fab.y;\\n\\tfloat Ems = 1.0 - Ess;\\n\\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\\n\\tsingleScatter += FssEss;\\n\\tmultiScatter += Fms * Ems;\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 normal = geometry.normal;\\n\\t\\tvec3 viewDir = geometry.viewDir;\\n\\t\\tvec3 position = geometry.position;\\n\\t\\tvec3 lightPos = rectAreaLight.position;\\n\\t\\tvec3 halfWidth = rectAreaLight.halfWidth;\\n\\t\\tvec3 halfHeight = rectAreaLight.halfHeight;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.roughness;\\n\\t\\tvec3 rectCoords[ 4 ];\\n\\t\\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\\t\\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\\n\\t\\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\\n\\t\\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\\n\\t\\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\\n\\t\\tvec4 t1 = texture2D( ltc_1, uv );\\n\\t\\tvec4 t2 = texture2D( ltc_2, uv );\\n\\t\\tmat3 mInv = mat3(\\n\\t\\t\\tvec3( t1.x, 0, t1.y ),\\n\\t\\t\\tvec3( 0, 1, 0 ),\\n\\t\\t\\tvec3( t1.z, 0, t1.w )\\n\\t\\t);\\n\\t\\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\\n\\t\\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\\n\\t\\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\\n\\t\\tvec3 ccIrradiance = dotNLcc * directLight.color;\\n\\t\\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\\n\\t#endif\\n\\t#ifdef USE_SHEEN\\n\\t\\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\\n\\t#endif\\n\\t#ifdef USE_IRIDESCENCE\\n\\t\\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\\n\\t#else\\n\\t\\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\\n\\t#endif\\n\\t#ifdef USE_SHEEN\\n\\t\\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\\n\\t#endif\\n\\tvec3 singleScattering = vec3( 0.0 );\\n\\tvec3 multiScattering = vec3( 0.0 );\\n\\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\\n\\t#ifdef USE_IRIDESCENCE\\n\\t\\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\\n\\t#else\\n\\t\\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\\n\\t#endif\\n\\tvec3 totalScattering = singleScattering + multiScattering;\\n\\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\\n\\treflectedLight.indirectSpecular += radiance * singleScattering;\\n\\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\\n\\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\";\n\nvar lights_fragment_begin = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\\n#ifdef USE_CLEARCOAT\\n\\tgeometry.clearcoatNormal = clearcoatNormal;\\n#endif\\n#ifdef USE_IRIDESCENCE\\nfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\\nif ( material.iridescenceThickness == 0.0 ) {\\n\\tmaterial.iridescence = 0.0;\\n} else {\\n\\tmaterial.iridescence = saturate( material.iridescence );\\n}\\nif ( material.iridescence > 0.0 ) {\\n\\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\\n\\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\\n}\\n#endif\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\\n\\tPointLightShadow pointLightShadow;\\n\\t#endif\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointLightInfo( pointLight, geometry, directLight );\\n\\t\\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\\n\\t\\tpointLightShadow = pointLightShadows[ i ];\\n\\t\\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\\n\\tSpotLightShadow spotLightShadow;\\n\\t#endif\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotLightInfo( spotLight, geometry, directLight );\\n\\t\\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\\n\\t\\tspotLightShadow = spotLightShadows[ i ];\\n\\t\\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\\n\\tDirectionalLightShadow directionalLightShadow;\\n\\t#endif\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalLightInfo( directionalLight, geometry, directLight );\\n\\t\\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\\n\\t\\tdirectionalLightShadow = directionalLightShadows[ i ];\\n\\t\\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n\\t#pragma unroll_loop_end\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 iblIrradiance = vec3( 0.0 );\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\tirradiance += getLightProbeIrradiance( lightProbe, geometry.normal );\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\t#pragma unroll_loop_start\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\\n\\t\\t}\\n\\t\\t#pragma unroll_loop_end\\n\\t#endif\\n#endif\\n#if defined( RE_IndirectSpecular )\\n\\tvec3 radiance = vec3( 0.0 );\\n\\tvec3 clearcoatRadiance = vec3( 0.0 );\\n#endif\";\n\nvar lights_fragment_maps = \"#if defined( RE_IndirectDiffuse )\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\\n\\t\\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tiblIrradiance += getIBLIrradiance( geometry.normal );\\n\\t#endif\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\\n\\t#endif\\n#endif\";\n\nvar lights_fragment_end = \"#if defined( RE_IndirectDiffuse )\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( RE_IndirectSpecular )\\n\\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\\n#endif\";\n\nvar logdepthbuf_fragment = \"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\\n\\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\\n#endif\";\n\nvar logdepthbuf_pars_fragment = \"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\\n\\tuniform float logDepthBufFC;\\n\\tvarying float vFragDepth;\\n\\tvarying float vIsPerspective;\\n#endif\";\n\nvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t\\tvarying float vIsPerspective;\\n\\t#else\\n\\t\\tuniform float logDepthBufFC;\\n\\t#endif\\n#endif\";\n\nvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t\\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\\n\\t#else\\n\\t\\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\\n\\t\\t\\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\\n\\t\\t\\tgl_Position.z *= gl_Position.w;\\n\\t\\t}\\n\\t#endif\\n#endif\";\n\nvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 sampledDiffuseColor = texture2D( map, vUv );\\n\\t#ifdef DECODE_VIDEO_TEXTURE\\n\\t\\tsampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w );\\n\\t#endif\\n\\tdiffuseColor *= sampledDiffuseColor;\\n#endif\";\n\nvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\";\n\nvar map_particle_fragment = \"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\\n\\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\\n#endif\\n#ifdef USE_MAP\\n\\tdiffuseColor *= texture2D( map, uv );\\n#endif\\n#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\\n#endif\";\n\nvar map_particle_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\\n\\tuniform mat3 uvTransform;\\n#endif\\n#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\";\n\nvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.b;\\n#endif\";\n\nvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\nvar morphcolor_vertex = \"#if defined( USE_MORPHCOLORS ) && defined( MORPHTARGETS_TEXTURE )\\n\\tvColor *= morphTargetBaseInfluence;\\n\\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\\n\\t\\t#if defined( USE_COLOR_ALPHA )\\n\\t\\t\\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\\n\\t\\t#elif defined( USE_COLOR )\\n\\t\\t\\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\\n\\t\\t#endif\\n\\t}\\n#endif\";\n\nvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal *= morphTargetBaseInfluence;\\n\\t#ifdef MORPHTARGETS_TEXTURE\\n\\t\\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\\n\\t\\t\\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\\n\\t\\t}\\n\\t#else\\n\\t\\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\\n\\t\\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\\n\\t\\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\\n\\t\\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\\n\\t#endif\\n#endif\";\n\nvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\tuniform float morphTargetBaseInfluence;\\n\\t#ifdef MORPHTARGETS_TEXTURE\\n\\t\\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\\n\\t\\tuniform sampler2DArray morphTargetsTexture;\\n\\t\\tuniform ivec2 morphTargetsTextureSize;\\n\\t\\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\\n\\t\\t\\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\\n\\t\\t\\tint y = texelIndex / morphTargetsTextureSize.x;\\n\\t\\t\\tint x = texelIndex - y * morphTargetsTextureSize.x;\\n\\t\\t\\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\\n\\t\\t\\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\\n\\t\\t}\\n\\t#else\\n\\t\\t#ifndef USE_MORPHNORMALS\\n\\t\\t\\tuniform float morphTargetInfluences[ 8 ];\\n\\t\\t#else\\n\\t\\t\\tuniform float morphTargetInfluences[ 4 ];\\n\\t\\t#endif\\n\\t#endif\\n#endif\";\n\nvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed *= morphTargetBaseInfluence;\\n\\t#ifdef MORPHTARGETS_TEXTURE\\n\\t\\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\\n\\t\\t\\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\\n\\t\\t}\\n\\t#else\\n\\t\\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\\n\\t\\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\\n\\t\\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\\n\\t\\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\\n\\t\\t#ifndef USE_MORPHNORMALS\\n\\t\\t\\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\\n\\t\\t\\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\\n\\t\\t\\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\\n\\t\\t\\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\\n\\t\\t#endif\\n\\t#endif\\n#endif\";\n\nvar normal_fragment_begin = \"float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\\n#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\tnormal = normal * faceDirection;\\n\\t#endif\\n\\t#ifdef USE_TANGENT\\n\\t\\tvec3 tangent = normalize( vTangent );\\n\\t\\tvec3 bitangent = normalize( vBitangent );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\ttangent = tangent * faceDirection;\\n\\t\\t\\tbitangent = bitangent * faceDirection;\\n\\t\\t#endif\\n\\t\\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\\n\\t\\t\\tmat3 vTBN = mat3( tangent, bitangent, normal );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\nvec3 geometryNormal = normal;\";\n\nvar normal_fragment_maps = \"#ifdef OBJECTSPACE_NORMALMAP\\n\\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t#ifdef FLIP_SIDED\\n\\t\\tnormal = - normal;\\n\\t#endif\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\tnormal = normal * faceDirection;\\n\\t#endif\\n\\tnormal = normalize( normalMatrix * normal );\\n#elif defined( TANGENTSPACE_NORMALMAP )\\n\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\tmapN.xy *= normalScale;\\n\\t#ifdef USE_TANGENT\\n\\t\\tnormal = normalize( vTBN * mapN );\\n\\t#else\\n\\t\\tnormal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );\\n\\t#endif\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\\n#endif\";\n\nvar normal_pars_fragment = \"#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n\\t#ifdef USE_TANGENT\\n\\t\\tvarying vec3 vTangent;\\n\\t\\tvarying vec3 vBitangent;\\n\\t#endif\\n#endif\";\n\nvar normal_pars_vertex = \"#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n\\t#ifdef USE_TANGENT\\n\\t\\tvarying vec3 vTangent;\\n\\t\\tvarying vec3 vBitangent;\\n\\t#endif\\n#endif\";\n\nvar normal_vertex = \"#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n\\t#ifdef USE_TANGENT\\n\\t\\tvTangent = normalize( transformedTangent );\\n\\t\\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\\n\\t#endif\\n#endif\";\n\nvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n#endif\\n#ifdef OBJECTSPACE_NORMALMAP\\n\\tuniform mat3 normalMatrix;\\n#endif\\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {\\n\\t\\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\\n\\t\\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 N = surf_norm;\\n\\t\\tvec3 q1perp = cross( q1, N );\\n\\t\\tvec3 q0perp = cross( N, q0 );\\n\\t\\tvec3 T = q1perp * st0.x + q0perp * st1.x;\\n\\t\\tvec3 B = q1perp * st0.y + q0perp * st1.y;\\n\\t\\tfloat det = max( dot( T, T ), dot( B, B ) );\\n\\t\\tfloat scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );\\n\\t\\treturn normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );\\n\\t}\\n#endif\";\n\nvar clearcoat_normal_fragment_begin = \"#ifdef USE_CLEARCOAT\\n\\tvec3 clearcoatNormal = geometryNormal;\\n#endif\";\n\nvar clearcoat_normal_fragment_maps = \"#ifdef USE_CLEARCOAT_NORMALMAP\\n\\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\\n\\tclearcoatMapN.xy *= clearcoatNormalScale;\\n\\t#ifdef USE_TANGENT\\n\\t\\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\\n\\t#else\\n\\t\\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection );\\n\\t#endif\\n#endif\";\n\nvar clearcoat_pars_fragment = \"#ifdef USE_CLEARCOATMAP\\n\\tuniform sampler2D clearcoatMap;\\n#endif\\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\\n\\tuniform sampler2D clearcoatRoughnessMap;\\n#endif\\n#ifdef USE_CLEARCOAT_NORMALMAP\\n\\tuniform sampler2D clearcoatNormalMap;\\n\\tuniform vec2 clearcoatNormalScale;\\n#endif\";\n\nvar iridescence_pars_fragment = \"#ifdef USE_IRIDESCENCEMAP\\n\\tuniform sampler2D iridescenceMap;\\n#endif\\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\\n\\tuniform sampler2D iridescenceThicknessMap;\\n#endif\";\n\nvar output_fragment = \"#ifdef OPAQUE\\ndiffuseColor.a = 1.0;\\n#endif\\n#ifdef USE_TRANSMISSION\\ndiffuseColor.a *= transmissionAlpha + 0.1;\\n#endif\\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );\";\n\nvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 2.0 * rgb.xyz - 1.0;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nvec4 pack2HalfToRGBA( vec2 v ) {\\n\\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\\n\\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\\n}\\nvec2 unpackRGBATo2Half( vec4 v ) {\\n\\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\";\n\nvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\";\n\nvar project_vertex = \"vec4 mvPosition = vec4( transformed, 1.0 );\\n#ifdef USE_INSTANCING\\n\\tmvPosition = instanceMatrix * mvPosition;\\n#endif\\nmvPosition = modelViewMatrix * mvPosition;\\ngl_Position = projectionMatrix * mvPosition;\";\n\nvar dithering_fragment = \"#ifdef DITHERING\\n\\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\\n#endif\";\n\nvar dithering_pars_fragment = \"#ifdef DITHERING\\n\\tvec3 dithering( vec3 color ) {\\n\\t\\tfloat grid_position = rand( gl_FragCoord.xy );\\n\\t\\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\\n\\t\\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\\n\\t\\treturn color + dither_shift_RGB;\\n\\t}\\n#endif\";\n\nvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.g;\\n#endif\";\n\nvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\nvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t\\tstruct DirectionalLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t};\\n\\t\\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHT_SHADOWS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t\\tstruct SpotLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t};\\n\\t\\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHT_SHADOWS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t\\tstruct PointLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t\\tfloat shadowCameraNear;\\n\\t\\t\\tfloat shadowCameraFar;\\n\\t\\t};\\n\\t\\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\\n\\t\\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\\n\\t}\\n\\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\\n\\t\\tfloat occlusion = 1.0;\\n\\t\\tvec2 distribution = texture2DDistribution( shadow, uv );\\n\\t\\tfloat hard_shadow = step( compare , distribution.x );\\n\\t\\tif (hard_shadow != 1.0 ) {\\n\\t\\t\\tfloat distance = compare - distribution.x ;\\n\\t\\t\\tfloat variance = max( 0.00000, distribution.y * distribution.y );\\n\\t\\t\\tfloat softness_probability = variance / (variance + distance * distance );\\t\\t\\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\\t\\t\\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\\n\\t\\t}\\n\\t\\treturn occlusion;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tfloat shadow = 1.0;\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx2 = dx0 / 2.0;\\n\\t\\t\\tfloat dy2 = dy0 / 2.0;\\n\\t\\t\\tfloat dx3 = dx1 / 2.0;\\n\\t\\t\\tfloat dy3 = dy1 / 2.0;\\n\\t\\t\\tshadow = (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 17.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx = texelSize.x;\\n\\t\\t\\tfloat dy = texelSize.y;\\n\\t\\t\\tvec2 uv = shadowCoord.xy;\\n\\t\\t\\tvec2 f = fract( uv * shadowMapSize + 0.5 );\\n\\t\\t\\tuv -= f * texelSize;\\n\\t\\t\\tshadow = (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\\n\\t\\t\\t\\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t f.x ) +\\n\\t\\t\\t\\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t f.x ) +\\n\\t\\t\\t\\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t f.y ) +\\n\\t\\t\\t\\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t f.y ) +\\n\\t\\t\\t\\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t\\t f.x ),\\n\\t\\t\\t\\t\\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \\n\\t\\t\\t\\t\\t\\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\\n\\t\\t\\t\\t\\t\\t f.x ),\\n\\t\\t\\t\\t\\t f.y )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_VSM )\\n\\t\\t\\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#else\\n\\t\\t\\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn shadow;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\\t\\tdp += shadowBias;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\";\n\nvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t\\tstruct DirectionalLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t};\\n\\t\\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHT_SHADOWS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t\\tstruct SpotLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t};\\n\\t\\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHT_SHADOWS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t\\tstruct PointLightShadow {\\n\\t\\t\\tfloat shadowBias;\\n\\t\\t\\tfloat shadowNormalBias;\\n\\t\\t\\tfloat shadowRadius;\\n\\t\\t\\tvec2 shadowMapSize;\\n\\t\\t\\tfloat shadowCameraNear;\\n\\t\\t\\tfloat shadowCameraFar;\\n\\t\\t};\\n\\t\\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\\n\\t#endif\\n#endif\";\n\nvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\\n\\t\\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\tvec4 shadowWorldPosition;\\n\\t#endif\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHT_SHADOWS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#if NUM_POINT_LIGHT_SHADOWS > 0\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n#endif\";\n\nvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHT_SHADOWS > 0\\n\\tDirectionalLightShadow directionalLight;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLightShadows[ i ];\\n\\t\\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHT_SHADOWS > 0\\n\\tSpotLightShadow spotLight;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tspotLight = spotLightShadows[ i ];\\n\\t\\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#if NUM_POINT_LIGHT_SHADOWS > 0\\n\\tPointLightShadow pointLight;\\n\\t#pragma unroll_loop_start\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\\n\\t\\tpointLight = pointLightShadows[ i ];\\n\\t\\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\\n\\t}\\n\\t#pragma unroll_loop_end\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\";\n\nvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\nvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\tuniform highp sampler2D boneTexture;\\n\\tuniform int boneTextureSize;\\n\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\tfloat j = i * 4.0;\\n\\t\\tfloat x = mod( j, float( boneTextureSize ) );\\n\\t\\tfloat y = floor( j / float( boneTextureSize ) );\\n\\t\\tfloat dx = 1.0 / float( boneTextureSize );\\n\\t\\tfloat dy = 1.0 / float( boneTextureSize );\\n\\t\\ty = dy * ( y + 0.5 );\\n\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\treturn bone;\\n\\t}\\n#endif\";\n\nvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\ttransformed = ( bindMatrixInverse * skinned ).xyz;\\n#endif\";\n\nvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n\\t#ifdef USE_TANGENT\\n\\t\\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\\n\\t#endif\\n#endif\";\n\nvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\nvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\nvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n\\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\";\n\nvar tonemapping_pars_fragment = \"#ifndef saturate\\n#define saturate( a ) clamp( a, 0.0, 1.0 )\\n#endif\\nuniform float toneMappingExposure;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\nvec3 RRTAndODTFit( vec3 v ) {\\n\\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\\n\\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\\n\\treturn a / b;\\n}\\nvec3 ACESFilmicToneMapping( vec3 color ) {\\n\\tconst mat3 ACESInputMat = mat3(\\n\\t\\tvec3( 0.59719, 0.07600, 0.02840 ),\\t\\tvec3( 0.35458, 0.90834, 0.13383 ),\\n\\t\\tvec3( 0.04823, 0.01566, 0.83777 )\\n\\t);\\n\\tconst mat3 ACESOutputMat = mat3(\\n\\t\\tvec3( 1.60475, -0.10208, -0.00327 ),\\t\\tvec3( -0.53108, 1.10813, -0.07276 ),\\n\\t\\tvec3( -0.07367, -0.00605, 1.07602 )\\n\\t);\\n\\tcolor *= toneMappingExposure / 0.6;\\n\\tcolor = ACESInputMat * color;\\n\\tcolor = RRTAndODTFit( color );\\n\\tcolor = ACESOutputMat * color;\\n\\treturn saturate( color );\\n}\\nvec3 CustomToneMapping( vec3 color ) { return color; }\";\n\nvar transmission_fragment = \"#ifdef USE_TRANSMISSION\\n\\tfloat transmissionAlpha = 1.0;\\n\\tfloat transmissionFactor = transmission;\\n\\tfloat thicknessFactor = thickness;\\n\\t#ifdef USE_TRANSMISSIONMAP\\n\\t\\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\\n\\t#endif\\n\\t#ifdef USE_THICKNESSMAP\\n\\t\\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\\n\\t#endif\\n\\tvec3 pos = vWorldPosition;\\n\\tvec3 v = normalize( cameraPosition - pos );\\n\\tvec3 n = inverseTransformDirection( normal, viewMatrix );\\n\\tvec4 transmission = getIBLVolumeRefraction(\\n\\t\\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\\n\\t\\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\\n\\t\\tattenuationColor, attenuationDistance );\\n\\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\\n\\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\\n#endif\";\n\nvar transmission_pars_fragment = \"#ifdef USE_TRANSMISSION\\n\\tuniform float transmission;\\n\\tuniform float thickness;\\n\\tuniform float attenuationDistance;\\n\\tuniform vec3 attenuationColor;\\n\\t#ifdef USE_TRANSMISSIONMAP\\n\\t\\tuniform sampler2D transmissionMap;\\n\\t#endif\\n\\t#ifdef USE_THICKNESSMAP\\n\\t\\tuniform sampler2D thicknessMap;\\n\\t#endif\\n\\tuniform vec2 transmissionSamplerSize;\\n\\tuniform sampler2D transmissionSamplerMap;\\n\\tuniform mat4 modelMatrix;\\n\\tuniform mat4 projectionMatrix;\\n\\tvarying vec3 vWorldPosition;\\n\\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\\n\\t\\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\\n\\t\\tvec3 modelScale;\\n\\t\\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\\n\\t\\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\\n\\t\\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\\n\\t\\treturn normalize( refractionVector ) * thickness * modelScale;\\n\\t}\\n\\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\\n\\t\\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\\n\\t}\\n\\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\\n\\t\\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\\n\\t\\t#ifdef texture2DLodEXT\\n\\t\\t\\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\\n\\t\\t#else\\n\\t\\t\\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\\n\\t\\t#endif\\n\\t}\\n\\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\\n\\t\\tif ( attenuationDistance == 0.0 ) {\\n\\t\\t\\treturn radiance;\\n\\t\\t} else {\\n\\t\\t\\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\\n\\t\\t\\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\\t\\t\\treturn transmittance * radiance;\\n\\t\\t}\\n\\t}\\n\\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\\n\\t\\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\\n\\t\\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\\n\\t\\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\\n\\t\\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\\n\\t\\tvec3 refractedRayExit = position + transmissionRay;\\n\\t\\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\\n\\t\\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\\n\\t\\trefractionCoords += 1.0;\\n\\t\\trefractionCoords /= 2.0;\\n\\t\\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\\n\\t\\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\\n\\t\\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\\n\\t\\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\\n\\t}\\n#endif\";\n\nvar uv_pars_fragment = \"#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\\n\\tvarying vec2 vUv;\\n#endif\";\n\nvar uv_pars_vertex = \"#ifdef USE_UV\\n\\t#ifdef UVS_VERTEX_ONLY\\n\\t\\tvec2 vUv;\\n\\t#else\\n\\t\\tvarying vec2 vUv;\\n\\t#endif\\n\\tuniform mat3 uvTransform;\\n#endif\";\n\nvar uv_vertex = \"#ifdef USE_UV\\n\\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\\n#endif\";\n\nvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\nvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n\\tuniform mat3 uv2Transform;\\n#endif\";\n\nvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\\n#endif\";\n\nvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\\n\\tvec4 worldPosition = vec4( transformed, 1.0 );\\n\\t#ifdef USE_INSTANCING\\n\\t\\tworldPosition = instanceMatrix * worldPosition;\\n\\t#endif\\n\\tworldPosition = modelMatrix * worldPosition;\\n#endif\";\n\nconst vertex$g = \"varying vec2 vUv;\\nuniform mat3 uvTransform;\\nvoid main() {\\n\\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\\n\\tgl_Position = vec4( position.xy, 1.0, 1.0 );\\n}\";\n\nconst fragment$g = \"uniform sampler2D t2D;\\nvarying vec2 vUv;\\nvoid main() {\\n\\tgl_FragColor = texture2D( t2D, vUv );\\n\\t#ifdef DECODE_VIDEO_TEXTURE\\n\\t\\tgl_FragColor = vec4( mix( pow( gl_FragColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), gl_FragColor.rgb * 0.0773993808, vec3( lessThanEqual( gl_FragColor.rgb, vec3( 0.04045 ) ) ) ), gl_FragColor.w );\\n\\t#endif\\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$f = \"varying vec3 vWorldDirection;\\n#include \\nvoid main() {\\n\\tvWorldDirection = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n\\tgl_Position.z = gl_Position.w;\\n}\";\n\nconst fragment$f = \"#include \\nuniform float opacity;\\nvarying vec3 vWorldDirection;\\n#include \\nvoid main() {\\n\\tvec3 vReflect = vWorldDirection;\\n\\t#include \\n\\tgl_FragColor = envColor;\\n\\tgl_FragColor.a *= opacity;\\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$e = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvarying vec2 vHighPrecisionZW;\\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#ifdef USE_DISPLACEMENTMAP\\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvHighPrecisionZW = gl_Position.zw;\\n}\";\n\nconst fragment$e = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvarying vec2 vHighPrecisionZW;\\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( fragCoordZ );\\n\\t#endif\\n}\";\n\nconst vertex$d = \"#define DISTANCE\\nvarying vec3 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#ifdef USE_DISPLACEMENTMAP\\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition.xyz;\\n}\";\n\nconst fragment$d = \"#define DISTANCE\\nuniform vec3 referencePosition;\\nuniform float nearDistance;\\nuniform float farDistance;\\nvarying vec3 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tfloat dist = length( vWorldPosition - referencePosition );\\n\\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\\n\\tdist = saturate( dist );\\n\\tgl_FragColor = packDepthToRGBA( dist );\\n}\";\n\nconst vertex$c = \"varying vec3 vWorldDirection;\\n#include \\nvoid main() {\\n\\tvWorldDirection = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$c = \"uniform sampler2D tEquirect;\\nvarying vec3 vWorldDirection;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldDirection );\\n\\tvec2 sampleUV = equirectUv( direction );\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$b = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tvLineDistance = scale * lineDistance;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$b = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$a = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$a = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\\n\\t\\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$9 = \"#define LAMBERT\\nvarying vec3 vLightFront;\\nvarying vec3 vIndirectFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n\\tvarying vec3 vIndirectBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$9 = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\nvarying vec3 vIndirectFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n\\tvarying vec3 vIndirectBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vIndirectFront;\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$8 = \"#define MATCAP\\nvarying vec3 vViewPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n}\";\n\nconst fragment$8 = \"#define MATCAP\\nuniform vec3 diffuse;\\nuniform float opacity;\\nuniform sampler2D matcap;\\nvarying vec3 vViewPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 viewDir = normalize( vViewPosition );\\n\\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\\n\\tvec3 y = cross( viewDir, x );\\n\\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\\n\\t#ifdef USE_MATCAP\\n\\t\\tvec4 matcapColor = texture2D( matcap, uv );\\n\\t#else\\n\\t\\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\\n\\t#endif\\n\\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$7 = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\";\n\nconst fragment$7 = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n\\t#ifdef OPAQUE\\n\\t\\tgl_FragColor.a = 1.0;\\n\\t#endif\\n}\";\n\nconst vertex$6 = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$6 = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$5 = \"#define STANDARD\\nvarying vec3 vViewPosition;\\n#ifdef USE_TRANSMISSION\\n\\tvarying vec3 vWorldPosition;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n#ifdef USE_TRANSMISSION\\n\\tvWorldPosition = worldPosition.xyz;\\n#endif\\n}\";\n\nconst fragment$5 = \"#define STANDARD\\n#ifdef PHYSICAL\\n\\t#define IOR\\n\\t#define SPECULAR\\n#endif\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifdef IOR\\n\\tuniform float ior;\\n#endif\\n#ifdef SPECULAR\\n\\tuniform float specularIntensity;\\n\\tuniform vec3 specularColor;\\n\\t#ifdef USE_SPECULARINTENSITYMAP\\n\\t\\tuniform sampler2D specularIntensityMap;\\n\\t#endif\\n\\t#ifdef USE_SPECULARCOLORMAP\\n\\t\\tuniform sampler2D specularColorMap;\\n\\t#endif\\n#endif\\n#ifdef USE_CLEARCOAT\\n\\tuniform float clearcoat;\\n\\tuniform float clearcoatRoughness;\\n#endif\\n#ifdef USE_IRIDESCENCE\\n\\tuniform float iridescence;\\n\\tuniform float iridescenceIOR;\\n\\tuniform float iridescenceThicknessMinimum;\\n\\tuniform float iridescenceThicknessMaximum;\\n#endif\\n#ifdef USE_SHEEN\\n\\tuniform vec3 sheenColor;\\n\\tuniform float sheenRoughness;\\n\\t#ifdef USE_SHEENCOLORMAP\\n\\t\\tuniform sampler2D sheenColorMap;\\n\\t#endif\\n\\t#ifdef USE_SHEENROUGHNESSMAP\\n\\t\\tuniform sampler2D sheenRoughnessMap;\\n\\t#endif\\n#endif\\nvarying vec3 vViewPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\\n\\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\\n\\t#include \\n\\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\\n\\t#ifdef USE_SHEEN\\n\\t\\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\\n\\t\\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\\n\\t#endif\\n\\t#ifdef USE_CLEARCOAT\\n\\t\\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\\n\\t\\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\\n\\t\\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$4 = \"#define TOON\\nvarying vec3 vViewPosition;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$4 = \"#define TOON\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$3 = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_PointSize = size;\\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\\n\\t\\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$3 = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$2 = \"#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$2 = \"uniform vec3 color;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst vertex$1 = \"uniform float rotation;\\nuniform vec2 center;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\\n\\tvec2 scale;\\n\\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\\n\\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\\n\\t#ifndef USE_SIZEATTENUATION\\n\\t\\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\\n\\t\\tif ( isPerspective ) scale *= - mvPosition.z;\\n\\t#endif\\n\\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\\n\\tvec2 rotatedPosition;\\n\\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\\n\\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\\n\\tmvPosition.xy += rotatedPosition;\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst fragment$1 = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\";\n\nconst ShaderChunk = {\n\talphamap_fragment: alphamap_fragment,\n\talphamap_pars_fragment: alphamap_pars_fragment,\n\talphatest_fragment: alphatest_fragment,\n\talphatest_pars_fragment: alphatest_pars_fragment,\n\taomap_fragment: aomap_fragment,\n\taomap_pars_fragment: aomap_pars_fragment,\n\tbegin_vertex: begin_vertex,\n\tbeginnormal_vertex: beginnormal_vertex,\n\tbsdfs: bsdfs,\n\tiridescence_fragment: iridescence_fragment,\n\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\tclipping_planes_fragment: clipping_planes_fragment,\n\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\tclipping_planes_vertex: clipping_planes_vertex,\n\tcolor_fragment: color_fragment,\n\tcolor_pars_fragment: color_pars_fragment,\n\tcolor_pars_vertex: color_pars_vertex,\n\tcolor_vertex: color_vertex,\n\tcommon: common,\n\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\tdefaultnormal_vertex: defaultnormal_vertex,\n\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\tdisplacementmap_vertex: displacementmap_vertex,\n\temissivemap_fragment: emissivemap_fragment,\n\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\tencodings_fragment: encodings_fragment,\n\tencodings_pars_fragment: encodings_pars_fragment,\n\tenvmap_fragment: envmap_fragment,\n\tenvmap_common_pars_fragment: envmap_common_pars_fragment,\n\tenvmap_pars_fragment: envmap_pars_fragment,\n\tenvmap_pars_vertex: envmap_pars_vertex,\n\tenvmap_physical_pars_fragment: envmap_physical_pars_fragment,\n\tenvmap_vertex: envmap_vertex,\n\tfog_vertex: fog_vertex,\n\tfog_pars_vertex: fog_pars_vertex,\n\tfog_fragment: fog_fragment,\n\tfog_pars_fragment: fog_pars_fragment,\n\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\tlightmap_fragment: lightmap_fragment,\n\tlightmap_pars_fragment: lightmap_pars_fragment,\n\tlights_lambert_vertex: lights_lambert_vertex,\n\tlights_pars_begin: lights_pars_begin,\n\tlights_toon_fragment: lights_toon_fragment,\n\tlights_toon_pars_fragment: lights_toon_pars_fragment,\n\tlights_phong_fragment: lights_phong_fragment,\n\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\tlights_physical_fragment: lights_physical_fragment,\n\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\tlights_fragment_begin: lights_fragment_begin,\n\tlights_fragment_maps: lights_fragment_maps,\n\tlights_fragment_end: lights_fragment_end,\n\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\tmap_fragment: map_fragment,\n\tmap_pars_fragment: map_pars_fragment,\n\tmap_particle_fragment: map_particle_fragment,\n\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\tmetalnessmap_fragment: metalnessmap_fragment,\n\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\tmorphcolor_vertex: morphcolor_vertex,\n\tmorphnormal_vertex: morphnormal_vertex,\n\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\tmorphtarget_vertex: morphtarget_vertex,\n\tnormal_fragment_begin: normal_fragment_begin,\n\tnormal_fragment_maps: normal_fragment_maps,\n\tnormal_pars_fragment: normal_pars_fragment,\n\tnormal_pars_vertex: normal_pars_vertex,\n\tnormal_vertex: normal_vertex,\n\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\tclearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin,\n\tclearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps,\n\tclearcoat_pars_fragment: clearcoat_pars_fragment,\n\tiridescence_pars_fragment: iridescence_pars_fragment,\n\toutput_fragment: output_fragment,\n\tpacking: packing,\n\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\tproject_vertex: project_vertex,\n\tdithering_fragment: dithering_fragment,\n\tdithering_pars_fragment: dithering_pars_fragment,\n\troughnessmap_fragment: roughnessmap_fragment,\n\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\tshadowmap_vertex: shadowmap_vertex,\n\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\tskinbase_vertex: skinbase_vertex,\n\tskinning_pars_vertex: skinning_pars_vertex,\n\tskinning_vertex: skinning_vertex,\n\tskinnormal_vertex: skinnormal_vertex,\n\tspecularmap_fragment: specularmap_fragment,\n\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\ttonemapping_fragment: tonemapping_fragment,\n\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\ttransmission_fragment: transmission_fragment,\n\ttransmission_pars_fragment: transmission_pars_fragment,\n\tuv_pars_fragment: uv_pars_fragment,\n\tuv_pars_vertex: uv_pars_vertex,\n\tuv_vertex: uv_vertex,\n\tuv2_pars_fragment: uv2_pars_fragment,\n\tuv2_pars_vertex: uv2_pars_vertex,\n\tuv2_vertex: uv2_vertex,\n\tworldpos_vertex: worldpos_vertex,\n\n\tbackground_vert: vertex$g,\n\tbackground_frag: fragment$g,\n\tcube_vert: vertex$f,\n\tcube_frag: fragment$f,\n\tdepth_vert: vertex$e,\n\tdepth_frag: fragment$e,\n\tdistanceRGBA_vert: vertex$d,\n\tdistanceRGBA_frag: fragment$d,\n\tequirect_vert: vertex$c,\n\tequirect_frag: fragment$c,\n\tlinedashed_vert: vertex$b,\n\tlinedashed_frag: fragment$b,\n\tmeshbasic_vert: vertex$a,\n\tmeshbasic_frag: fragment$a,\n\tmeshlambert_vert: vertex$9,\n\tmeshlambert_frag: fragment$9,\n\tmeshmatcap_vert: vertex$8,\n\tmeshmatcap_frag: fragment$8,\n\tmeshnormal_vert: vertex$7,\n\tmeshnormal_frag: fragment$7,\n\tmeshphong_vert: vertex$6,\n\tmeshphong_frag: fragment$6,\n\tmeshphysical_vert: vertex$5,\n\tmeshphysical_frag: fragment$5,\n\tmeshtoon_vert: vertex$4,\n\tmeshtoon_frag: fragment$4,\n\tpoints_vert: vertex$3,\n\tpoints_frag: fragment$3,\n\tshadow_vert: vertex$2,\n\tshadow_frag: fragment$2,\n\tsprite_vert: vertex$1,\n\tsprite_frag: fragment$1\n};\n\n/**\n * Uniforms library for shared webgl shaders\n */\n\nconst UniformsLib = {\n\n\tcommon: {\n\n\t\tdiffuse: { value: new Color( 0xffffff ) },\n\t\topacity: { value: 1.0 },\n\n\t\tmap: { value: null },\n\t\tuvTransform: { value: new Matrix3() },\n\t\tuv2Transform: { value: new Matrix3() },\n\n\t\talphaMap: { value: null },\n\t\talphaTest: { value: 0 }\n\n\t},\n\n\tspecularmap: {\n\n\t\tspecularMap: { value: null },\n\n\t},\n\n\tenvmap: {\n\n\t\tenvMap: { value: null },\n\t\tflipEnvMap: { value: - 1 },\n\t\treflectivity: { value: 1.0 }, // basic, lambert, phong\n\t\tior: { value: 1.5 }, // physical\n\t\trefractionRatio: { value: 0.98 } // basic, lambert, phong\n\n\t},\n\n\taomap: {\n\n\t\taoMap: { value: null },\n\t\taoMapIntensity: { value: 1 }\n\n\t},\n\n\tlightmap: {\n\n\t\tlightMap: { value: null },\n\t\tlightMapIntensity: { value: 1 }\n\n\t},\n\n\temissivemap: {\n\n\t\temissiveMap: { value: null }\n\n\t},\n\n\tbumpmap: {\n\n\t\tbumpMap: { value: null },\n\t\tbumpScale: { value: 1 }\n\n\t},\n\n\tnormalmap: {\n\n\t\tnormalMap: { value: null },\n\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t},\n\n\tdisplacementmap: {\n\n\t\tdisplacementMap: { value: null },\n\t\tdisplacementScale: { value: 1 },\n\t\tdisplacementBias: { value: 0 }\n\n\t},\n\n\troughnessmap: {\n\n\t\troughnessMap: { value: null }\n\n\t},\n\n\tmetalnessmap: {\n\n\t\tmetalnessMap: { value: null }\n\n\t},\n\n\tgradientmap: {\n\n\t\tgradientMap: { value: null }\n\n\t},\n\n\tfog: {\n\n\t\tfogDensity: { value: 0.00025 },\n\t\tfogNear: { value: 1 },\n\t\tfogFar: { value: 2000 },\n\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t},\n\n\tlights: {\n\n\t\tambientLightColor: { value: [] },\n\n\t\tlightProbe: { value: [] },\n\n\t\tdirectionalLights: { value: [], properties: {\n\t\t\tdirection: {},\n\t\t\tcolor: {}\n\t\t} },\n\n\t\tdirectionalLightShadows: { value: [], properties: {\n\t\t\tshadowBias: {},\n\t\t\tshadowNormalBias: {},\n\t\t\tshadowRadius: {},\n\t\t\tshadowMapSize: {}\n\t\t} },\n\n\t\tdirectionalShadowMap: { value: [] },\n\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\tspotLights: { value: [], properties: {\n\t\t\tcolor: {},\n\t\t\tposition: {},\n\t\t\tdirection: {},\n\t\t\tdistance: {},\n\t\t\tconeCos: {},\n\t\t\tpenumbraCos: {},\n\t\t\tdecay: {}\n\t\t} },\n\n\t\tspotLightShadows: { value: [], properties: {\n\t\t\tshadowBias: {},\n\t\t\tshadowNormalBias: {},\n\t\t\tshadowRadius: {},\n\t\t\tshadowMapSize: {}\n\t\t} },\n\n\t\tspotShadowMap: { value: [] },\n\t\tspotShadowMatrix: { value: [] },\n\n\t\tpointLights: { value: [], properties: {\n\t\t\tcolor: {},\n\t\t\tposition: {},\n\t\t\tdecay: {},\n\t\t\tdistance: {}\n\t\t} },\n\n\t\tpointLightShadows: { value: [], properties: {\n\t\t\tshadowBias: {},\n\t\t\tshadowNormalBias: {},\n\t\t\tshadowRadius: {},\n\t\t\tshadowMapSize: {},\n\t\t\tshadowCameraNear: {},\n\t\t\tshadowCameraFar: {}\n\t\t} },\n\n\t\tpointShadowMap: { value: [] },\n\t\tpointShadowMatrix: { value: [] },\n\n\t\themisphereLights: { value: [], properties: {\n\t\t\tdirection: {},\n\t\t\tskyColor: {},\n\t\t\tgroundColor: {}\n\t\t} },\n\n\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\trectAreaLights: { value: [], properties: {\n\t\t\tcolor: {},\n\t\t\tposition: {},\n\t\t\twidth: {},\n\t\t\theight: {}\n\t\t} },\n\n\t\tltc_1: { value: null },\n\t\tltc_2: { value: null }\n\n\t},\n\n\tpoints: {\n\n\t\tdiffuse: { value: new Color( 0xffffff ) },\n\t\topacity: { value: 1.0 },\n\t\tsize: { value: 1.0 },\n\t\tscale: { value: 1.0 },\n\t\tmap: { value: null },\n\t\talphaMap: { value: null },\n\t\talphaTest: { value: 0 },\n\t\tuvTransform: { value: new Matrix3() }\n\n\t},\n\n\tsprite: {\n\n\t\tdiffuse: { value: new Color( 0xffffff ) },\n\t\topacity: { value: 1.0 },\n\t\tcenter: { value: new Vector2( 0.5, 0.5 ) },\n\t\trotation: { value: 0.0 },\n\t\tmap: { value: null },\n\t\talphaMap: { value: null },\n\t\talphaTest: { value: 0 },\n\t\tuvTransform: { value: new Matrix3() }\n\n\t}\n\n};\n\nconst ShaderLib = {\n\n\tbasic: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.specularmap,\n\t\t\tUniformsLib.envmap,\n\t\t\tUniformsLib.aomap,\n\t\t\tUniformsLib.lightmap,\n\t\t\tUniformsLib.fog\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t},\n\n\tlambert: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.specularmap,\n\t\t\tUniformsLib.envmap,\n\t\t\tUniformsLib.aomap,\n\t\t\tUniformsLib.lightmap,\n\t\t\tUniformsLib.emissivemap,\n\t\t\tUniformsLib.fog,\n\t\t\tUniformsLib.lights,\n\t\t\t{\n\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t},\n\n\tphong: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.specularmap,\n\t\t\tUniformsLib.envmap,\n\t\t\tUniformsLib.aomap,\n\t\t\tUniformsLib.lightmap,\n\t\t\tUniformsLib.emissivemap,\n\t\t\tUniformsLib.bumpmap,\n\t\t\tUniformsLib.normalmap,\n\t\t\tUniformsLib.displacementmap,\n\t\t\tUniformsLib.fog,\n\t\t\tUniformsLib.lights,\n\t\t\t{\n\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\tshininess: { value: 30 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t},\n\n\tstandard: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.envmap,\n\t\t\tUniformsLib.aomap,\n\t\t\tUniformsLib.lightmap,\n\t\t\tUniformsLib.emissivemap,\n\t\t\tUniformsLib.bumpmap,\n\t\t\tUniformsLib.normalmap,\n\t\t\tUniformsLib.displacementmap,\n\t\t\tUniformsLib.roughnessmap,\n\t\t\tUniformsLib.metalnessmap,\n\t\t\tUniformsLib.fog,\n\t\t\tUniformsLib.lights,\n\t\t\t{\n\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\troughness: { value: 1.0 },\n\t\t\t\tmetalness: { value: 0.0 },\n\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t},\n\n\ttoon: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.aomap,\n\t\t\tUniformsLib.lightmap,\n\t\t\tUniformsLib.emissivemap,\n\t\t\tUniformsLib.bumpmap,\n\t\t\tUniformsLib.normalmap,\n\t\t\tUniformsLib.displacementmap,\n\t\t\tUniformsLib.gradientmap,\n\t\t\tUniformsLib.fog,\n\t\t\tUniformsLib.lights,\n\t\t\t{\n\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshtoon_vert,\n\t\tfragmentShader: ShaderChunk.meshtoon_frag\n\n\t},\n\n\tmatcap: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.bumpmap,\n\t\t\tUniformsLib.normalmap,\n\t\t\tUniformsLib.displacementmap,\n\t\t\tUniformsLib.fog,\n\t\t\t{\n\t\t\t\tmatcap: { value: null }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshmatcap_vert,\n\t\tfragmentShader: ShaderChunk.meshmatcap_frag\n\n\t},\n\n\tpoints: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.points,\n\t\t\tUniformsLib.fog\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.points_vert,\n\t\tfragmentShader: ShaderChunk.points_frag\n\n\t},\n\n\tdashed: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.fog,\n\t\t\t{\n\t\t\t\tscale: { value: 1 },\n\t\t\t\tdashSize: { value: 1 },\n\t\t\t\ttotalSize: { value: 2 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t},\n\n\tdepth: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.displacementmap\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.depth_vert,\n\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t},\n\n\tnormal: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.bumpmap,\n\t\t\tUniformsLib.normalmap,\n\t\t\tUniformsLib.displacementmap,\n\t\t\t{\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshnormal_vert,\n\t\tfragmentShader: ShaderChunk.meshnormal_frag\n\n\t},\n\n\tsprite: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.sprite,\n\t\t\tUniformsLib.fog\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.sprite_vert,\n\t\tfragmentShader: ShaderChunk.sprite_frag\n\n\t},\n\n\tbackground: {\n\n\t\tuniforms: {\n\t\t\tuvTransform: { value: new Matrix3() },\n\t\t\tt2D: { value: null },\n\t\t},\n\n\t\tvertexShader: ShaderChunk.background_vert,\n\t\tfragmentShader: ShaderChunk.background_frag\n\n\t},\n\t/* -------------------------------------------------------------------------\n\t//\tCube map shader\n\t ------------------------------------------------------------------------- */\n\n\tcube: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.envmap,\n\t\t\t{\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.cube_vert,\n\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t},\n\n\tequirect: {\n\n\t\tuniforms: {\n\t\t\ttEquirect: { value: null },\n\t\t},\n\n\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t},\n\n\tdistanceRGBA: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.common,\n\t\t\tUniformsLib.displacementmap,\n\t\t\t{\n\t\t\t\treferencePosition: { value: new Vector3() },\n\t\t\t\tnearDistance: { value: 1 },\n\t\t\t\tfarDistance: { value: 1000 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t},\n\n\tshadow: {\n\n\t\tuniforms: mergeUniforms( [\n\t\t\tUniformsLib.lights,\n\t\t\tUniformsLib.fog,\n\t\t\t{\n\t\t\t\tcolor: { value: new Color( 0x00000 ) },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.shadow_vert,\n\t\tfragmentShader: ShaderChunk.shadow_frag\n\n\t}\n\n};\n\nShaderLib.physical = {\n\n\tuniforms: mergeUniforms( [\n\t\tShaderLib.standard.uniforms,\n\t\t{\n\t\t\tclearcoat: { value: 0 },\n\t\t\tclearcoatMap: { value: null },\n\t\t\tclearcoatRoughness: { value: 0 },\n\t\t\tclearcoatRoughnessMap: { value: null },\n\t\t\tclearcoatNormalScale: { value: new Vector2( 1, 1 ) },\n\t\t\tclearcoatNormalMap: { value: null },\n\t\t\tiridescence: { value: 0 },\n\t\t\tiridescenceMap: { value: null },\n\t\t\tiridescenceIOR: { value: 1.3 },\n\t\t\tiridescenceThicknessMinimum: { value: 100 },\n\t\t\tiridescenceThicknessMaximum: { value: 400 },\n\t\t\tiridescenceThicknessMap: { value: null },\n\t\t\tsheen: { value: 0 },\n\t\t\tsheenColor: { value: new Color( 0x000000 ) },\n\t\t\tsheenColorMap: { value: null },\n\t\t\tsheenRoughness: { value: 1 },\n\t\t\tsheenRoughnessMap: { value: null },\n\t\t\ttransmission: { value: 0 },\n\t\t\ttransmissionMap: { value: null },\n\t\t\ttransmissionSamplerSize: { value: new Vector2() },\n\t\t\ttransmissionSamplerMap: { value: null },\n\t\t\tthickness: { value: 0 },\n\t\t\tthicknessMap: { value: null },\n\t\t\tattenuationDistance: { value: 0 },\n\t\t\tattenuationColor: { value: new Color( 0x000000 ) },\n\t\t\tspecularIntensity: { value: 1 },\n\t\t\tspecularIntensityMap: { value: null },\n\t\t\tspecularColor: { value: new Color( 1, 1, 1 ) },\n\t\t\tspecularColorMap: { value: null },\n\t\t}\n\t] ),\n\n\tvertexShader: ShaderChunk.meshphysical_vert,\n\tfragmentShader: ShaderChunk.meshphysical_frag\n\n};\n\nfunction WebGLBackground( renderer, cubemaps, state, objects, alpha, premultipliedAlpha ) {\n\n\tconst clearColor = new Color( 0x000000 );\n\tlet clearAlpha = alpha === true ? 0 : 1;\n\n\tlet planeMesh;\n\tlet boxMesh;\n\n\tlet currentBackground = null;\n\tlet currentBackgroundVersion = 0;\n\tlet currentTonemapping = null;\n\n\tfunction render( renderList, scene ) {\n\n\t\tlet forceClear = false;\n\t\tlet background = scene.isScene === true ? scene.background : null;\n\n\t\tif ( background && background.isTexture ) {\n\n\t\t\tbackground = cubemaps.get( background );\n\n\t\t}\n\n\t\t// Ignore background in AR\n\t\t// TODO: Reconsider this.\n\n\t\tconst xr = renderer.xr;\n\t\tconst session = xr.getSession && xr.getSession();\n\n\t\tif ( session && session.environmentBlendMode === 'additive' ) {\n\n\t\t\tbackground = null;\n\n\t\t}\n\n\t\tif ( background === null ) {\n\n\t\t\tsetClear( clearColor, clearAlpha );\n\n\t\t} else if ( background && background.isColor ) {\n\n\t\t\tsetClear( background, 1 );\n\t\t\tforceClear = true;\n\n\t\t}\n\n\t\tif ( renderer.autoClear || forceClear ) {\n\n\t\t\trenderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );\n\n\t\t}\n\n\t\tif ( background && ( background.isCubeTexture || background.mapping === CubeUVReflectionMapping ) ) {\n\n\t\t\tif ( boxMesh === undefined ) {\n\n\t\t\t\tboxMesh = new Mesh(\n\t\t\t\t\tnew BoxGeometry( 1, 1, 1 ),\n\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\tname: 'BackgroundCubeMaterial',\n\t\t\t\t\t\tuniforms: cloneUniforms( ShaderLib.cube.uniforms ),\n\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\tfog: false\n\t\t\t\t\t} )\n\t\t\t\t);\n\n\t\t\t\tboxMesh.geometry.deleteAttribute( 'normal' );\n\t\t\t\tboxMesh.geometry.deleteAttribute( 'uv' );\n\n\t\t\t\tboxMesh.onBeforeRender = function ( renderer, scene, camera ) {\n\n\t\t\t\t\tthis.matrixWorld.copyPosition( camera.matrixWorld );\n\n\t\t\t\t};\n\n\t\t\t\t// enable code injection for non-built-in material\n\t\t\t\tObject.defineProperty( boxMesh.material, 'envMap', {\n\n\t\t\t\t\tget: function () {\n\n\t\t\t\t\t\treturn this.uniforms.envMap.value;\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\tobjects.update( boxMesh );\n\n\t\t\t}\n\n\t\t\tboxMesh.material.uniforms.envMap.value = background;\n\t\t\tboxMesh.material.uniforms.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? - 1 : 1;\n\n\t\t\tif ( currentBackground !== background ||\n\t\t\t\tcurrentBackgroundVersion !== background.version ||\n\t\t\t\tcurrentTonemapping !== renderer.toneMapping ) {\n\n\t\t\t\tboxMesh.material.needsUpdate = true;\n\n\t\t\t\tcurrentBackground = background;\n\t\t\t\tcurrentBackgroundVersion = background.version;\n\t\t\t\tcurrentTonemapping = renderer.toneMapping;\n\n\t\t\t}\n\n\t\t\tboxMesh.layers.enableAll();\n\n\t\t\t// push to the pre-sorted opaque render list\n\t\t\trenderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );\n\n\t\t} else if ( background && background.isTexture ) {\n\n\t\t\tif ( planeMesh === undefined ) {\n\n\t\t\t\tplaneMesh = new Mesh(\n\t\t\t\t\tnew PlaneGeometry( 2, 2 ),\n\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\tname: 'BackgroundMaterial',\n\t\t\t\t\t\tuniforms: cloneUniforms( ShaderLib.background.uniforms ),\n\t\t\t\t\t\tvertexShader: ShaderLib.background.vertexShader,\n\t\t\t\t\t\tfragmentShader: ShaderLib.background.fragmentShader,\n\t\t\t\t\t\tside: FrontSide,\n\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\tfog: false\n\t\t\t\t\t} )\n\t\t\t\t);\n\n\t\t\t\tplaneMesh.geometry.deleteAttribute( 'normal' );\n\n\t\t\t\t// enable code injection for non-built-in material\n\t\t\t\tObject.defineProperty( planeMesh.material, 'map', {\n\n\t\t\t\t\tget: function () {\n\n\t\t\t\t\t\treturn this.uniforms.t2D.value;\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\tobjects.update( planeMesh );\n\n\t\t\t}\n\n\t\t\tplaneMesh.material.uniforms.t2D.value = background;\n\n\t\t\tif ( background.matrixAutoUpdate === true ) {\n\n\t\t\t\tbackground.updateMatrix();\n\n\t\t\t}\n\n\t\t\tplaneMesh.material.uniforms.uvTransform.value.copy( background.matrix );\n\n\t\t\tif ( currentBackground !== background ||\n\t\t\t\tcurrentBackgroundVersion !== background.version ||\n\t\t\t\tcurrentTonemapping !== renderer.toneMapping ) {\n\n\t\t\t\tplaneMesh.material.needsUpdate = true;\n\n\t\t\t\tcurrentBackground = background;\n\t\t\t\tcurrentBackgroundVersion = background.version;\n\t\t\t\tcurrentTonemapping = renderer.toneMapping;\n\n\t\t\t}\n\n\t\t\tplaneMesh.layers.enableAll();\n\n\t\t\t// push to the pre-sorted opaque render list\n\t\t\trenderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );\n\n\t\t}\n\n\t}\n\n\tfunction setClear( color, alpha ) {\n\n\t\tstate.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );\n\n\t}\n\n\treturn {\n\n\t\tgetClearColor: function () {\n\n\t\t\treturn clearColor;\n\n\t\t},\n\t\tsetClearColor: function ( color, alpha = 1 ) {\n\n\t\t\tclearColor.set( color );\n\t\t\tclearAlpha = alpha;\n\t\t\tsetClear( clearColor, clearAlpha );\n\n\t\t},\n\t\tgetClearAlpha: function () {\n\n\t\t\treturn clearAlpha;\n\n\t\t},\n\t\tsetClearAlpha: function ( alpha ) {\n\n\t\t\tclearAlpha = alpha;\n\t\t\tsetClear( clearColor, clearAlpha );\n\n\t\t},\n\t\trender: render\n\n\t};\n\n}\n\nfunction WebGLBindingStates( gl, extensions, attributes, capabilities ) {\n\n\tconst maxVertexAttributes = gl.getParameter( 34921 );\n\n\tconst extension = capabilities.isWebGL2 ? null : extensions.get( 'OES_vertex_array_object' );\n\tconst vaoAvailable = capabilities.isWebGL2 || extension !== null;\n\n\tconst bindingStates = {};\n\n\tconst defaultState = createBindingState( null );\n\tlet currentState = defaultState;\n\tlet forceUpdate = false;\n\n\tfunction setup( object, material, program, geometry, index ) {\n\n\t\tlet updateBuffers = false;\n\n\t\tif ( vaoAvailable ) {\n\n\t\t\tconst state = getBindingState( geometry, program, material );\n\n\t\t\tif ( currentState !== state ) {\n\n\t\t\t\tcurrentState = state;\n\t\t\t\tbindVertexArrayObject( currentState.object );\n\n\t\t\t}\n\n\t\t\tupdateBuffers = needsUpdate( object, geometry, program, index );\n\n\t\t\tif ( updateBuffers ) saveCache( object, geometry, program, index );\n\n\t\t} else {\n\n\t\t\tconst wireframe = ( material.wireframe === true );\n\n\t\t\tif ( currentState.geometry !== geometry.id ||\n\t\t\t\tcurrentState.program !== program.id ||\n\t\t\t\tcurrentState.wireframe !== wireframe ) {\n\n\t\t\t\tcurrentState.geometry = geometry.id;\n\t\t\t\tcurrentState.program = program.id;\n\t\t\t\tcurrentState.wireframe = wireframe;\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( index !== null ) {\n\n\t\t\tattributes.update( index, 34963 );\n\n\t\t}\n\n\t\tif ( updateBuffers || forceUpdate ) {\n\n\t\t\tforceUpdate = false;\n\n\t\t\tsetupVertexAttributes( object, material, program, geometry );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tgl.bindBuffer( 34963, attributes.get( index ).buffer );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction createVertexArrayObject() {\n\n\t\tif ( capabilities.isWebGL2 ) return gl.createVertexArray();\n\n\t\treturn extension.createVertexArrayOES();\n\n\t}\n\n\tfunction bindVertexArrayObject( vao ) {\n\n\t\tif ( capabilities.isWebGL2 ) return gl.bindVertexArray( vao );\n\n\t\treturn extension.bindVertexArrayOES( vao );\n\n\t}\n\n\tfunction deleteVertexArrayObject( vao ) {\n\n\t\tif ( capabilities.isWebGL2 ) return gl.deleteVertexArray( vao );\n\n\t\treturn extension.deleteVertexArrayOES( vao );\n\n\t}\n\n\tfunction getBindingState( geometry, program, material ) {\n\n\t\tconst wireframe = ( material.wireframe === true );\n\n\t\tlet programMap = bindingStates[ geometry.id ];\n\n\t\tif ( programMap === undefined ) {\n\n\t\t\tprogramMap = {};\n\t\t\tbindingStates[ geometry.id ] = programMap;\n\n\t\t}\n\n\t\tlet stateMap = programMap[ program.id ];\n\n\t\tif ( stateMap === undefined ) {\n\n\t\t\tstateMap = {};\n\t\t\tprogramMap[ program.id ] = stateMap;\n\n\t\t}\n\n\t\tlet state = stateMap[ wireframe ];\n\n\t\tif ( state === undefined ) {\n\n\t\t\tstate = createBindingState( createVertexArrayObject() );\n\t\t\tstateMap[ wireframe ] = state;\n\n\t\t}\n\n\t\treturn state;\n\n\t}\n\n\tfunction createBindingState( vao ) {\n\n\t\tconst newAttributes = [];\n\t\tconst enabledAttributes = [];\n\t\tconst attributeDivisors = [];\n\n\t\tfor ( let i = 0; i < maxVertexAttributes; i ++ ) {\n\n\t\t\tnewAttributes[ i ] = 0;\n\t\t\tenabledAttributes[ i ] = 0;\n\t\t\tattributeDivisors[ i ] = 0;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\t// for backward compatibility on non-VAO support browser\n\t\t\tgeometry: null,\n\t\t\tprogram: null,\n\t\t\twireframe: false,\n\n\t\t\tnewAttributes: newAttributes,\n\t\t\tenabledAttributes: enabledAttributes,\n\t\t\tattributeDivisors: attributeDivisors,\n\t\t\tobject: vao,\n\t\t\tattributes: {},\n\t\t\tindex: null\n\n\t\t};\n\n\t}\n\n\tfunction needsUpdate( object, geometry, program, index ) {\n\n\t\tconst cachedAttributes = currentState.attributes;\n\t\tconst geometryAttributes = geometry.attributes;\n\n\t\tlet attributesNum = 0;\n\n\t\tconst programAttributes = program.getAttributes();\n\n\t\tfor ( const name in programAttributes ) {\n\n\t\t\tconst programAttribute = programAttributes[ name ];\n\n\t\t\tif ( programAttribute.location >= 0 ) {\n\n\t\t\t\tconst cachedAttribute = cachedAttributes[ name ];\n\t\t\t\tlet geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\tif ( geometryAttribute === undefined ) {\n\n\t\t\t\t\tif ( name === 'instanceMatrix' && object.instanceMatrix ) geometryAttribute = object.instanceMatrix;\n\t\t\t\t\tif ( name === 'instanceColor' && object.instanceColor ) geometryAttribute = object.instanceColor;\n\n\t\t\t\t}\n\n\t\t\t\tif ( cachedAttribute === undefined ) return true;\n\n\t\t\t\tif ( cachedAttribute.attribute !== geometryAttribute ) return true;\n\n\t\t\t\tif ( geometryAttribute && cachedAttribute.data !== geometryAttribute.data ) return true;\n\n\t\t\t\tattributesNum ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( currentState.attributesNum !== attributesNum ) return true;\n\n\t\tif ( currentState.index !== index ) return true;\n\n\t\treturn false;\n\n\t}\n\n\tfunction saveCache( object, geometry, program, index ) {\n\n\t\tconst cache = {};\n\t\tconst attributes = geometry.attributes;\n\t\tlet attributesNum = 0;\n\n\t\tconst programAttributes = program.getAttributes();\n\n\t\tfor ( const name in programAttributes ) {\n\n\t\t\tconst programAttribute = programAttributes[ name ];\n\n\t\t\tif ( programAttribute.location >= 0 ) {\n\n\t\t\t\tlet attribute = attributes[ name ];\n\n\t\t\t\tif ( attribute === undefined ) {\n\n\t\t\t\t\tif ( name === 'instanceMatrix' && object.instanceMatrix ) attribute = object.instanceMatrix;\n\t\t\t\t\tif ( name === 'instanceColor' && object.instanceColor ) attribute = object.instanceColor;\n\n\t\t\t\t}\n\n\t\t\t\tconst data = {};\n\t\t\t\tdata.attribute = attribute;\n\n\t\t\t\tif ( attribute && attribute.data ) {\n\n\t\t\t\t\tdata.data = attribute.data;\n\n\t\t\t\t}\n\n\t\t\t\tcache[ name ] = data;\n\n\t\t\t\tattributesNum ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\tcurrentState.attributes = cache;\n\t\tcurrentState.attributesNum = attributesNum;\n\n\t\tcurrentState.index = index;\n\n\t}\n\n\tfunction initAttributes() {\n\n\t\tconst newAttributes = currentState.newAttributes;\n\n\t\tfor ( let i = 0, il = newAttributes.length; i < il; i ++ ) {\n\n\t\t\tnewAttributes[ i ] = 0;\n\n\t\t}\n\n\t}\n\n\tfunction enableAttribute( attribute ) {\n\n\t\tenableAttributeAndDivisor( attribute, 0 );\n\n\t}\n\n\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute ) {\n\n\t\tconst newAttributes = currentState.newAttributes;\n\t\tconst enabledAttributes = currentState.enabledAttributes;\n\t\tconst attributeDivisors = currentState.attributeDivisors;\n\n\t\tnewAttributes[ attribute ] = 1;\n\n\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t}\n\n\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\tconst extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\textension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute );\n\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t}\n\n\t}\n\n\tfunction disableUnusedAttributes() {\n\n\t\tconst newAttributes = currentState.newAttributes;\n\t\tconst enabledAttributes = currentState.enabledAttributes;\n\n\t\tfor ( let i = 0, il = enabledAttributes.length; i < il; i ++ ) {\n\n\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction vertexAttribPointer( index, size, type, normalized, stride, offset ) {\n\n\t\tif ( capabilities.isWebGL2 === true && ( type === 5124 || type === 5125 ) ) {\n\n\t\t\tgl.vertexAttribIPointer( index, size, type, stride, offset );\n\n\t\t} else {\n\n\t\t\tgl.vertexAttribPointer( index, size, type, normalized, stride, offset );\n\n\t\t}\n\n\t}\n\n\tfunction setupVertexAttributes( object, material, program, geometry ) {\n\n\t\tif ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) {\n\n\t\t\tif ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) return;\n\n\t\t}\n\n\t\tinitAttributes();\n\n\t\tconst geometryAttributes = geometry.attributes;\n\n\t\tconst programAttributes = program.getAttributes();\n\n\t\tconst materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\tfor ( const name in programAttributes ) {\n\n\t\t\tconst programAttribute = programAttributes[ name ];\n\n\t\t\tif ( programAttribute.location >= 0 ) {\n\n\t\t\t\tlet geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\tif ( geometryAttribute === undefined ) {\n\n\t\t\t\t\tif ( name === 'instanceMatrix' && object.instanceMatrix ) geometryAttribute = object.instanceMatrix;\n\t\t\t\t\tif ( name === 'instanceColor' && object.instanceColor ) geometryAttribute = object.instanceColor;\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\tconst normalized = geometryAttribute.normalized;\n\t\t\t\t\tconst size = geometryAttribute.itemSize;\n\n\t\t\t\t\tconst attribute = attributes.get( geometryAttribute );\n\n\t\t\t\t\t// TODO Attribute may not be available on context restore\n\n\t\t\t\t\tif ( attribute === undefined ) continue;\n\n\t\t\t\t\tconst buffer = attribute.buffer;\n\t\t\t\t\tconst type = attribute.type;\n\t\t\t\t\tconst bytesPerElement = attribute.bytesPerElement;\n\n\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\tconst data = geometryAttribute.data;\n\t\t\t\t\t\tconst stride = data.stride;\n\t\t\t\t\t\tconst offset = geometryAttribute.offset;\n\n\t\t\t\t\t\tif ( data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\tfor ( let i = 0; i < programAttribute.locationSize; i ++ ) {\n\n\t\t\t\t\t\t\t\tenableAttributeAndDivisor( programAttribute.location + i, data.meshPerAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) {\n\n\t\t\t\t\t\t\t\tgeometry._maxInstanceCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tfor ( let i = 0; i < programAttribute.locationSize; i ++ ) {\n\n\t\t\t\t\t\t\t\tenableAttribute( programAttribute.location + i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgl.bindBuffer( 34962, buffer );\n\n\t\t\t\t\t\tfor ( let i = 0; i < programAttribute.locationSize; i ++ ) {\n\n\t\t\t\t\t\t\tvertexAttribPointer(\n\t\t\t\t\t\t\t\tprogramAttribute.location + i,\n\t\t\t\t\t\t\t\tsize / programAttribute.locationSize,\n\t\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\t\tnormalized,\n\t\t\t\t\t\t\t\tstride * bytesPerElement,\n\t\t\t\t\t\t\t\t( offset + ( size / programAttribute.locationSize ) * i ) * bytesPerElement\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\tfor ( let i = 0; i < programAttribute.locationSize; i ++ ) {\n\n\t\t\t\t\t\t\t\tenableAttributeAndDivisor( programAttribute.location + i, geometryAttribute.meshPerAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) {\n\n\t\t\t\t\t\t\t\tgeometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tfor ( let i = 0; i < programAttribute.locationSize; i ++ ) {\n\n\t\t\t\t\t\t\t\tenableAttribute( programAttribute.location + i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgl.bindBuffer( 34962, buffer );\n\n\t\t\t\t\t\tfor ( let i = 0; i < programAttribute.locationSize; i ++ ) {\n\n\t\t\t\t\t\t\tvertexAttribPointer(\n\t\t\t\t\t\t\t\tprogramAttribute.location + i,\n\t\t\t\t\t\t\t\tsize / programAttribute.locationSize,\n\t\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\t\tnormalized,\n\t\t\t\t\t\t\t\tsize * bytesPerElement,\n\t\t\t\t\t\t\t\t( size / programAttribute.locationSize ) * i * bytesPerElement\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\tconst value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\tgl.vertexAttrib2fv( programAttribute.location, value );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\tgl.vertexAttrib3fv( programAttribute.location, value );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\tgl.vertexAttrib4fv( programAttribute.location, value );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tgl.vertexAttrib1fv( programAttribute.location, value );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tdisableUnusedAttributes();\n\n\t}\n\n\tfunction dispose() {\n\n\t\treset();\n\n\t\tfor ( const geometryId in bindingStates ) {\n\n\t\t\tconst programMap = bindingStates[ geometryId ];\n\n\t\t\tfor ( const programId in programMap ) {\n\n\t\t\t\tconst stateMap = programMap[ programId ];\n\n\t\t\t\tfor ( const wireframe in stateMap ) {\n\n\t\t\t\t\tdeleteVertexArrayObject( stateMap[ wireframe ].object );\n\n\t\t\t\t\tdelete stateMap[ wireframe ];\n\n\t\t\t\t}\n\n\t\t\t\tdelete programMap[ programId ];\n\n\t\t\t}\n\n\t\t\tdelete bindingStates[ geometryId ];\n\n\t\t}\n\n\t}\n\n\tfunction releaseStatesOfGeometry( geometry ) {\n\n\t\tif ( bindingStates[ geometry.id ] === undefined ) return;\n\n\t\tconst programMap = bindingStates[ geometry.id ];\n\n\t\tfor ( const programId in programMap ) {\n\n\t\t\tconst stateMap = programMap[ programId ];\n\n\t\t\tfor ( const wireframe in stateMap ) {\n\n\t\t\t\tdeleteVertexArrayObject( stateMap[ wireframe ].object );\n\n\t\t\t\tdelete stateMap[ wireframe ];\n\n\t\t\t}\n\n\t\t\tdelete programMap[ programId ];\n\n\t\t}\n\n\t\tdelete bindingStates[ geometry.id ];\n\n\t}\n\n\tfunction releaseStatesOfProgram( program ) {\n\n\t\tfor ( const geometryId in bindingStates ) {\n\n\t\t\tconst programMap = bindingStates[ geometryId ];\n\n\t\t\tif ( programMap[ program.id ] === undefined ) continue;\n\n\t\t\tconst stateMap = programMap[ program.id ];\n\n\t\t\tfor ( const wireframe in stateMap ) {\n\n\t\t\t\tdeleteVertexArrayObject( stateMap[ wireframe ].object );\n\n\t\t\t\tdelete stateMap[ wireframe ];\n\n\t\t\t}\n\n\t\t\tdelete programMap[ program.id ];\n\n\t\t}\n\n\t}\n\n\tfunction reset() {\n\n\t\tresetDefaultState();\n\t\tforceUpdate = true;\n\n\t\tif ( currentState === defaultState ) return;\n\n\t\tcurrentState = defaultState;\n\t\tbindVertexArrayObject( currentState.object );\n\n\t}\n\n\t// for backward-compatibility\n\n\tfunction resetDefaultState() {\n\n\t\tdefaultState.geometry = null;\n\t\tdefaultState.program = null;\n\t\tdefaultState.wireframe = false;\n\n\t}\n\n\treturn {\n\n\t\tsetup: setup,\n\t\treset: reset,\n\t\tresetDefaultState: resetDefaultState,\n\t\tdispose: dispose,\n\t\treleaseStatesOfGeometry: releaseStatesOfGeometry,\n\t\treleaseStatesOfProgram: releaseStatesOfProgram,\n\n\t\tinitAttributes: initAttributes,\n\t\tenableAttribute: enableAttribute,\n\t\tdisableUnusedAttributes: disableUnusedAttributes\n\n\t};\n\n}\n\nfunction WebGLBufferRenderer( gl, extensions, info, capabilities ) {\n\n\tconst isWebGL2 = capabilities.isWebGL2;\n\n\tlet mode;\n\n\tfunction setMode( value ) {\n\n\t\tmode = value;\n\n\t}\n\n\tfunction render( start, count ) {\n\n\t\tgl.drawArrays( mode, start, count );\n\n\t\tinfo.update( count, mode, 1 );\n\n\t}\n\n\tfunction renderInstances( start, count, primcount ) {\n\n\t\tif ( primcount === 0 ) return;\n\n\t\tlet extension, methodName;\n\n\t\tif ( isWebGL2 ) {\n\n\t\t\textension = gl;\n\t\t\tmethodName = 'drawArraysInstanced';\n\n\t\t} else {\n\n\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\t\t\tmethodName = 'drawArraysInstancedANGLE';\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t}\n\n\t\textension[ methodName ]( mode, start, count, primcount );\n\n\t\tinfo.update( count, mode, primcount );\n\n\t}\n\n\t//\n\n\tthis.setMode = setMode;\n\tthis.render = render;\n\tthis.renderInstances = renderInstances;\n\n}\n\nfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\tlet maxAnisotropy;\n\n\tfunction getMaxAnisotropy() {\n\n\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\tif ( extensions.has( 'EXT_texture_filter_anisotropic' ) === true ) {\n\n\t\t\tconst extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t} else {\n\n\t\t\tmaxAnisotropy = 0;\n\n\t\t}\n\n\t\treturn maxAnisotropy;\n\n\t}\n\n\tfunction getMaxPrecision( precision ) {\n\n\t\tif ( precision === 'highp' ) {\n\n\t\t\tif ( gl.getShaderPrecisionFormat( 35633, 36338 ).precision > 0 &&\n\t\t\t\tgl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) {\n\n\t\t\t\treturn 'highp';\n\n\t\t\t}\n\n\t\t\tprecision = 'mediump';\n\n\t\t}\n\n\t\tif ( precision === 'mediump' ) {\n\n\t\t\tif ( gl.getShaderPrecisionFormat( 35633, 36337 ).precision > 0 &&\n\t\t\t\tgl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) {\n\n\t\t\t\treturn 'mediump';\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn 'lowp';\n\n\t}\n\n\tconst isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) ||\n\t\t( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext );\n\n\tlet precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\tconst maxPrecision = getMaxPrecision( precision );\n\n\tif ( maxPrecision !== precision ) {\n\n\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\tprecision = maxPrecision;\n\n\t}\n\n\tconst drawBuffers = isWebGL2 || extensions.has( 'WEBGL_draw_buffers' );\n\n\tconst logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;\n\n\tconst maxTextures = gl.getParameter( 34930 );\n\tconst maxVertexTextures = gl.getParameter( 35660 );\n\tconst maxTextureSize = gl.getParameter( 3379 );\n\tconst maxCubemapSize = gl.getParameter( 34076 );\n\n\tconst maxAttributes = gl.getParameter( 34921 );\n\tconst maxVertexUniforms = gl.getParameter( 36347 );\n\tconst maxVaryings = gl.getParameter( 36348 );\n\tconst maxFragmentUniforms = gl.getParameter( 36349 );\n\n\tconst vertexTextures = maxVertexTextures > 0;\n\tconst floatFragmentTextures = isWebGL2 || extensions.has( 'OES_texture_float' );\n\tconst floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\tconst maxSamples = isWebGL2 ? gl.getParameter( 36183 ) : 0;\n\n\treturn {\n\n\t\tisWebGL2: isWebGL2,\n\n\t\tdrawBuffers: drawBuffers,\n\n\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\tprecision: precision,\n\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\tmaxTextures: maxTextures,\n\t\tmaxVertexTextures: maxVertexTextures,\n\t\tmaxTextureSize: maxTextureSize,\n\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\tmaxAttributes: maxAttributes,\n\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\tmaxVaryings: maxVaryings,\n\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\tvertexTextures: vertexTextures,\n\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\tfloatVertexTextures: floatVertexTextures,\n\n\t\tmaxSamples: maxSamples\n\n\t};\n\n}\n\nfunction WebGLClipping( properties ) {\n\n\tconst scope = this;\n\n\tlet globalState = null,\n\t\tnumGlobalPlanes = 0,\n\t\tlocalClippingEnabled = false,\n\t\trenderingShadows = false;\n\n\tconst plane = new Plane(),\n\t\tviewNormalMatrix = new Matrix3(),\n\n\t\tuniform = { value: null, needsUpdate: false };\n\n\tthis.uniform = uniform;\n\tthis.numPlanes = 0;\n\tthis.numIntersection = 0;\n\n\tthis.init = function ( planes, enableLocalClipping, camera ) {\n\n\t\tconst enabled =\n\t\t\tplanes.length !== 0 ||\n\t\t\tenableLocalClipping ||\n\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t// run another frame in order to reset the state:\n\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\tlocalClippingEnabled;\n\n\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\tnumGlobalPlanes = planes.length;\n\n\t\treturn enabled;\n\n\t};\n\n\tthis.beginShadows = function () {\n\n\t\trenderingShadows = true;\n\t\tprojectPlanes( null );\n\n\t};\n\n\tthis.endShadows = function () {\n\n\t\trenderingShadows = false;\n\t\tresetGlobalState();\n\n\t};\n\n\tthis.setState = function ( material, camera, useCache ) {\n\n\t\tconst planes = material.clippingPlanes,\n\t\t\tclipIntersection = material.clipIntersection,\n\t\t\tclipShadows = material.clipShadows;\n\n\t\tconst materialProperties = properties.get( material );\n\n\t\tif ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) {\n\n\t\t\t// there's no local clipping\n\n\t\t\tif ( renderingShadows ) {\n\n\t\t\t\t// there's no global clipping\n\n\t\t\t\tprojectPlanes( null );\n\n\t\t\t} else {\n\n\t\t\t\tresetGlobalState();\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\tlGlobal = nGlobal * 4;\n\n\t\t\tlet dstArray = materialProperties.clippingState || null;\n\n\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, useCache );\n\n\t\t\tfor ( let i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t}\n\n\t\t\tmaterialProperties.clippingState = dstArray;\n\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\tthis.numPlanes += nGlobal;\n\n\t\t}\n\n\n\t};\n\n\tfunction resetGlobalState() {\n\n\t\tif ( uniform.value !== globalState ) {\n\n\t\t\tuniform.value = globalState;\n\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t}\n\n\t\tscope.numPlanes = numGlobalPlanes;\n\t\tscope.numIntersection = 0;\n\n\t}\n\n\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\tconst nPlanes = planes !== null ? planes.length : 0;\n\t\tlet dstArray = null;\n\n\t\tif ( nPlanes !== 0 ) {\n\n\t\t\tdstArray = uniform.value;\n\n\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\tconst flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\tplane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tuniform.value = dstArray;\n\t\t\tuniform.needsUpdate = true;\n\n\t\t}\n\n\t\tscope.numPlanes = nPlanes;\n\t\tscope.numIntersection = 0;\n\n\t\treturn dstArray;\n\n\t}\n\n}\n\nfunction WebGLCubeMaps( renderer ) {\n\n\tlet cubemaps = new WeakMap();\n\n\tfunction mapTextureMapping( texture, mapping ) {\n\n\t\tif ( mapping === EquirectangularReflectionMapping ) {\n\n\t\t\ttexture.mapping = CubeReflectionMapping;\n\n\t\t} else if ( mapping === EquirectangularRefractionMapping ) {\n\n\t\t\ttexture.mapping = CubeRefractionMapping;\n\n\t\t}\n\n\t\treturn texture;\n\n\t}\n\n\tfunction get( texture ) {\n\n\t\tif ( texture && texture.isTexture && texture.isRenderTargetTexture === false ) {\n\n\t\t\tconst mapping = texture.mapping;\n\n\t\t\tif ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ) {\n\n\t\t\t\tif ( cubemaps.has( texture ) ) {\n\n\t\t\t\t\tconst cubemap = cubemaps.get( texture ).texture;\n\t\t\t\t\treturn mapTextureMapping( cubemap, texture.mapping );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst image = texture.image;\n\n\t\t\t\t\tif ( image && image.height > 0 ) {\n\n\t\t\t\t\t\tconst renderTarget = new WebGLCubeRenderTarget( image.height / 2 );\n\t\t\t\t\t\trenderTarget.fromEquirectangularTexture( renderer, texture );\n\t\t\t\t\t\tcubemaps.set( texture, renderTarget );\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\treturn mapTextureMapping( renderTarget.texture, texture.mapping );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// image not yet ready. try the conversion next frame\n\n\t\t\t\t\t\treturn null;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn texture;\n\n\t}\n\n\tfunction onTextureDispose( event ) {\n\n\t\tconst texture = event.target;\n\n\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\tconst cubemap = cubemaps.get( texture );\n\n\t\tif ( cubemap !== undefined ) {\n\n\t\t\tcubemaps.delete( texture );\n\t\t\tcubemap.dispose();\n\n\t\t}\n\n\t}\n\n\tfunction dispose() {\n\n\t\tcubemaps = new WeakMap();\n\n\t}\n\n\treturn {\n\t\tget: get,\n\t\tdispose: dispose\n\t};\n\n}\n\nclass OrthographicCamera extends Camera {\n\n\tconstructor( left = - 1, right = 1, top = 1, bottom = - 1, near = 0.1, far = 2000 ) {\n\n\t\tsuper();\n\n\t\tthis.isOrthographicCamera = true;\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = near;\n\t\tthis.far = far;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.left = source.left;\n\t\tthis.right = source.right;\n\t\tthis.top = source.top;\n\t\tthis.bottom = source.bottom;\n\t\tthis.near = source.near;\n\t\tthis.far = source.far;\n\n\t\tthis.zoom = source.zoom;\n\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\treturn this;\n\n\t}\n\n\tsetViewOffset( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\tif ( this.view === null ) {\n\n\t\t\tthis.view = {\n\t\t\t\tenabled: true,\n\t\t\t\tfullWidth: 1,\n\t\t\t\tfullHeight: 1,\n\t\t\t\toffsetX: 0,\n\t\t\t\toffsetY: 0,\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1\n\t\t\t};\n\n\t\t}\n\n\t\tthis.view.enabled = true;\n\t\tthis.view.fullWidth = fullWidth;\n\t\tthis.view.fullHeight = fullHeight;\n\t\tthis.view.offsetX = x;\n\t\tthis.view.offsetY = y;\n\t\tthis.view.width = width;\n\t\tthis.view.height = height;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tclearViewOffset() {\n\n\t\tif ( this.view !== null ) {\n\n\t\t\tthis.view.enabled = false;\n\n\t\t}\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tupdateProjectionMatrix() {\n\n\t\tconst dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\tconst dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\tconst cx = ( this.right + this.left ) / 2;\n\t\tconst cy = ( this.top + this.bottom ) / 2;\n\n\t\tlet left = cx - dx;\n\t\tlet right = cx + dx;\n\t\tlet top = cy + dy;\n\t\tlet bottom = cy - dy;\n\n\t\tif ( this.view !== null && this.view.enabled ) {\n\n\t\t\tconst scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom;\n\t\t\tconst scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom;\n\n\t\t\tleft += scaleW * this.view.offsetX;\n\t\t\tright = left + scaleW * this.view.width;\n\t\t\ttop -= scaleH * this.view.offsetY;\n\t\t\tbottom = top - scaleH * this.view.height;\n\n\t\t}\n\n\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\tthis.projectionMatrixInverse.copy( this.projectionMatrix ).invert();\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tdata.object.zoom = this.zoom;\n\t\tdata.object.left = this.left;\n\t\tdata.object.right = this.right;\n\t\tdata.object.top = this.top;\n\t\tdata.object.bottom = this.bottom;\n\t\tdata.object.near = this.near;\n\t\tdata.object.far = this.far;\n\n\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\treturn data;\n\n\t}\n\n}\n\nconst LOD_MIN = 4;\n\n// The standard deviations (radians) associated with the extra mips. These are\n// chosen to approximate a Trowbridge-Reitz distribution function times the\n// geometric shadowing function. These sigma values squared must match the\n// variance #defines in cube_uv_reflection_fragment.glsl.js.\nconst EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];\n\n// The maximum length of the blur for loop. Smaller sigmas will use fewer\n// samples and exit early, but not recompile the shader.\nconst MAX_SAMPLES = 20;\n\nconst _flatCamera = /*@__PURE__*/ new OrthographicCamera();\nconst _clearColor = /*@__PURE__*/ new Color();\nlet _oldTarget = null;\n\n// Golden Ratio\nconst PHI = ( 1 + Math.sqrt( 5 ) ) / 2;\nconst INV_PHI = 1 / PHI;\n\n// Vertices of a dodecahedron (except the opposites, which represent the\n// same axis), used as axis directions evenly spread on a sphere.\nconst _axisDirections = [\n\t/*@__PURE__*/ new Vector3( 1, 1, 1 ),\n\t/*@__PURE__*/ new Vector3( - 1, 1, 1 ),\n\t/*@__PURE__*/ new Vector3( 1, 1, - 1 ),\n\t/*@__PURE__*/ new Vector3( - 1, 1, - 1 ),\n\t/*@__PURE__*/ new Vector3( 0, PHI, INV_PHI ),\n\t/*@__PURE__*/ new Vector3( 0, PHI, - INV_PHI ),\n\t/*@__PURE__*/ new Vector3( INV_PHI, 0, PHI ),\n\t/*@__PURE__*/ new Vector3( - INV_PHI, 0, PHI ),\n\t/*@__PURE__*/ new Vector3( PHI, INV_PHI, 0 ),\n\t/*@__PURE__*/ new Vector3( - PHI, INV_PHI, 0 ) ];\n\n/**\n * This class generates a Prefiltered, Mipmapped Radiance Environment Map\n * (PMREM) from a cubeMap environment texture. This allows different levels of\n * blur to be quickly accessed based on material roughness. It is packed into a\n * special CubeUV format that allows us to perform custom interpolation so that\n * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap\n * chain, it only goes down to the LOD_MIN level (above), and then creates extra\n * even more filtered 'mips' at the same LOD_MIN resolution, associated with\n * higher roughness levels. In this way we maintain resolution to smoothly\n * interpolate diffuse lighting while limiting sampling computation.\n *\n * Paper: Fast, Accurate Image-Based Lighting\n * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view\n*/\n\nclass PMREMGenerator {\n\n\tconstructor( renderer ) {\n\n\t\tthis._renderer = renderer;\n\t\tthis._pingPongRenderTarget = null;\n\n\t\tthis._lodMax = 0;\n\t\tthis._cubeSize = 0;\n\t\tthis._lodPlanes = [];\n\t\tthis._sizeLods = [];\n\t\tthis._sigmas = [];\n\n\t\tthis._blurMaterial = null;\n\t\tthis._cubemapMaterial = null;\n\t\tthis._equirectMaterial = null;\n\n\t\tthis._compileMaterial( this._blurMaterial );\n\n\t}\n\n\t/**\n\t * Generates a PMREM from a supplied Scene, which can be faster than using an\n\t * image if networking bandwidth is low. Optional sigma specifies a blur radius\n\t * in radians to be applied to the scene before PMREM generation. Optional near\n\t * and far planes ensure the scene is rendered in its entirety (the cubeCamera\n\t * is placed at the origin).\n\t */\n\tfromScene( scene, sigma = 0, near = 0.1, far = 100 ) {\n\n\t\t_oldTarget = this._renderer.getRenderTarget();\n\n\t\tthis._setSize( 256 );\n\n\t\tconst cubeUVRenderTarget = this._allocateTargets();\n\t\tcubeUVRenderTarget.depthBuffer = true;\n\n\t\tthis._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );\n\n\t\tif ( sigma > 0 ) {\n\n\t\t\tthis._blur( cubeUVRenderTarget, 0, 0, sigma );\n\n\t\t}\n\n\t\tthis._applyPMREM( cubeUVRenderTarget );\n\t\tthis._cleanup( cubeUVRenderTarget );\n\n\t\treturn cubeUVRenderTarget;\n\n\t}\n\n\t/**\n\t * Generates a PMREM from an equirectangular texture, which can be either LDR\n\t * or HDR. The ideal input image size is 1k (1024 x 512),\n\t * as this matches best with the 256 x 256 cubemap output.\n\t */\n\tfromEquirectangular( equirectangular, renderTarget = null ) {\n\n\t\treturn this._fromTexture( equirectangular, renderTarget );\n\n\t}\n\n\t/**\n\t * Generates a PMREM from an cubemap texture, which can be either LDR\n\t * or HDR. The ideal input cube size is 256 x 256,\n\t * as this matches best with the 256 x 256 cubemap output.\n\t */\n\tfromCubemap( cubemap, renderTarget = null ) {\n\n\t\treturn this._fromTexture( cubemap, renderTarget );\n\n\t}\n\n\t/**\n\t * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during\n\t * your texture's network fetch for increased concurrency.\n\t */\n\tcompileCubemapShader() {\n\n\t\tif ( this._cubemapMaterial === null ) {\n\n\t\t\tthis._cubemapMaterial = _getCubemapMaterial();\n\t\t\tthis._compileMaterial( this._cubemapMaterial );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during\n\t * your texture's network fetch for increased concurrency.\n\t */\n\tcompileEquirectangularShader() {\n\n\t\tif ( this._equirectMaterial === null ) {\n\n\t\t\tthis._equirectMaterial = _getEquirectMaterial();\n\t\t\tthis._compileMaterial( this._equirectMaterial );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,\n\t * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on\n\t * one of them will cause any others to also become unusable.\n\t */\n\tdispose() {\n\n\t\tthis._dispose();\n\n\t\tif ( this._cubemapMaterial !== null ) this._cubemapMaterial.dispose();\n\t\tif ( this._equirectMaterial !== null ) this._equirectMaterial.dispose();\n\n\t}\n\n\t// private interface\n\n\t_setSize( cubeSize ) {\n\n\t\tthis._lodMax = Math.floor( Math.log2( cubeSize ) );\n\t\tthis._cubeSize = Math.pow( 2, this._lodMax );\n\n\t}\n\n\t_dispose() {\n\n\t\tif ( this._blurMaterial !== null ) this._blurMaterial.dispose();\n\n\t\tif ( this._pingPongRenderTarget !== null ) this._pingPongRenderTarget.dispose();\n\n\t\tfor ( let i = 0; i < this._lodPlanes.length; i ++ ) {\n\n\t\t\tthis._lodPlanes[ i ].dispose();\n\n\t\t}\n\n\t}\n\n\t_cleanup( outputTarget ) {\n\n\t\tthis._renderer.setRenderTarget( _oldTarget );\n\t\toutputTarget.scissorTest = false;\n\t\t_setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );\n\n\t}\n\n\t_fromTexture( texture, renderTarget ) {\n\n\t\tif ( texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping ) {\n\n\t\t\tthis._setSize( texture.image.length === 0 ? 16 : ( texture.image[ 0 ].width || texture.image[ 0 ].image.width ) );\n\n\t\t} else { // Equirectangular\n\n\t\t\tthis._setSize( texture.image.width / 4 );\n\n\t\t}\n\n\t\t_oldTarget = this._renderer.getRenderTarget();\n\n\t\tconst cubeUVRenderTarget = renderTarget || this._allocateTargets();\n\t\tthis._textureToCubeUV( texture, cubeUVRenderTarget );\n\t\tthis._applyPMREM( cubeUVRenderTarget );\n\t\tthis._cleanup( cubeUVRenderTarget );\n\n\t\treturn cubeUVRenderTarget;\n\n\t}\n\n\t_allocateTargets() {\n\n\t\tconst width = 3 * Math.max( this._cubeSize, 16 * 7 );\n\t\tconst height = 4 * this._cubeSize;\n\n\t\tconst params = {\n\t\t\tmagFilter: LinearFilter,\n\t\t\tminFilter: LinearFilter,\n\t\t\tgenerateMipmaps: false,\n\t\t\ttype: HalfFloatType,\n\t\t\tformat: RGBAFormat,\n\t\t\tencoding: LinearEncoding,\n\t\t\tdepthBuffer: false\n\t\t};\n\n\t\tconst cubeUVRenderTarget = _createRenderTarget( width, height, params );\n\n\t\tif ( this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width ) {\n\n\t\t\tif ( this._pingPongRenderTarget !== null ) {\n\n\t\t\t\tthis._dispose();\n\n\t\t\t}\n\n\t\t\tthis._pingPongRenderTarget = _createRenderTarget( width, height, params );\n\n\t\t\tconst { _lodMax } = this;\n\t\t\t( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes( _lodMax ) );\n\n\t\t\tthis._blurMaterial = _getBlurShader( _lodMax, width, height );\n\n\t\t}\n\n\t\treturn cubeUVRenderTarget;\n\n\t}\n\n\t_compileMaterial( material ) {\n\n\t\tconst tmpMesh = new Mesh( this._lodPlanes[ 0 ], material );\n\t\tthis._renderer.compile( tmpMesh, _flatCamera );\n\n\t}\n\n\t_sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) {\n\n\t\tconst fov = 90;\n\t\tconst aspect = 1;\n\t\tconst cubeCamera = new PerspectiveCamera( fov, aspect, near, far );\n\t\tconst upSign = [ 1, - 1, 1, 1, 1, 1 ];\n\t\tconst forwardSign = [ 1, 1, 1, - 1, - 1, - 1 ];\n\t\tconst renderer = this._renderer;\n\n\t\tconst originalAutoClear = renderer.autoClear;\n\t\tconst toneMapping = renderer.toneMapping;\n\t\trenderer.getClearColor( _clearColor );\n\n\t\trenderer.toneMapping = NoToneMapping;\n\t\trenderer.autoClear = false;\n\n\t\tconst backgroundMaterial = new MeshBasicMaterial( {\n\t\t\tname: 'PMREM.Background',\n\t\t\tside: BackSide,\n\t\t\tdepthWrite: false,\n\t\t\tdepthTest: false,\n\t\t} );\n\n\t\tconst backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial );\n\n\t\tlet useSolidColor = false;\n\t\tconst background = scene.background;\n\n\t\tif ( background ) {\n\n\t\t\tif ( background.isColor ) {\n\n\t\t\t\tbackgroundMaterial.color.copy( background );\n\t\t\t\tscene.background = null;\n\t\t\t\tuseSolidColor = true;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tbackgroundMaterial.color.copy( _clearColor );\n\t\t\tuseSolidColor = true;\n\n\t\t}\n\n\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\tconst col = i % 3;\n\n\t\t\tif ( col === 0 ) {\n\n\t\t\t\tcubeCamera.up.set( 0, upSign[ i ], 0 );\n\t\t\t\tcubeCamera.lookAt( forwardSign[ i ], 0, 0 );\n\n\t\t\t} else if ( col === 1 ) {\n\n\t\t\t\tcubeCamera.up.set( 0, 0, upSign[ i ] );\n\t\t\t\tcubeCamera.lookAt( 0, forwardSign[ i ], 0 );\n\n\t\t\t} else {\n\n\t\t\t\tcubeCamera.up.set( 0, upSign[ i ], 0 );\n\t\t\t\tcubeCamera.lookAt( 0, 0, forwardSign[ i ] );\n\n\t\t\t}\n\n\t\t\tconst size = this._cubeSize;\n\n\t\t\t_setViewport( cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size );\n\n\t\t\trenderer.setRenderTarget( cubeUVRenderTarget );\n\n\t\t\tif ( useSolidColor ) {\n\n\t\t\t\trenderer.render( backgroundBox, cubeCamera );\n\n\t\t\t}\n\n\t\t\trenderer.render( scene, cubeCamera );\n\n\t\t}\n\n\t\tbackgroundBox.geometry.dispose();\n\t\tbackgroundBox.material.dispose();\n\n\t\trenderer.toneMapping = toneMapping;\n\t\trenderer.autoClear = originalAutoClear;\n\t\tscene.background = background;\n\n\t}\n\n\t_textureToCubeUV( texture, cubeUVRenderTarget ) {\n\n\t\tconst renderer = this._renderer;\n\n\t\tconst isCubeTexture = ( texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping );\n\n\t\tif ( isCubeTexture ) {\n\n\t\t\tif ( this._cubemapMaterial === null ) {\n\n\t\t\t\tthis._cubemapMaterial = _getCubemapMaterial();\n\n\t\t\t}\n\n\t\t\tthis._cubemapMaterial.uniforms.flipEnvMap.value = ( texture.isRenderTargetTexture === false ) ? - 1 : 1;\n\n\t\t} else {\n\n\t\t\tif ( this._equirectMaterial === null ) {\n\n\t\t\t\tthis._equirectMaterial = _getEquirectMaterial();\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial;\n\t\tconst mesh = new Mesh( this._lodPlanes[ 0 ], material );\n\n\t\tconst uniforms = material.uniforms;\n\n\t\tuniforms[ 'envMap' ].value = texture;\n\n\t\tconst size = this._cubeSize;\n\n\t\t_setViewport( cubeUVRenderTarget, 0, 0, 3 * size, 2 * size );\n\n\t\trenderer.setRenderTarget( cubeUVRenderTarget );\n\t\trenderer.render( mesh, _flatCamera );\n\n\t}\n\n\t_applyPMREM( cubeUVRenderTarget ) {\n\n\t\tconst renderer = this._renderer;\n\t\tconst autoClear = renderer.autoClear;\n\t\trenderer.autoClear = false;\n\n\t\tfor ( let i = 1; i < this._lodPlanes.length; i ++ ) {\n\n\t\t\tconst sigma = Math.sqrt( this._sigmas[ i ] * this._sigmas[ i ] - this._sigmas[ i - 1 ] * this._sigmas[ i - 1 ] );\n\n\t\t\tconst poleAxis = _axisDirections[ ( i - 1 ) % _axisDirections.length ];\n\n\t\t\tthis._blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis );\n\n\t\t}\n\n\t\trenderer.autoClear = autoClear;\n\n\t}\n\n\t/**\n\t * This is a two-pass Gaussian blur for a cubemap. Normally this is done\n\t * vertically and horizontally, but this breaks down on a cube. Here we apply\n\t * the blur latitudinally (around the poles), and then longitudinally (towards\n\t * the poles) to approximate the orthogonally-separable blur. It is least\n\t * accurate at the poles, but still does a decent job.\n\t */\n\t_blur( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) {\n\n\t\tconst pingPongRenderTarget = this._pingPongRenderTarget;\n\n\t\tthis._halfBlur(\n\t\t\tcubeUVRenderTarget,\n\t\t\tpingPongRenderTarget,\n\t\t\tlodIn,\n\t\t\tlodOut,\n\t\t\tsigma,\n\t\t\t'latitudinal',\n\t\t\tpoleAxis );\n\n\t\tthis._halfBlur(\n\t\t\tpingPongRenderTarget,\n\t\t\tcubeUVRenderTarget,\n\t\t\tlodOut,\n\t\t\tlodOut,\n\t\t\tsigma,\n\t\t\t'longitudinal',\n\t\t\tpoleAxis );\n\n\t}\n\n\t_halfBlur( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) {\n\n\t\tconst renderer = this._renderer;\n\t\tconst blurMaterial = this._blurMaterial;\n\n\t\tif ( direction !== 'latitudinal' && direction !== 'longitudinal' ) {\n\n\t\t\tconsole.error(\n\t\t\t\t'blur direction must be either latitudinal or longitudinal!' );\n\n\t\t}\n\n\t\t// Number of standard deviations at which to cut off the discrete approximation.\n\t\tconst STANDARD_DEVIATIONS = 3;\n\n\t\tconst blurMesh = new Mesh( this._lodPlanes[ lodOut ], blurMaterial );\n\t\tconst blurUniforms = blurMaterial.uniforms;\n\n\t\tconst pixels = this._sizeLods[ lodIn ] - 1;\n\t\tconst radiansPerPixel = isFinite( sigmaRadians ) ? Math.PI / ( 2 * pixels ) : 2 * Math.PI / ( 2 * MAX_SAMPLES - 1 );\n\t\tconst sigmaPixels = sigmaRadians / radiansPerPixel;\n\t\tconst samples = isFinite( sigmaRadians ) ? 1 + Math.floor( STANDARD_DEVIATIONS * sigmaPixels ) : MAX_SAMPLES;\n\n\t\tif ( samples > MAX_SAMPLES ) {\n\n\t\t\tconsole.warn( `sigmaRadians, ${\n\t\t\t\tsigmaRadians}, is too large and will clip, as it requested ${\n\t\t\t\tsamples} samples when the maximum is set to ${MAX_SAMPLES}` );\n\n\t\t}\n\n\t\tconst weights = [];\n\t\tlet sum = 0;\n\n\t\tfor ( let i = 0; i < MAX_SAMPLES; ++ i ) {\n\n\t\t\tconst x = i / sigmaPixels;\n\t\t\tconst weight = Math.exp( - x * x / 2 );\n\t\t\tweights.push( weight );\n\n\t\t\tif ( i === 0 ) {\n\n\t\t\t\tsum += weight;\n\n\t\t\t} else if ( i < samples ) {\n\n\t\t\t\tsum += 2 * weight;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let i = 0; i < weights.length; i ++ ) {\n\n\t\t\tweights[ i ] = weights[ i ] / sum;\n\n\t\t}\n\n\t\tblurUniforms[ 'envMap' ].value = targetIn.texture;\n\t\tblurUniforms[ 'samples' ].value = samples;\n\t\tblurUniforms[ 'weights' ].value = weights;\n\t\tblurUniforms[ 'latitudinal' ].value = direction === 'latitudinal';\n\n\t\tif ( poleAxis ) {\n\n\t\t\tblurUniforms[ 'poleAxis' ].value = poleAxis;\n\n\t\t}\n\n\t\tconst { _lodMax } = this;\n\t\tblurUniforms[ 'dTheta' ].value = radiansPerPixel;\n\t\tblurUniforms[ 'mipInt' ].value = _lodMax - lodIn;\n\n\t\tconst outputSize = this._sizeLods[ lodOut ];\n\t\tconst x = 3 * outputSize * ( lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0 );\n\t\tconst y = 4 * ( this._cubeSize - outputSize );\n\n\t\t_setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize );\n\t\trenderer.setRenderTarget( targetOut );\n\t\trenderer.render( blurMesh, _flatCamera );\n\n\t}\n\n}\n\n\n\nfunction _createPlanes( lodMax ) {\n\n\tconst lodPlanes = [];\n\tconst sizeLods = [];\n\tconst sigmas = [];\n\n\tlet lod = lodMax;\n\n\tconst totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length;\n\n\tfor ( let i = 0; i < totalLods; i ++ ) {\n\n\t\tconst sizeLod = Math.pow( 2, lod );\n\t\tsizeLods.push( sizeLod );\n\t\tlet sigma = 1.0 / sizeLod;\n\n\t\tif ( i > lodMax - LOD_MIN ) {\n\n\t\t\tsigma = EXTRA_LOD_SIGMA[ i - lodMax + LOD_MIN - 1 ];\n\n\t\t} else if ( i === 0 ) {\n\n\t\t\tsigma = 0;\n\n\t\t}\n\n\t\tsigmas.push( sigma );\n\n\t\tconst texelSize = 1.0 / ( sizeLod - 2 );\n\t\tconst min = - texelSize;\n\t\tconst max = 1 + texelSize;\n\t\tconst uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ];\n\n\t\tconst cubeFaces = 6;\n\t\tconst vertices = 6;\n\t\tconst positionSize = 3;\n\t\tconst uvSize = 2;\n\t\tconst faceIndexSize = 1;\n\n\t\tconst position = new Float32Array( positionSize * vertices * cubeFaces );\n\t\tconst uv = new Float32Array( uvSize * vertices * cubeFaces );\n\t\tconst faceIndex = new Float32Array( faceIndexSize * vertices * cubeFaces );\n\n\t\tfor ( let face = 0; face < cubeFaces; face ++ ) {\n\n\t\t\tconst x = ( face % 3 ) * 2 / 3 - 1;\n\t\t\tconst y = face > 2 ? 0 : - 1;\n\t\t\tconst coordinates = [\n\t\t\t\tx, y, 0,\n\t\t\t\tx + 2 / 3, y, 0,\n\t\t\t\tx + 2 / 3, y + 1, 0,\n\t\t\t\tx, y, 0,\n\t\t\t\tx + 2 / 3, y + 1, 0,\n\t\t\t\tx, y + 1, 0\n\t\t\t];\n\t\t\tposition.set( coordinates, positionSize * vertices * face );\n\t\t\tuv.set( uv1, uvSize * vertices * face );\n\t\t\tconst fill = [ face, face, face, face, face, face ];\n\t\t\tfaceIndex.set( fill, faceIndexSize * vertices * face );\n\n\t\t}\n\n\t\tconst planes = new BufferGeometry();\n\t\tplanes.setAttribute( 'position', new BufferAttribute( position, positionSize ) );\n\t\tplanes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );\n\t\tplanes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );\n\t\tlodPlanes.push( planes );\n\n\t\tif ( lod > LOD_MIN ) {\n\n\t\t\tlod --;\n\n\t\t}\n\n\t}\n\n\treturn { lodPlanes, sizeLods, sigmas };\n\n}\n\nfunction _createRenderTarget( width, height, params ) {\n\n\tconst cubeUVRenderTarget = new WebGLRenderTarget( width, height, params );\n\tcubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;\n\tcubeUVRenderTarget.texture.name = 'PMREM.cubeUv';\n\tcubeUVRenderTarget.scissorTest = true;\n\treturn cubeUVRenderTarget;\n\n}\n\nfunction _setViewport( target, x, y, width, height ) {\n\n\ttarget.viewport.set( x, y, width, height );\n\ttarget.scissor.set( x, y, width, height );\n\n}\n\nfunction _getBlurShader( lodMax, width, height ) {\n\n\tconst weights = new Float32Array( MAX_SAMPLES );\n\tconst poleAxis = new Vector3( 0, 1, 0 );\n\tconst shaderMaterial = new ShaderMaterial( {\n\n\t\tname: 'SphericalGaussianBlur',\n\n\t\tdefines: {\n\t\t\t'n': MAX_SAMPLES,\n\t\t\t'CUBEUV_TEXEL_WIDTH': 1.0 / width,\n\t\t\t'CUBEUV_TEXEL_HEIGHT': 1.0 / height,\n\t\t\t'CUBEUV_MAX_MIP': `${lodMax}.0`,\n\t\t},\n\n\t\tuniforms: {\n\t\t\t'envMap': { value: null },\n\t\t\t'samples': { value: 1 },\n\t\t\t'weights': { value: weights },\n\t\t\t'latitudinal': { value: false },\n\t\t\t'dTheta': { value: 0 },\n\t\t\t'mipInt': { value: 0 },\n\t\t\t'poleAxis': { value: poleAxis }\n\t\t},\n\n\t\tvertexShader: _getCommonVertexShader(),\n\n\t\tfragmentShader: /* glsl */`\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform int samples;\n\t\t\tuniform float weights[ n ];\n\t\t\tuniform bool latitudinal;\n\t\t\tuniform float dTheta;\n\t\t\tuniform float mipInt;\n\t\t\tuniform vec3 poleAxis;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include \n\n\t\t\tvec3 getSample( float theta, vec3 axis ) {\n\n\t\t\t\tfloat cosTheta = cos( theta );\n\t\t\t\t// Rodrigues' axis-angle rotation\n\t\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross( axis, vOutputDirection ) * sin( theta )\n\t\t\t\t\t+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );\n\n\t\t\t\treturn bilinearCubeUV( envMap, sampleDirection, mipInt );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );\n\n\t\t\t\tif ( all( equal( axis, vec3( 0.0 ) ) ) ) {\n\n\t\t\t\t\taxis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );\n\n\t\t\t\t}\n\n\t\t\t\taxis = normalize( axis );\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );\n\n\t\t\t\tfor ( int i = 1; i < n; i++ ) {\n\n\t\t\t\t\tif ( i >= samples ) {\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfloat theta = dTheta * float( i );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( theta, axis );\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t`,\n\n\t\tblending: NoBlending,\n\t\tdepthTest: false,\n\t\tdepthWrite: false\n\n\t} );\n\n\treturn shaderMaterial;\n\n}\n\nfunction _getEquirectMaterial() {\n\n\treturn new ShaderMaterial( {\n\n\t\tname: 'EquirectangularToCubeUV',\n\n\t\tuniforms: {\n\t\t\t'envMap': { value: null }\n\t\t},\n\n\t\tvertexShader: _getCommonVertexShader(),\n\n\t\tfragmentShader: /* glsl */`\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tgl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );\n\n\t\t\t}\n\t\t`,\n\n\t\tblending: NoBlending,\n\t\tdepthTest: false,\n\t\tdepthWrite: false\n\n\t} );\n\n}\n\nfunction _getCubemapMaterial() {\n\n\treturn new ShaderMaterial( {\n\n\t\tname: 'CubemapToCubeUV',\n\n\t\tuniforms: {\n\t\t\t'envMap': { value: null },\n\t\t\t'flipEnvMap': { value: - 1 }\n\t\t},\n\n\t\tvertexShader: _getCommonVertexShader(),\n\n\t\tfragmentShader: /* glsl */`\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tuniform float flipEnvMap;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );\n\n\t\t\t}\n\t\t`,\n\n\t\tblending: NoBlending,\n\t\tdepthTest: false,\n\t\tdepthWrite: false\n\n\t} );\n\n}\n\nfunction _getCommonVertexShader() {\n\n\treturn /* glsl */`\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t`;\n\n}\n\nfunction WebGLCubeUVMaps( renderer ) {\n\n\tlet cubeUVmaps = new WeakMap();\n\n\tlet pmremGenerator = null;\n\n\tfunction get( texture ) {\n\n\t\tif ( texture && texture.isTexture ) {\n\n\t\t\tconst mapping = texture.mapping;\n\n\t\t\tconst isEquirectMap = ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping );\n\t\t\tconst isCubeMap = ( mapping === CubeReflectionMapping || mapping === CubeRefractionMapping );\n\n\t\t\t// equirect/cube map to cubeUV conversion\n\n\t\t\tif ( isEquirectMap || isCubeMap ) {\n\n\t\t\t\tif ( texture.isRenderTargetTexture && texture.needsPMREMUpdate === true ) {\n\n\t\t\t\t\ttexture.needsPMREMUpdate = false;\n\n\t\t\t\t\tlet renderTarget = cubeUVmaps.get( texture );\n\n\t\t\t\t\tif ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer );\n\n\t\t\t\t\trenderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture, renderTarget ) : pmremGenerator.fromCubemap( texture, renderTarget );\n\t\t\t\t\tcubeUVmaps.set( texture, renderTarget );\n\n\t\t\t\t\treturn renderTarget.texture;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( cubeUVmaps.has( texture ) ) {\n\n\t\t\t\t\t\treturn cubeUVmaps.get( texture ).texture;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconst image = texture.image;\n\n\t\t\t\t\t\tif ( ( isEquirectMap && image && image.height > 0 ) || ( isCubeMap && image && isCubeTextureComplete( image ) ) ) {\n\n\t\t\t\t\t\t\tif ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer );\n\n\t\t\t\t\t\t\tconst renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture ) : pmremGenerator.fromCubemap( texture );\n\t\t\t\t\t\t\tcubeUVmaps.set( texture, renderTarget );\n\n\t\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\t\treturn renderTarget.texture;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// image not yet ready. try the conversion next frame\n\n\t\t\t\t\t\t\treturn null;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn texture;\n\n\t}\n\n\tfunction isCubeTextureComplete( image ) {\n\n\t\tlet count = 0;\n\t\tconst length = 6;\n\n\t\tfor ( let i = 0; i < length; i ++ ) {\n\n\t\t\tif ( image[ i ] !== undefined ) count ++;\n\n\t\t}\n\n\t\treturn count === length;\n\n\n\t}\n\n\tfunction onTextureDispose( event ) {\n\n\t\tconst texture = event.target;\n\n\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\tconst cubemapUV = cubeUVmaps.get( texture );\n\n\t\tif ( cubemapUV !== undefined ) {\n\n\t\t\tcubeUVmaps.delete( texture );\n\t\t\tcubemapUV.dispose();\n\n\t\t}\n\n\t}\n\n\tfunction dispose() {\n\n\t\tcubeUVmaps = new WeakMap();\n\n\t\tif ( pmremGenerator !== null ) {\n\n\t\t\tpmremGenerator.dispose();\n\t\t\tpmremGenerator = null;\n\n\t\t}\n\n\t}\n\n\treturn {\n\t\tget: get,\n\t\tdispose: dispose\n\t};\n\n}\n\nfunction WebGLExtensions( gl ) {\n\n\tconst extensions = {};\n\n\tfunction getExtension( name ) {\n\n\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\treturn extensions[ name ];\n\n\t\t}\n\n\t\tlet extension;\n\n\t\tswitch ( name ) {\n\n\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\tbreak;\n\n\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\tbreak;\n\n\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\tbreak;\n\n\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\textension = gl.getExtension( name );\n\n\t\t}\n\n\t\textensions[ name ] = extension;\n\n\t\treturn extension;\n\n\t}\n\n\treturn {\n\n\t\thas: function ( name ) {\n\n\t\t\treturn getExtension( name ) !== null;\n\n\t\t},\n\n\t\tinit: function ( capabilities ) {\n\n\t\t\tif ( capabilities.isWebGL2 ) {\n\n\t\t\t\tgetExtension( 'EXT_color_buffer_float' );\n\n\t\t\t} else {\n\n\t\t\t\tgetExtension( 'WEBGL_depth_texture' );\n\t\t\t\tgetExtension( 'OES_texture_float' );\n\t\t\t\tgetExtension( 'OES_texture_half_float' );\n\t\t\t\tgetExtension( 'OES_texture_half_float_linear' );\n\t\t\t\tgetExtension( 'OES_standard_derivatives' );\n\t\t\t\tgetExtension( 'OES_element_index_uint' );\n\t\t\t\tgetExtension( 'OES_vertex_array_object' );\n\t\t\t\tgetExtension( 'ANGLE_instanced_arrays' );\n\n\t\t\t}\n\n\t\t\tgetExtension( 'OES_texture_float_linear' );\n\t\t\tgetExtension( 'EXT_color_buffer_half_float' );\n\t\t\tgetExtension( 'WEBGL_multisampled_render_to_texture' );\n\n\t\t},\n\n\t\tget: function ( name ) {\n\n\t\t\tconst extension = getExtension( name );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t}\n\n\t\t\treturn extension;\n\n\t\t}\n\n\t};\n\n}\n\nfunction WebGLGeometries( gl, attributes, info, bindingStates ) {\n\n\tconst geometries = {};\n\tconst wireframeAttributes = new WeakMap();\n\n\tfunction onGeometryDispose( event ) {\n\n\t\tconst geometry = event.target;\n\n\t\tif ( geometry.index !== null ) {\n\n\t\t\tattributes.remove( geometry.index );\n\n\t\t}\n\n\t\tfor ( const name in geometry.attributes ) {\n\n\t\t\tattributes.remove( geometry.attributes[ name ] );\n\n\t\t}\n\n\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\tdelete geometries[ geometry.id ];\n\n\t\tconst attribute = wireframeAttributes.get( geometry );\n\n\t\tif ( attribute ) {\n\n\t\t\tattributes.remove( attribute );\n\t\t\twireframeAttributes.delete( geometry );\n\n\t\t}\n\n\t\tbindingStates.releaseStatesOfGeometry( geometry );\n\n\t\tif ( geometry.isInstancedBufferGeometry === true ) {\n\n\t\t\tdelete geometry._maxInstanceCount;\n\n\t\t}\n\n\t\t//\n\n\t\tinfo.memory.geometries --;\n\n\t}\n\n\tfunction get( object, geometry ) {\n\n\t\tif ( geometries[ geometry.id ] === true ) return geometry;\n\n\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\tgeometries[ geometry.id ] = true;\n\n\t\tinfo.memory.geometries ++;\n\n\t\treturn geometry;\n\n\t}\n\n\tfunction update( geometry ) {\n\n\t\tconst geometryAttributes = geometry.attributes;\n\n\t\t// Updating index buffer in VAO now. See WebGLBindingStates.\n\n\t\tfor ( const name in geometryAttributes ) {\n\n\t\t\tattributes.update( geometryAttributes[ name ], 34962 );\n\n\t\t}\n\n\t\t// morph targets\n\n\t\tconst morphAttributes = geometry.morphAttributes;\n\n\t\tfor ( const name in morphAttributes ) {\n\n\t\t\tconst array = morphAttributes[ name ];\n\n\t\t\tfor ( let i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\tattributes.update( array[ i ], 34962 );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction updateWireframeAttribute( geometry ) {\n\n\t\tconst indices = [];\n\n\t\tconst geometryIndex = geometry.index;\n\t\tconst geometryPosition = geometry.attributes.position;\n\t\tlet version = 0;\n\n\t\tif ( geometryIndex !== null ) {\n\n\t\t\tconst array = geometryIndex.array;\n\t\t\tversion = geometryIndex.version;\n\n\t\t\tfor ( let i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tconst a = array[ i + 0 ];\n\t\t\t\tconst b = array[ i + 1 ];\n\t\t\t\tconst c = array[ i + 2 ];\n\n\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst array = geometryPosition.array;\n\t\t\tversion = geometryPosition.version;\n\n\t\t\tfor ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\tconst a = i + 0;\n\t\t\t\tconst b = i + 1;\n\t\t\t\tconst c = i + 2;\n\n\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\t\tattribute.version = version;\n\n\t\t// Updating index buffer in VAO now. See WebGLBindingStates\n\n\t\t//\n\n\t\tconst previousAttribute = wireframeAttributes.get( geometry );\n\n\t\tif ( previousAttribute ) attributes.remove( previousAttribute );\n\n\t\t//\n\n\t\twireframeAttributes.set( geometry, attribute );\n\n\t}\n\n\tfunction getWireframeAttribute( geometry ) {\n\n\t\tconst currentAttribute = wireframeAttributes.get( geometry );\n\n\t\tif ( currentAttribute ) {\n\n\t\t\tconst geometryIndex = geometry.index;\n\n\t\t\tif ( geometryIndex !== null ) {\n\n\t\t\t\t// if the attribute is obsolete, create a new one\n\n\t\t\t\tif ( currentAttribute.version < geometryIndex.version ) {\n\n\t\t\t\t\tupdateWireframeAttribute( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tupdateWireframeAttribute( geometry );\n\n\t\t}\n\n\t\treturn wireframeAttributes.get( geometry );\n\n\t}\n\n\treturn {\n\n\t\tget: get,\n\t\tupdate: update,\n\n\t\tgetWireframeAttribute: getWireframeAttribute\n\n\t};\n\n}\n\nfunction WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) {\n\n\tconst isWebGL2 = capabilities.isWebGL2;\n\n\tlet mode;\n\n\tfunction setMode( value ) {\n\n\t\tmode = value;\n\n\t}\n\n\tlet type, bytesPerElement;\n\n\tfunction setIndex( value ) {\n\n\t\ttype = value.type;\n\t\tbytesPerElement = value.bytesPerElement;\n\n\t}\n\n\tfunction render( start, count ) {\n\n\t\tgl.drawElements( mode, count, type, start * bytesPerElement );\n\n\t\tinfo.update( count, mode, 1 );\n\n\t}\n\n\tfunction renderInstances( start, count, primcount ) {\n\n\t\tif ( primcount === 0 ) return;\n\n\t\tlet extension, methodName;\n\n\t\tif ( isWebGL2 ) {\n\n\t\t\textension = gl;\n\t\t\tmethodName = 'drawElementsInstanced';\n\n\t\t} else {\n\n\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\t\t\tmethodName = 'drawElementsInstancedANGLE';\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t}\n\n\t\textension[ methodName ]( mode, count, type, start * bytesPerElement, primcount );\n\n\t\tinfo.update( count, mode, primcount );\n\n\t}\n\n\t//\n\n\tthis.setMode = setMode;\n\tthis.setIndex = setIndex;\n\tthis.render = render;\n\tthis.renderInstances = renderInstances;\n\n}\n\nfunction WebGLInfo( gl ) {\n\n\tconst memory = {\n\t\tgeometries: 0,\n\t\ttextures: 0\n\t};\n\n\tconst render = {\n\t\tframe: 0,\n\t\tcalls: 0,\n\t\ttriangles: 0,\n\t\tpoints: 0,\n\t\tlines: 0\n\t};\n\n\tfunction update( count, mode, instanceCount ) {\n\n\t\trender.calls ++;\n\n\t\tswitch ( mode ) {\n\n\t\t\tcase 4:\n\t\t\t\trender.triangles += instanceCount * ( count / 3 );\n\t\t\t\tbreak;\n\n\t\t\tcase 1:\n\t\t\t\trender.lines += instanceCount * ( count / 2 );\n\t\t\t\tbreak;\n\n\t\t\tcase 3:\n\t\t\t\trender.lines += instanceCount * ( count - 1 );\n\t\t\t\tbreak;\n\n\t\t\tcase 2:\n\t\t\t\trender.lines += instanceCount * count;\n\t\t\t\tbreak;\n\n\t\t\tcase 0:\n\t\t\t\trender.points += instanceCount * count;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tconsole.error( 'THREE.WebGLInfo: Unknown draw mode:', mode );\n\t\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\tfunction reset() {\n\n\t\trender.frame ++;\n\t\trender.calls = 0;\n\t\trender.triangles = 0;\n\t\trender.points = 0;\n\t\trender.lines = 0;\n\n\t}\n\n\treturn {\n\t\tmemory: memory,\n\t\trender: render,\n\t\tprograms: null,\n\t\tautoReset: true,\n\t\treset: reset,\n\t\tupdate: update\n\t};\n\n}\n\nfunction numericalSort( a, b ) {\n\n\treturn a[ 0 ] - b[ 0 ];\n\n}\n\nfunction absNumericalSort( a, b ) {\n\n\treturn Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] );\n\n}\n\nfunction denormalize( morph, attribute ) {\n\n\tlet denominator = 1;\n\tconst array = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array;\n\n\tif ( array instanceof Int8Array ) denominator = 127;\n\telse if ( array instanceof Int16Array ) denominator = 32767;\n\telse if ( array instanceof Int32Array ) denominator = 2147483647;\n\telse console.error( 'THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array );\n\n\tmorph.divideScalar( denominator );\n\n}\n\nfunction WebGLMorphtargets( gl, capabilities, textures ) {\n\n\tconst influencesList = {};\n\tconst morphInfluences = new Float32Array( 8 );\n\tconst morphTextures = new WeakMap();\n\tconst morph = new Vector4();\n\n\tconst workInfluences = [];\n\n\tfor ( let i = 0; i < 8; i ++ ) {\n\n\t\tworkInfluences[ i ] = [ i, 0 ];\n\n\t}\n\n\tfunction update( object, geometry, material, program ) {\n\n\t\tconst objectInfluences = object.morphTargetInfluences;\n\n\t\tif ( capabilities.isWebGL2 === true ) {\n\n\t\t\t// instead of using attributes, the WebGL 2 code path encodes morph targets\n\t\t\t// into an array of data textures. Each layer represents a single morph target.\n\n\t\t\tconst morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;\n\t\t\tconst morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;\n\n\t\t\tlet entry = morphTextures.get( geometry );\n\n\t\t\tif ( entry === undefined || entry.count !== morphTargetsCount ) {\n\n\t\t\t\tif ( entry !== undefined ) entry.texture.dispose();\n\n\t\t\t\tconst hasMorphPosition = geometry.morphAttributes.position !== undefined;\n\t\t\t\tconst hasMorphNormals = geometry.morphAttributes.normal !== undefined;\n\t\t\t\tconst hasMorphColors = geometry.morphAttributes.color !== undefined;\n\n\t\t\t\tconst morphTargets = geometry.morphAttributes.position || [];\n\t\t\t\tconst morphNormals = geometry.morphAttributes.normal || [];\n\t\t\t\tconst morphColors = geometry.morphAttributes.color || [];\n\n\t\t\t\tlet vertexDataCount = 0;\n\n\t\t\t\tif ( hasMorphPosition === true ) vertexDataCount = 1;\n\t\t\t\tif ( hasMorphNormals === true ) vertexDataCount = 2;\n\t\t\t\tif ( hasMorphColors === true ) vertexDataCount = 3;\n\n\t\t\t\tlet width = geometry.attributes.position.count * vertexDataCount;\n\t\t\t\tlet height = 1;\n\n\t\t\t\tif ( width > capabilities.maxTextureSize ) {\n\n\t\t\t\t\theight = Math.ceil( width / capabilities.maxTextureSize );\n\t\t\t\t\twidth = capabilities.maxTextureSize;\n\n\t\t\t\t}\n\n\t\t\t\tconst buffer = new Float32Array( width * height * 4 * morphTargetsCount );\n\n\t\t\t\tconst texture = new DataArrayTexture( buffer, width, height, morphTargetsCount );\n\t\t\t\ttexture.type = FloatType;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t// fill buffer\n\n\t\t\t\tconst vertexDataStride = vertexDataCount * 4;\n\n\t\t\t\tfor ( let i = 0; i < morphTargetsCount; i ++ ) {\n\n\t\t\t\t\tconst morphTarget = morphTargets[ i ];\n\t\t\t\t\tconst morphNormal = morphNormals[ i ];\n\t\t\t\t\tconst morphColor = morphColors[ i ];\n\n\t\t\t\t\tconst offset = width * height * 4 * i;\n\n\t\t\t\t\tfor ( let j = 0; j < morphTarget.count; j ++ ) {\n\n\t\t\t\t\t\tconst stride = j * vertexDataStride;\n\n\t\t\t\t\t\tif ( hasMorphPosition === true ) {\n\n\t\t\t\t\t\t\tmorph.fromBufferAttribute( morphTarget, j );\n\n\t\t\t\t\t\t\tif ( morphTarget.normalized === true ) denormalize( morph, morphTarget );\n\n\t\t\t\t\t\t\tbuffer[ offset + stride + 0 ] = morph.x;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 1 ] = morph.y;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 2 ] = morph.z;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 3 ] = 0;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasMorphNormals === true ) {\n\n\t\t\t\t\t\t\tmorph.fromBufferAttribute( morphNormal, j );\n\n\t\t\t\t\t\t\tif ( morphNormal.normalized === true ) denormalize( morph, morphNormal );\n\n\t\t\t\t\t\t\tbuffer[ offset + stride + 4 ] = morph.x;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 5 ] = morph.y;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 6 ] = morph.z;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 7 ] = 0;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasMorphColors === true ) {\n\n\t\t\t\t\t\t\tmorph.fromBufferAttribute( morphColor, j );\n\n\t\t\t\t\t\t\tif ( morphColor.normalized === true ) denormalize( morph, morphColor );\n\n\t\t\t\t\t\t\tbuffer[ offset + stride + 8 ] = morph.x;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 9 ] = morph.y;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 10 ] = morph.z;\n\t\t\t\t\t\t\tbuffer[ offset + stride + 11 ] = ( morphColor.itemSize === 4 ) ? morph.w : 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tentry = {\n\t\t\t\t\tcount: morphTargetsCount,\n\t\t\t\t\ttexture: texture,\n\t\t\t\t\tsize: new Vector2( width, height )\n\t\t\t\t};\n\n\t\t\t\tmorphTextures.set( geometry, entry );\n\n\t\t\t\tfunction disposeTexture() {\n\n\t\t\t\t\ttexture.dispose();\n\n\t\t\t\t\tmorphTextures.delete( geometry );\n\n\t\t\t\t\tgeometry.removeEventListener( 'dispose', disposeTexture );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', disposeTexture );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tlet morphInfluencesSum = 0;\n\n\t\t\tfor ( let i = 0; i < objectInfluences.length; i ++ ) {\n\n\t\t\t\tmorphInfluencesSum += objectInfluences[ i ];\n\n\t\t\t}\n\n\t\t\tconst morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;\n\n\t\t\tprogram.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence );\n\t\t\tprogram.getUniforms().setValue( gl, 'morphTargetInfluences', objectInfluences );\n\n\t\t\tprogram.getUniforms().setValue( gl, 'morphTargetsTexture', entry.texture, textures );\n\t\t\tprogram.getUniforms().setValue( gl, 'morphTargetsTextureSize', entry.size );\n\n\n\t\t} else {\n\n\t\t\t// When object doesn't have morph target influences defined, we treat it as a 0-length array\n\t\t\t// This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences\n\n\t\t\tconst length = objectInfluences === undefined ? 0 : objectInfluences.length;\n\n\t\t\tlet influences = influencesList[ geometry.id ];\n\n\t\t\tif ( influences === undefined || influences.length !== length ) {\n\n\t\t\t\t// initialise list\n\n\t\t\t\tinfluences = [];\n\n\t\t\t\tfor ( let i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tinfluences[ i ] = [ i, 0 ];\n\n\t\t\t\t}\n\n\t\t\t\tinfluencesList[ geometry.id ] = influences;\n\n\t\t\t}\n\n\t\t\t// Collect influences\n\n\t\t\tfor ( let i = 0; i < length; i ++ ) {\n\n\t\t\t\tconst influence = influences[ i ];\n\n\t\t\t\tinfluence[ 0 ] = i;\n\t\t\t\tinfluence[ 1 ] = objectInfluences[ i ];\n\n\t\t\t}\n\n\t\t\tinfluences.sort( absNumericalSort );\n\n\t\t\tfor ( let i = 0; i < 8; i ++ ) {\n\n\t\t\t\tif ( i < length && influences[ i ][ 1 ] ) {\n\n\t\t\t\t\tworkInfluences[ i ][ 0 ] = influences[ i ][ 0 ];\n\t\t\t\t\tworkInfluences[ i ][ 1 ] = influences[ i ][ 1 ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tworkInfluences[ i ][ 0 ] = Number.MAX_SAFE_INTEGER;\n\t\t\t\t\tworkInfluences[ i ][ 1 ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tworkInfluences.sort( numericalSort );\n\n\t\t\tconst morphTargets = geometry.morphAttributes.position;\n\t\t\tconst morphNormals = geometry.morphAttributes.normal;\n\n\t\t\tlet morphInfluencesSum = 0;\n\n\t\t\tfor ( let i = 0; i < 8; i ++ ) {\n\n\t\t\t\tconst influence = workInfluences[ i ];\n\t\t\t\tconst index = influence[ 0 ];\n\t\t\t\tconst value = influence[ 1 ];\n\n\t\t\t\tif ( index !== Number.MAX_SAFE_INTEGER && value ) {\n\n\t\t\t\t\tif ( morphTargets && geometry.getAttribute( 'morphTarget' + i ) !== morphTargets[ index ] ) {\n\n\t\t\t\t\t\tgeometry.setAttribute( 'morphTarget' + i, morphTargets[ index ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( morphNormals && geometry.getAttribute( 'morphNormal' + i ) !== morphNormals[ index ] ) {\n\n\t\t\t\t\t\tgeometry.setAttribute( 'morphNormal' + i, morphNormals[ index ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tmorphInfluences[ i ] = value;\n\t\t\t\t\tmorphInfluencesSum += value;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( morphTargets && geometry.hasAttribute( 'morphTarget' + i ) === true ) {\n\n\t\t\t\t\t\tgeometry.deleteAttribute( 'morphTarget' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( morphNormals && geometry.hasAttribute( 'morphNormal' + i ) === true ) {\n\n\t\t\t\t\t\tgeometry.deleteAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tmorphInfluences[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// GLSL shader uses formula baseinfluence * base + sum(target * influence)\n\t\t\t// This allows us to switch between absolute morphs and relative morphs without changing shader code\n\t\t\t// When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence)\n\t\t\tconst morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;\n\n\t\t\tprogram.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence );\n\t\t\tprogram.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t}\n\n\t}\n\n\treturn {\n\n\t\tupdate: update\n\n\t};\n\n}\n\nfunction WebGLObjects( gl, geometries, attributes, info ) {\n\n\tlet updateMap = new WeakMap();\n\n\tfunction update( object ) {\n\n\t\tconst frame = info.render.frame;\n\n\t\tconst geometry = object.geometry;\n\t\tconst buffergeometry = geometries.get( object, geometry );\n\n\t\t// Update once per frame\n\n\t\tif ( updateMap.get( buffergeometry ) !== frame ) {\n\n\t\t\tgeometries.update( buffergeometry );\n\n\t\t\tupdateMap.set( buffergeometry, frame );\n\n\t\t}\n\n\t\tif ( object.isInstancedMesh ) {\n\n\t\t\tif ( object.hasEventListener( 'dispose', onInstancedMeshDispose ) === false ) {\n\n\t\t\t\tobject.addEventListener( 'dispose', onInstancedMeshDispose );\n\n\t\t\t}\n\n\t\t\tattributes.update( object.instanceMatrix, 34962 );\n\n\t\t\tif ( object.instanceColor !== null ) {\n\n\t\t\t\tattributes.update( object.instanceColor, 34962 );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn buffergeometry;\n\n\t}\n\n\tfunction dispose() {\n\n\t\tupdateMap = new WeakMap();\n\n\t}\n\n\tfunction onInstancedMeshDispose( event ) {\n\n\t\tconst instancedMesh = event.target;\n\n\t\tinstancedMesh.removeEventListener( 'dispose', onInstancedMeshDispose );\n\n\t\tattributes.remove( instancedMesh.instanceMatrix );\n\n\t\tif ( instancedMesh.instanceColor !== null ) attributes.remove( instancedMesh.instanceColor );\n\n\t}\n\n\treturn {\n\n\t\tupdate: update,\n\t\tdispose: dispose\n\n\t};\n\n}\n\n/**\n * Uniforms of a program.\n * Those form a tree structure with a special top-level container for the root,\n * which you get by calling 'new WebGLUniforms( gl, program )'.\n *\n *\n * Properties of inner nodes including the top-level container:\n *\n * .seq - array of nested uniforms\n * .map - nested uniforms by name\n *\n *\n * Methods of all nodes except the top-level container:\n *\n * .setValue( gl, value, [textures] )\n *\n * \t\tuploads a uniform value(s)\n * \tthe 'textures' parameter is needed for sampler uniforms\n *\n *\n * Static methods of the top-level container (textures factorizations):\n *\n * .upload( gl, seq, values, textures )\n *\n * \t\tsets uniforms in 'seq' to 'values[id].value'\n *\n * .seqWithValue( seq, values ) : filteredSeq\n *\n * \t\tfilters 'seq' entries with corresponding entry in values\n *\n *\n * Methods of the top-level container (textures factorizations):\n *\n * .setValue( gl, name, value, textures )\n *\n * \t\tsets uniform with name 'name' to 'value'\n *\n * .setOptional( gl, obj, prop )\n *\n * \t\tlike .set for an optional property of the object\n *\n */\n\nconst emptyTexture = new Texture();\nconst emptyArrayTexture = new DataArrayTexture();\nconst empty3dTexture = new Data3DTexture();\nconst emptyCubeTexture = new CubeTexture();\n\n// --- Utilities ---\n\n// Array Caches (provide typed arrays for temporary by size)\n\nconst arrayCacheF32 = [];\nconst arrayCacheI32 = [];\n\n// Float32Array caches used for uploading Matrix uniforms\n\nconst mat4array = new Float32Array( 16 );\nconst mat3array = new Float32Array( 9 );\nconst mat2array = new Float32Array( 4 );\n\n// Flattening for arrays of vectors and matrices\n\nfunction flatten( array, nBlocks, blockSize ) {\n\n\tconst firstElem = array[ 0 ];\n\n\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t// unoptimized: ! isNaN( firstElem )\n\t// see http://jacksondunstan.com/articles/983\n\n\tconst n = nBlocks * blockSize;\n\tlet r = arrayCacheF32[ n ];\n\n\tif ( r === undefined ) {\n\n\t\tr = new Float32Array( n );\n\t\tarrayCacheF32[ n ] = r;\n\n\t}\n\n\tif ( nBlocks !== 0 ) {\n\n\t\tfirstElem.toArray( r, 0 );\n\n\t\tfor ( let i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\toffset += blockSize;\n\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t}\n\n\t}\n\n\treturn r;\n\n}\n\nfunction arraysEqual( a, b ) {\n\n\tif ( a.length !== b.length ) return false;\n\n\tfor ( let i = 0, l = a.length; i < l; i ++ ) {\n\n\t\tif ( a[ i ] !== b[ i ] ) return false;\n\n\t}\n\n\treturn true;\n\n}\n\nfunction copyArray( a, b ) {\n\n\tfor ( let i = 0, l = b.length; i < l; i ++ ) {\n\n\t\ta[ i ] = b[ i ];\n\n\t}\n\n}\n\n// Texture unit allocation\n\nfunction allocTexUnits( textures, n ) {\n\n\tlet r = arrayCacheI32[ n ];\n\n\tif ( r === undefined ) {\n\n\t\tr = new Int32Array( n );\n\t\tarrayCacheI32[ n ] = r;\n\n\t}\n\n\tfor ( let i = 0; i !== n; ++ i ) {\n\n\t\tr[ i ] = textures.allocateTextureUnit();\n\n\t}\n\n\treturn r;\n\n}\n\n// --- Setters ---\n\n// Note: Defining these methods externally, because they come in a bunch\n// and this way their names minify.\n\n// Single scalar\n\nfunction setValueV1f( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( cache[ 0 ] === v ) return;\n\n\tgl.uniform1f( this.addr, v );\n\n\tcache[ 0 ] = v;\n\n}\n\n// Single float vector (from flat array or THREE.VectorN)\n\nfunction setValueV2f( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( v.x !== undefined ) {\n\n\t\tif ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) {\n\n\t\t\tgl.uniform2f( this.addr, v.x, v.y );\n\n\t\t\tcache[ 0 ] = v.x;\n\t\t\tcache[ 1 ] = v.y;\n\n\t\t}\n\n\t} else {\n\n\t\tif ( arraysEqual( cache, v ) ) return;\n\n\t\tgl.uniform2fv( this.addr, v );\n\n\t\tcopyArray( cache, v );\n\n\t}\n\n}\n\nfunction setValueV3f( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( v.x !== undefined ) {\n\n\t\tif ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) {\n\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\n\t\t\tcache[ 0 ] = v.x;\n\t\t\tcache[ 1 ] = v.y;\n\t\t\tcache[ 2 ] = v.z;\n\n\t\t}\n\n\t} else if ( v.r !== undefined ) {\n\n\t\tif ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) {\n\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\n\t\t\tcache[ 0 ] = v.r;\n\t\t\tcache[ 1 ] = v.g;\n\t\t\tcache[ 2 ] = v.b;\n\n\t\t}\n\n\t} else {\n\n\t\tif ( arraysEqual( cache, v ) ) return;\n\n\t\tgl.uniform3fv( this.addr, v );\n\n\t\tcopyArray( cache, v );\n\n\t}\n\n}\n\nfunction setValueV4f( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( v.x !== undefined ) {\n\n\t\tif ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) {\n\n\t\t\tgl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t\t\tcache[ 0 ] = v.x;\n\t\t\tcache[ 1 ] = v.y;\n\t\t\tcache[ 2 ] = v.z;\n\t\t\tcache[ 3 ] = v.w;\n\n\t\t}\n\n\t} else {\n\n\t\tif ( arraysEqual( cache, v ) ) return;\n\n\t\tgl.uniform4fv( this.addr, v );\n\n\t\tcopyArray( cache, v );\n\n\t}\n\n}\n\n// Single matrix (from flat array or THREE.MatrixN)\n\nfunction setValueM2( gl, v ) {\n\n\tconst cache = this.cache;\n\tconst elements = v.elements;\n\n\tif ( elements === undefined ) {\n\n\t\tif ( arraysEqual( cache, v ) ) return;\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v );\n\n\t\tcopyArray( cache, v );\n\n\t} else {\n\n\t\tif ( arraysEqual( cache, elements ) ) return;\n\n\t\tmat2array.set( elements );\n\n\t\tgl.uniformMatrix2fv( this.addr, false, mat2array );\n\n\t\tcopyArray( cache, elements );\n\n\t}\n\n}\n\nfunction setValueM3( gl, v ) {\n\n\tconst cache = this.cache;\n\tconst elements = v.elements;\n\n\tif ( elements === undefined ) {\n\n\t\tif ( arraysEqual( cache, v ) ) return;\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v );\n\n\t\tcopyArray( cache, v );\n\n\t} else {\n\n\t\tif ( arraysEqual( cache, elements ) ) return;\n\n\t\tmat3array.set( elements );\n\n\t\tgl.uniformMatrix3fv( this.addr, false, mat3array );\n\n\t\tcopyArray( cache, elements );\n\n\t}\n\n}\n\nfunction setValueM4( gl, v ) {\n\n\tconst cache = this.cache;\n\tconst elements = v.elements;\n\n\tif ( elements === undefined ) {\n\n\t\tif ( arraysEqual( cache, v ) ) return;\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v );\n\n\t\tcopyArray( cache, v );\n\n\t} else {\n\n\t\tif ( arraysEqual( cache, elements ) ) return;\n\n\t\tmat4array.set( elements );\n\n\t\tgl.uniformMatrix4fv( this.addr, false, mat4array );\n\n\t\tcopyArray( cache, elements );\n\n\t}\n\n}\n\n// Single integer / boolean\n\nfunction setValueV1i( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( cache[ 0 ] === v ) return;\n\n\tgl.uniform1i( this.addr, v );\n\n\tcache[ 0 ] = v;\n\n}\n\n// Single integer / boolean vector (from flat array)\n\nfunction setValueV2i( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( arraysEqual( cache, v ) ) return;\n\n\tgl.uniform2iv( this.addr, v );\n\n\tcopyArray( cache, v );\n\n}\n\nfunction setValueV3i( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( arraysEqual( cache, v ) ) return;\n\n\tgl.uniform3iv( this.addr, v );\n\n\tcopyArray( cache, v );\n\n}\n\nfunction setValueV4i( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( arraysEqual( cache, v ) ) return;\n\n\tgl.uniform4iv( this.addr, v );\n\n\tcopyArray( cache, v );\n\n}\n\n// Single unsigned integer\n\nfunction setValueV1ui( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( cache[ 0 ] === v ) return;\n\n\tgl.uniform1ui( this.addr, v );\n\n\tcache[ 0 ] = v;\n\n}\n\n// Single unsigned integer vector (from flat array)\n\nfunction setValueV2ui( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( arraysEqual( cache, v ) ) return;\n\n\tgl.uniform2uiv( this.addr, v );\n\n\tcopyArray( cache, v );\n\n}\n\nfunction setValueV3ui( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( arraysEqual( cache, v ) ) return;\n\n\tgl.uniform3uiv( this.addr, v );\n\n\tcopyArray( cache, v );\n\n}\n\nfunction setValueV4ui( gl, v ) {\n\n\tconst cache = this.cache;\n\n\tif ( arraysEqual( cache, v ) ) return;\n\n\tgl.uniform4uiv( this.addr, v );\n\n\tcopyArray( cache, v );\n\n}\n\n\n// Single texture (2D / Cube)\n\nfunction setValueT1( gl, v, textures ) {\n\n\tconst cache = this.cache;\n\tconst unit = textures.allocateTextureUnit();\n\n\tif ( cache[ 0 ] !== unit ) {\n\n\t\tgl.uniform1i( this.addr, unit );\n\t\tcache[ 0 ] = unit;\n\n\t}\n\n\ttextures.setTexture2D( v || emptyTexture, unit );\n\n}\n\nfunction setValueT3D1( gl, v, textures ) {\n\n\tconst cache = this.cache;\n\tconst unit = textures.allocateTextureUnit();\n\n\tif ( cache[ 0 ] !== unit ) {\n\n\t\tgl.uniform1i( this.addr, unit );\n\t\tcache[ 0 ] = unit;\n\n\t}\n\n\ttextures.setTexture3D( v || empty3dTexture, unit );\n\n}\n\nfunction setValueT6( gl, v, textures ) {\n\n\tconst cache = this.cache;\n\tconst unit = textures.allocateTextureUnit();\n\n\tif ( cache[ 0 ] !== unit ) {\n\n\t\tgl.uniform1i( this.addr, unit );\n\t\tcache[ 0 ] = unit;\n\n\t}\n\n\ttextures.setTextureCube( v || emptyCubeTexture, unit );\n\n}\n\nfunction setValueT2DArray1( gl, v, textures ) {\n\n\tconst cache = this.cache;\n\tconst unit = textures.allocateTextureUnit();\n\n\tif ( cache[ 0 ] !== unit ) {\n\n\t\tgl.uniform1i( this.addr, unit );\n\t\tcache[ 0 ] = unit;\n\n\t}\n\n\ttextures.setTexture2DArray( v || emptyArrayTexture, unit );\n\n}\n\n// Helper to pick the right setter for the singular case\n\nfunction getSingularSetter( type ) {\n\n\tswitch ( type ) {\n\n\t\tcase 0x1406: return setValueV1f; // FLOAT\n\t\tcase 0x8b50: return setValueV2f; // _VEC2\n\t\tcase 0x8b51: return setValueV3f; // _VEC3\n\t\tcase 0x8b52: return setValueV4f; // _VEC4\n\n\t\tcase 0x8b5a: return setValueM2; // _MAT2\n\t\tcase 0x8b5b: return setValueM3; // _MAT3\n\t\tcase 0x8b5c: return setValueM4; // _MAT4\n\n\t\tcase 0x1404: case 0x8b56: return setValueV1i; // INT, BOOL\n\t\tcase 0x8b53: case 0x8b57: return setValueV2i; // _VEC2\n\t\tcase 0x8b54: case 0x8b58: return setValueV3i; // _VEC3\n\t\tcase 0x8b55: case 0x8b59: return setValueV4i; // _VEC4\n\n\t\tcase 0x1405: return setValueV1ui; // UINT\n\t\tcase 0x8dc6: return setValueV2ui; // _VEC2\n\t\tcase 0x8dc7: return setValueV3ui; // _VEC3\n\t\tcase 0x8dc8: return setValueV4ui; // _VEC4\n\n\t\tcase 0x8b5e: // SAMPLER_2D\n\t\tcase 0x8d66: // SAMPLER_EXTERNAL_OES\n\t\tcase 0x8dca: // INT_SAMPLER_2D\n\t\tcase 0x8dd2: // UNSIGNED_INT_SAMPLER_2D\n\t\tcase 0x8b62: // SAMPLER_2D_SHADOW\n\t\t\treturn setValueT1;\n\n\t\tcase 0x8b5f: // SAMPLER_3D\n\t\tcase 0x8dcb: // INT_SAMPLER_3D\n\t\tcase 0x8dd3: // UNSIGNED_INT_SAMPLER_3D\n\t\t\treturn setValueT3D1;\n\n\t\tcase 0x8b60: // SAMPLER_CUBE\n\t\tcase 0x8dcc: // INT_SAMPLER_CUBE\n\t\tcase 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE\n\t\tcase 0x8dc5: // SAMPLER_CUBE_SHADOW\n\t\t\treturn setValueT6;\n\n\t\tcase 0x8dc1: // SAMPLER_2D_ARRAY\n\t\tcase 0x8dcf: // INT_SAMPLER_2D_ARRAY\n\t\tcase 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY\n\t\tcase 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW\n\t\t\treturn setValueT2DArray1;\n\n\t}\n\n}\n\n\n// Array of scalars\n\nfunction setValueV1fArray( gl, v ) {\n\n\tgl.uniform1fv( this.addr, v );\n\n}\n\n// Array of vectors (from flat array or array of THREE.VectorN)\n\nfunction setValueV2fArray( gl, v ) {\n\n\tconst data = flatten( v, this.size, 2 );\n\n\tgl.uniform2fv( this.addr, data );\n\n}\n\nfunction setValueV3fArray( gl, v ) {\n\n\tconst data = flatten( v, this.size, 3 );\n\n\tgl.uniform3fv( this.addr, data );\n\n}\n\nfunction setValueV4fArray( gl, v ) {\n\n\tconst data = flatten( v, this.size, 4 );\n\n\tgl.uniform4fv( this.addr, data );\n\n}\n\n// Array of matrices (from flat array or array of THREE.MatrixN)\n\nfunction setValueM2Array( gl, v ) {\n\n\tconst data = flatten( v, this.size, 4 );\n\n\tgl.uniformMatrix2fv( this.addr, false, data );\n\n}\n\nfunction setValueM3Array( gl, v ) {\n\n\tconst data = flatten( v, this.size, 9 );\n\n\tgl.uniformMatrix3fv( this.addr, false, data );\n\n}\n\nfunction setValueM4Array( gl, v ) {\n\n\tconst data = flatten( v, this.size, 16 );\n\n\tgl.uniformMatrix4fv( this.addr, false, data );\n\n}\n\n// Array of integer / boolean\n\nfunction setValueV1iArray( gl, v ) {\n\n\tgl.uniform1iv( this.addr, v );\n\n}\n\n// Array of integer / boolean vectors (from flat array)\n\nfunction setValueV2iArray( gl, v ) {\n\n\tgl.uniform2iv( this.addr, v );\n\n}\n\nfunction setValueV3iArray( gl, v ) {\n\n\tgl.uniform3iv( this.addr, v );\n\n}\n\nfunction setValueV4iArray( gl, v ) {\n\n\tgl.uniform4iv( this.addr, v );\n\n}\n\n// Array of unsigned integer\n\nfunction setValueV1uiArray( gl, v ) {\n\n\tgl.uniform1uiv( this.addr, v );\n\n}\n\n// Array of unsigned integer vectors (from flat array)\n\nfunction setValueV2uiArray( gl, v ) {\n\n\tgl.uniform2uiv( this.addr, v );\n\n}\n\nfunction setValueV3uiArray( gl, v ) {\n\n\tgl.uniform3uiv( this.addr, v );\n\n}\n\nfunction setValueV4uiArray( gl, v ) {\n\n\tgl.uniform4uiv( this.addr, v );\n\n}\n\n\n// Array of textures (2D / 3D / Cube / 2DArray)\n\nfunction setValueT1Array( gl, v, textures ) {\n\n\tconst n = v.length;\n\n\tconst units = allocTexUnits( textures, n );\n\n\tgl.uniform1iv( this.addr, units );\n\n\tfor ( let i = 0; i !== n; ++ i ) {\n\n\t\ttextures.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t}\n\n}\n\nfunction setValueT3DArray( gl, v, textures ) {\n\n\tconst n = v.length;\n\n\tconst units = allocTexUnits( textures, n );\n\n\tgl.uniform1iv( this.addr, units );\n\n\tfor ( let i = 0; i !== n; ++ i ) {\n\n\t\ttextures.setTexture3D( v[ i ] || empty3dTexture, units[ i ] );\n\n\t}\n\n}\n\nfunction setValueT6Array( gl, v, textures ) {\n\n\tconst n = v.length;\n\n\tconst units = allocTexUnits( textures, n );\n\n\tgl.uniform1iv( this.addr, units );\n\n\tfor ( let i = 0; i !== n; ++ i ) {\n\n\t\ttextures.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t}\n\n}\n\nfunction setValueT2DArrayArray( gl, v, textures ) {\n\n\tconst n = v.length;\n\n\tconst units = allocTexUnits( textures, n );\n\n\tgl.uniform1iv( this.addr, units );\n\n\tfor ( let i = 0; i !== n; ++ i ) {\n\n\t\ttextures.setTexture2DArray( v[ i ] || emptyArrayTexture, units[ i ] );\n\n\t}\n\n}\n\n\n// Helper to pick the right setter for a pure (bottom-level) array\n\nfunction getPureArraySetter( type ) {\n\n\tswitch ( type ) {\n\n\t\tcase 0x1406: return setValueV1fArray; // FLOAT\n\t\tcase 0x8b50: return setValueV2fArray; // _VEC2\n\t\tcase 0x8b51: return setValueV3fArray; // _VEC3\n\t\tcase 0x8b52: return setValueV4fArray; // _VEC4\n\n\t\tcase 0x8b5a: return setValueM2Array; // _MAT2\n\t\tcase 0x8b5b: return setValueM3Array; // _MAT3\n\t\tcase 0x8b5c: return setValueM4Array; // _MAT4\n\n\t\tcase 0x1404: case 0x8b56: return setValueV1iArray; // INT, BOOL\n\t\tcase 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2\n\t\tcase 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3\n\t\tcase 0x8b55: case 0x8b59: return setValueV4iArray; // _VEC4\n\n\t\tcase 0x1405: return setValueV1uiArray; // UINT\n\t\tcase 0x8dc6: return setValueV2uiArray; // _VEC2\n\t\tcase 0x8dc7: return setValueV3uiArray; // _VEC3\n\t\tcase 0x8dc8: return setValueV4uiArray; // _VEC4\n\n\t\tcase 0x8b5e: // SAMPLER_2D\n\t\tcase 0x8d66: // SAMPLER_EXTERNAL_OES\n\t\tcase 0x8dca: // INT_SAMPLER_2D\n\t\tcase 0x8dd2: // UNSIGNED_INT_SAMPLER_2D\n\t\tcase 0x8b62: // SAMPLER_2D_SHADOW\n\t\t\treturn setValueT1Array;\n\n\t\tcase 0x8b5f: // SAMPLER_3D\n\t\tcase 0x8dcb: // INT_SAMPLER_3D\n\t\tcase 0x8dd3: // UNSIGNED_INT_SAMPLER_3D\n\t\t\treturn setValueT3DArray;\n\n\t\tcase 0x8b60: // SAMPLER_CUBE\n\t\tcase 0x8dcc: // INT_SAMPLER_CUBE\n\t\tcase 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE\n\t\tcase 0x8dc5: // SAMPLER_CUBE_SHADOW\n\t\t\treturn setValueT6Array;\n\n\t\tcase 0x8dc1: // SAMPLER_2D_ARRAY\n\t\tcase 0x8dcf: // INT_SAMPLER_2D_ARRAY\n\t\tcase 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY\n\t\tcase 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW\n\t\t\treturn setValueT2DArrayArray;\n\n\t}\n\n}\n\n// --- Uniform Classes ---\n\nclass SingleUniform {\n\n\tconstructor( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.cache = [];\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n}\n\nclass PureArrayUniform {\n\n\tconstructor( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.cache = [];\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n}\n\nclass StructuredUniform {\n\n\tconstructor( id ) {\n\n\t\tthis.id = id;\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\tsetValue( gl, value, textures ) {\n\n\t\tconst seq = this.seq;\n\n\t\tfor ( let i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tconst u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ], textures );\n\n\t\t}\n\n\t}\n\n}\n\n// --- Top-level ---\n\n// Parser - builds up the property tree from the path strings\n\nconst RePathPart = /(\\w+)(\\])?(\\[|\\.)?/g;\n\n// extracts\n// \t- the identifier (member name or array index)\n// - followed by an optional right bracket (found when array index)\n// - followed by an optional left bracket or dot (type of subscript)\n//\n// Note: These portions can be read in a non-overlapping fashion and\n// allow straightforward parsing of the hierarchy that WebGL encodes\n// in the uniform names.\n\nfunction addUniform( container, uniformObject ) {\n\n\tcontainer.seq.push( uniformObject );\n\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n}\n\nfunction parseUniform( activeInfo, addr, container ) {\n\n\tconst path = activeInfo.name,\n\t\tpathLength = path.length;\n\n\t// reset RegExp object, because of the early exit of a previous run\n\tRePathPart.lastIndex = 0;\n\n\twhile ( true ) {\n\n\t\tconst match = RePathPart.exec( path ),\n\t\t\tmatchEnd = RePathPart.lastIndex;\n\n\t\tlet id = match[ 1 ];\n\t\tconst idIsIndex = match[ 2 ] === ']',\n\t\t\tsubscript = match[ 3 ];\n\n\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\tif ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {\n\n\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\tbreak;\n\n\t\t} else {\n\n\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\tconst map = container.map;\n\t\t\tlet next = map[ id ];\n\n\t\t\tif ( next === undefined ) {\n\n\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\taddUniform( container, next );\n\n\t\t\t}\n\n\t\t\tcontainer = next;\n\n\t\t}\n\n\t}\n\n}\n\n// Root Container\n\nclass WebGLUniforms {\n\n\tconstructor( gl, program ) {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t\tconst n = gl.getProgramParameter( program, 35718 );\n\n\t\tfor ( let i = 0; i < n; ++ i ) {\n\n\t\t\tconst info = gl.getActiveUniform( program, i ),\n\t\t\t\taddr = gl.getUniformLocation( program, info.name );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tsetValue( gl, name, value, textures ) {\n\n\t\tconst u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, textures );\n\n\t}\n\n\tsetOptional( gl, object, name ) {\n\n\t\tconst v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t}\n\n\tstatic upload( gl, seq, values, textures ) {\n\n\t\tfor ( let i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tconst u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\t\t\t\tu.setValue( gl, v.value, textures );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tstatic seqWithValue( seq, values ) {\n\n\t\tconst r = [];\n\n\t\tfor ( let i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tconst u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n}\n\nfunction WebGLShader( gl, type, string ) {\n\n\tconst shader = gl.createShader( type );\n\n\tgl.shaderSource( shader, string );\n\tgl.compileShader( shader );\n\n\treturn shader;\n\n}\n\nlet programIdCount = 0;\n\nfunction handleSource( string, errorLine ) {\n\n\tconst lines = string.split( '\\n' );\n\tconst lines2 = [];\n\n\tconst from = Math.max( errorLine - 6, 0 );\n\tconst to = Math.min( errorLine + 6, lines.length );\n\n\tfor ( let i = from; i < to; i ++ ) {\n\n\t\tconst line = i + 1;\n\t\tlines2.push( `${line === errorLine ? '>' : ' '} ${line}: ${lines[ i ]}` );\n\n\t}\n\n\treturn lines2.join( '\\n' );\n\n}\n\nfunction getEncodingComponents( encoding ) {\n\n\tswitch ( encoding ) {\n\n\t\tcase LinearEncoding:\n\t\t\treturn [ 'Linear', '( value )' ];\n\t\tcase sRGBEncoding:\n\t\t\treturn [ 'sRGB', '( value )' ];\n\t\tdefault:\n\t\t\tconsole.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding );\n\t\t\treturn [ 'Linear', '( value )' ];\n\n\t}\n\n}\n\nfunction getShaderErrors( gl, shader, type ) {\n\n\tconst status = gl.getShaderParameter( shader, 35713 );\n\tconst errors = gl.getShaderInfoLog( shader ).trim();\n\n\tif ( status && errors === '' ) return '';\n\n\tconst errorMatches = /ERROR: 0:(\\d+)/.exec( errors );\n\tif ( errorMatches ) {\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\tconst errorLine = parseInt( errorMatches[ 1 ] );\n\t\treturn type.toUpperCase() + '\\n\\n' + errors + '\\n\\n' + handleSource( gl.getShaderSource( shader ), errorLine );\n\n\t} else {\n\n\t\treturn errors;\n\n\t}\n\n}\n\nfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\tconst components = getEncodingComponents( encoding );\n\treturn 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }';\n\n}\n\nfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\tlet toneMappingName;\n\n\tswitch ( toneMapping ) {\n\n\t\tcase LinearToneMapping:\n\t\t\ttoneMappingName = 'Linear';\n\t\t\tbreak;\n\n\t\tcase ReinhardToneMapping:\n\t\t\ttoneMappingName = 'Reinhard';\n\t\t\tbreak;\n\n\t\tcase CineonToneMapping:\n\t\t\ttoneMappingName = 'OptimizedCineon';\n\t\t\tbreak;\n\n\t\tcase ACESFilmicToneMapping:\n\t\t\ttoneMappingName = 'ACESFilmic';\n\t\t\tbreak;\n\n\t\tcase CustomToneMapping:\n\t\t\ttoneMappingName = 'Custom';\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tconsole.warn( 'THREE.WebGLProgram: Unsupported toneMapping:', toneMapping );\n\t\t\ttoneMappingName = 'Linear';\n\n\t}\n\n\treturn 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }';\n\n}\n\nfunction generateExtensions( parameters ) {\n\n\tconst chunks = [\n\t\t( parameters.extensionDerivatives || !! parameters.envMapCubeUVHeight || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t( parameters.extensionShaderTextureLOD || parameters.envMap || parameters.transmission ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t];\n\n\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n}\n\nfunction generateDefines( defines ) {\n\n\tconst chunks = [];\n\n\tfor ( const name in defines ) {\n\n\t\tconst value = defines[ name ];\n\n\t\tif ( value === false ) continue;\n\n\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t}\n\n\treturn chunks.join( '\\n' );\n\n}\n\nfunction fetchAttributeLocations( gl, program ) {\n\n\tconst attributes = {};\n\n\tconst n = gl.getProgramParameter( program, 35721 );\n\n\tfor ( let i = 0; i < n; i ++ ) {\n\n\t\tconst info = gl.getActiveAttrib( program, i );\n\t\tconst name = info.name;\n\n\t\tlet locationSize = 1;\n\t\tif ( info.type === 35674 ) locationSize = 2;\n\t\tif ( info.type === 35675 ) locationSize = 3;\n\t\tif ( info.type === 35676 ) locationSize = 4;\n\n\t\t// console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i );\n\n\t\tattributes[ name ] = {\n\t\t\ttype: info.type,\n\t\t\tlocation: gl.getAttribLocation( program, name ),\n\t\t\tlocationSize: locationSize\n\t\t};\n\n\t}\n\n\treturn attributes;\n\n}\n\nfunction filterEmptyLine( string ) {\n\n\treturn string !== '';\n\n}\n\nfunction replaceLightNums( string, parameters ) {\n\n\treturn string\n\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights )\n\t\t.replace( /NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows )\n\t\t.replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows )\n\t\t.replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows );\n\n}\n\nfunction replaceClippingPlaneNums( string, parameters ) {\n\n\treturn string\n\t\t.replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes )\n\t\t.replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) );\n\n}\n\n// Resolve Includes\n\nconst includePattern = /^[ \\t]*#include +<([\\w\\d./]+)>/gm;\n\nfunction resolveIncludes( string ) {\n\n\treturn string.replace( includePattern, includeReplacer );\n\n}\n\nfunction includeReplacer( match, include ) {\n\n\tconst string = ShaderChunk[ include ];\n\n\tif ( string === undefined ) {\n\n\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t}\n\n\treturn resolveIncludes( string );\n\n}\n\n// Unroll Loops\n\nconst deprecatedUnrollLoopPattern = /#pragma unroll_loop[\\s]+?for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\nconst unrollLoopPattern = /#pragma unroll_loop_start\\s+for\\s*\\(\\s*int\\s+i\\s*=\\s*(\\d+)\\s*;\\s*i\\s*<\\s*(\\d+)\\s*;\\s*i\\s*\\+\\+\\s*\\)\\s*{([\\s\\S]+?)}\\s+#pragma unroll_loop_end/g;\n\nfunction unrollLoops( string ) {\n\n\treturn string\n\t\t.replace( unrollLoopPattern, loopReplacer )\n\t\t.replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer );\n\n}\n\nfunction deprecatedLoopReplacer( match, start, end, snippet ) {\n\n\tconsole.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' );\n\treturn loopReplacer( match, start, end, snippet );\n\n}\n\nfunction loopReplacer( match, start, end, snippet ) {\n\n\tlet string = '';\n\n\tfor ( let i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\tstring += snippet\n\t\t\t.replace( /\\[\\s*i\\s*\\]/g, '[ ' + i + ' ]' )\n\t\t\t.replace( /UNROLLED_LOOP_INDEX/g, i );\n\n\t}\n\n\treturn string;\n\n}\n\n//\n\nfunction generatePrecision( parameters ) {\n\n\tlet precisionstring = 'precision ' + parameters.precision + ' float;\\nprecision ' + parameters.precision + ' int;';\n\n\tif ( parameters.precision === 'highp' ) {\n\n\t\tprecisionstring += '\\n#define HIGH_PRECISION';\n\n\t} else if ( parameters.precision === 'mediump' ) {\n\n\t\tprecisionstring += '\\n#define MEDIUM_PRECISION';\n\n\t} else if ( parameters.precision === 'lowp' ) {\n\n\t\tprecisionstring += '\\n#define LOW_PRECISION';\n\n\t}\n\n\treturn precisionstring;\n\n}\n\nfunction generateShadowMapTypeDefine( parameters ) {\n\n\tlet shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t} else if ( parameters.shadowMapType === VSMShadowMap ) {\n\n\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';\n\n\t}\n\n\treturn shadowMapTypeDefine;\n\n}\n\nfunction generateEnvMapTypeDefine( parameters ) {\n\n\tlet envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\n\tif ( parameters.envMap ) {\n\n\t\tswitch ( parameters.envMapMode ) {\n\n\t\t\tcase CubeReflectionMapping:\n\t\t\tcase CubeRefractionMapping:\n\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\tbreak;\n\n\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\treturn envMapTypeDefine;\n\n}\n\nfunction generateEnvMapModeDefine( parameters ) {\n\n\tlet envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\n\tif ( parameters.envMap ) {\n\n\t\tswitch ( parameters.envMapMode ) {\n\n\t\t\tcase CubeRefractionMapping:\n\n\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\treturn envMapModeDefine;\n\n}\n\nfunction generateEnvMapBlendingDefine( parameters ) {\n\n\tlet envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';\n\n\tif ( parameters.envMap ) {\n\n\t\tswitch ( parameters.combine ) {\n\n\t\t\tcase MultiplyOperation:\n\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\tbreak;\n\n\t\t\tcase MixOperation:\n\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\tbreak;\n\n\t\t\tcase AddOperation:\n\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\treturn envMapBlendingDefine;\n\n}\n\nfunction generateCubeUVSize( parameters ) {\n\n\tconst imageHeight = parameters.envMapCubeUVHeight;\n\n\tif ( imageHeight === null ) return null;\n\n\tconst maxMip = Math.log2( imageHeight ) - 2;\n\n\tconst texelHeight = 1.0 / imageHeight;\n\n\tconst texelWidth = 1.0 / ( 3 * Math.max( Math.pow( 2, maxMip ), 7 * 16 ) );\n\n\treturn { texelWidth, texelHeight, maxMip };\n\n}\n\nfunction WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {\n\n\t// TODO Send this event to Three.js DevTools\n\t// console.log( 'WebGLProgram', cacheKey );\n\n\tconst gl = renderer.getContext();\n\n\tconst defines = parameters.defines;\n\n\tlet vertexShader = parameters.vertexShader;\n\tlet fragmentShader = parameters.fragmentShader;\n\n\tconst shadowMapTypeDefine = generateShadowMapTypeDefine( parameters );\n\tconst envMapTypeDefine = generateEnvMapTypeDefine( parameters );\n\tconst envMapModeDefine = generateEnvMapModeDefine( parameters );\n\tconst envMapBlendingDefine = generateEnvMapBlendingDefine( parameters );\n\tconst envMapCubeUVSize = generateCubeUVSize( parameters );\n\n\tconst customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters );\n\n\tconst customDefines = generateDefines( defines );\n\n\tconst program = gl.createProgram();\n\n\tlet prefixVertex, prefixFragment;\n\tlet versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\\n' : '';\n\n\tif ( parameters.isRawShaderMaterial ) {\n\n\t\tprefixVertex = [\n\n\t\t\tcustomDefines\n\n\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\tif ( prefixVertex.length > 0 ) {\n\n\t\t\tprefixVertex += '\\n';\n\n\t\t}\n\n\t\tprefixFragment = [\n\n\t\t\tcustomExtensions,\n\t\t\tcustomDefines\n\n\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\tif ( prefixFragment.length > 0 ) {\n\n\t\t\tprefixFragment += '\\n';\n\n\t\t}\n\n\t} else {\n\n\t\tprefixVertex = [\n\n\t\t\tgeneratePrecision( parameters ),\n\n\t\t\t'#define SHADER_NAME ' + parameters.shaderName,\n\n\t\t\tcustomDefines,\n\n\t\t\tparameters.instancing ? '#define USE_INSTANCING' : '',\n\t\t\tparameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '',\n\n\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',\n\n\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',\n\t\t\t( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',\n\n\t\t\tparameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',\n\t\t\tparameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',\n\t\t\tparameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',\n\n\t\t\tparameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '',\n\t\t\tparameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '',\n\n\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\n\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\tparameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '',\n\t\t\tparameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '',\n\n\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\n\t\t\tparameters.transmission ? '#define USE_TRANSMISSION' : '',\n\t\t\tparameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',\n\t\t\tparameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',\n\n\t\t\tparameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '',\n\t\t\tparameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '',\n\n\t\t\tparameters.vertexTangents ? '#define USE_TANGENT' : '',\n\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\t\t\tparameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',\n\t\t\tparameters.vertexUvs ? '#define USE_UV' : '',\n\t\t\tparameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',\n\n\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\n\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t( parameters.morphColors && parameters.isWebGL2 ) ? '#define USE_MORPHCOLORS' : '',\n\t\t\t( parameters.morphTargetsCount > 0 && parameters.isWebGL2 ) ? '#define MORPHTARGETS_TEXTURE' : '',\n\t\t\t( parameters.morphTargetsCount > 0 && parameters.isWebGL2 ) ? '#define MORPHTARGETS_TEXTURE_STRIDE ' + parameters.morphTextureStride : '',\n\t\t\t( parameters.morphTargetsCount > 0 && parameters.isWebGL2 ) ? '#define MORPHTARGETS_COUNT ' + parameters.morphTargetsCount : '',\n\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t'uniform vec3 cameraPosition;',\n\t\t\t'uniform bool isOrthographic;',\n\n\t\t\t'#ifdef USE_INSTANCING',\n\n\t\t\t'\tattribute mat4 instanceMatrix;',\n\n\t\t\t'#endif',\n\n\t\t\t'#ifdef USE_INSTANCING_COLOR',\n\n\t\t\t'\tattribute vec3 instanceColor;',\n\n\t\t\t'#endif',\n\n\t\t\t'attribute vec3 position;',\n\t\t\t'attribute vec3 normal;',\n\t\t\t'attribute vec2 uv;',\n\n\t\t\t'#ifdef USE_TANGENT',\n\n\t\t\t'\tattribute vec4 tangent;',\n\n\t\t\t'#endif',\n\n\t\t\t'#if defined( USE_COLOR_ALPHA )',\n\n\t\t\t'\tattribute vec4 color;',\n\n\t\t\t'#elif defined( USE_COLOR )',\n\n\t\t\t'\tattribute vec3 color;',\n\n\t\t\t'#endif',\n\n\t\t\t'#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )',\n\n\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t'\t#else',\n\n\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t'\t#endif',\n\n\t\t\t'#endif',\n\n\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t'#endif',\n\n\t\t\t'\\n'\n\n\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\tprefixFragment = [\n\n\t\t\tcustomExtensions,\n\n\t\t\tgeneratePrecision( parameters ),\n\n\t\t\t'#define SHADER_NAME ' + parameters.shaderName,\n\n\t\t\tcustomDefines,\n\n\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',\n\n\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\tparameters.matcap ? '#define USE_MATCAP' : '',\n\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\tenvMapCubeUVSize ? '#define CUBEUV_TEXEL_WIDTH ' + envMapCubeUVSize.texelWidth : '',\n\t\t\tenvMapCubeUVSize ? '#define CUBEUV_TEXEL_HEIGHT ' + envMapCubeUVSize.texelHeight : '',\n\t\t\tenvMapCubeUVSize ? '#define CUBEUV_MAX_MIP ' + envMapCubeUVSize.maxMip + '.0' : '',\n\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',\n\t\t\t( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',\n\n\t\t\tparameters.clearcoat ? '#define USE_CLEARCOAT' : '',\n\t\t\tparameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',\n\t\t\tparameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',\n\t\t\tparameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',\n\n\t\t\tparameters.iridescence ? '#define USE_IRIDESCENCE' : '',\n\t\t\tparameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '',\n\t\t\tparameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '',\n\n\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\tparameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '',\n\t\t\tparameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '',\n\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\n\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\tparameters.alphaTest ? '#define USE_ALPHATEST' : '',\n\n\t\t\tparameters.sheen ? '#define USE_SHEEN' : '',\n\t\t\tparameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '',\n\t\t\tparameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '',\n\n\t\t\tparameters.transmission ? '#define USE_TRANSMISSION' : '',\n\t\t\tparameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',\n\t\t\tparameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',\n\n\t\t\tparameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '',\n\n\t\t\tparameters.vertexTangents ? '#define USE_TANGENT' : '',\n\t\t\tparameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '',\n\t\t\tparameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',\n\t\t\tparameters.vertexUvs ? '#define USE_UV' : '',\n\t\t\tparameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',\n\n\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\tparameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '',\n\n\t\t\tparameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '',\n\n\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t'uniform vec3 cameraPosition;',\n\t\t\t'uniform bool isOrthographic;',\n\n\t\t\t( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',\n\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',\n\n\t\t\tparameters.dithering ? '#define DITHERING' : '',\n\t\t\tparameters.opaque ? '#define OPAQUE' : '',\n\n\t\t\tShaderChunk[ 'encodings_pars_fragment' ], // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\tgetTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ),\n\n\t\t\tparameters.useDepthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '',\n\n\t\t\t'\\n'\n\n\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tvertexShader = resolveIncludes( vertexShader );\n\tvertexShader = replaceLightNums( vertexShader, parameters );\n\tvertexShader = replaceClippingPlaneNums( vertexShader, parameters );\n\n\tfragmentShader = resolveIncludes( fragmentShader );\n\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\tfragmentShader = replaceClippingPlaneNums( fragmentShader, parameters );\n\n\tvertexShader = unrollLoops( vertexShader );\n\tfragmentShader = unrollLoops( fragmentShader );\n\n\tif ( parameters.isWebGL2 && parameters.isRawShaderMaterial !== true ) {\n\n\t\t// GLSL 3.0 conversion for built-in materials and ShaderMaterial\n\n\t\tversionString = '#version 300 es\\n';\n\n\t\tprefixVertex = [\n\t\t\t'precision mediump sampler2DArray;',\n\t\t\t'#define attribute in',\n\t\t\t'#define varying out',\n\t\t\t'#define texture2D texture'\n\t\t].join( '\\n' ) + '\\n' + prefixVertex;\n\n\t\tprefixFragment = [\n\t\t\t'#define varying in',\n\t\t\t( parameters.glslVersion === GLSL3 ) ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;',\n\t\t\t( parameters.glslVersion === GLSL3 ) ? '' : '#define gl_FragColor pc_fragColor',\n\t\t\t'#define gl_FragDepthEXT gl_FragDepth',\n\t\t\t'#define texture2D texture',\n\t\t\t'#define textureCube texture',\n\t\t\t'#define texture2DProj textureProj',\n\t\t\t'#define texture2DLodEXT textureLod',\n\t\t\t'#define texture2DProjLodEXT textureProjLod',\n\t\t\t'#define textureCubeLodEXT textureLod',\n\t\t\t'#define texture2DGradEXT textureGrad',\n\t\t\t'#define texture2DProjGradEXT textureProjGrad',\n\t\t\t'#define textureCubeGradEXT textureGrad'\n\t\t].join( '\\n' ) + '\\n' + prefixFragment;\n\n\t}\n\n\tconst vertexGlsl = versionString + prefixVertex + vertexShader;\n\tconst fragmentGlsl = versionString + prefixFragment + fragmentShader;\n\n\t// console.log( '*VERTEX*', vertexGlsl );\n\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\tconst glVertexShader = WebGLShader( gl, 35633, vertexGlsl );\n\tconst glFragmentShader = WebGLShader( gl, 35632, fragmentGlsl );\n\n\tgl.attachShader( program, glVertexShader );\n\tgl.attachShader( program, glFragmentShader );\n\n\t// Force a particular attribute to index 0.\n\n\tif ( parameters.index0AttributeName !== undefined ) {\n\n\t\tgl.bindAttribLocation( program, 0, parameters.index0AttributeName );\n\n\t} else if ( parameters.morphTargets === true ) {\n\n\t\t// programs with morphTargets displace position out of attribute 0\n\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t}\n\n\tgl.linkProgram( program );\n\n\t// check for link errors\n\tif ( renderer.debug.checkShaderErrors ) {\n\n\t\tconst programLog = gl.getProgramInfoLog( program ).trim();\n\t\tconst vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();\n\t\tconst fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();\n\n\t\tlet runnable = true;\n\t\tlet haveDiagnostics = true;\n\n\t\tif ( gl.getProgramParameter( program, 35714 ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconst vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );\n\t\t\tconst fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );\n\n\t\t\tconsole.error(\n\t\t\t\t'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +\n\t\t\t\t'VALIDATE_STATUS ' + gl.getProgramParameter( program, 35715 ) + '\\n\\n' +\n\t\t\t\t'Program Info Log: ' + programLog + '\\n' +\n\t\t\t\tvertexErrors + '\\n' +\n\t\t\t\tfragmentErrors\n\t\t\t);\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: Program Info Log:', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t}\n\n\t// Clean up\n\n\t// Crashes in iOS9 and iOS10. #18402\n\t// gl.detachShader( program, glVertexShader );\n\t// gl.detachShader( program, glFragmentShader );\n\n\tgl.deleteShader( glVertexShader );\n\tgl.deleteShader( glFragmentShader );\n\n\t// set up caching for uniform locations\n\n\tlet cachedUniforms;\n\n\tthis.getUniforms = function () {\n\n\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\tcachedUniforms = new WebGLUniforms( gl, program );\n\n\t\t}\n\n\t\treturn cachedUniforms;\n\n\t};\n\n\t// set up caching for attribute locations\n\n\tlet cachedAttributes;\n\n\tthis.getAttributes = function () {\n\n\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t}\n\n\t\treturn cachedAttributes;\n\n\t};\n\n\t// free resource\n\n\tthis.destroy = function () {\n\n\t\tbindingStates.releaseStatesOfProgram( this );\n\n\t\tgl.deleteProgram( program );\n\t\tthis.program = undefined;\n\n\t};\n\n\t//\n\n\tthis.name = parameters.shaderName;\n\tthis.id = programIdCount ++;\n\tthis.cacheKey = cacheKey;\n\tthis.usedTimes = 1;\n\tthis.program = program;\n\tthis.vertexShader = glVertexShader;\n\tthis.fragmentShader = glFragmentShader;\n\n\treturn this;\n\n}\n\nlet _id = 0;\n\nclass WebGLShaderCache {\n\n\tconstructor() {\n\n\t\tthis.shaderCache = new Map();\n\t\tthis.materialCache = new Map();\n\n\t}\n\n\tupdate( material ) {\n\n\t\tconst vertexShader = material.vertexShader;\n\t\tconst fragmentShader = material.fragmentShader;\n\n\t\tconst vertexShaderStage = this._getShaderStage( vertexShader );\n\t\tconst fragmentShaderStage = this._getShaderStage( fragmentShader );\n\n\t\tconst materialShaders = this._getShaderCacheForMaterial( material );\n\n\t\tif ( materialShaders.has( vertexShaderStage ) === false ) {\n\n\t\t\tmaterialShaders.add( vertexShaderStage );\n\t\t\tvertexShaderStage.usedTimes ++;\n\n\t\t}\n\n\t\tif ( materialShaders.has( fragmentShaderStage ) === false ) {\n\n\t\t\tmaterialShaders.add( fragmentShaderStage );\n\t\t\tfragmentShaderStage.usedTimes ++;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tremove( material ) {\n\n\t\tconst materialShaders = this.materialCache.get( material );\n\n\t\tfor ( const shaderStage of materialShaders ) {\n\n\t\t\tshaderStage.usedTimes --;\n\n\t\t\tif ( shaderStage.usedTimes === 0 ) this.shaderCache.delete( shaderStage.code );\n\n\t\t}\n\n\t\tthis.materialCache.delete( material );\n\n\t\treturn this;\n\n\t}\n\n\tgetVertexShaderID( material ) {\n\n\t\treturn this._getShaderStage( material.vertexShader ).id;\n\n\t}\n\n\tgetFragmentShaderID( material ) {\n\n\t\treturn this._getShaderStage( material.fragmentShader ).id;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.shaderCache.clear();\n\t\tthis.materialCache.clear();\n\n\t}\n\n\t_getShaderCacheForMaterial( material ) {\n\n\t\tconst cache = this.materialCache;\n\n\t\tif ( cache.has( material ) === false ) {\n\n\t\t\tcache.set( material, new Set() );\n\n\t\t}\n\n\t\treturn cache.get( material );\n\n\t}\n\n\t_getShaderStage( code ) {\n\n\t\tconst cache = this.shaderCache;\n\n\t\tif ( cache.has( code ) === false ) {\n\n\t\t\tconst stage = new WebGLShaderStage( code );\n\t\t\tcache.set( code, stage );\n\n\t\t}\n\n\t\treturn cache.get( code );\n\n\t}\n\n}\n\nclass WebGLShaderStage {\n\n\tconstructor( code ) {\n\n\t\tthis.id = _id ++;\n\n\t\tthis.code = code;\n\t\tthis.usedTimes = 0;\n\n\t}\n\n}\n\nfunction WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping ) {\n\n\tconst _programLayers = new Layers();\n\tconst _customShaders = new WebGLShaderCache();\n\tconst programs = [];\n\n\tconst isWebGL2 = capabilities.isWebGL2;\n\tconst logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;\n\tconst vertexTextures = capabilities.vertexTextures;\n\tlet precision = capabilities.precision;\n\n\tconst shaderIDs = {\n\t\tMeshDepthMaterial: 'depth',\n\t\tMeshDistanceMaterial: 'distanceRGBA',\n\t\tMeshNormalMaterial: 'normal',\n\t\tMeshBasicMaterial: 'basic',\n\t\tMeshLambertMaterial: 'lambert',\n\t\tMeshPhongMaterial: 'phong',\n\t\tMeshToonMaterial: 'toon',\n\t\tMeshStandardMaterial: 'physical',\n\t\tMeshPhysicalMaterial: 'physical',\n\t\tMeshMatcapMaterial: 'matcap',\n\t\tLineBasicMaterial: 'basic',\n\t\tLineDashedMaterial: 'dashed',\n\t\tPointsMaterial: 'points',\n\t\tShadowMaterial: 'shadow',\n\t\tSpriteMaterial: 'sprite'\n\t};\n\n\tfunction getParameters( material, lights, shadows, scene, object ) {\n\n\t\tconst fog = scene.fog;\n\t\tconst geometry = object.geometry;\n\t\tconst environment = material.isMeshStandardMaterial ? scene.environment : null;\n\n\t\tconst envMap = ( material.isMeshStandardMaterial ? cubeuvmaps : cubemaps ).get( material.envMap || environment );\n\t\tconst envMapCubeUVHeight = ( !! envMap ) && ( envMap.mapping === CubeUVReflectionMapping ) ? envMap.image.height : null;\n\n\t\tconst shaderID = shaderIDs[ material.type ];\n\n\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t// (not to blow over maxLights budget)\n\n\t\tif ( material.precision !== null ) {\n\n\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tconst morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;\n\t\tconst morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;\n\n\t\tlet morphTextureStride = 0;\n\n\t\tif ( geometry.morphAttributes.position !== undefined ) morphTextureStride = 1;\n\t\tif ( geometry.morphAttributes.normal !== undefined ) morphTextureStride = 2;\n\t\tif ( geometry.morphAttributes.color !== undefined ) morphTextureStride = 3;\n\n\t\t//\n\n\t\tlet vertexShader, fragmentShader;\n\t\tlet customVertexShaderID, customFragmentShaderID;\n\n\t\tif ( shaderID ) {\n\n\t\t\tconst shader = ShaderLib[ shaderID ];\n\n\t\t\tvertexShader = shader.vertexShader;\n\t\t\tfragmentShader = shader.fragmentShader;\n\n\t\t} else {\n\n\t\t\tvertexShader = material.vertexShader;\n\t\t\tfragmentShader = material.fragmentShader;\n\n\t\t\t_customShaders.update( material );\n\n\t\t\tcustomVertexShaderID = _customShaders.getVertexShaderID( material );\n\t\t\tcustomFragmentShaderID = _customShaders.getFragmentShaderID( material );\n\n\t\t}\n\n\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\tconst useAlphaTest = material.alphaTest > 0;\n\t\tconst useClearcoat = material.clearcoat > 0;\n\t\tconst useIridescence = material.iridescence > 0;\n\n\t\tconst parameters = {\n\n\t\t\tisWebGL2: isWebGL2,\n\n\t\t\tshaderID: shaderID,\n\t\t\tshaderName: material.type,\n\n\t\t\tvertexShader: vertexShader,\n\t\t\tfragmentShader: fragmentShader,\n\t\t\tdefines: material.defines,\n\n\t\t\tcustomVertexShaderID: customVertexShaderID,\n\t\t\tcustomFragmentShaderID: customFragmentShaderID,\n\n\t\t\tisRawShaderMaterial: material.isRawShaderMaterial === true,\n\t\t\tglslVersion: material.glslVersion,\n\n\t\t\tprecision: precision,\n\n\t\t\tinstancing: object.isInstancedMesh === true,\n\t\t\tinstancingColor: object.isInstancedMesh === true && object.instanceColor !== null,\n\n\t\t\tsupportsVertexTextures: vertexTextures,\n\t\t\toutputEncoding: ( currentRenderTarget === null ) ? renderer.outputEncoding : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.encoding : LinearEncoding ),\n\t\t\tmap: !! material.map,\n\t\t\tmatcap: !! material.matcap,\n\t\t\tenvMap: !! envMap,\n\t\t\tenvMapMode: envMap && envMap.mapping,\n\t\t\tenvMapCubeUVHeight: envMapCubeUVHeight,\n\t\t\tlightMap: !! material.lightMap,\n\t\t\taoMap: !! material.aoMap,\n\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\tbumpMap: !! material.bumpMap,\n\t\t\tnormalMap: !! material.normalMap,\n\t\t\tobjectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap,\n\t\t\ttangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap,\n\n\t\t\tdecodeVideoTexture: !! material.map && ( material.map.isVideoTexture === true ) && ( material.map.encoding === sRGBEncoding ),\n\n\t\t\tclearcoat: useClearcoat,\n\t\t\tclearcoatMap: useClearcoat && !! material.clearcoatMap,\n\t\t\tclearcoatRoughnessMap: useClearcoat && !! material.clearcoatRoughnessMap,\n\t\t\tclearcoatNormalMap: useClearcoat && !! material.clearcoatNormalMap,\n\n\t\t\tiridescence: useIridescence,\n\t\t\tiridescenceMap: useIridescence && !! material.iridescenceMap,\n\t\t\tiridescenceThicknessMap: useIridescence && !! material.iridescenceThicknessMap,\n\n\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\tspecularMap: !! material.specularMap,\n\t\t\tspecularIntensityMap: !! material.specularIntensityMap,\n\t\t\tspecularColorMap: !! material.specularColorMap,\n\n\t\t\topaque: material.transparent === false && material.blending === NormalBlending,\n\n\t\t\talphaMap: !! material.alphaMap,\n\t\t\talphaTest: useAlphaTest,\n\n\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\tsheen: material.sheen > 0,\n\t\t\tsheenColorMap: !! material.sheenColorMap,\n\t\t\tsheenRoughnessMap: !! material.sheenRoughnessMap,\n\n\t\t\ttransmission: material.transmission > 0,\n\t\t\ttransmissionMap: !! material.transmissionMap,\n\t\t\tthicknessMap: !! material.thicknessMap,\n\n\t\t\tcombine: material.combine,\n\n\t\t\tvertexTangents: ( !! material.normalMap && !! geometry.attributes.tangent ),\n\t\t\tvertexColors: material.vertexColors,\n\t\t\tvertexAlphas: material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4,\n\t\t\tvertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.iridescenceMap || !! material.iridescenceThicknessMap || !! material.displacementMap || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || !! material.sheenColorMap || !! material.sheenRoughnessMap,\n\t\t\tuvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || !! material.iridescenceMap || !! material.iridescenceThicknessMap || material.transmission > 0 || !! material.transmissionMap || !! material.thicknessMap || !! material.specularIntensityMap || !! material.specularColorMap || material.sheen > 0 || !! material.sheenColorMap || !! material.sheenRoughnessMap ) && !! material.displacementMap,\n\n\t\t\tfog: !! fog,\n\t\t\tuseFog: material.fog === true,\n\t\t\tfogExp2: ( fog && fog.isFogExp2 ),\n\n\t\t\tflatShading: !! material.flatShading,\n\n\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tskinning: object.isSkinnedMesh === true,\n\n\t\t\tmorphTargets: geometry.morphAttributes.position !== undefined,\n\t\t\tmorphNormals: geometry.morphAttributes.normal !== undefined,\n\t\t\tmorphColors: geometry.morphAttributes.color !== undefined,\n\t\t\tmorphTargetsCount: morphTargetsCount,\n\t\t\tmorphTextureStride: morphTextureStride,\n\n\t\t\tnumDirLights: lights.directional.length,\n\t\t\tnumPointLights: lights.point.length,\n\t\t\tnumSpotLights: lights.spot.length,\n\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\tnumDirLightShadows: lights.directionalShadowMap.length,\n\t\t\tnumPointLightShadows: lights.pointShadowMap.length,\n\t\t\tnumSpotLightShadows: lights.spotShadowMap.length,\n\n\t\t\tnumClippingPlanes: clipping.numPlanes,\n\t\t\tnumClipIntersection: clipping.numIntersection,\n\n\t\t\tdithering: material.dithering,\n\n\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,\n\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\ttoneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,\n\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\tflipSided: material.side === BackSide,\n\n\t\t\tuseDepthPacking: !! material.depthPacking,\n\t\t\tdepthPacking: material.depthPacking || 0,\n\n\t\t\tindex0AttributeName: material.index0AttributeName,\n\n\t\t\textensionDerivatives: material.extensions && material.extensions.derivatives,\n\t\t\textensionFragDepth: material.extensions && material.extensions.fragDepth,\n\t\t\textensionDrawBuffers: material.extensions && material.extensions.drawBuffers,\n\t\t\textensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD,\n\n\t\t\trendererExtensionFragDepth: isWebGL2 || extensions.has( 'EXT_frag_depth' ),\n\t\t\trendererExtensionDrawBuffers: isWebGL2 || extensions.has( 'WEBGL_draw_buffers' ),\n\t\t\trendererExtensionShaderTextureLod: isWebGL2 || extensions.has( 'EXT_shader_texture_lod' ),\n\n\t\t\tcustomProgramCacheKey: material.customProgramCacheKey()\n\n\t\t};\n\n\t\treturn parameters;\n\n\t}\n\n\tfunction getProgramCacheKey( parameters ) {\n\n\t\tconst array = [];\n\n\t\tif ( parameters.shaderID ) {\n\n\t\t\tarray.push( parameters.shaderID );\n\n\t\t} else {\n\n\t\t\tarray.push( parameters.customVertexShaderID );\n\t\t\tarray.push( parameters.customFragmentShaderID );\n\n\t\t}\n\n\t\tif ( parameters.defines !== undefined ) {\n\n\t\t\tfor ( const name in parameters.defines ) {\n\n\t\t\t\tarray.push( name );\n\t\t\t\tarray.push( parameters.defines[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( parameters.isRawShaderMaterial === false ) {\n\n\t\t\tgetProgramCacheKeyParameters( array, parameters );\n\t\t\tgetProgramCacheKeyBooleans( array, parameters );\n\t\t\tarray.push( renderer.outputEncoding );\n\n\t\t}\n\n\t\tarray.push( parameters.customProgramCacheKey );\n\n\t\treturn array.join();\n\n\t}\n\n\tfunction getProgramCacheKeyParameters( array, parameters ) {\n\n\t\tarray.push( parameters.precision );\n\t\tarray.push( parameters.outputEncoding );\n\t\tarray.push( parameters.envMapMode );\n\t\tarray.push( parameters.envMapCubeUVHeight );\n\t\tarray.push( parameters.combine );\n\t\tarray.push( parameters.vertexUvs );\n\t\tarray.push( parameters.fogExp2 );\n\t\tarray.push( parameters.sizeAttenuation );\n\t\tarray.push( parameters.morphTargetsCount );\n\t\tarray.push( parameters.morphAttributeCount );\n\t\tarray.push( parameters.numDirLights );\n\t\tarray.push( parameters.numPointLights );\n\t\tarray.push( parameters.numSpotLights );\n\t\tarray.push( parameters.numHemiLights );\n\t\tarray.push( parameters.numRectAreaLights );\n\t\tarray.push( parameters.numDirLightShadows );\n\t\tarray.push( parameters.numPointLightShadows );\n\t\tarray.push( parameters.numSpotLightShadows );\n\t\tarray.push( parameters.shadowMapType );\n\t\tarray.push( parameters.toneMapping );\n\t\tarray.push( parameters.numClippingPlanes );\n\t\tarray.push( parameters.numClipIntersection );\n\t\tarray.push( parameters.depthPacking );\n\n\t}\n\n\tfunction getProgramCacheKeyBooleans( array, parameters ) {\n\n\t\t_programLayers.disableAll();\n\n\t\tif ( parameters.isWebGL2 )\n\t\t\t_programLayers.enable( 0 );\n\t\tif ( parameters.supportsVertexTextures )\n\t\t\t_programLayers.enable( 1 );\n\t\tif ( parameters.instancing )\n\t\t\t_programLayers.enable( 2 );\n\t\tif ( parameters.instancingColor )\n\t\t\t_programLayers.enable( 3 );\n\t\tif ( parameters.map )\n\t\t\t_programLayers.enable( 4 );\n\t\tif ( parameters.matcap )\n\t\t\t_programLayers.enable( 5 );\n\t\tif ( parameters.envMap )\n\t\t\t_programLayers.enable( 6 );\n\t\tif ( parameters.lightMap )\n\t\t\t_programLayers.enable( 7 );\n\t\tif ( parameters.aoMap )\n\t\t\t_programLayers.enable( 8 );\n\t\tif ( parameters.emissiveMap )\n\t\t\t_programLayers.enable( 9 );\n\t\tif ( parameters.bumpMap )\n\t\t\t_programLayers.enable( 10 );\n\t\tif ( parameters.normalMap )\n\t\t\t_programLayers.enable( 11 );\n\t\tif ( parameters.objectSpaceNormalMap )\n\t\t\t_programLayers.enable( 12 );\n\t\tif ( parameters.tangentSpaceNormalMap )\n\t\t\t_programLayers.enable( 13 );\n\t\tif ( parameters.clearcoat )\n\t\t\t_programLayers.enable( 14 );\n\t\tif ( parameters.clearcoatMap )\n\t\t\t_programLayers.enable( 15 );\n\t\tif ( parameters.clearcoatRoughnessMap )\n\t\t\t_programLayers.enable( 16 );\n\t\tif ( parameters.clearcoatNormalMap )\n\t\t\t_programLayers.enable( 17 );\n\t\tif ( parameters.iridescence )\n\t\t\t_programLayers.enable( 18 );\n\t\tif ( parameters.iridescenceMap )\n\t\t\t_programLayers.enable( 19 );\n\t\tif ( parameters.iridescenceThicknessMap )\n\t\t\t_programLayers.enable( 20 );\n\t\tif ( parameters.displacementMap )\n\t\t\t_programLayers.enable( 21 );\n\t\tif ( parameters.specularMap )\n\t\t\t_programLayers.enable( 22 );\n\t\tif ( parameters.roughnessMap )\n\t\t\t_programLayers.enable( 23 );\n\t\tif ( parameters.metalnessMap )\n\t\t\t_programLayers.enable( 24 );\n\t\tif ( parameters.gradientMap )\n\t\t\t_programLayers.enable( 25 );\n\t\tif ( parameters.alphaMap )\n\t\t\t_programLayers.enable( 26 );\n\t\tif ( parameters.alphaTest )\n\t\t\t_programLayers.enable( 27 );\n\t\tif ( parameters.vertexColors )\n\t\t\t_programLayers.enable( 28 );\n\t\tif ( parameters.vertexAlphas )\n\t\t\t_programLayers.enable( 29 );\n\t\tif ( parameters.vertexUvs )\n\t\t\t_programLayers.enable( 30 );\n\t\tif ( parameters.vertexTangents )\n\t\t\t_programLayers.enable( 31 );\n\t\tif ( parameters.uvsVertexOnly )\n\t\t\t_programLayers.enable( 32 );\n\t\tif ( parameters.fog )\n\t\t\t_programLayers.enable( 33 );\n\n\t\tarray.push( _programLayers.mask );\n\t\t_programLayers.disableAll();\n\n\t\tif ( parameters.useFog )\n\t\t\t_programLayers.enable( 0 );\n\t\tif ( parameters.flatShading )\n\t\t\t_programLayers.enable( 1 );\n\t\tif ( parameters.logarithmicDepthBuffer )\n\t\t\t_programLayers.enable( 2 );\n\t\tif ( parameters.skinning )\n\t\t\t_programLayers.enable( 3 );\n\t\tif ( parameters.morphTargets )\n\t\t\t_programLayers.enable( 4 );\n\t\tif ( parameters.morphNormals )\n\t\t\t_programLayers.enable( 5 );\n\t\tif ( parameters.morphColors )\n\t\t\t_programLayers.enable( 6 );\n\t\tif ( parameters.premultipliedAlpha )\n\t\t\t_programLayers.enable( 7 );\n\t\tif ( parameters.shadowMapEnabled )\n\t\t\t_programLayers.enable( 8 );\n\t\tif ( parameters.physicallyCorrectLights )\n\t\t\t_programLayers.enable( 9 );\n\t\tif ( parameters.doubleSided )\n\t\t\t_programLayers.enable( 10 );\n\t\tif ( parameters.flipSided )\n\t\t\t_programLayers.enable( 11 );\n\t\tif ( parameters.useDepthPacking )\n\t\t\t_programLayers.enable( 12 );\n\t\tif ( parameters.dithering )\n\t\t\t_programLayers.enable( 13 );\n\t\tif ( parameters.specularIntensityMap )\n\t\t\t_programLayers.enable( 14 );\n\t\tif ( parameters.specularColorMap )\n\t\t\t_programLayers.enable( 15 );\n\t\tif ( parameters.transmission )\n\t\t\t_programLayers.enable( 16 );\n\t\tif ( parameters.transmissionMap )\n\t\t\t_programLayers.enable( 17 );\n\t\tif ( parameters.thicknessMap )\n\t\t\t_programLayers.enable( 18 );\n\t\tif ( parameters.sheen )\n\t\t\t_programLayers.enable( 19 );\n\t\tif ( parameters.sheenColorMap )\n\t\t\t_programLayers.enable( 20 );\n\t\tif ( parameters.sheenRoughnessMap )\n\t\t\t_programLayers.enable( 21 );\n\t\tif ( parameters.decodeVideoTexture )\n\t\t\t_programLayers.enable( 22 );\n\t\tif ( parameters.opaque )\n\t\t\t_programLayers.enable( 23 );\n\n\t\tarray.push( _programLayers.mask );\n\n\t}\n\n\tfunction getUniforms( material ) {\n\n\t\tconst shaderID = shaderIDs[ material.type ];\n\t\tlet uniforms;\n\n\t\tif ( shaderID ) {\n\n\t\t\tconst shader = ShaderLib[ shaderID ];\n\t\t\tuniforms = UniformsUtils.clone( shader.uniforms );\n\n\t\t} else {\n\n\t\t\tuniforms = material.uniforms;\n\n\t\t}\n\n\t\treturn uniforms;\n\n\t}\n\n\tfunction acquireProgram( parameters, cacheKey ) {\n\n\t\tlet program;\n\n\t\t// Check if code has been already compiled\n\t\tfor ( let p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\tconst preexistingProgram = programs[ p ];\n\n\t\t\tif ( preexistingProgram.cacheKey === cacheKey ) {\n\n\t\t\t\tprogram = preexistingProgram;\n\t\t\t\t++ program.usedTimes;\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( program === undefined ) {\n\n\t\t\tprogram = new WebGLProgram( renderer, cacheKey, parameters, bindingStates );\n\t\t\tprograms.push( program );\n\n\t\t}\n\n\t\treturn program;\n\n\t}\n\n\tfunction releaseProgram( program ) {\n\n\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t// Remove from unordered set\n\t\t\tconst i = programs.indexOf( program );\n\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\tprograms.pop();\n\n\t\t\t// Free WebGL resources\n\t\t\tprogram.destroy();\n\n\t\t}\n\n\t}\n\n\tfunction releaseShaderCache( material ) {\n\n\t\t_customShaders.remove( material );\n\n\t}\n\n\tfunction dispose() {\n\n\t\t_customShaders.dispose();\n\n\t}\n\n\treturn {\n\t\tgetParameters: getParameters,\n\t\tgetProgramCacheKey: getProgramCacheKey,\n\t\tgetUniforms: getUniforms,\n\t\tacquireProgram: acquireProgram,\n\t\treleaseProgram: releaseProgram,\n\t\treleaseShaderCache: releaseShaderCache,\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tprograms: programs,\n\t\tdispose: dispose\n\t};\n\n}\n\nfunction WebGLProperties() {\n\n\tlet properties = new WeakMap();\n\n\tfunction get( object ) {\n\n\t\tlet map = properties.get( object );\n\n\t\tif ( map === undefined ) {\n\n\t\t\tmap = {};\n\t\t\tproperties.set( object, map );\n\n\t\t}\n\n\t\treturn map;\n\n\t}\n\n\tfunction remove( object ) {\n\n\t\tproperties.delete( object );\n\n\t}\n\n\tfunction update( object, key, value ) {\n\n\t\tproperties.get( object )[ key ] = value;\n\n\t}\n\n\tfunction dispose() {\n\n\t\tproperties = new WeakMap();\n\n\t}\n\n\treturn {\n\t\tget: get,\n\t\tremove: remove,\n\t\tupdate: update,\n\t\tdispose: dispose\n\t};\n\n}\n\nfunction painterSortStable( a, b ) {\n\n\tif ( a.groupOrder !== b.groupOrder ) {\n\n\t\treturn a.groupOrder - b.groupOrder;\n\n\t} else if ( a.renderOrder !== b.renderOrder ) {\n\n\t\treturn a.renderOrder - b.renderOrder;\n\n\t} else if ( a.material.id !== b.material.id ) {\n\n\t\treturn a.material.id - b.material.id;\n\n\t} else if ( a.z !== b.z ) {\n\n\t\treturn a.z - b.z;\n\n\t} else {\n\n\t\treturn a.id - b.id;\n\n\t}\n\n}\n\nfunction reversePainterSortStable( a, b ) {\n\n\tif ( a.groupOrder !== b.groupOrder ) {\n\n\t\treturn a.groupOrder - b.groupOrder;\n\n\t} else if ( a.renderOrder !== b.renderOrder ) {\n\n\t\treturn a.renderOrder - b.renderOrder;\n\n\t} else if ( a.z !== b.z ) {\n\n\t\treturn b.z - a.z;\n\n\t} else {\n\n\t\treturn a.id - b.id;\n\n\t}\n\n}\n\n\nfunction WebGLRenderList() {\n\n\tconst renderItems = [];\n\tlet renderItemsIndex = 0;\n\n\tconst opaque = [];\n\tconst transmissive = [];\n\tconst transparent = [];\n\n\tfunction init() {\n\n\t\trenderItemsIndex = 0;\n\n\t\topaque.length = 0;\n\t\ttransmissive.length = 0;\n\t\ttransparent.length = 0;\n\n\t}\n\n\tfunction getNextRenderItem( object, geometry, material, groupOrder, z, group ) {\n\n\t\tlet renderItem = renderItems[ renderItemsIndex ];\n\n\t\tif ( renderItem === undefined ) {\n\n\t\t\trenderItem = {\n\t\t\t\tid: object.id,\n\t\t\t\tobject: object,\n\t\t\t\tgeometry: geometry,\n\t\t\t\tmaterial: material,\n\t\t\t\tgroupOrder: groupOrder,\n\t\t\t\trenderOrder: object.renderOrder,\n\t\t\t\tz: z,\n\t\t\t\tgroup: group\n\t\t\t};\n\n\t\t\trenderItems[ renderItemsIndex ] = renderItem;\n\n\t\t} else {\n\n\t\t\trenderItem.id = object.id;\n\t\t\trenderItem.object = object;\n\t\t\trenderItem.geometry = geometry;\n\t\t\trenderItem.material = material;\n\t\t\trenderItem.groupOrder = groupOrder;\n\t\t\trenderItem.renderOrder = object.renderOrder;\n\t\t\trenderItem.z = z;\n\t\t\trenderItem.group = group;\n\n\t\t}\n\n\t\trenderItemsIndex ++;\n\n\t\treturn renderItem;\n\n\t}\n\n\tfunction push( object, geometry, material, groupOrder, z, group ) {\n\n\t\tconst renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );\n\n\t\tif ( material.transmission > 0.0 ) {\n\n\t\t\ttransmissive.push( renderItem );\n\n\t\t} else if ( material.transparent === true ) {\n\n\t\t\ttransparent.push( renderItem );\n\n\t\t} else {\n\n\t\t\topaque.push( renderItem );\n\n\t\t}\n\n\t}\n\n\tfunction unshift( object, geometry, material, groupOrder, z, group ) {\n\n\t\tconst renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );\n\n\t\tif ( material.transmission > 0.0 ) {\n\n\t\t\ttransmissive.unshift( renderItem );\n\n\t\t} else if ( material.transparent === true ) {\n\n\t\t\ttransparent.unshift( renderItem );\n\n\t\t} else {\n\n\t\t\topaque.unshift( renderItem );\n\n\t\t}\n\n\t}\n\n\tfunction sort( customOpaqueSort, customTransparentSort ) {\n\n\t\tif ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable );\n\t\tif ( transmissive.length > 1 ) transmissive.sort( customTransparentSort || reversePainterSortStable );\n\t\tif ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable );\n\n\t}\n\n\tfunction finish() {\n\n\t\t// Clear references from inactive renderItems in the list\n\n\t\tfor ( let i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) {\n\n\t\t\tconst renderItem = renderItems[ i ];\n\n\t\t\tif ( renderItem.id === null ) break;\n\n\t\t\trenderItem.id = null;\n\t\t\trenderItem.object = null;\n\t\t\trenderItem.geometry = null;\n\t\t\trenderItem.material = null;\n\t\t\trenderItem.group = null;\n\n\t\t}\n\n\t}\n\n\treturn {\n\n\t\topaque: opaque,\n\t\ttransmissive: transmissive,\n\t\ttransparent: transparent,\n\n\t\tinit: init,\n\t\tpush: push,\n\t\tunshift: unshift,\n\t\tfinish: finish,\n\n\t\tsort: sort\n\t};\n\n}\n\nfunction WebGLRenderLists() {\n\n\tlet lists = new WeakMap();\n\n\tfunction get( scene, renderCallDepth ) {\n\n\t\tlet list;\n\n\t\tif ( lists.has( scene ) === false ) {\n\n\t\t\tlist = new WebGLRenderList();\n\t\t\tlists.set( scene, [ list ] );\n\n\t\t} else {\n\n\t\t\tif ( renderCallDepth >= lists.get( scene ).length ) {\n\n\t\t\t\tlist = new WebGLRenderList();\n\t\t\t\tlists.get( scene ).push( list );\n\n\t\t\t} else {\n\n\t\t\t\tlist = lists.get( scene )[ renderCallDepth ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn list;\n\n\t}\n\n\tfunction dispose() {\n\n\t\tlists = new WeakMap();\n\n\t}\n\n\treturn {\n\t\tget: get,\n\t\tdispose: dispose\n\t};\n\n}\n\nfunction UniformsCache() {\n\n\tconst lights = {};\n\n\treturn {\n\n\t\tget: function ( light ) {\n\n\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\treturn lights[ light.id ];\n\n\t\t\t}\n\n\t\t\tlet uniforms;\n\n\t\t\tswitch ( light.type ) {\n\n\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\tuniforms = {\n\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\tcolor: new Color()\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'SpotLight':\n\t\t\t\t\tuniforms = {\n\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\tdecay: 0\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'PointLight':\n\t\t\t\t\tuniforms = {\n\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\tdecay: 0\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\tuniforms = {\n\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\tuniforms = {\n\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\treturn uniforms;\n\n\t\t}\n\n\t};\n\n}\n\nfunction ShadowUniformsCache() {\n\n\tconst lights = {};\n\n\treturn {\n\n\t\tget: function ( light ) {\n\n\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\treturn lights[ light.id ];\n\n\t\t\t}\n\n\t\t\tlet uniforms;\n\n\t\t\tswitch ( light.type ) {\n\n\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\tuniforms = {\n\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\tshadowNormalBias: 0,\n\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'SpotLight':\n\t\t\t\t\tuniforms = {\n\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\tshadowNormalBias: 0,\n\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'PointLight':\n\t\t\t\t\tuniforms = {\n\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\tshadowNormalBias: 0,\n\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\tshadowMapSize: new Vector2(),\n\t\t\t\t\t\tshadowCameraNear: 1,\n\t\t\t\t\t\tshadowCameraFar: 1000\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\n\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\n\t\t\t}\n\n\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\treturn uniforms;\n\n\t\t}\n\n\t};\n\n}\n\n\n\nlet nextVersion = 0;\n\nfunction shadowCastingLightsFirst( lightA, lightB ) {\n\n\treturn ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 );\n\n}\n\nfunction WebGLLights( extensions, capabilities ) {\n\n\tconst cache = new UniformsCache();\n\n\tconst shadowCache = ShadowUniformsCache();\n\n\tconst state = {\n\n\t\tversion: 0,\n\n\t\thash: {\n\t\t\tdirectionalLength: - 1,\n\t\t\tpointLength: - 1,\n\t\t\tspotLength: - 1,\n\t\t\trectAreaLength: - 1,\n\t\t\themiLength: - 1,\n\n\t\t\tnumDirectionalShadows: - 1,\n\t\t\tnumPointShadows: - 1,\n\t\t\tnumSpotShadows: - 1\n\t\t},\n\n\t\tambient: [ 0, 0, 0 ],\n\t\tprobe: [],\n\t\tdirectional: [],\n\t\tdirectionalShadow: [],\n\t\tdirectionalShadowMap: [],\n\t\tdirectionalShadowMatrix: [],\n\t\tspot: [],\n\t\tspotShadow: [],\n\t\tspotShadowMap: [],\n\t\tspotShadowMatrix: [],\n\t\trectArea: [],\n\t\trectAreaLTC1: null,\n\t\trectAreaLTC2: null,\n\t\tpoint: [],\n\t\tpointShadow: [],\n\t\tpointShadowMap: [],\n\t\tpointShadowMatrix: [],\n\t\themi: []\n\n\t};\n\n\tfor ( let i = 0; i < 9; i ++ ) state.probe.push( new Vector3() );\n\n\tconst vector3 = new Vector3();\n\tconst matrix4 = new Matrix4();\n\tconst matrix42 = new Matrix4();\n\n\tfunction setup( lights, physicallyCorrectLights ) {\n\n\t\tlet r = 0, g = 0, b = 0;\n\n\t\tfor ( let i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 );\n\n\t\tlet directionalLength = 0;\n\t\tlet pointLength = 0;\n\t\tlet spotLength = 0;\n\t\tlet rectAreaLength = 0;\n\t\tlet hemiLength = 0;\n\n\t\tlet numDirectionalShadows = 0;\n\t\tlet numPointShadows = 0;\n\t\tlet numSpotShadows = 0;\n\n\t\tlights.sort( shadowCastingLightsFirst );\n\n\t\t// artist-friendly light intensity scaling factor\n\t\tconst scaleFactor = ( physicallyCorrectLights !== true ) ? Math.PI : 1;\n\n\t\tfor ( let i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\tconst light = lights[ i ];\n\n\t\t\tconst color = light.color;\n\t\t\tconst intensity = light.intensity;\n\t\t\tconst distance = light.distance;\n\n\t\t\tconst shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\tr += color.r * intensity * scaleFactor;\n\t\t\t\tg += color.g * intensity * scaleFactor;\n\t\t\t\tb += color.b * intensity * scaleFactor;\n\n\t\t\t} else if ( light.isLightProbe ) {\n\n\t\t\t\tfor ( let j = 0; j < 9; j ++ ) {\n\n\t\t\t\t\tstate.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity );\n\n\t\t\t\t}\n\n\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\tconst uniforms = cache.get( light );\n\n\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity * scaleFactor );\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\tconst shadow = light.shadow;\n\n\t\t\t\t\tconst shadowUniforms = shadowCache.get( light );\n\n\t\t\t\t\tshadowUniforms.shadowBias = shadow.bias;\n\t\t\t\t\tshadowUniforms.shadowNormalBias = shadow.normalBias;\n\t\t\t\t\tshadowUniforms.shadowRadius = shadow.radius;\n\t\t\t\t\tshadowUniforms.shadowMapSize = shadow.mapSize;\n\n\t\t\t\t\tstate.directionalShadow[ directionalLength ] = shadowUniforms;\n\t\t\t\t\tstate.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\tstate.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\n\t\t\t\t\tnumDirectionalShadows ++;\n\n\t\t\t\t}\n\n\t\t\t\tstate.directional[ directionalLength ] = uniforms;\n\n\t\t\t\tdirectionalLength ++;\n\n\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\tconst uniforms = cache.get( light );\n\n\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\n\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity * scaleFactor );\n\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\tuniforms.decay = light.decay;\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\tconst shadow = light.shadow;\n\n\t\t\t\t\tconst shadowUniforms = shadowCache.get( light );\n\n\t\t\t\t\tshadowUniforms.shadowBias = shadow.bias;\n\t\t\t\t\tshadowUniforms.shadowNormalBias = shadow.normalBias;\n\t\t\t\t\tshadowUniforms.shadowRadius = shadow.radius;\n\t\t\t\t\tshadowUniforms.shadowMapSize = shadow.mapSize;\n\n\t\t\t\t\tstate.spotShadow[ spotLength ] = shadowUniforms;\n\t\t\t\t\tstate.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\tstate.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\n\t\t\t\t\tnumSpotShadows ++;\n\n\t\t\t\t}\n\n\t\t\t\tstate.spot[ spotLength ] = uniforms;\n\n\t\t\t\tspotLength ++;\n\n\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\tconst uniforms = cache.get( light );\n\n\t\t\t\t// (a) intensity is the total visible light emitted\n\t\t\t\t//uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) );\n\n\t\t\t\t// (b) intensity is the brightness of the light\n\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\tstate.rectArea[ rectAreaLength ] = uniforms;\n\n\t\t\t\trectAreaLength ++;\n\n\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\tconst uniforms = cache.get( light );\n\n\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity * scaleFactor );\n\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\tuniforms.decay = light.decay;\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\tconst shadow = light.shadow;\n\n\t\t\t\t\tconst shadowUniforms = shadowCache.get( light );\n\n\t\t\t\t\tshadowUniforms.shadowBias = shadow.bias;\n\t\t\t\t\tshadowUniforms.shadowNormalBias = shadow.normalBias;\n\t\t\t\t\tshadowUniforms.shadowRadius = shadow.radius;\n\t\t\t\t\tshadowUniforms.shadowMapSize = shadow.mapSize;\n\t\t\t\t\tshadowUniforms.shadowCameraNear = shadow.camera.near;\n\t\t\t\t\tshadowUniforms.shadowCameraFar = shadow.camera.far;\n\n\t\t\t\t\tstate.pointShadow[ pointLength ] = shadowUniforms;\n\t\t\t\t\tstate.pointShadowMap[ pointLength ] = shadowMap;\n\t\t\t\t\tstate.pointShadowMatrix[ pointLength ] = light.shadow.matrix;\n\n\t\t\t\t\tnumPointShadows ++;\n\n\t\t\t\t}\n\n\t\t\t\tstate.point[ pointLength ] = uniforms;\n\n\t\t\t\tpointLength ++;\n\n\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\tconst uniforms = cache.get( light );\n\n\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity * scaleFactor );\n\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity * scaleFactor );\n\n\t\t\t\tstate.hemi[ hemiLength ] = uniforms;\n\n\t\t\t\themiLength ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( rectAreaLength > 0 ) {\n\n\t\t\tif ( capabilities.isWebGL2 ) {\n\n\t\t\t\t// WebGL 2\n\n\t\t\t\tstate.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;\n\t\t\t\tstate.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;\n\n\t\t\t} else {\n\n\t\t\t\t// WebGL 1\n\n\t\t\t\tif ( extensions.has( 'OES_texture_float_linear' ) === true ) {\n\n\t\t\t\t\tstate.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;\n\t\t\t\t\tstate.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;\n\n\t\t\t\t} else if ( extensions.has( 'OES_texture_half_float_linear' ) === true ) {\n\n\t\t\t\t\tstate.rectAreaLTC1 = UniformsLib.LTC_HALF_1;\n\t\t\t\t\tstate.rectAreaLTC2 = UniformsLib.LTC_HALF_2;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tstate.ambient[ 0 ] = r;\n\t\tstate.ambient[ 1 ] = g;\n\t\tstate.ambient[ 2 ] = b;\n\n\t\tconst hash = state.hash;\n\n\t\tif ( hash.directionalLength !== directionalLength ||\n\t\t\thash.pointLength !== pointLength ||\n\t\t\thash.spotLength !== spotLength ||\n\t\t\thash.rectAreaLength !== rectAreaLength ||\n\t\t\thash.hemiLength !== hemiLength ||\n\t\t\thash.numDirectionalShadows !== numDirectionalShadows ||\n\t\t\thash.numPointShadows !== numPointShadows ||\n\t\t\thash.numSpotShadows !== numSpotShadows ) {\n\n\t\t\tstate.directional.length = directionalLength;\n\t\t\tstate.spot.length = spotLength;\n\t\t\tstate.rectArea.length = rectAreaLength;\n\t\t\tstate.point.length = pointLength;\n\t\t\tstate.hemi.length = hemiLength;\n\n\t\t\tstate.directionalShadow.length = numDirectionalShadows;\n\t\t\tstate.directionalShadowMap.length = numDirectionalShadows;\n\t\t\tstate.pointShadow.length = numPointShadows;\n\t\t\tstate.pointShadowMap.length = numPointShadows;\n\t\t\tstate.spotShadow.length = numSpotShadows;\n\t\t\tstate.spotShadowMap.length = numSpotShadows;\n\t\t\tstate.directionalShadowMatrix.length = numDirectionalShadows;\n\t\t\tstate.pointShadowMatrix.length = numPointShadows;\n\t\t\tstate.spotShadowMatrix.length = numSpotShadows;\n\n\t\t\thash.directionalLength = directionalLength;\n\t\t\thash.pointLength = pointLength;\n\t\t\thash.spotLength = spotLength;\n\t\t\thash.rectAreaLength = rectAreaLength;\n\t\t\thash.hemiLength = hemiLength;\n\n\t\t\thash.numDirectionalShadows = numDirectionalShadows;\n\t\t\thash.numPointShadows = numPointShadows;\n\t\t\thash.numSpotShadows = numSpotShadows;\n\n\t\t\tstate.version = nextVersion ++;\n\n\t\t}\n\n\t}\n\n\tfunction setupView( lights, camera ) {\n\n\t\tlet directionalLength = 0;\n\t\tlet pointLength = 0;\n\t\tlet spotLength = 0;\n\t\tlet rectAreaLength = 0;\n\t\tlet hemiLength = 0;\n\n\t\tconst viewMatrix = camera.matrixWorldInverse;\n\n\t\tfor ( let i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\tconst light = lights[ i ];\n\n\t\t\tif ( light.isDirectionalLight ) {\n\n\t\t\t\tconst uniforms = state.directional[ directionalLength ];\n\n\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tvector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\tuniforms.direction.sub( vector3 );\n\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\tdirectionalLength ++;\n\n\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\tconst uniforms = state.spot[ spotLength ];\n\n\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tvector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\tuniforms.direction.sub( vector3 );\n\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\tspotLength ++;\n\n\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\tconst uniforms = state.rectArea[ rectAreaLength ];\n\n\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\tmatrix42.identity();\n\t\t\t\tmatrix4.copy( light.matrixWorld );\n\t\t\t\tmatrix4.premultiply( viewMatrix );\n\t\t\t\tmatrix42.extractRotation( matrix4 );\n\n\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\tuniforms.halfWidth.applyMatrix4( matrix42 );\n\t\t\t\tuniforms.halfHeight.applyMatrix4( matrix42 );\n\n\t\t\t\trectAreaLength ++;\n\n\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\tconst uniforms = state.point[ pointLength ];\n\n\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\tpointLength ++;\n\n\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\tconst uniforms = state.hemi[ hemiLength ];\n\n\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\themiLength ++;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\treturn {\n\t\tsetup: setup,\n\t\tsetupView: setupView,\n\t\tstate: state\n\t};\n\n}\n\nfunction WebGLRenderState( extensions, capabilities ) {\n\n\tconst lights = new WebGLLights( extensions, capabilities );\n\n\tconst lightsArray = [];\n\tconst shadowsArray = [];\n\n\tfunction init() {\n\n\t\tlightsArray.length = 0;\n\t\tshadowsArray.length = 0;\n\n\t}\n\n\tfunction pushLight( light ) {\n\n\t\tlightsArray.push( light );\n\n\t}\n\n\tfunction pushShadow( shadowLight ) {\n\n\t\tshadowsArray.push( shadowLight );\n\n\t}\n\n\tfunction setupLights( physicallyCorrectLights ) {\n\n\t\tlights.setup( lightsArray, physicallyCorrectLights );\n\n\t}\n\n\tfunction setupLightsView( camera ) {\n\n\t\tlights.setupView( lightsArray, camera );\n\n\t}\n\n\tconst state = {\n\t\tlightsArray: lightsArray,\n\t\tshadowsArray: shadowsArray,\n\n\t\tlights: lights\n\t};\n\n\treturn {\n\t\tinit: init,\n\t\tstate: state,\n\t\tsetupLights: setupLights,\n\t\tsetupLightsView: setupLightsView,\n\n\t\tpushLight: pushLight,\n\t\tpushShadow: pushShadow\n\t};\n\n}\n\nfunction WebGLRenderStates( extensions, capabilities ) {\n\n\tlet renderStates = new WeakMap();\n\n\tfunction get( scene, renderCallDepth = 0 ) {\n\n\t\tlet renderState;\n\n\t\tif ( renderStates.has( scene ) === false ) {\n\n\t\t\trenderState = new WebGLRenderState( extensions, capabilities );\n\t\t\trenderStates.set( scene, [ renderState ] );\n\n\t\t} else {\n\n\t\t\tif ( renderCallDepth >= renderStates.get( scene ).length ) {\n\n\t\t\t\trenderState = new WebGLRenderState( extensions, capabilities );\n\t\t\t\trenderStates.get( scene ).push( renderState );\n\n\t\t\t} else {\n\n\t\t\t\trenderState = renderStates.get( scene )[ renderCallDepth ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn renderState;\n\n\t}\n\n\tfunction dispose() {\n\n\t\trenderStates = new WeakMap();\n\n\t}\n\n\treturn {\n\t\tget: get,\n\t\tdispose: dispose\n\t};\n\n}\n\nclass MeshDepthMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshDepthMaterial = true;\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass MeshDistanceMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshDistanceMaterial = true;\n\n\t\tthis.type = 'MeshDistanceMaterial';\n\n\t\tthis.referencePosition = new Vector3();\n\t\tthis.nearDistance = 1;\n\t\tthis.farDistance = 1000;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.referencePosition.copy( source.referencePosition );\n\t\tthis.nearDistance = source.nearDistance;\n\t\tthis.farDistance = source.farDistance;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst vertex = \"void main() {\\n\\tgl_Position = vec4( position, 1.0 );\\n}\";\n\nconst fragment = \"uniform sampler2D shadow_pass;\\nuniform vec2 resolution;\\nuniform float radius;\\n#include \\nvoid main() {\\n\\tconst float samples = float( VSM_SAMPLES );\\n\\tfloat mean = 0.0;\\n\\tfloat squared_mean = 0.0;\\n\\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\\n\\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\\n\\tfor ( float i = 0.0; i < samples; i ++ ) {\\n\\t\\tfloat uvOffset = uvStart + i * uvStride;\\n\\t\\t#ifdef HORIZONTAL_PASS\\n\\t\\t\\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) );\\n\\t\\t\\tmean += distribution.x;\\n\\t\\t\\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\\n\\t\\t#else\\n\\t\\t\\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) );\\n\\t\\t\\tmean += depth;\\n\\t\\t\\tsquared_mean += depth * depth;\\n\\t\\t#endif\\n\\t}\\n\\tmean = mean / samples;\\n\\tsquared_mean = squared_mean / samples;\\n\\tfloat std_dev = sqrt( squared_mean - mean * mean );\\n\\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\\n}\";\n\nfunction WebGLShadowMap( _renderer, _objects, _capabilities ) {\n\n\tlet _frustum = new Frustum();\n\n\tconst _shadowMapSize = new Vector2(),\n\t\t_viewportSize = new Vector2(),\n\n\t\t_viewport = new Vector4(),\n\n\t\t_depthMaterial = new MeshDepthMaterial( { depthPacking: RGBADepthPacking } ),\n\t\t_distanceMaterial = new MeshDistanceMaterial(),\n\n\t\t_materialCache = {},\n\n\t\t_maxTextureSize = _capabilities.maxTextureSize;\n\n\tconst shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide };\n\n\tconst shadowMaterialVertical = new ShaderMaterial( {\n\t\tdefines: {\n\t\t\tVSM_SAMPLES: 8\n\t\t},\n\t\tuniforms: {\n\t\t\tshadow_pass: { value: null },\n\t\t\tresolution: { value: new Vector2() },\n\t\t\tradius: { value: 4.0 }\n\t\t},\n\n\t\tvertexShader: vertex,\n\t\tfragmentShader: fragment\n\n\t} );\n\n\tconst shadowMaterialHorizontal = shadowMaterialVertical.clone();\n\tshadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1;\n\n\tconst fullScreenTri = new BufferGeometry();\n\tfullScreenTri.setAttribute(\n\t\t'position',\n\t\tnew BufferAttribute(\n\t\t\tnew Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ),\n\t\t\t3\n\t\t)\n\t);\n\n\tconst fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical );\n\n\tconst scope = this;\n\n\tthis.enabled = false;\n\n\tthis.autoUpdate = true;\n\tthis.needsUpdate = false;\n\n\tthis.type = PCFShadowMap;\n\n\tthis.render = function ( lights, scene, camera ) {\n\n\t\tif ( scope.enabled === false ) return;\n\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\tif ( lights.length === 0 ) return;\n\n\t\tconst currentRenderTarget = _renderer.getRenderTarget();\n\t\tconst activeCubeFace = _renderer.getActiveCubeFace();\n\t\tconst activeMipmapLevel = _renderer.getActiveMipmapLevel();\n\n\t\tconst _state = _renderer.state;\n\n\t\t// Set GL state for depth map.\n\t\t_state.setBlending( NoBlending );\n\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t_state.buffers.depth.setTest( true );\n\t\t_state.setScissorTest( false );\n\n\t\t// render depth map\n\n\t\tfor ( let i = 0, il = lights.length; i < il; i ++ ) {\n\n\t\t\tconst light = lights[ i ];\n\t\t\tconst shadow = light.shadow;\n\n\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\tif ( shadow.autoUpdate === false && shadow.needsUpdate === false ) continue;\n\n\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\n\t\t\tconst shadowFrameExtents = shadow.getFrameExtents();\n\n\t\t\t_shadowMapSize.multiply( shadowFrameExtents );\n\n\t\t\t_viewportSize.copy( shadow.mapSize );\n\n\t\t\tif ( _shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize ) {\n\n\t\t\t\tif ( _shadowMapSize.x > _maxTextureSize ) {\n\n\t\t\t\t\t_viewportSize.x = Math.floor( _maxTextureSize / shadowFrameExtents.x );\n\t\t\t\t\t_shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;\n\t\t\t\t\tshadow.mapSize.x = _viewportSize.x;\n\n\t\t\t\t}\n\n\t\t\t\tif ( _shadowMapSize.y > _maxTextureSize ) {\n\n\t\t\t\t\t_viewportSize.y = Math.floor( _maxTextureSize / shadowFrameExtents.y );\n\t\t\t\t\t_shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;\n\t\t\t\t\tshadow.mapSize.y = _viewportSize.y;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) {\n\n\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y );\n\t\t\t\tshadow.map.texture.name = light.name + '.shadowMap';\n\n\t\t\t\tshadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y );\n\n\t\t\t\tshadow.camera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\tconst pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\t\t\t\tshadow.map.texture.name = light.name + '.shadowMap';\n\n\t\t\t\tshadow.camera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t\t_renderer.setRenderTarget( shadow.map );\n\t\t\t_renderer.clear();\n\n\t\t\tconst viewportCount = shadow.getViewportCount();\n\n\t\t\tfor ( let vp = 0; vp < viewportCount; vp ++ ) {\n\n\t\t\t\tconst viewport = shadow.getViewport( vp );\n\n\t\t\t\t_viewport.set(\n\t\t\t\t\t_viewportSize.x * viewport.x,\n\t\t\t\t\t_viewportSize.y * viewport.y,\n\t\t\t\t\t_viewportSize.x * viewport.z,\n\t\t\t\t\t_viewportSize.y * viewport.w\n\t\t\t\t);\n\n\t\t\t\t_state.viewport( _viewport );\n\n\t\t\t\tshadow.updateMatrices( light, vp );\n\n\t\t\t\t_frustum = shadow.getFrustum();\n\n\t\t\t\trenderObject( scene, camera, shadow.camera, light, this.type );\n\n\t\t\t}\n\n\t\t\t// do blur pass for VSM\n\n\t\t\tif ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) {\n\n\t\t\t\tVSMPass( shadow, camera );\n\n\t\t\t}\n\n\t\t\tshadow.needsUpdate = false;\n\n\t\t}\n\n\t\tscope.needsUpdate = false;\n\n\t\t_renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel );\n\n\t};\n\n\tfunction VSMPass( shadow, camera ) {\n\n\t\tconst geometry = _objects.update( fullScreenMesh );\n\n\t\tif ( shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples ) {\n\n\t\t\tshadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples;\n\t\t\tshadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples;\n\n\t\t\tshadowMaterialVertical.needsUpdate = true;\n\t\t\tshadowMaterialHorizontal.needsUpdate = true;\n\n\t\t}\n\n\t\t// vertical pass\n\n\t\tshadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture;\n\t\tshadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;\n\t\tshadowMaterialVertical.uniforms.radius.value = shadow.radius;\n\t\t_renderer.setRenderTarget( shadow.mapPass );\n\t\t_renderer.clear();\n\t\t_renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null );\n\n\t\t// horizontal pass\n\n\t\tshadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture;\n\t\tshadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize;\n\t\tshadowMaterialHorizontal.uniforms.radius.value = shadow.radius;\n\t\t_renderer.setRenderTarget( shadow.map );\n\t\t_renderer.clear();\n\t\t_renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null );\n\n\t}\n\n\tfunction getDepthMaterial( object, material, light, shadowCameraNear, shadowCameraFar, type ) {\n\n\t\tlet result = null;\n\n\t\tconst customMaterial = ( light.isPointLight === true ) ? object.customDistanceMaterial : object.customDepthMaterial;\n\n\t\tif ( customMaterial !== undefined ) {\n\n\t\t\tresult = customMaterial;\n\n\t\t} else {\n\n\t\t\tresult = ( light.isPointLight === true ) ? _distanceMaterial : _depthMaterial;\n\n\t\t}\n\n\t\tif ( ( _renderer.localClippingEnabled && material.clipShadows === true && material.clippingPlanes.length !== 0 ) ||\n\t\t\t( material.displacementMap && material.displacementScale !== 0 ) ||\n\t\t\t( material.alphaMap && material.alphaTest > 0 ) ) {\n\n\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t// appropriate state\n\n\t\t\tconst keyA = result.uuid, keyB = material.uuid;\n\n\t\t\tlet materialsForVariant = _materialCache[ keyA ];\n\n\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t}\n\n\t\t\tlet cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult = cachedMaterial;\n\n\t\t}\n\n\t\tresult.visible = material.visible;\n\t\tresult.wireframe = material.wireframe;\n\n\t\tif ( type === VSMShadowMap ) {\n\n\t\t\tresult.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side;\n\n\t\t} else {\n\n\t\t\tresult.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ];\n\n\t\t}\n\n\t\tresult.alphaMap = material.alphaMap;\n\t\tresult.alphaTest = material.alphaTest;\n\n\t\tresult.clipShadows = material.clipShadows;\n\t\tresult.clippingPlanes = material.clippingPlanes;\n\t\tresult.clipIntersection = material.clipIntersection;\n\n\t\tresult.displacementMap = material.displacementMap;\n\t\tresult.displacementScale = material.displacementScale;\n\t\tresult.displacementBias = material.displacementBias;\n\n\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\tresult.linewidth = material.linewidth;\n\n\t\tif ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) {\n\n\t\t\tresult.referencePosition.setFromMatrixPosition( light.matrixWorld );\n\t\t\tresult.nearDistance = shadowCameraNear;\n\t\t\tresult.farDistance = shadowCameraFar;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\tfunction renderObject( object, camera, shadowCamera, light, type ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tconst visible = object.layers.test( camera.layers );\n\n\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\tif ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) {\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\n\t\t\t\tconst geometry = _objects.update( object );\n\t\t\t\tconst material = object.material;\n\n\t\t\t\tif ( Array.isArray( material ) ) {\n\n\t\t\t\t\tconst groups = geometry.groups;\n\n\t\t\t\t\tfor ( let k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tconst group = groups[ k ];\n\t\t\t\t\t\tconst groupMaterial = material[ group.materialIndex ];\n\n\t\t\t\t\t\tif ( groupMaterial && groupMaterial.visible ) {\n\n\t\t\t\t\t\t\tconst depthMaterial = getDepthMaterial( object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type );\n\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.visible ) {\n\n\t\t\t\t\tconst depthMaterial = getDepthMaterial( object, material, light, shadowCamera.near, shadowCamera.far, type );\n\n\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst children = object.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\trenderObject( children[ i ], camera, shadowCamera, light, type );\n\n\t\t}\n\n\t}\n\n}\n\nfunction WebGLState( gl, extensions, capabilities ) {\n\n\tconst isWebGL2 = capabilities.isWebGL2;\n\n\tfunction ColorBuffer() {\n\n\t\tlet locked = false;\n\n\t\tconst color = new Vector4();\n\t\tlet currentColorMask = null;\n\t\tconst currentColorClear = new Vector4( 0, 0, 0, 0 );\n\n\t\treturn {\n\n\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\tlocked = lock;\n\n\t\t\t},\n\n\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t}\n\n\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\treset: function () {\n\n\t\t\t\tlocked = false;\n\n\t\t\t\tcurrentColorMask = null;\n\t\t\t\tcurrentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tfunction DepthBuffer() {\n\n\t\tlet locked = false;\n\n\t\tlet currentDepthMask = null;\n\t\tlet currentDepthFunc = null;\n\t\tlet currentDepthClear = null;\n\n\t\treturn {\n\n\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\tenable( 2929 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tdisable( 2929 );\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 512 );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 519 );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 513 );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 515 );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 514 );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 518 );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 516 );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 517 );\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\tgl.depthFunc( 515 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.depthFunc( 515 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\tlocked = lock;\n\n\t\t\t},\n\n\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\treset: function () {\n\n\t\t\t\tlocked = false;\n\n\t\t\t\tcurrentDepthMask = null;\n\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tfunction StencilBuffer() {\n\n\t\tlet locked = false;\n\n\t\tlet currentStencilMask = null;\n\t\tlet currentStencilFunc = null;\n\t\tlet currentStencilRef = null;\n\t\tlet currentStencilFuncMask = null;\n\t\tlet currentStencilFail = null;\n\t\tlet currentStencilZFail = null;\n\t\tlet currentStencilZPass = null;\n\t\tlet currentStencilClear = null;\n\n\t\treturn {\n\n\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\tif ( ! locked ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( 2960 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( 2960 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t currentStencilRef !== stencilRef ||\n\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\tif ( currentStencilFail !== stencilFail ||\n\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\tlocked = lock;\n\n\t\t\t},\n\n\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\treset: function () {\n\n\t\t\t\tlocked = false;\n\n\t\t\t\tcurrentStencilMask = null;\n\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\tcurrentStencilRef = null;\n\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\tcurrentStencilFail = null;\n\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tconst colorBuffer = new ColorBuffer();\n\tconst depthBuffer = new DepthBuffer();\n\tconst stencilBuffer = new StencilBuffer();\n\n\tlet enabledCapabilities = {};\n\n\tlet currentBoundFramebuffers = {};\n\tlet currentDrawbuffers = new WeakMap();\n\tlet defaultDrawbuffers = [];\n\n\tlet currentProgram = null;\n\n\tlet currentBlendingEnabled = false;\n\tlet currentBlending = null;\n\tlet currentBlendEquation = null;\n\tlet currentBlendSrc = null;\n\tlet currentBlendDst = null;\n\tlet currentBlendEquationAlpha = null;\n\tlet currentBlendSrcAlpha = null;\n\tlet currentBlendDstAlpha = null;\n\tlet currentPremultipledAlpha = false;\n\n\tlet currentFlipSided = null;\n\tlet currentCullFace = null;\n\n\tlet currentLineWidth = null;\n\n\tlet currentPolygonOffsetFactor = null;\n\tlet currentPolygonOffsetUnits = null;\n\n\tconst maxTextures = gl.getParameter( 35661 );\n\n\tlet lineWidthAvailable = false;\n\tlet version = 0;\n\tconst glVersion = gl.getParameter( 7938 );\n\n\tif ( glVersion.indexOf( 'WebGL' ) !== - 1 ) {\n\n\t\tversion = parseFloat( /^WebGL (\\d)/.exec( glVersion )[ 1 ] );\n\t\tlineWidthAvailable = ( version >= 1.0 );\n\n\t} else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) {\n\n\t\tversion = parseFloat( /^OpenGL ES (\\d)/.exec( glVersion )[ 1 ] );\n\t\tlineWidthAvailable = ( version >= 2.0 );\n\n\t}\n\n\tlet currentTextureSlot = null;\n\tlet currentBoundTextures = {};\n\n\tconst scissorParam = gl.getParameter( 3088 );\n\tconst viewportParam = gl.getParameter( 2978 );\n\n\tconst currentScissor = new Vector4().fromArray( scissorParam );\n\tconst currentViewport = new Vector4().fromArray( viewportParam );\n\n\tfunction createTexture( type, target, count ) {\n\n\t\tconst data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\tconst texture = gl.createTexture();\n\n\t\tgl.bindTexture( type, texture );\n\t\tgl.texParameteri( type, 10241, 9728 );\n\t\tgl.texParameteri( type, 10240, 9728 );\n\n\t\tfor ( let i = 0; i < count; i ++ ) {\n\n\t\t\tgl.texImage2D( target + i, 0, 6408, 1, 1, 0, 6408, 5121, data );\n\n\t\t}\n\n\t\treturn texture;\n\n\t}\n\n\tconst emptyTextures = {};\n\temptyTextures[ 3553 ] = createTexture( 3553, 3553, 1 );\n\temptyTextures[ 34067 ] = createTexture( 34067, 34069, 6 );\n\n\t// init\n\n\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\tdepthBuffer.setClear( 1 );\n\tstencilBuffer.setClear( 0 );\n\n\tenable( 2929 );\n\tdepthBuffer.setFunc( LessEqualDepth );\n\n\tsetFlipSided( false );\n\tsetCullFace( CullFaceBack );\n\tenable( 2884 );\n\n\tsetBlending( NoBlending );\n\n\t//\n\n\tfunction enable( id ) {\n\n\t\tif ( enabledCapabilities[ id ] !== true ) {\n\n\t\t\tgl.enable( id );\n\t\t\tenabledCapabilities[ id ] = true;\n\n\t\t}\n\n\t}\n\n\tfunction disable( id ) {\n\n\t\tif ( enabledCapabilities[ id ] !== false ) {\n\n\t\t\tgl.disable( id );\n\t\t\tenabledCapabilities[ id ] = false;\n\n\t\t}\n\n\t}\n\n\tfunction bindFramebuffer( target, framebuffer ) {\n\n\t\tif ( currentBoundFramebuffers[ target ] !== framebuffer ) {\n\n\t\t\tgl.bindFramebuffer( target, framebuffer );\n\n\t\t\tcurrentBoundFramebuffers[ target ] = framebuffer;\n\n\t\t\tif ( isWebGL2 ) {\n\n\t\t\t\t// 36009 is equivalent to 36160\n\n\t\t\t\tif ( target === 36009 ) {\n\n\t\t\t\t\tcurrentBoundFramebuffers[ 36160 ] = framebuffer;\n\n\t\t\t\t}\n\n\t\t\t\tif ( target === 36160 ) {\n\n\t\t\t\t\tcurrentBoundFramebuffers[ 36009 ] = framebuffer;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\tfunction drawBuffers( renderTarget, framebuffer ) {\n\n\t\tlet drawBuffers = defaultDrawbuffers;\n\n\t\tlet needsUpdate = false;\n\n\t\tif ( renderTarget ) {\n\n\t\t\tdrawBuffers = currentDrawbuffers.get( framebuffer );\n\n\t\t\tif ( drawBuffers === undefined ) {\n\n\t\t\t\tdrawBuffers = [];\n\t\t\t\tcurrentDrawbuffers.set( framebuffer, drawBuffers );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLMultipleRenderTargets ) {\n\n\t\t\t\tconst textures = renderTarget.texture;\n\n\t\t\t\tif ( drawBuffers.length !== textures.length || drawBuffers[ 0 ] !== 36064 ) {\n\n\t\t\t\t\tfor ( let i = 0, il = textures.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tdrawBuffers[ i ] = 36064 + i;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tdrawBuffers.length = textures.length;\n\n\t\t\t\t\tneedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( drawBuffers[ 0 ] !== 36064 ) {\n\n\t\t\t\t\tdrawBuffers[ 0 ] = 36064;\n\n\t\t\t\t\tneedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif ( drawBuffers[ 0 ] !== 1029 ) {\n\n\t\t\t\tdrawBuffers[ 0 ] = 1029;\n\n\t\t\t\tneedsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( needsUpdate ) {\n\n\t\t\tif ( capabilities.isWebGL2 ) {\n\n\t\t\t\tgl.drawBuffers( drawBuffers );\n\n\t\t\t} else {\n\n\t\t\t\textensions.get( 'WEBGL_draw_buffers' ).drawBuffersWEBGL( drawBuffers );\n\n\t\t\t}\n\n\t\t}\n\n\n\t}\n\n\tfunction useProgram( program ) {\n\n\t\tif ( currentProgram !== program ) {\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tcurrentProgram = program;\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\treturn false;\n\n\t}\n\n\tconst equationToGL = {\n\t\t[ AddEquation ]: 32774,\n\t\t[ SubtractEquation ]: 32778,\n\t\t[ ReverseSubtractEquation ]: 32779\n\t};\n\n\tif ( isWebGL2 ) {\n\n\t\tequationToGL[ MinEquation ] = 32775;\n\t\tequationToGL[ MaxEquation ] = 32776;\n\n\t} else {\n\n\t\tconst extension = extensions.get( 'EXT_blend_minmax' );\n\n\t\tif ( extension !== null ) {\n\n\t\t\tequationToGL[ MinEquation ] = extension.MIN_EXT;\n\t\t\tequationToGL[ MaxEquation ] = extension.MAX_EXT;\n\n\t\t}\n\n\t}\n\n\tconst factorToGL = {\n\t\t[ ZeroFactor ]: 0,\n\t\t[ OneFactor ]: 1,\n\t\t[ SrcColorFactor ]: 768,\n\t\t[ SrcAlphaFactor ]: 770,\n\t\t[ SrcAlphaSaturateFactor ]: 776,\n\t\t[ DstColorFactor ]: 774,\n\t\t[ DstAlphaFactor ]: 772,\n\t\t[ OneMinusSrcColorFactor ]: 769,\n\t\t[ OneMinusSrcAlphaFactor ]: 771,\n\t\t[ OneMinusDstColorFactor ]: 775,\n\t\t[ OneMinusDstAlphaFactor ]: 773\n\t};\n\n\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\tif ( blending === NoBlending ) {\n\n\t\t\tif ( currentBlendingEnabled === true ) {\n\n\t\t\t\tdisable( 3042 );\n\t\t\t\tcurrentBlendingEnabled = false;\n\n\t\t\t}\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( currentBlendingEnabled === false ) {\n\n\t\t\tenable( 3042 );\n\t\t\tcurrentBlendingEnabled = true;\n\n\t\t}\n\n\t\tif ( blending !== CustomBlending ) {\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation ) {\n\n\t\t\t\t\tgl.blendEquation( 32774 );\n\n\t\t\t\t\tcurrentBlendEquation = AddEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = AddEquation;\n\n\t\t\t\t}\n\n\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\tswitch ( blending ) {\n\n\t\t\t\t\t\tcase NormalBlending:\n\t\t\t\t\t\t\tgl.blendFuncSeparate( 1, 771, 1, 771 );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase AdditiveBlending:\n\t\t\t\t\t\t\tgl.blendFunc( 1, 1 );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase SubtractiveBlending:\n\t\t\t\t\t\t\tgl.blendFuncSeparate( 0, 769, 0, 1 );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase MultiplyBlending:\n\t\t\t\t\t\t\tgl.blendFuncSeparate( 0, 768, 0, 770 );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.WebGLState: Invalid blending: ', blending );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( blending ) {\n\n\t\t\t\t\t\tcase NormalBlending:\n\t\t\t\t\t\t\tgl.blendFuncSeparate( 770, 771, 1, 771 );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase AdditiveBlending:\n\t\t\t\t\t\t\tgl.blendFunc( 770, 1 );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase SubtractiveBlending:\n\t\t\t\t\t\t\tgl.blendFuncSeparate( 0, 769, 0, 1 );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase MultiplyBlending:\n\t\t\t\t\t\t\tgl.blendFunc( 0, 768 );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.WebGLState: Invalid blending: ', blending );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t// custom blending\n\n\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\tgl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] );\n\n\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t}\n\n\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\tgl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] );\n\n\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\tcurrentBlendDst = blendDst;\n\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t}\n\n\t\tcurrentBlending = blending;\n\t\tcurrentPremultipledAlpha = null;\n\n\t}\n\n\tfunction setMaterial( material, frontFaceCW ) {\n\n\t\tmaterial.side === DoubleSide\n\t\t\t? disable( 2884 )\n\t\t\t: enable( 2884 );\n\n\t\tlet flipSided = ( material.side === BackSide );\n\t\tif ( frontFaceCW ) flipSided = ! flipSided;\n\n\t\tsetFlipSided( flipSided );\n\n\t\t( material.blending === NormalBlending && material.transparent === false )\n\t\t\t? setBlending( NoBlending )\n\t\t\t: setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );\n\n\t\tdepthBuffer.setFunc( material.depthFunc );\n\t\tdepthBuffer.setTest( material.depthTest );\n\t\tdepthBuffer.setMask( material.depthWrite );\n\t\tcolorBuffer.setMask( material.colorWrite );\n\n\t\tconst stencilWrite = material.stencilWrite;\n\t\tstencilBuffer.setTest( stencilWrite );\n\t\tif ( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( material.stencilWriteMask );\n\t\t\tstencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask );\n\t\t\tstencilBuffer.setOp( material.stencilFail, material.stencilZFail, material.stencilZPass );\n\n\t\t}\n\n\t\tsetPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\tmaterial.alphaToCoverage === true\n\t\t\t? enable( 32926 )\n\t\t\t: disable( 32926 );\n\n\t}\n\n\t//\n\n\tfunction setFlipSided( flipSided ) {\n\n\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\tif ( flipSided ) {\n\n\t\t\t\tgl.frontFace( 2304 );\n\n\t\t\t} else {\n\n\t\t\t\tgl.frontFace( 2305 );\n\n\t\t\t}\n\n\t\t\tcurrentFlipSided = flipSided;\n\n\t\t}\n\n\t}\n\n\tfunction setCullFace( cullFace ) {\n\n\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\tenable( 2884 );\n\n\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\tgl.cullFace( 1029 );\n\n\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\tgl.cullFace( 1028 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.cullFace( 1032 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tdisable( 2884 );\n\n\t\t}\n\n\t\tcurrentCullFace = cullFace;\n\n\t}\n\n\tfunction setLineWidth( width ) {\n\n\t\tif ( width !== currentLineWidth ) {\n\n\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\tcurrentLineWidth = width;\n\n\t\t}\n\n\t}\n\n\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\tif ( polygonOffset ) {\n\n\t\t\tenable( 32823 );\n\n\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tdisable( 32823 );\n\n\t\t}\n\n\t}\n\n\tfunction setScissorTest( scissorTest ) {\n\n\t\tif ( scissorTest ) {\n\n\t\t\tenable( 3089 );\n\n\t\t} else {\n\n\t\t\tdisable( 3089 );\n\n\t\t}\n\n\t}\n\n\t// texture\n\n\tfunction activeTexture( webglSlot ) {\n\n\t\tif ( webglSlot === undefined ) webglSlot = 33984 + maxTextures - 1;\n\n\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\tgl.activeTexture( webglSlot );\n\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t}\n\n\t}\n\n\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\tif ( currentTextureSlot === null ) {\n\n\t\t\tactiveTexture();\n\n\t\t}\n\n\t\tlet boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\tif ( boundTexture === undefined ) {\n\n\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t}\n\n\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\tboundTexture.type = webglType;\n\t\t\tboundTexture.texture = webglTexture;\n\n\t\t}\n\n\t}\n\n\tfunction unbindTexture() {\n\n\t\tconst boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\tif ( boundTexture !== undefined && boundTexture.type !== undefined ) {\n\n\t\t\tgl.bindTexture( boundTexture.type, null );\n\n\t\t\tboundTexture.type = undefined;\n\t\t\tboundTexture.texture = undefined;\n\n\t\t}\n\n\t}\n\n\tfunction compressedTexImage2D() {\n\n\t\ttry {\n\n\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLState:', error );\n\n\t\t}\n\n\t}\n\n\tfunction texSubImage2D() {\n\n\t\ttry {\n\n\t\t\tgl.texSubImage2D.apply( gl, arguments );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLState:', error );\n\n\t\t}\n\n\t}\n\n\tfunction texSubImage3D() {\n\n\t\ttry {\n\n\t\t\tgl.texSubImage3D.apply( gl, arguments );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLState:', error );\n\n\t\t}\n\n\t}\n\n\tfunction compressedTexSubImage2D() {\n\n\t\ttry {\n\n\t\t\tgl.compressedTexSubImage2D.apply( gl, arguments );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLState:', error );\n\n\t\t}\n\n\t}\n\n\tfunction texStorage2D() {\n\n\t\ttry {\n\n\t\t\tgl.texStorage2D.apply( gl, arguments );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLState:', error );\n\n\t\t}\n\n\t}\n\n\tfunction texStorage3D() {\n\n\t\ttry {\n\n\t\t\tgl.texStorage3D.apply( gl, arguments );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLState:', error );\n\n\t\t}\n\n\t}\n\n\tfunction texImage2D() {\n\n\t\ttry {\n\n\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLState:', error );\n\n\t\t}\n\n\t}\n\n\tfunction texImage3D() {\n\n\t\ttry {\n\n\t\t\tgl.texImage3D.apply( gl, arguments );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLState:', error );\n\n\t\t}\n\n\t}\n\n\t//\n\n\tfunction scissor( scissor ) {\n\n\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\tcurrentScissor.copy( scissor );\n\n\t\t}\n\n\t}\n\n\tfunction viewport( viewport ) {\n\n\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\tcurrentViewport.copy( viewport );\n\n\t\t}\n\n\t}\n\n\t//\n\n\tfunction reset() {\n\n\t\t// reset state\n\n\t\tgl.disable( 3042 );\n\t\tgl.disable( 2884 );\n\t\tgl.disable( 2929 );\n\t\tgl.disable( 32823 );\n\t\tgl.disable( 3089 );\n\t\tgl.disable( 2960 );\n\t\tgl.disable( 32926 );\n\n\t\tgl.blendEquation( 32774 );\n\t\tgl.blendFunc( 1, 0 );\n\t\tgl.blendFuncSeparate( 1, 0, 1, 0 );\n\n\t\tgl.colorMask( true, true, true, true );\n\t\tgl.clearColor( 0, 0, 0, 0 );\n\n\t\tgl.depthMask( true );\n\t\tgl.depthFunc( 513 );\n\t\tgl.clearDepth( 1 );\n\n\t\tgl.stencilMask( 0xffffffff );\n\t\tgl.stencilFunc( 519, 0, 0xffffffff );\n\t\tgl.stencilOp( 7680, 7680, 7680 );\n\t\tgl.clearStencil( 0 );\n\n\t\tgl.cullFace( 1029 );\n\t\tgl.frontFace( 2305 );\n\n\t\tgl.polygonOffset( 0, 0 );\n\n\t\tgl.activeTexture( 33984 );\n\n\t\tgl.bindFramebuffer( 36160, null );\n\n\t\tif ( isWebGL2 === true ) {\n\n\t\t\tgl.bindFramebuffer( 36009, null );\n\t\t\tgl.bindFramebuffer( 36008, null );\n\n\t\t}\n\n\t\tgl.useProgram( null );\n\n\t\tgl.lineWidth( 1 );\n\n\t\tgl.scissor( 0, 0, gl.canvas.width, gl.canvas.height );\n\t\tgl.viewport( 0, 0, gl.canvas.width, gl.canvas.height );\n\n\t\t// reset internals\n\n\t\tenabledCapabilities = {};\n\n\t\tcurrentTextureSlot = null;\n\t\tcurrentBoundTextures = {};\n\n\t\tcurrentBoundFramebuffers = {};\n\t\tcurrentDrawbuffers = new WeakMap();\n\t\tdefaultDrawbuffers = [];\n\n\t\tcurrentProgram = null;\n\n\t\tcurrentBlendingEnabled = false;\n\t\tcurrentBlending = null;\n\t\tcurrentBlendEquation = null;\n\t\tcurrentBlendSrc = null;\n\t\tcurrentBlendDst = null;\n\t\tcurrentBlendEquationAlpha = null;\n\t\tcurrentBlendSrcAlpha = null;\n\t\tcurrentBlendDstAlpha = null;\n\t\tcurrentPremultipledAlpha = false;\n\n\t\tcurrentFlipSided = null;\n\t\tcurrentCullFace = null;\n\n\t\tcurrentLineWidth = null;\n\n\t\tcurrentPolygonOffsetFactor = null;\n\t\tcurrentPolygonOffsetUnits = null;\n\n\t\tcurrentScissor.set( 0, 0, gl.canvas.width, gl.canvas.height );\n\t\tcurrentViewport.set( 0, 0, gl.canvas.width, gl.canvas.height );\n\n\t\tcolorBuffer.reset();\n\t\tdepthBuffer.reset();\n\t\tstencilBuffer.reset();\n\n\t}\n\n\treturn {\n\n\t\tbuffers: {\n\t\t\tcolor: colorBuffer,\n\t\t\tdepth: depthBuffer,\n\t\t\tstencil: stencilBuffer\n\t\t},\n\n\t\tenable: enable,\n\t\tdisable: disable,\n\n\t\tbindFramebuffer: bindFramebuffer,\n\t\tdrawBuffers: drawBuffers,\n\n\t\tuseProgram: useProgram,\n\n\t\tsetBlending: setBlending,\n\t\tsetMaterial: setMaterial,\n\n\t\tsetFlipSided: setFlipSided,\n\t\tsetCullFace: setCullFace,\n\n\t\tsetLineWidth: setLineWidth,\n\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\tsetScissorTest: setScissorTest,\n\n\t\tactiveTexture: activeTexture,\n\t\tbindTexture: bindTexture,\n\t\tunbindTexture: unbindTexture,\n\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\ttexImage2D: texImage2D,\n\t\ttexImage3D: texImage3D,\n\n\t\ttexStorage2D: texStorage2D,\n\t\ttexStorage3D: texStorage3D,\n\t\ttexSubImage2D: texSubImage2D,\n\t\ttexSubImage3D: texSubImage3D,\n\t\tcompressedTexSubImage2D: compressedTexSubImage2D,\n\n\t\tscissor: scissor,\n\t\tviewport: viewport,\n\n\t\treset: reset\n\n\t};\n\n}\n\nfunction WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {\n\n\tconst isWebGL2 = capabilities.isWebGL2;\n\tconst maxTextures = capabilities.maxTextures;\n\tconst maxCubemapSize = capabilities.maxCubemapSize;\n\tconst maxTextureSize = capabilities.maxTextureSize;\n\tconst maxSamples = capabilities.maxSamples;\n\tconst multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null;\n\tconst supportsInvalidateFramebuffer = /OculusBrowser/g.test( navigator.userAgent );\n\n\tconst _videoTextures = new WeakMap();\n\tlet _canvas;\n\n\tconst _sources = new WeakMap(); // maps WebglTexture objects to instances of Source\n\n\t// cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,\n\t// also OffscreenCanvas.getContext(\"webgl\"), but not OffscreenCanvas.getContext(\"2d\")!\n\t// Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).\n\n\tlet useOffscreenCanvas = false;\n\n\ttry {\n\n\t\tuseOffscreenCanvas = typeof OffscreenCanvas !== 'undefined'\n\t\t\t// eslint-disable-next-line compat/compat\n\t\t\t&& ( new OffscreenCanvas( 1, 1 ).getContext( '2d' ) ) !== null;\n\n\t} catch ( err ) {\n\n\t\t// Ignore any errors\n\n\t}\n\n\tfunction createCanvas( width, height ) {\n\n\t\t// Use OffscreenCanvas when available. Specially needed in web workers\n\n\t\treturn useOffscreenCanvas ?\n\t\t\t// eslint-disable-next-line compat/compat\n\t\t\tnew OffscreenCanvas( width, height ) : createElementNS( 'canvas' );\n\n\t}\n\n\tfunction resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) {\n\n\t\tlet scale = 1;\n\n\t\t// handle case if texture exceeds max size\n\n\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\tscale = maxSize / Math.max( image.width, image.height );\n\n\t\t}\n\n\t\t// only perform resize if necessary\n\n\t\tif ( scale < 1 || needsPowerOfTwo === true ) {\n\n\t\t\t// only perform resize for certain image types\n\n\t\t\tif ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||\n\t\t\t\t( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||\n\t\t\t\t( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {\n\n\t\t\t\tconst floor = needsPowerOfTwo ? floorPowerOfTwo : Math.floor;\n\n\t\t\t\tconst width = floor( scale * image.width );\n\t\t\t\tconst height = floor( scale * image.height );\n\n\t\t\t\tif ( _canvas === undefined ) _canvas = createCanvas( width, height );\n\n\t\t\t\t// cube textures can't reuse the same canvas\n\n\t\t\t\tconst canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas;\n\n\t\t\t\tcanvas.width = width;\n\t\t\t\tcanvas.height = height;\n\n\t\t\t\tconst context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, width, height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );\n\n\t\t\t\treturn canvas;\n\n\t\t\t} else {\n\n\t\t\t\tif ( 'data' in image ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );\n\n\t\t\t\t}\n\n\t\t\t\treturn image;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn image;\n\n\t}\n\n\tfunction isPowerOfTwo$1( image ) {\n\n\t\treturn isPowerOfTwo( image.width ) && isPowerOfTwo( image.height );\n\n\t}\n\n\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\tif ( isWebGL2 ) return false;\n\n\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t}\n\n\tfunction textureNeedsGenerateMipmaps( texture, supportsMips ) {\n\n\t\treturn texture.generateMipmaps && supportsMips &&\n\t\t\ttexture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;\n\n\t}\n\n\tfunction generateMipmap( target ) {\n\n\t\t_gl.generateMipmap( target );\n\n\t}\n\n\tfunction getInternalFormat( internalFormatName, glFormat, glType, encoding, isVideoTexture = false ) {\n\n\t\tif ( isWebGL2 === false ) return glFormat;\n\n\t\tif ( internalFormatName !== null ) {\n\n\t\t\tif ( _gl[ internalFormatName ] !== undefined ) return _gl[ internalFormatName ];\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \\'' + internalFormatName + '\\'' );\n\n\t\t}\n\n\t\tlet internalFormat = glFormat;\n\n\t\tif ( glFormat === 6403 ) {\n\n\t\t\tif ( glType === 5126 ) internalFormat = 33326;\n\t\t\tif ( glType === 5131 ) internalFormat = 33325;\n\t\t\tif ( glType === 5121 ) internalFormat = 33321;\n\n\t\t}\n\n\t\tif ( glFormat === 33319 ) {\n\n\t\t\tif ( glType === 5126 ) internalFormat = 33328;\n\t\t\tif ( glType === 5131 ) internalFormat = 33327;\n\t\t\tif ( glType === 5121 ) internalFormat = 33323;\n\n\t\t}\n\n\t\tif ( glFormat === 6408 ) {\n\n\t\t\tif ( glType === 5126 ) internalFormat = 34836;\n\t\t\tif ( glType === 5131 ) internalFormat = 34842;\n\t\t\tif ( glType === 5121 ) internalFormat = ( encoding === sRGBEncoding && isVideoTexture === false ) ? 35907 : 32856;\n\t\t\tif ( glType === 32819 ) internalFormat = 32854;\n\t\t\tif ( glType === 32820 ) internalFormat = 32855;\n\n\t\t}\n\n\t\tif ( internalFormat === 33325 || internalFormat === 33326 ||\n\t\t\tinternalFormat === 33327 || internalFormat === 33328 ||\n\t\t\tinternalFormat === 34842 || internalFormat === 34836 ) {\n\n\t\t\textensions.get( 'EXT_color_buffer_float' );\n\n\t\t}\n\n\t\treturn internalFormat;\n\n\t}\n\n\tfunction getMipLevels( texture, image, supportsMips ) {\n\n\t\tif ( textureNeedsGenerateMipmaps( texture, supportsMips ) === true || ( texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) ) {\n\n\t\t\treturn Math.log2( Math.max( image.width, image.height ) ) + 1;\n\n\t\t} else if ( texture.mipmaps !== undefined && texture.mipmaps.length > 0 ) {\n\n\t\t\t// user-defined mipmaps\n\n\t\t\treturn texture.mipmaps.length;\n\n\t\t} else if ( texture.isCompressedTexture && Array.isArray( texture.image ) ) {\n\n\t\t\treturn image.mipmaps.length;\n\n\t\t} else {\n\n\t\t\t// texture without mipmaps (only base level)\n\n\t\t\treturn 1;\n\n\t\t}\n\n\t}\n\n\t// Fallback filters for non-power-of-2 textures\n\n\tfunction filterFallback( f ) {\n\n\t\tif ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) {\n\n\t\t\treturn 9728;\n\n\t\t}\n\n\t\treturn 9729;\n\n\t}\n\n\t//\n\n\tfunction onTextureDispose( event ) {\n\n\t\tconst texture = event.target;\n\n\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\tdeallocateTexture( texture );\n\n\t\tif ( texture.isVideoTexture ) {\n\n\t\t\t_videoTextures.delete( texture );\n\n\t\t}\n\n\t}\n\n\tfunction onRenderTargetDispose( event ) {\n\n\t\tconst renderTarget = event.target;\n\n\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\tdeallocateRenderTarget( renderTarget );\n\n\t}\n\n\t//\n\n\tfunction deallocateTexture( texture ) {\n\n\t\tconst textureProperties = properties.get( texture );\n\n\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t// check if it's necessary to remove the WebGLTexture object\n\n\t\tconst source = texture.source;\n\t\tconst webglTextures = _sources.get( source );\n\n\t\tif ( webglTextures ) {\n\n\t\t\tconst webglTexture = webglTextures[ textureProperties.__cacheKey ];\n\t\t\twebglTexture.usedTimes --;\n\n\t\t\t// the WebGLTexture object is not used anymore, remove it\n\n\t\t\tif ( webglTexture.usedTimes === 0 ) {\n\n\t\t\t\tdeleteTexture( texture );\n\n\t\t\t}\n\n\t\t\t// remove the weak map entry if no WebGLTexture uses the source anymore\n\n\t\t\tif ( Object.keys( webglTextures ).length === 0 ) {\n\n\t\t\t\t_sources.delete( source );\n\n\t\t\t}\n\n\t\t}\n\n\t\tproperties.remove( texture );\n\n\t}\n\n\tfunction deleteTexture( texture ) {\n\n\t\tconst textureProperties = properties.get( texture );\n\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\tconst source = texture.source;\n\t\tconst webglTextures = _sources.get( source );\n\t\tdelete webglTextures[ textureProperties.__cacheKey ];\n\n\t\tinfo.memory.textures --;\n\n\t}\n\n\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\tconst texture = renderTarget.texture;\n\n\t\tconst renderTargetProperties = properties.get( renderTarget );\n\t\tconst textureProperties = properties.get( texture );\n\n\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\tinfo.memory.textures --;\n\n\t\t}\n\n\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t}\n\n\t\tif ( renderTarget.isWebGLCubeRenderTarget ) {\n\n\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\t\t\tif ( renderTargetProperties.__webglMultisampledFramebuffer ) _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledFramebuffer );\n\n\t\t\tif ( renderTargetProperties.__webglColorRenderbuffer ) {\n\n\t\t\t\tfor ( let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i ++ ) {\n\n\t\t\t\t\tif ( renderTargetProperties.__webglColorRenderbuffer[ i ] ) _gl.deleteRenderbuffer( renderTargetProperties.__webglColorRenderbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( renderTargetProperties.__webglDepthRenderbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthRenderbuffer );\n\n\t\t}\n\n\t\tif ( renderTarget.isWebGLMultipleRenderTargets ) {\n\n\t\t\tfor ( let i = 0, il = texture.length; i < il; i ++ ) {\n\n\t\t\t\tconst attachmentProperties = properties.get( texture[ i ] );\n\n\t\t\t\tif ( attachmentProperties.__webglTexture ) {\n\n\t\t\t\t\t_gl.deleteTexture( attachmentProperties.__webglTexture );\n\n\t\t\t\t\tinfo.memory.textures --;\n\n\t\t\t\t}\n\n\t\t\t\tproperties.remove( texture[ i ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tproperties.remove( texture );\n\t\tproperties.remove( renderTarget );\n\n\t}\n\n\t//\n\n\tlet textureUnits = 0;\n\n\tfunction resetTextureUnits() {\n\n\t\ttextureUnits = 0;\n\n\t}\n\n\tfunction allocateTextureUnit() {\n\n\t\tconst textureUnit = textureUnits;\n\n\t\tif ( textureUnit >= maxTextures ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures );\n\n\t\t}\n\n\t\ttextureUnits += 1;\n\n\t\treturn textureUnit;\n\n\t}\n\n\tfunction getTextureCacheKey( texture ) {\n\n\t\tconst array = [];\n\n\t\tarray.push( texture.wrapS );\n\t\tarray.push( texture.wrapT );\n\t\tarray.push( texture.magFilter );\n\t\tarray.push( texture.minFilter );\n\t\tarray.push( texture.anisotropy );\n\t\tarray.push( texture.internalFormat );\n\t\tarray.push( texture.format );\n\t\tarray.push( texture.type );\n\t\tarray.push( texture.generateMipmaps );\n\t\tarray.push( texture.premultiplyAlpha );\n\t\tarray.push( texture.flipY );\n\t\tarray.push( texture.unpackAlignment );\n\t\tarray.push( texture.encoding );\n\n\t\treturn array.join();\n\n\t}\n\n\t//\n\n\tfunction setTexture2D( texture, slot ) {\n\n\t\tconst textureProperties = properties.get( texture );\n\n\t\tif ( texture.isVideoTexture ) updateVideoTexture( texture );\n\n\t\tif ( texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\tconst image = texture.image;\n\n\t\t\tif ( image === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but no image data found.' );\n\n\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' );\n\n\t\t\t} else {\n\n\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t}\n\n\t\tstate.activeTexture( 33984 + slot );\n\t\tstate.bindTexture( 3553, textureProperties.__webglTexture );\n\n\t}\n\n\tfunction setTexture2DArray( texture, slot ) {\n\n\t\tconst textureProperties = properties.get( texture );\n\n\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\treturn;\n\n\t\t}\n\n\t\tstate.activeTexture( 33984 + slot );\n\t\tstate.bindTexture( 35866, textureProperties.__webglTexture );\n\n\t}\n\n\tfunction setTexture3D( texture, slot ) {\n\n\t\tconst textureProperties = properties.get( texture );\n\n\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\treturn;\n\n\t\t}\n\n\t\tstate.activeTexture( 33984 + slot );\n\t\tstate.bindTexture( 32879, textureProperties.__webglTexture );\n\n\t}\n\n\tfunction setTextureCube( texture, slot ) {\n\n\t\tconst textureProperties = properties.get( texture );\n\n\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\tuploadCubeTexture( textureProperties, texture, slot );\n\t\t\treturn;\n\n\t\t}\n\n\t\tstate.activeTexture( 33984 + slot );\n\t\tstate.bindTexture( 34067, textureProperties.__webglTexture );\n\n\t}\n\n\tconst wrappingToGL = {\n\t\t[ RepeatWrapping ]: 10497,\n\t\t[ ClampToEdgeWrapping ]: 33071,\n\t\t[ MirroredRepeatWrapping ]: 33648\n\t};\n\n\tconst filterToGL = {\n\t\t[ NearestFilter ]: 9728,\n\t\t[ NearestMipmapNearestFilter ]: 9984,\n\t\t[ NearestMipmapLinearFilter ]: 9986,\n\n\t\t[ LinearFilter ]: 9729,\n\t\t[ LinearMipmapNearestFilter ]: 9985,\n\t\t[ LinearMipmapLinearFilter ]: 9987\n\t};\n\n\tfunction setTextureParameters( textureType, texture, supportsMips ) {\n\n\t\tif ( supportsMips ) {\n\n\t\t\t_gl.texParameteri( textureType, 10242, wrappingToGL[ texture.wrapS ] );\n\t\t\t_gl.texParameteri( textureType, 10243, wrappingToGL[ texture.wrapT ] );\n\n\t\t\tif ( textureType === 32879 || textureType === 35866 ) {\n\n\t\t\t\t_gl.texParameteri( textureType, 32882, wrappingToGL[ texture.wrapR ] );\n\n\t\t\t}\n\n\t\t\t_gl.texParameteri( textureType, 10240, filterToGL[ texture.magFilter ] );\n\t\t\t_gl.texParameteri( textureType, 10241, filterToGL[ texture.minFilter ] );\n\n\t\t} else {\n\n\t\t\t_gl.texParameteri( textureType, 10242, 33071 );\n\t\t\t_gl.texParameteri( textureType, 10243, 33071 );\n\n\t\t\tif ( textureType === 32879 || textureType === 35866 ) {\n\n\t\t\t\t_gl.texParameteri( textureType, 32882, 33071 );\n\n\t\t\t}\n\n\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' );\n\n\t\t\t}\n\n\t\t\t_gl.texParameteri( textureType, 10240, filterFallback( texture.magFilter ) );\n\t\t\t_gl.texParameteri( textureType, 10241, filterFallback( texture.minFilter ) );\n\n\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( extensions.has( 'EXT_texture_filter_anisotropic' ) === true ) {\n\n\t\t\tconst extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( texture.type === FloatType && extensions.has( 'OES_texture_float_linear' ) === false ) return; // verify extension for WebGL 1 and WebGL 2\n\t\t\tif ( isWebGL2 === false && ( texture.type === HalfFloatType && extensions.has( 'OES_texture_half_float_linear' ) === false ) ) return; // verify extension for WebGL 1 only\n\n\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction initTexture( textureProperties, texture ) {\n\n\t\tlet forceUpload = false;\n\n\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t}\n\n\t\t// create Source <-> WebGLTextures mapping if necessary\n\n\t\tconst source = texture.source;\n\t\tlet webglTextures = _sources.get( source );\n\n\t\tif ( webglTextures === undefined ) {\n\n\t\t\twebglTextures = {};\n\t\t\t_sources.set( source, webglTextures );\n\n\t\t}\n\n\t\t// check if there is already a WebGLTexture object for the given texture parameters\n\n\t\tconst textureCacheKey = getTextureCacheKey( texture );\n\n\t\tif ( textureCacheKey !== textureProperties.__cacheKey ) {\n\n\t\t\t// if not, create a new instance of WebGLTexture\n\n\t\t\tif ( webglTextures[ textureCacheKey ] === undefined ) {\n\n\t\t\t\t// create new entry\n\n\t\t\t\twebglTextures[ textureCacheKey ] = {\n\t\t\t\t\ttexture: _gl.createTexture(),\n\t\t\t\t\tusedTimes: 0\n\t\t\t\t};\n\n\t\t\t\tinfo.memory.textures ++;\n\n\t\t\t\t// when a new instance of WebGLTexture was created, a texture upload is required\n\t\t\t\t// even if the image contents are identical\n\n\t\t\t\tforceUpload = true;\n\n\t\t\t}\n\n\t\t\twebglTextures[ textureCacheKey ].usedTimes ++;\n\n\t\t\t// every time the texture cache key changes, it's necessary to check if an instance of\n\t\t\t// WebGLTexture can be deleted in order to avoid a memory leak.\n\n\t\t\tconst webglTexture = webglTextures[ textureProperties.__cacheKey ];\n\n\t\t\tif ( webglTexture !== undefined ) {\n\n\t\t\t\twebglTextures[ textureProperties.__cacheKey ].usedTimes --;\n\n\t\t\t\tif ( webglTexture.usedTimes === 0 ) {\n\n\t\t\t\t\tdeleteTexture( texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// store references to cache key and WebGLTexture object\n\n\t\t\ttextureProperties.__cacheKey = textureCacheKey;\n\t\t\ttextureProperties.__webglTexture = webglTextures[ textureCacheKey ].texture;\n\n\t\t}\n\n\t\treturn forceUpload;\n\n\t}\n\n\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\tlet textureType = 3553;\n\n\t\tif ( texture.isDataArrayTexture ) textureType = 35866;\n\t\tif ( texture.isData3DTexture ) textureType = 32879;\n\n\t\tconst forceUpload = initTexture( textureProperties, texture );\n\t\tconst source = texture.source;\n\n\t\tstate.activeTexture( 33984 + slot );\n\t\tstate.bindTexture( textureType, textureProperties.__webglTexture );\n\n\t\tif ( source.version !== source.__currentVersion || forceUpload === true ) {\n\n\t\t\t_gl.pixelStorei( 37440, texture.flipY );\n\t\t\t_gl.pixelStorei( 37441, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( 3317, texture.unpackAlignment );\n\t\t\t_gl.pixelStorei( 37443, 0 );\n\n\t\t\tconst needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo$1( texture.image ) === false;\n\t\t\tlet image = resizeImage( texture.image, needsPowerOfTwo, false, maxTextureSize );\n\t\t\timage = verifyColorSpace( texture, image );\n\n\t\t\tconst supportsMips = isPowerOfTwo$1( image ) || isWebGL2,\n\t\t\t\tglFormat = utils.convert( texture.format, texture.encoding );\n\n\t\t\tlet glType = utils.convert( texture.type ),\n\t\t\t\tglInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding, texture.isVideoTexture );\n\n\t\t\tsetTextureParameters( textureType, texture, supportsMips );\n\n\t\t\tlet mipmap;\n\t\t\tconst mipmaps = texture.mipmaps;\n\n\t\t\tconst useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true );\n\t\t\tconst allocateMemory = ( source.__currentVersion === undefined ) || ( forceUpload === true );\n\t\t\tconst levels = getMipLevels( texture, image, supportsMips );\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tglInternalFormat = 6402;\n\n\t\t\t\tif ( isWebGL2 ) {\n\n\t\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\t\tglInternalFormat = 36012;\n\n\t\t\t\t\t} else if ( texture.type === UnsignedIntType ) {\n\n\t\t\t\t\t\tglInternalFormat = 33190;\n\n\t\t\t\t\t} else if ( texture.type === UnsignedInt248Type ) {\n\n\t\t\t\t\t\tglInternalFormat = 35056;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tglInternalFormat = 33189; // WebGL2 requires sized internalformat for glTexImage2D\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\t\tconsole.error( 'WebGLRenderer: Floating point depth texture requires WebGL2.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// validation checks for WebGL 1\n\n\t\t\t\tif ( texture.format === DepthFormat && glInternalFormat === 6402 ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedIntType;\n\t\t\t\t\t\tglType = utils.convert( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthStencilFormat && glInternalFormat === 6402 ) {\n\n\t\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tglInternalFormat = 34041;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = utils.convert( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tif ( allocateMemory ) {\n\n\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\tstate.texStorage2D( 3553, 1, glInternalFormat, image.width, image.height );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && supportsMips ) {\n\n\t\t\t\t\tif ( useTexStorage && allocateMemory ) {\n\n\t\t\t\t\t\tstate.texStorage2D( 3553, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( let i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\tstate.texSubImage2D( 3553, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tstate.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\tif ( allocateMemory ) {\n\n\t\t\t\t\t\t\tstate.texStorage2D( 3553, levels, glInternalFormat, image.width, image.height );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstate.texSubImage2D( 3553, 0, 0, 0, image.width, image.height, glFormat, glType, image.data );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tif ( useTexStorage && allocateMemory ) {\n\n\t\t\t\t\tstate.texStorage2D( 3553, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat ) {\n\n\t\t\t\t\t\tif ( glFormat !== null ) {\n\n\t\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\t\tstate.compressedTexSubImage2D( 3553, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.compressedTexImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\tstate.texSubImage2D( 3553, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tstate.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isDataArrayTexture ) {\n\n\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\tif ( allocateMemory ) {\n\n\t\t\t\t\t\tstate.texStorage3D( 35866, levels, glInternalFormat, image.width, image.height, image.depth );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.texSubImage3D( 35866, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage3D( 35866, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isData3DTexture ) {\n\n\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\tif ( allocateMemory ) {\n\n\t\t\t\t\t\tstate.texStorage3D( 32879, levels, glInternalFormat, image.width, image.height, image.depth );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.texSubImage3D( 32879, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage3D( 32879, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isFramebufferTexture ) {\n\n\t\t\t\tif ( allocateMemory ) {\n\n\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\tstate.texStorage2D( 3553, levels, glInternalFormat, image.width, image.height );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tlet width = image.width, height = image.height;\n\n\t\t\t\t\t\tfor ( let i = 0; i < levels; i ++ ) {\n\n\t\t\t\t\t\t\tstate.texImage2D( 3553, i, glInternalFormat, width, height, 0, glFormat, glType, null );\n\n\t\t\t\t\t\t\twidth >>= 1;\n\t\t\t\t\t\t\theight >>= 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && supportsMips ) {\n\n\t\t\t\t\tif ( useTexStorage && allocateMemory ) {\n\n\t\t\t\t\t\tstate.texStorage2D( 3553, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( let i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\tstate.texSubImage2D( 3553, i, 0, 0, glFormat, glType, mipmap );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tstate.texImage2D( 3553, i, glInternalFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\tif ( allocateMemory ) {\n\n\t\t\t\t\t\t\tstate.texStorage2D( 3553, levels, glInternalFormat, image.width, image.height );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstate.texSubImage2D( 3553, 0, 0, 0, glFormat, glType, image );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( 3553, 0, glInternalFormat, glFormat, glType, image );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {\n\n\t\t\t\tgenerateMipmap( textureType );\n\n\t\t\t}\n\n\t\t\tsource.__currentVersion = source.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\ttextureProperties.__version = texture.version;\n\n\t}\n\n\tfunction uploadCubeTexture( textureProperties, texture, slot ) {\n\n\t\tif ( texture.image.length !== 6 ) return;\n\n\t\tconst forceUpload = initTexture( textureProperties, texture );\n\t\tconst source = texture.source;\n\n\t\tstate.activeTexture( 33984 + slot );\n\t\tstate.bindTexture( 34067, textureProperties.__webglTexture );\n\n\t\tif ( source.version !== source.__currentVersion || forceUpload === true ) {\n\n\t\t\t_gl.pixelStorei( 37440, texture.flipY );\n\t\t\t_gl.pixelStorei( 37441, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( 3317, texture.unpackAlignment );\n\t\t\t_gl.pixelStorei( 37443, 0 );\n\n\t\t\tconst isCompressed = ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture );\n\t\t\tconst isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\tconst cubeImage = [];\n\n\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\tcubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcubeImage[ i ] = verifyColorSpace( texture, cubeImage[ i ] );\n\n\t\t\t}\n\n\t\t\tconst image = cubeImage[ 0 ],\n\t\t\t\tsupportsMips = isPowerOfTwo$1( image ) || isWebGL2,\n\t\t\t\tglFormat = utils.convert( texture.format, texture.encoding ),\n\t\t\t\tglType = utils.convert( texture.type ),\n\t\t\t\tglInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );\n\n\t\t\tconst useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true );\n\t\t\tconst allocateMemory = ( source.__currentVersion === undefined ) || ( forceUpload === true );\n\t\t\tlet levels = getMipLevels( texture, image, supportsMips );\n\n\t\t\tsetTextureParameters( 34067, texture, supportsMips );\n\n\t\t\tlet mipmaps;\n\n\t\t\tif ( isCompressed ) {\n\n\t\t\t\tif ( useTexStorage && allocateMemory ) {\n\n\t\t\t\t\tstate.texStorage2D( 34067, levels, glInternalFormat, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tmipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\tfor ( let j = 0; j < mipmaps.length; j ++ ) {\n\n\t\t\t\t\t\tconst mipmap = mipmaps[ j ];\n\n\t\t\t\t\t\tif ( texture.format !== RGBAFormat ) {\n\n\t\t\t\t\t\t\tif ( glFormat !== null ) {\n\n\t\t\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\t\t\tstate.compressedTexSubImage2D( 34069 + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\t\tstate.texSubImage2D( 34069 + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tmipmaps = texture.mipmaps;\n\n\t\t\t\tif ( useTexStorage && allocateMemory ) {\n\n\t\t\t\t\t// TODO: Uniformly handle mipmap definitions\n\t\t\t\t\t// Normal textures and compressed cube textures define base level + mips with their mipmap array\n\t\t\t\t\t// Uncompressed cube textures use their mipmap array only for mips (no base level)\n\n\t\t\t\t\tif ( mipmaps.length > 0 ) levels ++;\n\n\t\t\t\t\tstate.texStorage2D( 34067, levels, glInternalFormat, cubeImage[ 0 ].width, cubeImage[ 0 ].height );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\tstate.texSubImage2D( 34069 + i, 0, 0, 0, cubeImage[ i ].width, cubeImage[ i ].height, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tstate.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor ( let j = 0; j < mipmaps.length; j ++ ) {\n\n\t\t\t\t\t\t\tconst mipmap = mipmaps[ j ];\n\t\t\t\t\t\t\tconst mipmapImage = mipmap.image[ i ].image;\n\n\t\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\t\tstate.texSubImage2D( 34069 + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( 34069 + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\tstate.texSubImage2D( 34069 + i, 0, 0, 0, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tstate.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor ( let j = 0; j < mipmaps.length; j ++ ) {\n\n\t\t\t\t\t\t\tconst mipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\tif ( useTexStorage ) {\n\n\t\t\t\t\t\t\t\tstate.texSubImage2D( 34069 + i, j + 1, 0, 0, glFormat, glType, mipmap.image[ i ] );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( 34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {\n\n\t\t\t\t// We assume images for cube map have the same size.\n\t\t\t\tgenerateMipmap( 34067 );\n\n\t\t\t}\n\n\t\t\tsource.__currentVersion = source.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\ttextureProperties.__version = texture.version;\n\n\t}\n\n\t// Render targets\n\n\t// Setup storage for target texture and bind it to correct framebuffer\n\tfunction setupFrameBufferTexture( framebuffer, renderTarget, texture, attachment, textureTarget ) {\n\n\t\tconst glFormat = utils.convert( texture.format, texture.encoding );\n\t\tconst glType = utils.convert( texture.type );\n\t\tconst glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );\n\t\tconst renderTargetProperties = properties.get( renderTarget );\n\n\t\tif ( ! renderTargetProperties.__hasExternalTextures ) {\n\n\t\t\tif ( textureTarget === 32879 || textureTarget === 35866 ) {\n\n\t\t\t\tstate.texImage3D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.depth, 0, glFormat, glType, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tstate.bindFramebuffer( 36160, framebuffer );\n\n\t\tif ( useMultisampledRTT( renderTarget ) ) {\n\n\t\t\tmultisampledRTTExt.framebufferTexture2DMultisampleEXT( 36160, attachment, textureTarget, properties.get( texture ).__webglTexture, 0, getRenderTargetSamples( renderTarget ) );\n\n\t\t} else {\n\n\t\t\t_gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( texture ).__webglTexture, 0 );\n\n\t\t}\n\n\t\tstate.bindFramebuffer( 36160, null );\n\n\t}\n\n\n\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\tfunction setupRenderBufferStorage( renderbuffer, renderTarget, isMultisample ) {\n\n\t\t_gl.bindRenderbuffer( 36161, renderbuffer );\n\n\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\tlet glInternalFormat = 33189;\n\n\t\t\tif ( isMultisample || useMultisampledRTT( renderTarget ) ) {\n\n\t\t\t\tconst depthTexture = renderTarget.depthTexture;\n\n\t\t\t\tif ( depthTexture && depthTexture.isDepthTexture ) {\n\n\t\t\t\t\tif ( depthTexture.type === FloatType ) {\n\n\t\t\t\t\t\tglInternalFormat = 36012;\n\n\t\t\t\t\t} else if ( depthTexture.type === UnsignedIntType ) {\n\n\t\t\t\t\t\tglInternalFormat = 33190;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconst samples = getRenderTargetSamples( renderTarget );\n\n\t\t\t\tif ( useMultisampledRTT( renderTarget ) ) {\n\n\t\t\t\t\tmultisampledRTTExt.renderbufferStorageMultisampleEXT( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.renderbufferStorage( 36161, glInternalFormat, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.framebufferRenderbuffer( 36160, 36096, 36161, renderbuffer );\n\n\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\tconst samples = getRenderTargetSamples( renderTarget );\n\n\t\t\tif ( isMultisample && useMultisampledRTT( renderTarget ) === false ) {\n\n\t\t\t\t_gl.renderbufferStorageMultisample( 36161, samples, 35056, renderTarget.width, renderTarget.height );\n\n\t\t\t} else if ( useMultisampledRTT( renderTarget ) ) {\n\n\t\t\t\tmultisampledRTTExt.renderbufferStorageMultisampleEXT( 36161, samples, 35056, renderTarget.width, renderTarget.height );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.renderbufferStorage( 36161, 34041, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\n\t\t\t_gl.framebufferRenderbuffer( 36160, 33306, 36161, renderbuffer );\n\n\t\t} else {\n\n\t\t\tconst textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [ renderTarget.texture ];\n\n\t\t\tfor ( let i = 0; i < textures.length; i ++ ) {\n\n\t\t\t\tconst texture = textures[ i ];\n\n\t\t\t\tconst glFormat = utils.convert( texture.format, texture.encoding );\n\t\t\t\tconst glType = utils.convert( texture.type );\n\t\t\t\tconst glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );\n\t\t\t\tconst samples = getRenderTargetSamples( renderTarget );\n\n\t\t\t\tif ( isMultisample && useMultisampledRTT( renderTarget ) === false ) {\n\n\t\t\t\t\t_gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );\n\n\t\t\t\t} else if ( useMultisampledRTT( renderTarget ) ) {\n\n\t\t\t\t\tmultisampledRTTExt.renderbufferStorageMultisampleEXT( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.renderbufferStorage( 36161, glInternalFormat, renderTarget.width, renderTarget.height );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t_gl.bindRenderbuffer( 36161, null );\n\n\t}\n\n\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\tconst isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget );\n\t\tif ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' );\n\n\t\tstate.bindFramebuffer( 36160, framebuffer );\n\n\t\tif ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\tthrow new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' );\n\n\t\t}\n\n\t\t// upload an empty depth texture with framebuffer size\n\t\tif ( ! properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\n\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\n\t\t}\n\n\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\tconst webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\t\tconst samples = getRenderTargetSamples( renderTarget );\n\n\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\tif ( useMultisampledRTT( renderTarget ) ) {\n\n\t\t\t\tmultisampledRTTExt.framebufferTexture2DMultisampleEXT( 36160, 36096, 3553, webglDepthTexture, 0, samples );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.framebufferTexture2D( 36160, 36096, 3553, webglDepthTexture, 0 );\n\n\t\t\t}\n\n\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\tif ( useMultisampledRTT( renderTarget ) ) {\n\n\t\t\t\tmultisampledRTTExt.framebufferTexture2DMultisampleEXT( 36160, 33306, 3553, webglDepthTexture, 0, samples );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.framebufferTexture2D( 36160, 33306, 3553, webglDepthTexture, 0 );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tthrow new Error( 'Unknown depthTexture format' );\n\n\t\t}\n\n\t}\n\n\t// Setup GL resources for a non-texture depth buffer\n\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\tconst renderTargetProperties = properties.get( renderTarget );\n\t\tconst isCube = ( renderTarget.isWebGLCubeRenderTarget === true );\n\n\t\tif ( renderTarget.depthTexture && ! renderTargetProperties.__autoAllocateDepthBuffer ) {\n\n\t\t\tif ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' );\n\n\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t} else {\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tstate.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer );\n\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false );\n\n\t\t\t}\n\n\t\t}\n\n\t\tstate.bindFramebuffer( 36160, null );\n\n\t}\n\n\t// rebind framebuffer with external textures\n\tfunction rebindTextures( renderTarget, colorTexture, depthTexture ) {\n\n\t\tconst renderTargetProperties = properties.get( renderTarget );\n\n\t\tif ( colorTexture !== undefined ) {\n\n\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, 36064, 3553 );\n\n\t\t}\n\n\t\tif ( depthTexture !== undefined ) {\n\n\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t}\n\n\t}\n\n\t// Set up GL resources for the render target\n\tfunction setupRenderTarget( renderTarget ) {\n\n\t\tconst texture = renderTarget.texture;\n\n\t\tconst renderTargetProperties = properties.get( renderTarget );\n\t\tconst textureProperties = properties.get( texture );\n\n\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\tif ( renderTarget.isWebGLMultipleRenderTargets !== true ) {\n\n\t\t\tif ( textureProperties.__webglTexture === undefined ) {\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t}\n\n\t\t\ttextureProperties.__version = texture.version;\n\t\t\tinfo.memory.textures ++;\n\n\t\t}\n\n\t\tconst isCube = ( renderTarget.isWebGLCubeRenderTarget === true );\n\t\tconst isMultipleRenderTargets = ( renderTarget.isWebGLMultipleRenderTargets === true );\n\t\tconst supportsMips = isPowerOfTwo$1( renderTarget ) || isWebGL2;\n\n\t\t// Setup framebuffer\n\n\t\tif ( isCube ) {\n\n\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\tif ( isMultipleRenderTargets ) {\n\n\t\t\t\tif ( capabilities.drawBuffers ) {\n\n\t\t\t\t\tconst textures = renderTarget.texture;\n\n\t\t\t\t\tfor ( let i = 0, il = textures.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tconst attachmentProperties = properties.get( textures[ i ] );\n\n\t\t\t\t\t\tif ( attachmentProperties.__webglTexture === undefined ) {\n\n\t\t\t\t\t\t\tattachmentProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t\t\t\tinfo.memory.textures ++;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( ( isWebGL2 && renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) === false ) {\n\n\t\t\t\tconst textures = isMultipleRenderTargets ? texture : [ texture ];\n\n\t\t\t\trenderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer();\n\t\t\t\trenderTargetProperties.__webglColorRenderbuffer = [];\n\n\t\t\t\tstate.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );\n\n\t\t\t\tfor ( let i = 0; i < textures.length; i ++ ) {\n\n\t\t\t\t\tconst texture = textures[ i ];\n\t\t\t\t\trenderTargetProperties.__webglColorRenderbuffer[ i ] = _gl.createRenderbuffer();\n\n\t\t\t\t\t_gl.bindRenderbuffer( 36161, renderTargetProperties.__webglColorRenderbuffer[ i ] );\n\n\t\t\t\t\tconst glFormat = utils.convert( texture.format, texture.encoding );\n\t\t\t\t\tconst glType = utils.convert( texture.type );\n\t\t\t\t\tconst glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding );\n\t\t\t\t\tconst samples = getRenderTargetSamples( renderTarget );\n\t\t\t\t\t_gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );\n\n\t\t\t\t\t_gl.framebufferRenderbuffer( 36160, 36064 + i, 36161, renderTargetProperties.__webglColorRenderbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bindRenderbuffer( 36161, null );\n\n\t\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true );\n\n\t\t\t\t}\n\n\t\t\t\tstate.bindFramebuffer( 36160, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup color buffer\n\n\t\tif ( isCube ) {\n\n\t\t\tstate.bindTexture( 34067, textureProperties.__webglTexture );\n\t\t\tsetTextureParameters( 34067, texture, supportsMips );\n\n\t\t\tfor ( let i = 0; i < 6; i ++ ) {\n\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, texture, 36064, 34069 + i );\n\n\t\t\t}\n\n\t\t\tif ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {\n\n\t\t\t\tgenerateMipmap( 34067 );\n\n\t\t\t}\n\n\t\t\tstate.unbindTexture();\n\n\t\t} else if ( isMultipleRenderTargets ) {\n\n\t\t\tconst textures = renderTarget.texture;\n\n\t\t\tfor ( let i = 0, il = textures.length; i < il; i ++ ) {\n\n\t\t\t\tconst attachment = textures[ i ];\n\t\t\t\tconst attachmentProperties = properties.get( attachment );\n\n\t\t\t\tstate.bindTexture( 3553, attachmentProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( 3553, attachment, supportsMips );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, attachment, 36064 + i, 3553 );\n\n\t\t\t\tif ( textureNeedsGenerateMipmaps( attachment, supportsMips ) ) {\n\n\t\t\t\t\tgenerateMipmap( 3553 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.unbindTexture();\n\n\t\t} else {\n\n\t\t\tlet glTextureType = 3553;\n\n\t\t\tif ( renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget ) {\n\n\t\t\t\tif ( isWebGL2 ) {\n\n\t\t\t\t\tglTextureType = renderTarget.isWebGL3DRenderTarget ? 32879 : 35866;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLTextures: THREE.Data3DTexture and THREE.DataArrayTexture only supported with WebGL2.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.bindTexture( glTextureType, textureProperties.__webglTexture );\n\t\t\tsetTextureParameters( glTextureType, texture, supportsMips );\n\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, texture, 36064, glTextureType );\n\n\t\t\tif ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {\n\n\t\t\t\tgenerateMipmap( glTextureType );\n\n\t\t\t}\n\n\t\t\tstate.unbindTexture();\n\n\t\t}\n\n\t\t// Setup depth and stencil buffers\n\n\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t}\n\n\t}\n\n\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\tconst supportsMips = isPowerOfTwo$1( renderTarget ) || isWebGL2;\n\n\t\tconst textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [ renderTarget.texture ];\n\n\t\tfor ( let i = 0, il = textures.length; i < il; i ++ ) {\n\n\t\t\tconst texture = textures[ i ];\n\n\t\t\tif ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {\n\n\t\t\t\tconst target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553;\n\t\t\t\tconst webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\tgenerateMipmap( target );\n\t\t\t\tstate.unbindTexture();\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction updateMultisampleRenderTarget( renderTarget ) {\n\n\t\tif ( ( isWebGL2 && renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) === false ) {\n\n\t\t\tconst textures = renderTarget.isWebGLMultipleRenderTargets ? renderTarget.texture : [ renderTarget.texture ];\n\t\t\tconst width = renderTarget.width;\n\t\t\tconst height = renderTarget.height;\n\t\t\tlet mask = 16384;\n\t\t\tconst invalidationArray = [];\n\t\t\tconst depthStyle = renderTarget.stencilBuffer ? 33306 : 36096;\n\t\t\tconst renderTargetProperties = properties.get( renderTarget );\n\t\t\tconst isMultipleRenderTargets = ( renderTarget.isWebGLMultipleRenderTargets === true );\n\n\t\t\t// If MRT we need to remove FBO attachments\n\t\t\tif ( isMultipleRenderTargets ) {\n\n\t\t\t\tfor ( let i = 0; i < textures.length; i ++ ) {\n\n\t\t\t\t\tstate.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );\n\t\t\t\t\t_gl.framebufferRenderbuffer( 36160, 36064 + i, 36161, null );\n\n\t\t\t\t\tstate.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\t_gl.framebufferTexture2D( 36009, 36064 + i, 3553, null, 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.bindFramebuffer( 36008, renderTargetProperties.__webglMultisampledFramebuffer );\n\t\t\tstate.bindFramebuffer( 36009, renderTargetProperties.__webglFramebuffer );\n\n\t\t\tfor ( let i = 0; i < textures.length; i ++ ) {\n\n\t\t\t\tinvalidationArray.push( 36064 + i );\n\n\t\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\t\tinvalidationArray.push( depthStyle );\n\n\t\t\t\t}\n\n\t\t\t\tconst ignoreDepthValues = ( renderTargetProperties.__ignoreDepthValues !== undefined ) ? renderTargetProperties.__ignoreDepthValues : false;\n\n\t\t\t\tif ( ignoreDepthValues === false ) {\n\n\t\t\t\t\tif ( renderTarget.depthBuffer ) mask |= 256;\n\t\t\t\t\tif ( renderTarget.stencilBuffer ) mask |= 1024;\n\n\t\t\t\t}\n\n\t\t\t\tif ( isMultipleRenderTargets ) {\n\n\t\t\t\t\t_gl.framebufferRenderbuffer( 36008, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ignoreDepthValues === true ) {\n\n\t\t\t\t\t_gl.invalidateFramebuffer( 36008, [ depthStyle ] );\n\t\t\t\t\t_gl.invalidateFramebuffer( 36009, [ depthStyle ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( isMultipleRenderTargets ) {\n\n\t\t\t\t\tconst webglTexture = properties.get( textures[ i ] ).__webglTexture;\n\t\t\t\t\t_gl.framebufferTexture2D( 36009, 36064, 3553, webglTexture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, 9728 );\n\n\t\t\t\tif ( supportsInvalidateFramebuffer ) {\n\n\t\t\t\t\t_gl.invalidateFramebuffer( 36008, invalidationArray );\n\n\t\t\t\t}\n\n\n\t\t\t}\n\n\t\t\tstate.bindFramebuffer( 36008, null );\n\t\t\tstate.bindFramebuffer( 36009, null );\n\n\t\t\t// If MRT since pre-blit we removed the FBO we need to reconstruct the attachments\n\t\t\tif ( isMultipleRenderTargets ) {\n\n\t\t\t\tfor ( let i = 0; i < textures.length; i ++ ) {\n\n\t\t\t\t\tstate.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );\n\t\t\t\t\t_gl.framebufferRenderbuffer( 36160, 36064 + i, 36161, renderTargetProperties.__webglColorRenderbuffer[ i ] );\n\n\t\t\t\t\tconst webglTexture = properties.get( textures[ i ] ).__webglTexture;\n\n\t\t\t\t\tstate.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\t_gl.framebufferTexture2D( 36009, 36064 + i, 3553, webglTexture, 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.bindFramebuffer( 36009, renderTargetProperties.__webglMultisampledFramebuffer );\n\n\t\t}\n\n\t}\n\n\tfunction getRenderTargetSamples( renderTarget ) {\n\n\t\treturn Math.min( maxSamples, renderTarget.samples );\n\n\t}\n\n\tfunction useMultisampledRTT( renderTarget ) {\n\n\t\tconst renderTargetProperties = properties.get( renderTarget );\n\n\t\treturn isWebGL2 && renderTarget.samples > 0 && extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true && renderTargetProperties.__useRenderToTexture !== false;\n\n\t}\n\n\tfunction updateVideoTexture( texture ) {\n\n\t\tconst frame = info.render.frame;\n\n\t\t// Check the last frame we updated the VideoTexture\n\n\t\tif ( _videoTextures.get( texture ) !== frame ) {\n\n\t\t\t_videoTextures.set( texture, frame );\n\t\t\ttexture.update();\n\n\t\t}\n\n\t}\n\n\tfunction verifyColorSpace( texture, image ) {\n\n\t\tconst encoding = texture.encoding;\n\t\tconst format = texture.format;\n\t\tconst type = texture.type;\n\n\t\tif ( texture.isCompressedTexture === true || texture.isVideoTexture === true || texture.format === _SRGBAFormat ) return image;\n\n\t\tif ( encoding !== LinearEncoding ) {\n\n\t\t\t// sRGB\n\n\t\t\tif ( encoding === sRGBEncoding ) {\n\n\t\t\t\tif ( isWebGL2 === false ) {\n\n\t\t\t\t\t// in WebGL 1, try to use EXT_sRGB extension and unsized formats\n\n\t\t\t\t\tif ( extensions.has( 'EXT_sRGB' ) === true && format === RGBAFormat ) {\n\n\t\t\t\t\t\ttexture.format = _SRGBAFormat;\n\n\t\t\t\t\t\t// it's not possible to generate mips in WebGL 1 with this extension\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\t\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// slow fallback (CPU decode)\n\n\t\t\t\t\t\timage = ImageUtils.sRGBToLinear( image );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// in WebGL 2 uncompressed textures can only be sRGB encoded if they have the RGBA8 format\n\n\t\t\t\t\tif ( format !== RGBAFormat || type !== UnsignedByteType ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.WebGLTextures: Unsupported texture encoding:', encoding );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn image;\n\n\t}\n\n\t//\n\n\tthis.allocateTextureUnit = allocateTextureUnit;\n\tthis.resetTextureUnits = resetTextureUnits;\n\n\tthis.setTexture2D = setTexture2D;\n\tthis.setTexture2DArray = setTexture2DArray;\n\tthis.setTexture3D = setTexture3D;\n\tthis.setTextureCube = setTextureCube;\n\tthis.rebindTextures = rebindTextures;\n\tthis.setupRenderTarget = setupRenderTarget;\n\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\tthis.updateMultisampleRenderTarget = updateMultisampleRenderTarget;\n\tthis.setupDepthRenderbuffer = setupDepthRenderbuffer;\n\tthis.setupFrameBufferTexture = setupFrameBufferTexture;\n\tthis.useMultisampledRTT = useMultisampledRTT;\n\n}\n\nfunction WebGLUtils( gl, extensions, capabilities ) {\n\n\tconst isWebGL2 = capabilities.isWebGL2;\n\n\tfunction convert( p, encoding = null ) {\n\n\t\tlet extension;\n\n\t\tif ( p === UnsignedByteType ) return 5121;\n\t\tif ( p === UnsignedShort4444Type ) return 32819;\n\t\tif ( p === UnsignedShort5551Type ) return 32820;\n\n\t\tif ( p === ByteType ) return 5120;\n\t\tif ( p === ShortType ) return 5122;\n\t\tif ( p === UnsignedShortType ) return 5123;\n\t\tif ( p === IntType ) return 5124;\n\t\tif ( p === UnsignedIntType ) return 5125;\n\t\tif ( p === FloatType ) return 5126;\n\n\t\tif ( p === HalfFloatType ) {\n\n\t\t\tif ( isWebGL2 ) return 5131;\n\n\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\treturn extension.HALF_FLOAT_OES;\n\n\t\t\t} else {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( p === AlphaFormat ) return 6406;\n\t\tif ( p === RGBAFormat ) return 6408;\n\t\tif ( p === LuminanceFormat ) return 6409;\n\t\tif ( p === LuminanceAlphaFormat ) return 6410;\n\t\tif ( p === DepthFormat ) return 6402;\n\t\tif ( p === DepthStencilFormat ) return 34041;\n\t\tif ( p === RedFormat ) return 6403;\n\n\t\tif ( p === RGBFormat ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: THREE.RGBFormat has been removed. Use THREE.RGBAFormat instead. https://github.com/mrdoob/three.js/pull/23228' );\n\t\t\treturn 6408;\n\n\t\t}\n\n\t\t// WebGL 1 sRGB fallback\n\n\t\tif ( p === _SRGBAFormat ) {\n\n\t\t\textension = extensions.get( 'EXT_sRGB' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\treturn extension.SRGB_ALPHA_EXT;\n\n\t\t\t} else {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// WebGL2 formats.\n\n\t\tif ( p === RedIntegerFormat ) return 36244;\n\t\tif ( p === RGFormat ) return 33319;\n\t\tif ( p === RGIntegerFormat ) return 33320;\n\t\tif ( p === RGBAIntegerFormat ) return 36249;\n\n\t\t// S3TC\n\n\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\tif ( encoding === sRGBEncoding ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc_srgb' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// PVRTC\n\n\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t} else {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// ETC1\n\n\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\treturn extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t} else {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// ETC2\n\n\t\tif ( p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format ) {\n\n\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tif ( p === RGB_ETC2_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2;\n\t\t\t\tif ( p === RGBA_ETC2_EAC_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC;\n\n\t\t\t} else {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// ASTC\n\n\t\tif ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format ||\n\t\t\tp === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format ||\n\t\t\tp === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format ||\n\t\t\tp === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format ||\n\t\t\tp === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ) {\n\n\t\t\textension = extensions.get( 'WEBGL_compressed_texture_astc' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tif ( p === RGBA_ASTC_4x4_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_5x4_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_5x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_6x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_6x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_8x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_8x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_8x8_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_10x5_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_10x6_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_10x8_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_10x10_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_12x10_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR;\n\t\t\t\tif ( p === RGBA_ASTC_12x12_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR;\n\n\t\t\t} else {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// BPTC\n\n\t\tif ( p === RGBA_BPTC_Format ) {\n\n\t\t\textension = extensions.get( 'EXT_texture_compression_bptc' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tif ( p === RGBA_BPTC_Format ) return ( encoding === sRGBEncoding ) ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT;\n\n\t\t\t} else {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\tif ( isWebGL2 ) return 34042;\n\n\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\treturn extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t} else {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// if \"p\" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats)\n\n\t\treturn ( gl[ p ] !== undefined ) ? gl[ p ] : null;\n\n\t}\n\n\treturn { convert: convert };\n\n}\n\nclass ArrayCamera extends PerspectiveCamera {\n\n\tconstructor( array = [] ) {\n\n\t\tsuper();\n\n\t\tthis.isArrayCamera = true;\n\n\t\tthis.cameras = array;\n\n\t}\n\n}\n\nclass Group extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isGroup = true;\n\n\t\tthis.type = 'Group';\n\n\t}\n\n}\n\nconst _moveEvent = { type: 'move' };\n\nclass WebXRController {\n\n\tconstructor() {\n\n\t\tthis._targetRay = null;\n\t\tthis._grip = null;\n\t\tthis._hand = null;\n\n\t}\n\n\tgetHandSpace() {\n\n\t\tif ( this._hand === null ) {\n\n\t\t\tthis._hand = new Group();\n\t\t\tthis._hand.matrixAutoUpdate = false;\n\t\t\tthis._hand.visible = false;\n\n\t\t\tthis._hand.joints = {};\n\t\t\tthis._hand.inputState = { pinching: false };\n\n\t\t}\n\n\t\treturn this._hand;\n\n\t}\n\n\tgetTargetRaySpace() {\n\n\t\tif ( this._targetRay === null ) {\n\n\t\t\tthis._targetRay = new Group();\n\t\t\tthis._targetRay.matrixAutoUpdate = false;\n\t\t\tthis._targetRay.visible = false;\n\t\t\tthis._targetRay.hasLinearVelocity = false;\n\t\t\tthis._targetRay.linearVelocity = new Vector3();\n\t\t\tthis._targetRay.hasAngularVelocity = false;\n\t\t\tthis._targetRay.angularVelocity = new Vector3();\n\n\t\t}\n\n\t\treturn this._targetRay;\n\n\t}\n\n\tgetGripSpace() {\n\n\t\tif ( this._grip === null ) {\n\n\t\t\tthis._grip = new Group();\n\t\t\tthis._grip.matrixAutoUpdate = false;\n\t\t\tthis._grip.visible = false;\n\t\t\tthis._grip.hasLinearVelocity = false;\n\t\t\tthis._grip.linearVelocity = new Vector3();\n\t\t\tthis._grip.hasAngularVelocity = false;\n\t\t\tthis._grip.angularVelocity = new Vector3();\n\n\t\t}\n\n\t\treturn this._grip;\n\n\t}\n\n\tdispatchEvent( event ) {\n\n\t\tif ( this._targetRay !== null ) {\n\n\t\t\tthis._targetRay.dispatchEvent( event );\n\n\t\t}\n\n\t\tif ( this._grip !== null ) {\n\n\t\t\tthis._grip.dispatchEvent( event );\n\n\t\t}\n\n\t\tif ( this._hand !== null ) {\n\n\t\t\tthis._hand.dispatchEvent( event );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tdisconnect( inputSource ) {\n\n\t\tthis.dispatchEvent( { type: 'disconnected', data: inputSource } );\n\n\t\tif ( this._targetRay !== null ) {\n\n\t\t\tthis._targetRay.visible = false;\n\n\t\t}\n\n\t\tif ( this._grip !== null ) {\n\n\t\t\tthis._grip.visible = false;\n\n\t\t}\n\n\t\tif ( this._hand !== null ) {\n\n\t\t\tthis._hand.visible = false;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tupdate( inputSource, frame, referenceSpace ) {\n\n\t\tlet inputPose = null;\n\t\tlet gripPose = null;\n\t\tlet handPose = null;\n\n\t\tconst targetRay = this._targetRay;\n\t\tconst grip = this._grip;\n\t\tconst hand = this._hand;\n\n\t\tif ( inputSource && frame.session.visibilityState !== 'visible-blurred' ) {\n\n\t\t\tif ( targetRay !== null ) {\n\n\t\t\t\tinputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace );\n\n\t\t\t\tif ( inputPose !== null ) {\n\n\t\t\t\t\ttargetRay.matrix.fromArray( inputPose.transform.matrix );\n\t\t\t\t\ttargetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale );\n\n\t\t\t\t\tif ( inputPose.linearVelocity ) {\n\n\t\t\t\t\t\ttargetRay.hasLinearVelocity = true;\n\t\t\t\t\t\ttargetRay.linearVelocity.copy( inputPose.linearVelocity );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttargetRay.hasLinearVelocity = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( inputPose.angularVelocity ) {\n\n\t\t\t\t\t\ttargetRay.hasAngularVelocity = true;\n\t\t\t\t\t\ttargetRay.angularVelocity.copy( inputPose.angularVelocity );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttargetRay.hasAngularVelocity = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.dispatchEvent( _moveEvent );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( hand && inputSource.hand ) {\n\n\t\t\t\thandPose = true;\n\n\t\t\t\tfor ( const inputjoint of inputSource.hand.values() ) {\n\n\t\t\t\t\t// Update the joints groups with the XRJoint poses\n\t\t\t\t\tconst jointPose = frame.getJointPose( inputjoint, referenceSpace );\n\n\t\t\t\t\tif ( hand.joints[ inputjoint.jointName ] === undefined ) {\n\n\t\t\t\t\t\t// The transform of this joint will be updated with the joint pose on each frame\n\t\t\t\t\t\tconst joint = new Group();\n\t\t\t\t\t\tjoint.matrixAutoUpdate = false;\n\t\t\t\t\t\tjoint.visible = false;\n\t\t\t\t\t\thand.joints[ inputjoint.jointName ] = joint;\n\t\t\t\t\t\t// ??\n\t\t\t\t\t\thand.add( joint );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst joint = hand.joints[ inputjoint.jointName ];\n\n\t\t\t\t\tif ( jointPose !== null ) {\n\n\t\t\t\t\t\tjoint.matrix.fromArray( jointPose.transform.matrix );\n\t\t\t\t\t\tjoint.matrix.decompose( joint.position, joint.rotation, joint.scale );\n\t\t\t\t\t\tjoint.jointRadius = jointPose.radius;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tjoint.visible = jointPose !== null;\n\n\t\t\t\t}\n\n\t\t\t\t// Custom events\n\n\t\t\t\t// Check pinchz\n\t\t\t\tconst indexTip = hand.joints[ 'index-finger-tip' ];\n\t\t\t\tconst thumbTip = hand.joints[ 'thumb-tip' ];\n\t\t\t\tconst distance = indexTip.position.distanceTo( thumbTip.position );\n\n\t\t\t\tconst distanceToPinch = 0.02;\n\t\t\t\tconst threshold = 0.005;\n\n\t\t\t\tif ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {\n\n\t\t\t\t\thand.inputState.pinching = false;\n\t\t\t\t\tthis.dispatchEvent( {\n\t\t\t\t\t\ttype: 'pinchend',\n\t\t\t\t\t\thandedness: inputSource.handedness,\n\t\t\t\t\t\ttarget: this\n\t\t\t\t\t} );\n\n\t\t\t\t} else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {\n\n\t\t\t\t\thand.inputState.pinching = true;\n\t\t\t\t\tthis.dispatchEvent( {\n\t\t\t\t\t\ttype: 'pinchstart',\n\t\t\t\t\t\thandedness: inputSource.handedness,\n\t\t\t\t\t\ttarget: this\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( grip !== null && inputSource.gripSpace ) {\n\n\t\t\t\t\tgripPose = frame.getPose( inputSource.gripSpace, referenceSpace );\n\n\t\t\t\t\tif ( gripPose !== null ) {\n\n\t\t\t\t\t\tgrip.matrix.fromArray( gripPose.transform.matrix );\n\t\t\t\t\t\tgrip.matrix.decompose( grip.position, grip.rotation, grip.scale );\n\n\t\t\t\t\t\tif ( gripPose.linearVelocity ) {\n\n\t\t\t\t\t\t\tgrip.hasLinearVelocity = true;\n\t\t\t\t\t\t\tgrip.linearVelocity.copy( gripPose.linearVelocity );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgrip.hasLinearVelocity = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( gripPose.angularVelocity ) {\n\n\t\t\t\t\t\t\tgrip.hasAngularVelocity = true;\n\t\t\t\t\t\t\tgrip.angularVelocity.copy( gripPose.angularVelocity );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgrip.hasAngularVelocity = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( targetRay !== null ) {\n\n\t\t\ttargetRay.visible = ( inputPose !== null );\n\n\t\t}\n\n\t\tif ( grip !== null ) {\n\n\t\t\tgrip.visible = ( gripPose !== null );\n\n\t\t}\n\n\t\tif ( hand !== null ) {\n\n\t\t\thand.visible = ( handPose !== null );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass DepthTexture extends Texture {\n\n\tconstructor( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedIntType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tsuper( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.isDepthTexture = true;\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\n}\n\nclass WebXRManager extends EventDispatcher {\n\n\tconstructor( renderer, gl ) {\n\n\t\tsuper();\n\n\t\tconst scope = this;\n\n\t\tlet session = null;\n\t\tlet framebufferScaleFactor = 1.0;\n\n\t\tlet referenceSpace = null;\n\t\tlet referenceSpaceType = 'local-floor';\n\t\tlet customReferenceSpace = null;\n\n\t\tlet pose = null;\n\t\tlet glBinding = null;\n\t\tlet glProjLayer = null;\n\t\tlet glBaseLayer = null;\n\t\tlet xrFrame = null;\n\t\tconst attributes = gl.getContextAttributes();\n\t\tlet initialRenderTarget = null;\n\t\tlet newRenderTarget = null;\n\n\t\tconst controllers = [];\n\t\tconst inputSourcesMap = new Map();\n\n\t\t//\n\n\t\tconst cameraL = new PerspectiveCamera();\n\t\tcameraL.layers.enable( 1 );\n\t\tcameraL.viewport = new Vector4();\n\n\t\tconst cameraR = new PerspectiveCamera();\n\t\tcameraR.layers.enable( 2 );\n\t\tcameraR.viewport = new Vector4();\n\n\t\tconst cameras = [ cameraL, cameraR ];\n\n\t\tconst cameraVR = new ArrayCamera();\n\t\tcameraVR.layers.enable( 1 );\n\t\tcameraVR.layers.enable( 2 );\n\n\t\tlet _currentDepthNear = null;\n\t\tlet _currentDepthFar = null;\n\n\t\t//\n\n\t\tthis.cameraAutoUpdate = true;\n\t\tthis.enabled = false;\n\n\t\tthis.isPresenting = false;\n\n\t\tthis.getController = function ( index ) {\n\n\t\t\tlet controller = controllers[ index ];\n\n\t\t\tif ( controller === undefined ) {\n\n\t\t\t\tcontroller = new WebXRController();\n\t\t\t\tcontrollers[ index ] = controller;\n\n\t\t\t}\n\n\t\t\treturn controller.getTargetRaySpace();\n\n\t\t};\n\n\t\tthis.getControllerGrip = function ( index ) {\n\n\t\t\tlet controller = controllers[ index ];\n\n\t\t\tif ( controller === undefined ) {\n\n\t\t\t\tcontroller = new WebXRController();\n\t\t\t\tcontrollers[ index ] = controller;\n\n\t\t\t}\n\n\t\t\treturn controller.getGripSpace();\n\n\t\t};\n\n\t\tthis.getHand = function ( index ) {\n\n\t\t\tlet controller = controllers[ index ];\n\n\t\t\tif ( controller === undefined ) {\n\n\t\t\t\tcontroller = new WebXRController();\n\t\t\t\tcontrollers[ index ] = controller;\n\n\t\t\t}\n\n\t\t\treturn controller.getHandSpace();\n\n\t\t};\n\n\t\t//\n\n\t\tfunction onSessionEvent( event ) {\n\n\t\t\tconst controller = inputSourcesMap.get( event.inputSource );\n\n\t\t\tif ( controller !== undefined ) {\n\n\t\t\t\tcontroller.dispatchEvent( { type: event.type, data: event.inputSource } );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onSessionEnd() {\n\n\t\t\tsession.removeEventListener( 'select', onSessionEvent );\n\t\t\tsession.removeEventListener( 'selectstart', onSessionEvent );\n\t\t\tsession.removeEventListener( 'selectend', onSessionEvent );\n\t\t\tsession.removeEventListener( 'squeeze', onSessionEvent );\n\t\t\tsession.removeEventListener( 'squeezestart', onSessionEvent );\n\t\t\tsession.removeEventListener( 'squeezeend', onSessionEvent );\n\t\t\tsession.removeEventListener( 'end', onSessionEnd );\n\t\t\tsession.removeEventListener( 'inputsourceschange', onInputSourcesChange );\n\n\t\t\tinputSourcesMap.forEach( function ( controller, inputSource ) {\n\n\t\t\t\tif ( controller !== undefined ) {\n\n\t\t\t\t\tcontroller.disconnect( inputSource );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tinputSourcesMap.clear();\n\n\t\t\t_currentDepthNear = null;\n\t\t\t_currentDepthFar = null;\n\n\t\t\t// restore framebuffer/rendering state\n\n\t\t\trenderer.setRenderTarget( initialRenderTarget );\n\n\t\t\tglBaseLayer = null;\n\t\t\tglProjLayer = null;\n\t\t\tglBinding = null;\n\t\t\tsession = null;\n\t\t\tnewRenderTarget = null;\n\n\t\t\t//\n\n\t\t\tanimation.stop();\n\n\t\t\tscope.isPresenting = false;\n\n\t\t\tscope.dispatchEvent( { type: 'sessionend' } );\n\n\t\t}\n\n\t\tthis.setFramebufferScaleFactor = function ( value ) {\n\n\t\t\tframebufferScaleFactor = value;\n\n\t\t\tif ( scope.isPresenting === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebXRManager: Cannot change framebuffer scale while presenting.' );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setReferenceSpaceType = function ( value ) {\n\n\t\t\treferenceSpaceType = value;\n\n\t\t\tif ( scope.isPresenting === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebXRManager: Cannot change reference space type while presenting.' );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getReferenceSpace = function () {\n\n\t\t\treturn customReferenceSpace || referenceSpace;\n\n\t\t};\n\n\t\tthis.setReferenceSpace = function ( space ) {\n\n\t\t\tcustomReferenceSpace = space;\n\n\t\t};\n\n\t\tthis.getBaseLayer = function () {\n\n\t\t\treturn glProjLayer !== null ? glProjLayer : glBaseLayer;\n\n\t\t};\n\n\t\tthis.getBinding = function () {\n\n\t\t\treturn glBinding;\n\n\t\t};\n\n\t\tthis.getFrame = function () {\n\n\t\t\treturn xrFrame;\n\n\t\t};\n\n\t\tthis.getSession = function () {\n\n\t\t\treturn session;\n\n\t\t};\n\n\t\tthis.setSession = async function ( value ) {\n\n\t\t\tsession = value;\n\n\t\t\tif ( session !== null ) {\n\n\t\t\t\tinitialRenderTarget = renderer.getRenderTarget();\n\n\t\t\t\tsession.addEventListener( 'select', onSessionEvent );\n\t\t\t\tsession.addEventListener( 'selectstart', onSessionEvent );\n\t\t\t\tsession.addEventListener( 'selectend', onSessionEvent );\n\t\t\t\tsession.addEventListener( 'squeeze', onSessionEvent );\n\t\t\t\tsession.addEventListener( 'squeezestart', onSessionEvent );\n\t\t\t\tsession.addEventListener( 'squeezeend', onSessionEvent );\n\t\t\t\tsession.addEventListener( 'end', onSessionEnd );\n\t\t\t\tsession.addEventListener( 'inputsourceschange', onInputSourcesChange );\n\n\t\t\t\tif ( attributes.xrCompatible !== true ) {\n\n\t\t\t\t\tawait gl.makeXRCompatible();\n\n\t\t\t\t}\n\n\t\t\t\tif ( ( session.renderState.layers === undefined ) || ( renderer.capabilities.isWebGL2 === false ) ) {\n\n\t\t\t\t\tconst layerInit = {\n\t\t\t\t\t\tantialias: ( session.renderState.layers === undefined ) ? attributes.antialias : true,\n\t\t\t\t\t\talpha: attributes.alpha,\n\t\t\t\t\t\tdepth: attributes.depth,\n\t\t\t\t\t\tstencil: attributes.stencil,\n\t\t\t\t\t\tframebufferScaleFactor: framebufferScaleFactor\n\t\t\t\t\t};\n\n\t\t\t\t\tglBaseLayer = new XRWebGLLayer( session, gl, layerInit );\n\n\t\t\t\t\tsession.updateRenderState( { baseLayer: glBaseLayer } );\n\n\t\t\t\t\tnewRenderTarget = new WebGLRenderTarget(\n\t\t\t\t\t\tglBaseLayer.framebufferWidth,\n\t\t\t\t\t\tglBaseLayer.framebufferHeight,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tformat: RGBAFormat,\n\t\t\t\t\t\t\ttype: UnsignedByteType,\n\t\t\t\t\t\t\tencoding: renderer.outputEncoding\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlet depthFormat = null;\n\t\t\t\t\tlet depthType = null;\n\t\t\t\t\tlet glDepthFormat = null;\n\n\t\t\t\t\tif ( attributes.depth ) {\n\n\t\t\t\t\t\tglDepthFormat = attributes.stencil ? 35056 : 33190;\n\t\t\t\t\t\tdepthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat;\n\t\t\t\t\t\tdepthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst projectionlayerInit = {\n\t\t\t\t\t\tcolorFormat: ( renderer.outputEncoding === sRGBEncoding ) ? 35907 : 32856,\n\t\t\t\t\t\tdepthFormat: glDepthFormat,\n\t\t\t\t\t\tscaleFactor: framebufferScaleFactor\n\t\t\t\t\t};\n\n\t\t\t\t\tglBinding = new XRWebGLBinding( session, gl );\n\n\t\t\t\t\tglProjLayer = glBinding.createProjectionLayer( projectionlayerInit );\n\n\t\t\t\t\tsession.updateRenderState( { layers: [ glProjLayer ] } );\n\n\t\t\t\t\tnewRenderTarget = new WebGLRenderTarget(\n\t\t\t\t\t\tglProjLayer.textureWidth,\n\t\t\t\t\t\tglProjLayer.textureHeight,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tformat: RGBAFormat,\n\t\t\t\t\t\t\ttype: UnsignedByteType,\n\t\t\t\t\t\t\tdepthTexture: new DepthTexture( glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat ),\n\t\t\t\t\t\t\tstencilBuffer: attributes.stencil,\n\t\t\t\t\t\t\tencoding: renderer.outputEncoding,\n\t\t\t\t\t\t\tsamples: attributes.antialias ? 4 : 0\n\t\t\t\t\t\t} );\n\n\t\t\t\t\tconst renderTargetProperties = renderer.properties.get( newRenderTarget );\n\t\t\t\t\trenderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues;\n\n\t\t\t\t}\n\n\t\t\t\tnewRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278\n\n\t\t\t\t// Set foveation to maximum.\n\t\t\t\tthis.setFoveation( 1.0 );\n\n\t\t\t\tcustomReferenceSpace = null;\n\t\t\t\treferenceSpace = await session.requestReferenceSpace( referenceSpaceType );\n\n\t\t\t\tanimation.setContext( session );\n\t\t\t\tanimation.start();\n\n\t\t\t\tscope.isPresenting = true;\n\n\t\t\t\tscope.dispatchEvent( { type: 'sessionstart' } );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction onInputSourcesChange( event ) {\n\n\t\t\tconst inputSources = session.inputSources;\n\n\t\t\t// Assign controllers to available inputSources\n\n\t\t\tfor ( let i = 0; i < inputSources.length; i ++ ) {\n\n\t\t\t\tconst index = inputSources[ i ].handedness === 'right' ? 1 : 0;\n\t\t\t\tinputSourcesMap.set( inputSources[ i ], controllers[ index ] );\n\n\t\t\t}\n\n\t\t\t// Notify disconnected\n\n\t\t\tfor ( let i = 0; i < event.removed.length; i ++ ) {\n\n\t\t\t\tconst inputSource = event.removed[ i ];\n\t\t\t\tconst controller = inputSourcesMap.get( inputSource );\n\n\t\t\t\tif ( controller ) {\n\n\t\t\t\t\tcontroller.dispatchEvent( { type: 'disconnected', data: inputSource } );\n\t\t\t\t\tinputSourcesMap.delete( inputSource );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Notify connected\n\n\t\t\tfor ( let i = 0; i < event.added.length; i ++ ) {\n\n\t\t\t\tconst inputSource = event.added[ i ];\n\t\t\t\tconst controller = inputSourcesMap.get( inputSource );\n\n\t\t\t\tif ( controller ) {\n\n\t\t\t\t\tcontroller.dispatchEvent( { type: 'connected', data: inputSource } );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tconst cameraLPos = new Vector3();\n\t\tconst cameraRPos = new Vector3();\n\n\t\t/**\n\t\t * Assumes 2 cameras that are parallel and share an X-axis, and that\n\t\t * the cameras' projection and world matrices have already been set.\n\t\t * And that near and far planes are identical for both cameras.\n\t\t * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765\n\t\t */\n\t\tfunction setProjectionFromUnion( camera, cameraL, cameraR ) {\n\n\t\t\tcameraLPos.setFromMatrixPosition( cameraL.matrixWorld );\n\t\t\tcameraRPos.setFromMatrixPosition( cameraR.matrixWorld );\n\n\t\t\tconst ipd = cameraLPos.distanceTo( cameraRPos );\n\n\t\t\tconst projL = cameraL.projectionMatrix.elements;\n\t\t\tconst projR = cameraR.projectionMatrix.elements;\n\n\t\t\t// VR systems will have identical far and near planes, and\n\t\t\t// most likely identical top and bottom frustum extents.\n\t\t\t// Use the left camera for these values.\n\t\t\tconst near = projL[ 14 ] / ( projL[ 10 ] - 1 );\n\t\t\tconst far = projL[ 14 ] / ( projL[ 10 ] + 1 );\n\t\t\tconst topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ];\n\t\t\tconst bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ];\n\n\t\t\tconst leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];\n\t\t\tconst rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];\n\t\t\tconst left = near * leftFov;\n\t\t\tconst right = near * rightFov;\n\n\t\t\t// Calculate the new camera's position offset from the\n\t\t\t// left camera. xOffset should be roughly half `ipd`.\n\t\t\tconst zOffset = ipd / ( - leftFov + rightFov );\n\t\t\tconst xOffset = zOffset * - leftFov;\n\n\t\t\t// TODO: Better way to apply this offset?\n\t\t\tcameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );\n\t\t\tcamera.translateX( xOffset );\n\t\t\tcamera.translateZ( zOffset );\n\t\t\tcamera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale );\n\t\t\tcamera.matrixWorldInverse.copy( camera.matrixWorld ).invert();\n\n\t\t\t// Find the union of the frustum values of the cameras and scale\n\t\t\t// the values so that the near plane's position does not change in world space,\n\t\t\t// although must now be relative to the new union camera.\n\t\t\tconst near2 = near + zOffset;\n\t\t\tconst far2 = far + zOffset;\n\t\t\tconst left2 = left - xOffset;\n\t\t\tconst right2 = right + ( ipd - xOffset );\n\t\t\tconst top2 = topFov * far / far2 * near2;\n\t\t\tconst bottom2 = bottomFov * far / far2 * near2;\n\n\t\t\tcamera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );\n\n\t\t}\n\n\t\tfunction updateCamera( camera, parent ) {\n\n\t\t\tif ( parent === null ) {\n\n\t\t\t\tcamera.matrixWorld.copy( camera.matrix );\n\n\t\t\t} else {\n\n\t\t\t\tcamera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix );\n\n\t\t\t}\n\n\t\t\tcamera.matrixWorldInverse.copy( camera.matrixWorld ).invert();\n\n\t\t}\n\n\t\tthis.updateCamera = function ( camera ) {\n\n\t\t\tif ( session === null ) return;\n\n\t\t\tcameraVR.near = cameraR.near = cameraL.near = camera.near;\n\t\t\tcameraVR.far = cameraR.far = cameraL.far = camera.far;\n\n\t\t\tif ( _currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far ) {\n\n\t\t\t\t// Note that the new renderState won't apply until the next frame. See #18320\n\n\t\t\t\tsession.updateRenderState( {\n\t\t\t\t\tdepthNear: cameraVR.near,\n\t\t\t\t\tdepthFar: cameraVR.far\n\t\t\t\t} );\n\n\t\t\t\t_currentDepthNear = cameraVR.near;\n\t\t\t\t_currentDepthFar = cameraVR.far;\n\n\t\t\t}\n\n\t\t\tconst parent = camera.parent;\n\t\t\tconst cameras = cameraVR.cameras;\n\n\t\t\tupdateCamera( cameraVR, parent );\n\n\t\t\tfor ( let i = 0; i < cameras.length; i ++ ) {\n\n\t\t\t\tupdateCamera( cameras[ i ], parent );\n\n\t\t\t}\n\n\t\t\tcameraVR.matrixWorld.decompose( cameraVR.position, cameraVR.quaternion, cameraVR.scale );\n\n\t\t\t// update user camera and its children\n\n\t\t\tcamera.position.copy( cameraVR.position );\n\t\t\tcamera.quaternion.copy( cameraVR.quaternion );\n\t\t\tcamera.scale.copy( cameraVR.scale );\n\t\t\tcamera.matrix.copy( cameraVR.matrix );\n\t\t\tcamera.matrixWorld.copy( cameraVR.matrixWorld );\n\n\t\t\tconst children = camera.children;\n\n\t\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( true );\n\n\t\t\t}\n\n\t\t\t// update projection matrix for proper view frustum culling\n\n\t\t\tif ( cameras.length === 2 ) {\n\n\t\t\t\tsetProjectionFromUnion( cameraVR, cameraL, cameraR );\n\n\t\t\t} else {\n\n\t\t\t\t// assume single camera setup (AR)\n\n\t\t\t\tcameraVR.projectionMatrix.copy( cameraL.projectionMatrix );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getCamera = function () {\n\n\t\t\treturn cameraVR;\n\n\t\t};\n\n\t\tthis.getFoveation = function () {\n\n\t\t\tif ( glProjLayer !== null ) {\n\n\t\t\t\treturn glProjLayer.fixedFoveation;\n\n\t\t\t}\n\n\t\t\tif ( glBaseLayer !== null ) {\n\n\t\t\t\treturn glBaseLayer.fixedFoveation;\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t};\n\n\t\tthis.setFoveation = function ( foveation ) {\n\n\t\t\t// 0 = no foveation = full resolution\n\t\t\t// 1 = maximum foveation = the edges render at lower resolution\n\n\t\t\tif ( glProjLayer !== null ) {\n\n\t\t\t\tglProjLayer.fixedFoveation = foveation;\n\n\t\t\t}\n\n\t\t\tif ( glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined ) {\n\n\t\t\t\tglBaseLayer.fixedFoveation = foveation;\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Animation Loop\n\n\t\tlet onAnimationFrameCallback = null;\n\n\t\tfunction onAnimationFrame( time, frame ) {\n\n\t\t\tpose = frame.getViewerPose( customReferenceSpace || referenceSpace );\n\t\t\txrFrame = frame;\n\n\t\t\tif ( pose !== null ) {\n\n\t\t\t\tconst views = pose.views;\n\n\t\t\t\tif ( glBaseLayer !== null ) {\n\n\t\t\t\t\trenderer.setRenderTargetFramebuffer( newRenderTarget, glBaseLayer.framebuffer );\n\t\t\t\t\trenderer.setRenderTarget( newRenderTarget );\n\n\t\t\t\t}\n\n\t\t\t\tlet cameraVRNeedsUpdate = false;\n\n\t\t\t\t// check if it's necessary to rebuild cameraVR's camera list\n\n\t\t\t\tif ( views.length !== cameraVR.cameras.length ) {\n\n\t\t\t\t\tcameraVR.cameras.length = 0;\n\t\t\t\t\tcameraVRNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let i = 0; i < views.length; i ++ ) {\n\n\t\t\t\t\tconst view = views[ i ];\n\n\t\t\t\t\tlet viewport = null;\n\n\t\t\t\t\tif ( glBaseLayer !== null ) {\n\n\t\t\t\t\t\tviewport = glBaseLayer.getViewport( view );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconst glSubImage = glBinding.getViewSubImage( glProjLayer, view );\n\t\t\t\t\t\tviewport = glSubImage.viewport;\n\n\t\t\t\t\t\t// For side-by-side projection, we only produce a single texture for both eyes.\n\t\t\t\t\t\tif ( i === 0 ) {\n\n\t\t\t\t\t\t\trenderer.setRenderTargetTextures(\n\t\t\t\t\t\t\t\tnewRenderTarget,\n\t\t\t\t\t\t\t\tglSubImage.colorTexture,\n\t\t\t\t\t\t\t\tglProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture );\n\n\t\t\t\t\t\t\trenderer.setRenderTarget( newRenderTarget );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlet camera = cameras[ i ];\n\n\t\t\t\t\tif ( camera === undefined ) {\n\n\t\t\t\t\t\tcamera = new PerspectiveCamera();\n\t\t\t\t\t\tcamera.layers.enable( i );\n\t\t\t\t\t\tcamera.viewport = new Vector4();\n\t\t\t\t\t\tcameras[ i ] = camera;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcamera.matrix.fromArray( view.transform.matrix );\n\t\t\t\t\tcamera.projectionMatrix.fromArray( view.projectionMatrix );\n\t\t\t\t\tcamera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );\n\n\t\t\t\t\tif ( i === 0 ) {\n\n\t\t\t\t\t\tcameraVR.matrix.copy( camera.matrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( cameraVRNeedsUpdate === true ) {\n\n\t\t\t\t\t\tcameraVR.cameras.push( camera );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tconst inputSources = session.inputSources;\n\n\t\t\tfor ( let i = 0; i < controllers.length; i ++ ) {\n\n\t\t\t\tconst inputSource = inputSources[ i ];\n\t\t\t\tconst controller = inputSourcesMap.get( inputSource );\n\n\t\t\t\tif ( controller !== undefined ) {\n\n\t\t\t\t\tcontroller.update( inputSource, frame, customReferenceSpace || referenceSpace );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( onAnimationFrameCallback ) onAnimationFrameCallback( time, frame );\n\n\t\t\txrFrame = null;\n\n\t\t}\n\n\t\tconst animation = new WebGLAnimation();\n\n\t\tanimation.setAnimationLoop( onAnimationFrame );\n\n\t\tthis.setAnimationLoop = function ( callback ) {\n\n\t\t\tonAnimationFrameCallback = callback;\n\n\t\t};\n\n\t\tthis.dispose = function () {};\n\n\t}\n\n}\n\nfunction WebGLMaterials( renderer, properties ) {\n\n\tfunction refreshFogUniforms( uniforms, fog ) {\n\n\t\tuniforms.fogColor.value.copy( fog.color );\n\n\t\tif ( fog.isFog ) {\n\n\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t}\n\n\t}\n\n\tfunction refreshMaterialUniforms( uniforms, material, pixelRatio, height, transmissionRenderTarget ) {\n\n\t\tif ( material.isMeshBasicMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\n\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\n\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\t\t\trefreshUniformsToon( uniforms, material );\n\n\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t\tif ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\trefreshUniformsPhysical( uniforms, material, transmissionRenderTarget );\n\n\t\t\t}\n\n\t\t} else if ( material.isMeshMatcapMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\t\t\trefreshUniformsMatcap( uniforms, material );\n\n\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\n\t\t} else if ( material.isMeshDistanceMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\t\t\trefreshUniformsDistance( uniforms, material );\n\n\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\trefreshUniformsCommon( uniforms, material );\n\n\t\t} else if ( material.isLineBasicMaterial ) {\n\n\t\t\trefreshUniformsLine( uniforms, material );\n\n\t\t\tif ( material.isLineDashedMaterial ) {\n\n\t\t\t\trefreshUniformsDash( uniforms, material );\n\n\t\t\t}\n\n\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\trefreshUniformsPoints( uniforms, material, pixelRatio, height );\n\n\t\t} else if ( material.isSpriteMaterial ) {\n\n\t\t\trefreshUniformsSprites( uniforms, material );\n\n\t\t} else if ( material.isShadowMaterial ) {\n\n\t\t\tuniforms.color.value.copy( material.color );\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t} else if ( material.isShaderMaterial ) {\n\n\t\t\tmaterial.uniformsNeedUpdate = false; // #15581\n\n\t\t}\n\n\t}\n\n\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\tuniforms.opacity.value = material.opacity;\n\n\t\tif ( material.color ) {\n\n\t\t\tuniforms.diffuse.value.copy( material.color );\n\n\t\t}\n\n\t\tif ( material.emissive ) {\n\n\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t}\n\n\t\tif ( material.map ) {\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t}\n\n\t\tif ( material.alphaMap ) {\n\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t}\n\n\t\tif ( material.bumpMap ) {\n\n\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\t\t\tif ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;\n\n\t\t}\n\n\t\tif ( material.displacementMap ) {\n\n\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t}\n\n\t\tif ( material.emissiveMap ) {\n\n\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t}\n\n\t\tif ( material.normalMap ) {\n\n\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\t\t\tif ( material.side === BackSide ) uniforms.normalScale.value.negate();\n\n\t\t}\n\n\t\tif ( material.specularMap ) {\n\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\n\t\t}\n\n\t\tif ( material.alphaTest > 0 ) {\n\n\t\t\tuniforms.alphaTest.value = material.alphaTest;\n\n\t\t}\n\n\t\tconst envMap = properties.get( material ).envMap;\n\n\t\tif ( envMap ) {\n\n\t\t\tuniforms.envMap.value = envMap;\n\n\t\t\tuniforms.flipEnvMap.value = ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) ? - 1 : 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.ior.value = material.ior;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tif ( material.lightMap ) {\n\n\t\t\tuniforms.lightMap.value = material.lightMap;\n\n\t\t\t// artist-friendly light intensity scaling factor\n\t\t\tconst scaleFactor = ( renderer.physicallyCorrectLights !== true ) ? Math.PI : 1;\n\n\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity * scaleFactor;\n\n\t\t}\n\n\t\tif ( material.aoMap ) {\n\n\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t}\n\n\t\t// uv repeat and offset setting priorities\n\t\t// 1. color map\n\t\t// 2. specular map\n\t\t// 3. displacementMap map\n\t\t// 4. normal map\n\t\t// 5. bump map\n\t\t// 6. roughnessMap map\n\t\t// 7. metalnessMap map\n\t\t// 8. alphaMap map\n\t\t// 9. emissiveMap map\n\t\t// 10. clearcoat map\n\t\t// 11. clearcoat normal map\n\t\t// 12. clearcoat roughnessMap map\n\t\t// 13. iridescence map\n\t\t// 14. iridescence thickness map\n\t\t// 15. specular intensity map\n\t\t// 16. specular tint map\n\t\t// 17. transmission map\n\t\t// 18. thickness map\n\n\t\tlet uvScaleMap;\n\n\t\tif ( material.map ) {\n\n\t\t\tuvScaleMap = material.map;\n\n\t\t} else if ( material.specularMap ) {\n\n\t\t\tuvScaleMap = material.specularMap;\n\n\t\t} else if ( material.displacementMap ) {\n\n\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t} else if ( material.normalMap ) {\n\n\t\t\tuvScaleMap = material.normalMap;\n\n\t\t} else if ( material.bumpMap ) {\n\n\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t} else if ( material.roughnessMap ) {\n\n\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t} else if ( material.metalnessMap ) {\n\n\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t} else if ( material.alphaMap ) {\n\n\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t} else if ( material.emissiveMap ) {\n\n\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t} else if ( material.clearcoatMap ) {\n\n\t\t\tuvScaleMap = material.clearcoatMap;\n\n\t\t} else if ( material.clearcoatNormalMap ) {\n\n\t\t\tuvScaleMap = material.clearcoatNormalMap;\n\n\t\t} else if ( material.clearcoatRoughnessMap ) {\n\n\t\t\tuvScaleMap = material.clearcoatRoughnessMap;\n\n\t\t} else if ( material.iridescenceMap ) {\n\n\t\t\tuvScaleMap = material.iridescenceMap;\n\n\t\t} else if ( material.iridescenceThicknessMap ) {\n\n\t\t\tuvScaleMap = material.iridescenceThicknessMap;\n\n\t\t} else if ( material.specularIntensityMap ) {\n\n\t\t\tuvScaleMap = material.specularIntensityMap;\n\n\t\t} else if ( material.specularColorMap ) {\n\n\t\t\tuvScaleMap = material.specularColorMap;\n\n\t\t} else if ( material.transmissionMap ) {\n\n\t\t\tuvScaleMap = material.transmissionMap;\n\n\t\t} else if ( material.thicknessMap ) {\n\n\t\t\tuvScaleMap = material.thicknessMap;\n\n\t\t} else if ( material.sheenColorMap ) {\n\n\t\t\tuvScaleMap = material.sheenColorMap;\n\n\t\t} else if ( material.sheenRoughnessMap ) {\n\n\t\t\tuvScaleMap = material.sheenRoughnessMap;\n\n\t\t}\n\n\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t// backwards compatibility\n\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap.matrixAutoUpdate === true ) {\n\n\t\t\t\tuvScaleMap.updateMatrix();\n\n\t\t\t}\n\n\t\t\tuniforms.uvTransform.value.copy( uvScaleMap.matrix );\n\n\t\t}\n\n\t\t// uv repeat and offset setting priorities for uv2\n\t\t// 1. ao map\n\t\t// 2. light map\n\n\t\tlet uv2ScaleMap;\n\n\t\tif ( material.aoMap ) {\n\n\t\t\tuv2ScaleMap = material.aoMap;\n\n\t\t} else if ( material.lightMap ) {\n\n\t\t\tuv2ScaleMap = material.lightMap;\n\n\t\t}\n\n\t\tif ( uv2ScaleMap !== undefined ) {\n\n\t\t\t// backwards compatibility\n\t\t\tif ( uv2ScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\tuv2ScaleMap = uv2ScaleMap.texture;\n\n\t\t\t}\n\n\t\t\tif ( uv2ScaleMap.matrixAutoUpdate === true ) {\n\n\t\t\t\tuv2ScaleMap.updateMatrix();\n\n\t\t\t}\n\n\t\t\tuniforms.uv2Transform.value.copy( uv2ScaleMap.matrix );\n\n\t\t}\n\n\t}\n\n\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\tuniforms.diffuse.value.copy( material.color );\n\t\tuniforms.opacity.value = material.opacity;\n\n\t}\n\n\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\tuniforms.dashSize.value = material.dashSize;\n\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\tuniforms.scale.value = material.scale;\n\n\t}\n\n\tfunction refreshUniformsPoints( uniforms, material, pixelRatio, height ) {\n\n\t\tuniforms.diffuse.value.copy( material.color );\n\t\tuniforms.opacity.value = material.opacity;\n\t\tuniforms.size.value = material.size * pixelRatio;\n\t\tuniforms.scale.value = height * 0.5;\n\n\t\tif ( material.map ) {\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t}\n\n\t\tif ( material.alphaMap ) {\n\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t}\n\n\t\tif ( material.alphaTest > 0 ) {\n\n\t\t\tuniforms.alphaTest.value = material.alphaTest;\n\n\t\t}\n\n\t\t// uv repeat and offset setting priorities\n\t\t// 1. color map\n\t\t// 2. alpha map\n\n\t\tlet uvScaleMap;\n\n\t\tif ( material.map ) {\n\n\t\t\tuvScaleMap = material.map;\n\n\t\t} else if ( material.alphaMap ) {\n\n\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t}\n\n\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\tif ( uvScaleMap.matrixAutoUpdate === true ) {\n\n\t\t\t\tuvScaleMap.updateMatrix();\n\n\t\t\t}\n\n\t\t\tuniforms.uvTransform.value.copy( uvScaleMap.matrix );\n\n\t\t}\n\n\t}\n\n\tfunction refreshUniformsSprites( uniforms, material ) {\n\n\t\tuniforms.diffuse.value.copy( material.color );\n\t\tuniforms.opacity.value = material.opacity;\n\t\tuniforms.rotation.value = material.rotation;\n\n\t\tif ( material.map ) {\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t}\n\n\t\tif ( material.alphaMap ) {\n\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t}\n\n\t\tif ( material.alphaTest > 0 ) {\n\n\t\t\tuniforms.alphaTest.value = material.alphaTest;\n\n\t\t}\n\n\t\t// uv repeat and offset setting priorities\n\t\t// 1. color map\n\t\t// 2. alpha map\n\n\t\tlet uvScaleMap;\n\n\t\tif ( material.map ) {\n\n\t\t\tuvScaleMap = material.map;\n\n\t\t} else if ( material.alphaMap ) {\n\n\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t}\n\n\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\tif ( uvScaleMap.matrixAutoUpdate === true ) {\n\n\t\t\t\tuvScaleMap.updateMatrix();\n\n\t\t\t}\n\n\t\t\tuniforms.uvTransform.value.copy( uvScaleMap.matrix );\n\n\t\t}\n\n\t}\n\n\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\tuniforms.specular.value.copy( material.specular );\n\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t}\n\n\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\tif ( material.gradientMap ) {\n\n\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t}\n\n\t}\n\n\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\tuniforms.roughness.value = material.roughness;\n\t\tuniforms.metalness.value = material.metalness;\n\n\t\tif ( material.roughnessMap ) {\n\n\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t}\n\n\t\tif ( material.metalnessMap ) {\n\n\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t}\n\n\t\tconst envMap = properties.get( material ).envMap;\n\n\t\tif ( envMap ) {\n\n\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t}\n\n\t}\n\n\tfunction refreshUniformsPhysical( uniforms, material, transmissionRenderTarget ) {\n\n\t\tuniforms.ior.value = material.ior; // also part of uniforms common\n\n\t\tif ( material.sheen > 0 ) {\n\n\t\t\tuniforms.sheenColor.value.copy( material.sheenColor ).multiplyScalar( material.sheen );\n\n\t\t\tuniforms.sheenRoughness.value = material.sheenRoughness;\n\n\t\t\tif ( material.sheenColorMap ) {\n\n\t\t\t\tuniforms.sheenColorMap.value = material.sheenColorMap;\n\n\t\t\t}\n\n\t\t\tif ( material.sheenRoughnessMap ) {\n\n\t\t\t\tuniforms.sheenRoughnessMap.value = material.sheenRoughnessMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( material.clearcoat > 0 ) {\n\n\t\t\tuniforms.clearcoat.value = material.clearcoat;\n\t\t\tuniforms.clearcoatRoughness.value = material.clearcoatRoughness;\n\n\t\t\tif ( material.clearcoatMap ) {\n\n\t\t\t\tuniforms.clearcoatMap.value = material.clearcoatMap;\n\n\t\t\t}\n\n\t\t\tif ( material.clearcoatRoughnessMap ) {\n\n\t\t\t\tuniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.clearcoatNormalMap ) {\n\n\t\t\t\tuniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale );\n\t\t\t\tuniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tuniforms.clearcoatNormalScale.value.negate();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( material.iridescence > 0 ) {\n\n\t\t\tuniforms.iridescence.value = material.iridescence;\n\t\t\tuniforms.iridescenceIOR.value = material.iridescenceIOR;\n\t\t\tuniforms.iridescenceThicknessMinimum.value = material.iridescenceThicknessRange[ 0 ];\n\t\t\tuniforms.iridescenceThicknessMaximum.value = material.iridescenceThicknessRange[ 1 ];\n\n\t\t\tif ( material.iridescenceMap ) {\n\n\t\t\t\tuniforms.iridescenceMap.value = material.iridescenceMap;\n\n\t\t\t}\n\n\t\t\tif ( material.iridescenceThicknessMap ) {\n\n\t\t\t\tuniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( material.transmission > 0 ) {\n\n\t\t\tuniforms.transmission.value = material.transmission;\n\t\t\tuniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture;\n\t\t\tuniforms.transmissionSamplerSize.value.set( transmissionRenderTarget.width, transmissionRenderTarget.height );\n\n\t\t\tif ( material.transmissionMap ) {\n\n\t\t\t\tuniforms.transmissionMap.value = material.transmissionMap;\n\n\t\t\t}\n\n\t\t\tuniforms.thickness.value = material.thickness;\n\n\t\t\tif ( material.thicknessMap ) {\n\n\t\t\t\tuniforms.thicknessMap.value = material.thicknessMap;\n\n\t\t\t}\n\n\t\t\tuniforms.attenuationDistance.value = material.attenuationDistance;\n\t\t\tuniforms.attenuationColor.value.copy( material.attenuationColor );\n\n\t\t}\n\n\t\tuniforms.specularIntensity.value = material.specularIntensity;\n\t\tuniforms.specularColor.value.copy( material.specularColor );\n\n\t\tif ( material.specularIntensityMap ) {\n\n\t\t\tuniforms.specularIntensityMap.value = material.specularIntensityMap;\n\n\t\t}\n\n\t\tif ( material.specularColorMap ) {\n\n\t\t\tuniforms.specularColorMap.value = material.specularColorMap;\n\n\t\t}\n\n\t}\n\n\tfunction refreshUniformsMatcap( uniforms, material ) {\n\n\t\tif ( material.matcap ) {\n\n\t\t\tuniforms.matcap.value = material.matcap;\n\n\t\t}\n\n\t}\n\n\tfunction refreshUniformsDistance( uniforms, material ) {\n\n\t\tuniforms.referencePosition.value.copy( material.referencePosition );\n\t\tuniforms.nearDistance.value = material.nearDistance;\n\t\tuniforms.farDistance.value = material.farDistance;\n\n\t}\n\n\treturn {\n\t\trefreshFogUniforms: refreshFogUniforms,\n\t\trefreshMaterialUniforms: refreshMaterialUniforms\n\t};\n\n}\n\nfunction createCanvasElement() {\n\n\tconst canvas = createElementNS( 'canvas' );\n\tcanvas.style.display = 'block';\n\treturn canvas;\n\n}\n\nfunction WebGLRenderer( parameters = {} ) {\n\n\tthis.isWebGLRenderer = true;\n\n\tconst _canvas = parameters.canvas !== undefined ? parameters.canvas : createCanvasElement(),\n\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,\n\t\t_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default',\n\t\t_failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false;\n\n\tlet _alpha;\n\n\tif ( _context !== null ) {\n\n\t\t_alpha = _context.getContextAttributes().alpha;\n\n\t} else {\n\n\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false;\n\n\t}\n\n\tlet currentRenderList = null;\n\tlet currentRenderState = null;\n\n\t// render() can be called from within a callback triggered by another render.\n\t// We track this so that the nested render call gets its list and state isolated from the parent render call.\n\n\tconst renderListStack = [];\n\tconst renderStateStack = [];\n\n\t// public properties\n\n\tthis.domElement = _canvas;\n\n\t// Debug configuration container\n\tthis.debug = {\n\n\t\t/**\n\t\t * Enables error checking and reporting when shader programs are being compiled\n\t\t * @type {boolean}\n\t\t */\n\t\tcheckShaderErrors: true\n\t};\n\n\t// clearing\n\n\tthis.autoClear = true;\n\tthis.autoClearColor = true;\n\tthis.autoClearDepth = true;\n\tthis.autoClearStencil = true;\n\n\t// scene graph\n\n\tthis.sortObjects = true;\n\n\t// user-defined clipping\n\n\tthis.clippingPlanes = [];\n\tthis.localClippingEnabled = false;\n\n\t// physically based shading\n\n\tthis.outputEncoding = LinearEncoding;\n\n\t// physical lights\n\n\tthis.physicallyCorrectLights = false;\n\n\t// tone mapping\n\n\tthis.toneMapping = NoToneMapping;\n\tthis.toneMappingExposure = 1.0;\n\n\t//\n\n\tObject.defineProperties( this, {\n\n\t\t// @deprecated since r136, 0e21088102b4de7e0a0a33140620b7a3424b9e6d\n\n\t\tgammaFactor: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .gammaFactor has been removed.' );\n\t\t\t\treturn 2;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .gammaFactor has been removed.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t// internal properties\n\n\tconst _this = this;\n\n\tlet _isContextLost = false;\n\n\t// internal state cache\n\n\tlet _currentActiveCubeFace = 0;\n\tlet _currentActiveMipmapLevel = 0;\n\tlet _currentRenderTarget = null;\n\tlet _currentMaterialId = - 1;\n\n\tlet _currentCamera = null;\n\n\tconst _currentViewport = new Vector4();\n\tconst _currentScissor = new Vector4();\n\tlet _currentScissorTest = null;\n\n\t//\n\n\tlet _width = _canvas.width;\n\tlet _height = _canvas.height;\n\n\tlet _pixelRatio = 1;\n\tlet _opaqueSort = null;\n\tlet _transparentSort = null;\n\n\tconst _viewport = new Vector4( 0, 0, _width, _height );\n\tconst _scissor = new Vector4( 0, 0, _width, _height );\n\tlet _scissorTest = false;\n\n\t// frustum\n\n\tconst _frustum = new Frustum();\n\n\t// clipping\n\n\tlet _clippingEnabled = false;\n\tlet _localClippingEnabled = false;\n\n\t// transmission\n\n\tlet _transmissionRenderTarget = null;\n\n\t// camera matrices cache\n\n\tconst _projScreenMatrix = new Matrix4();\n\n\tconst _vector2 = new Vector2();\n\tconst _vector3 = new Vector3();\n\n\tconst _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true };\n\n\tfunction getTargetPixelRatio() {\n\n\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t}\n\n\t// initialize\n\n\tlet _gl = _context;\n\n\tfunction getContext( contextNames, contextAttributes ) {\n\n\t\tfor ( let i = 0; i < contextNames.length; i ++ ) {\n\n\t\t\tconst contextName = contextNames[ i ];\n\t\t\tconst context = _canvas.getContext( contextName, contextAttributes );\n\t\t\tif ( context !== null ) return context;\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\ttry {\n\n\t\tconst contextAttributes = {\n\t\t\talpha: true,\n\t\t\tdepth: _depth,\n\t\t\tstencil: _stencil,\n\t\t\tantialias: _antialias,\n\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer,\n\t\t\tpowerPreference: _powerPreference,\n\t\t\tfailIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat\n\t\t};\n\n\t\t// OffscreenCanvas does not have setAttribute, see #22811\n\t\tif ( 'setAttribute' in _canvas ) _canvas.setAttribute( 'data-engine', `three.js r${REVISION}` );\n\n\t\t// event listeners must be registered before WebGL context is created, see #12753\n\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\t\t_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );\n\t\t_canvas.addEventListener( 'webglcontextcreationerror', onContextCreationError, false );\n\n\t\tif ( _gl === null ) {\n\n\t\t\tconst contextNames = [ 'webgl2', 'webgl', 'experimental-webgl' ];\n\n\t\t\tif ( _this.isWebGL1Renderer === true ) {\n\n\t\t\t\tcontextNames.shift();\n\n\t\t\t}\n\n\t\t\t_gl = getContext( contextNames, contextAttributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( getContext( contextNames ) ) {\n\n\t\t\t\t\tthrow new Error( 'Error creating WebGL context with your selected attributes.' );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( 'Error creating WebGL context.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t};\n\n\t\t}\n\n\t} catch ( error ) {\n\n\t\tconsole.error( 'THREE.WebGLRenderer: ' + error.message );\n\t\tthrow error;\n\n\t}\n\n\tlet extensions, capabilities, state, info;\n\tlet properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects;\n\tlet programCache, materials, renderLists, renderStates, clipping, shadowMap;\n\n\tlet background, morphtargets, bufferRenderer, indexedBufferRenderer;\n\n\tlet utils, bindingStates;\n\n\tfunction initGLContext() {\n\n\t\textensions = new WebGLExtensions( _gl );\n\n\t\tcapabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\textensions.init( capabilities );\n\n\t\tutils = new WebGLUtils( _gl, extensions, capabilities );\n\n\t\tstate = new WebGLState( _gl, extensions, capabilities );\n\n\t\tinfo = new WebGLInfo( _gl );\n\t\tproperties = new WebGLProperties();\n\t\ttextures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );\n\t\tcubemaps = new WebGLCubeMaps( _this );\n\t\tcubeuvmaps = new WebGLCubeUVMaps( _this );\n\t\tattributes = new WebGLAttributes( _gl, capabilities );\n\t\tbindingStates = new WebGLBindingStates( _gl, extensions, attributes, capabilities );\n\t\tgeometries = new WebGLGeometries( _gl, attributes, info, bindingStates );\n\t\tobjects = new WebGLObjects( _gl, geometries, attributes, info );\n\t\tmorphtargets = new WebGLMorphtargets( _gl, capabilities, textures );\n\t\tclipping = new WebGLClipping( properties );\n\t\tprogramCache = new WebGLPrograms( _this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping );\n\t\tmaterials = new WebGLMaterials( _this, properties );\n\t\trenderLists = new WebGLRenderLists();\n\t\trenderStates = new WebGLRenderStates( extensions, capabilities );\n\t\tbackground = new WebGLBackground( _this, cubemaps, state, objects, _alpha, _premultipliedAlpha );\n\t\tshadowMap = new WebGLShadowMap( _this, objects, capabilities );\n\n\t\tbufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities );\n\t\tindexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities );\n\n\t\tinfo.programs = programCache.programs;\n\n\t\t_this.capabilities = capabilities;\n\t\t_this.extensions = extensions;\n\t\t_this.properties = properties;\n\t\t_this.renderLists = renderLists;\n\t\t_this.shadowMap = shadowMap;\n\t\t_this.state = state;\n\t\t_this.info = info;\n\n\t}\n\n\tinitGLContext();\n\n\t// xr\n\n\tconst xr = new WebXRManager( _this, _gl );\n\n\tthis.xr = xr;\n\n\t// API\n\n\tthis.getContext = function () {\n\n\t\treturn _gl;\n\n\t};\n\n\tthis.getContextAttributes = function () {\n\n\t\treturn _gl.getContextAttributes();\n\n\t};\n\n\tthis.forceContextLoss = function () {\n\n\t\tconst extension = extensions.get( 'WEBGL_lose_context' );\n\t\tif ( extension ) extension.loseContext();\n\n\t};\n\n\tthis.forceContextRestore = function () {\n\n\t\tconst extension = extensions.get( 'WEBGL_lose_context' );\n\t\tif ( extension ) extension.restoreContext();\n\n\t};\n\n\tthis.getPixelRatio = function () {\n\n\t\treturn _pixelRatio;\n\n\t};\n\n\tthis.setPixelRatio = function ( value ) {\n\n\t\tif ( value === undefined ) return;\n\n\t\t_pixelRatio = value;\n\n\t\tthis.setSize( _width, _height, false );\n\n\t};\n\n\tthis.getSize = function ( target ) {\n\n\t\treturn target.set( _width, _height );\n\n\t};\n\n\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\tif ( xr.isPresenting ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: Can\\'t change size while VR device is presenting.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\t_width = width;\n\t\t_height = height;\n\n\t\t_canvas.width = Math.floor( width * _pixelRatio );\n\t\t_canvas.height = Math.floor( height * _pixelRatio );\n\n\t\tif ( updateStyle !== false ) {\n\n\t\t\t_canvas.style.width = width + 'px';\n\t\t\t_canvas.style.height = height + 'px';\n\n\t\t}\n\n\t\tthis.setViewport( 0, 0, width, height );\n\n\t};\n\n\tthis.getDrawingBufferSize = function ( target ) {\n\n\t\treturn target.set( _width * _pixelRatio, _height * _pixelRatio ).floor();\n\n\t};\n\n\tthis.setDrawingBufferSize = function ( width, height, pixelRatio ) {\n\n\t\t_width = width;\n\t\t_height = height;\n\n\t\t_pixelRatio = pixelRatio;\n\n\t\t_canvas.width = Math.floor( width * pixelRatio );\n\t\t_canvas.height = Math.floor( height * pixelRatio );\n\n\t\tthis.setViewport( 0, 0, width, height );\n\n\t};\n\n\tthis.getCurrentViewport = function ( target ) {\n\n\t\treturn target.copy( _currentViewport );\n\n\t};\n\n\tthis.getViewport = function ( target ) {\n\n\t\treturn target.copy( _viewport );\n\n\t};\n\n\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\tif ( x.isVector4 ) {\n\n\t\t\t_viewport.set( x.x, x.y, x.z, x.w );\n\n\t\t} else {\n\n\t\t\t_viewport.set( x, y, width, height );\n\n\t\t}\n\n\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );\n\n\t};\n\n\tthis.getScissor = function ( target ) {\n\n\t\treturn target.copy( _scissor );\n\n\t};\n\n\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\tif ( x.isVector4 ) {\n\n\t\t\t_scissor.set( x.x, x.y, x.z, x.w );\n\n\t\t} else {\n\n\t\t\t_scissor.set( x, y, width, height );\n\n\t\t}\n\n\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );\n\n\t};\n\n\tthis.getScissorTest = function () {\n\n\t\treturn _scissorTest;\n\n\t};\n\n\tthis.setScissorTest = function ( boolean ) {\n\n\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t};\n\n\tthis.setOpaqueSort = function ( method ) {\n\n\t\t_opaqueSort = method;\n\n\t};\n\n\tthis.setTransparentSort = function ( method ) {\n\n\t\t_transparentSort = method;\n\n\t};\n\n\t// Clearing\n\n\tthis.getClearColor = function ( target ) {\n\n\t\treturn target.copy( background.getClearColor() );\n\n\t};\n\n\tthis.setClearColor = function () {\n\n\t\tbackground.setClearColor.apply( background, arguments );\n\n\t};\n\n\tthis.getClearAlpha = function () {\n\n\t\treturn background.getClearAlpha();\n\n\t};\n\n\tthis.setClearAlpha = function () {\n\n\t\tbackground.setClearAlpha.apply( background, arguments );\n\n\t};\n\n\tthis.clear = function ( color = true, depth = true, stencil = true ) {\n\n\t\tlet bits = 0;\n\n\t\tif ( color ) bits |= 16384;\n\t\tif ( depth ) bits |= 256;\n\t\tif ( stencil ) bits |= 1024;\n\n\t\t_gl.clear( bits );\n\n\t};\n\n\tthis.clearColor = function () {\n\n\t\tthis.clear( true, false, false );\n\n\t};\n\n\tthis.clearDepth = function () {\n\n\t\tthis.clear( false, true, false );\n\n\t};\n\n\tthis.clearStencil = function () {\n\n\t\tthis.clear( false, false, true );\n\n\t};\n\n\t//\n\n\tthis.dispose = function () {\n\n\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\t\t_canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false );\n\t\t_canvas.removeEventListener( 'webglcontextcreationerror', onContextCreationError, false );\n\n\t\trenderLists.dispose();\n\t\trenderStates.dispose();\n\t\tproperties.dispose();\n\t\tcubemaps.dispose();\n\t\tcubeuvmaps.dispose();\n\t\tobjects.dispose();\n\t\tbindingStates.dispose();\n\t\tprogramCache.dispose();\n\n\t\txr.dispose();\n\n\t\txr.removeEventListener( 'sessionstart', onXRSessionStart );\n\t\txr.removeEventListener( 'sessionend', onXRSessionEnd );\n\n\t\tif ( _transmissionRenderTarget ) {\n\n\t\t\t_transmissionRenderTarget.dispose();\n\t\t\t_transmissionRenderTarget = null;\n\n\t\t}\n\n\t\tanimation.stop();\n\n\t};\n\n\t// Events\n\n\tfunction onContextLost( event ) {\n\n\t\tevent.preventDefault();\n\n\t\tconsole.log( 'THREE.WebGLRenderer: Context Lost.' );\n\n\t\t_isContextLost = true;\n\n\t}\n\n\tfunction onContextRestore( /* event */ ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer: Context Restored.' );\n\n\t\t_isContextLost = false;\n\n\t\tconst infoAutoReset = info.autoReset;\n\t\tconst shadowMapEnabled = shadowMap.enabled;\n\t\tconst shadowMapAutoUpdate = shadowMap.autoUpdate;\n\t\tconst shadowMapNeedsUpdate = shadowMap.needsUpdate;\n\t\tconst shadowMapType = shadowMap.type;\n\n\t\tinitGLContext();\n\n\t\tinfo.autoReset = infoAutoReset;\n\t\tshadowMap.enabled = shadowMapEnabled;\n\t\tshadowMap.autoUpdate = shadowMapAutoUpdate;\n\t\tshadowMap.needsUpdate = shadowMapNeedsUpdate;\n\t\tshadowMap.type = shadowMapType;\n\n\t}\n\n\tfunction onContextCreationError( event ) {\n\n\t\tconsole.error( 'THREE.WebGLRenderer: A WebGL context could not be created. Reason: ', event.statusMessage );\n\n\t}\n\n\tfunction onMaterialDispose( event ) {\n\n\t\tconst material = event.target;\n\n\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\tdeallocateMaterial( material );\n\n\t}\n\n\t// Buffer deallocation\n\n\tfunction deallocateMaterial( material ) {\n\n\t\treleaseMaterialProgramReferences( material );\n\n\t\tproperties.remove( material );\n\n\t}\n\n\n\tfunction releaseMaterialProgramReferences( material ) {\n\n\t\tconst programs = properties.get( material ).programs;\n\n\t\tif ( programs !== undefined ) {\n\n\t\t\tprograms.forEach( function ( program ) {\n\n\t\t\t\tprogramCache.releaseProgram( program );\n\n\t\t\t} );\n\n\t\t\tif ( material.isShaderMaterial ) {\n\n\t\t\t\tprogramCache.releaseShaderCache( material );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Buffer rendering\n\n\tthis.renderBufferDirect = function ( camera, scene, geometry, material, object, group ) {\n\n\t\tif ( scene === null ) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null)\n\n\t\tconst frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );\n\n\t\tconst program = setProgram( camera, scene, geometry, material, object );\n\n\t\tstate.setMaterial( material, frontFaceCW );\n\n\t\t//\n\n\t\tlet index = geometry.index;\n\t\tconst position = geometry.attributes.position;\n\n\t\t//\n\n\t\tif ( index === null ) {\n\n\t\t\tif ( position === undefined || position.count === 0 ) return;\n\n\t\t} else if ( index.count === 0 ) {\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t//\n\n\t\tlet rangeFactor = 1;\n\n\t\tif ( material.wireframe === true ) {\n\n\t\t\tindex = geometries.getWireframeAttribute( geometry );\n\t\t\trangeFactor = 2;\n\n\t\t}\n\n\t\tbindingStates.setup( object, material, program, geometry, index );\n\n\t\tlet attribute;\n\t\tlet renderer = bufferRenderer;\n\n\t\tif ( index !== null ) {\n\n\t\t\tattribute = attributes.get( index );\n\n\t\t\trenderer = indexedBufferRenderer;\n\t\t\trenderer.setIndex( attribute );\n\n\t\t}\n\n\t\t//\n\n\t\tconst dataCount = ( index !== null ) ? index.count : position.count;\n\n\t\tconst rangeStart = geometry.drawRange.start * rangeFactor;\n\t\tconst rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\tconst groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\tconst groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\tconst drawStart = Math.max( rangeStart, groupStart );\n\t\tconst drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\tconst drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\tif ( drawCount === 0 ) return;\n\n\t\t//\n\n\t\tif ( object.isMesh ) {\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\trenderer.setMode( 1 );\n\n\t\t\t} else {\n\n\t\t\t\trenderer.setMode( 4 );\n\n\t\t\t}\n\n\t\t} else if ( object.isLine ) {\n\n\t\t\tlet lineWidth = material.linewidth;\n\n\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\trenderer.setMode( 1 );\n\n\t\t\t} else if ( object.isLineLoop ) {\n\n\t\t\t\trenderer.setMode( 2 );\n\n\t\t\t} else {\n\n\t\t\t\trenderer.setMode( 3 );\n\n\t\t\t}\n\n\t\t} else if ( object.isPoints ) {\n\n\t\t\trenderer.setMode( 0 );\n\n\t\t} else if ( object.isSprite ) {\n\n\t\t\trenderer.setMode( 4 );\n\n\t\t}\n\n\t\tif ( object.isInstancedMesh ) {\n\n\t\t\trenderer.renderInstances( drawStart, drawCount, object.count );\n\n\t\t} else if ( geometry.isInstancedBufferGeometry ) {\n\n\t\t\tconst instanceCount = Math.min( geometry.instanceCount, geometry._maxInstanceCount );\n\n\t\t\trenderer.renderInstances( drawStart, drawCount, instanceCount );\n\n\t\t} else {\n\n\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t}\n\n\t};\n\n\t// Compile\n\n\tthis.compile = function ( scene, camera ) {\n\n\t\tcurrentRenderState = renderStates.get( scene );\n\t\tcurrentRenderState.init();\n\n\t\trenderStateStack.push( currentRenderState );\n\n\t\tscene.traverseVisible( function ( object ) {\n\n\t\t\tif ( object.isLight && object.layers.test( camera.layers ) ) {\n\n\t\t\t\tcurrentRenderState.pushLight( object );\n\n\t\t\t\tif ( object.castShadow ) {\n\n\t\t\t\t\tcurrentRenderState.pushShadow( object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} );\n\n\t\tcurrentRenderState.setupLights( _this.physicallyCorrectLights );\n\n\t\tscene.traverse( function ( object ) {\n\n\t\t\tconst material = object.material;\n\n\t\t\tif ( material ) {\n\n\t\t\t\tif ( Array.isArray( material ) ) {\n\n\t\t\t\t\tfor ( let i = 0; i < material.length; i ++ ) {\n\n\t\t\t\t\t\tconst material2 = material[ i ];\n\n\t\t\t\t\t\tgetProgram( material2, scene, object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgetProgram( material, scene, object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} );\n\n\t\trenderStateStack.pop();\n\t\tcurrentRenderState = null;\n\n\t};\n\n\t// Animation Loop\n\n\tlet onAnimationFrameCallback = null;\n\n\tfunction onAnimationFrame( time ) {\n\n\t\tif ( onAnimationFrameCallback ) onAnimationFrameCallback( time );\n\n\t}\n\n\tfunction onXRSessionStart() {\n\n\t\tanimation.stop();\n\n\t}\n\n\tfunction onXRSessionEnd() {\n\n\t\tanimation.start();\n\n\t}\n\n\tconst animation = new WebGLAnimation();\n\tanimation.setAnimationLoop( onAnimationFrame );\n\n\tif ( typeof self !== 'undefined' ) animation.setContext( self );\n\n\tthis.setAnimationLoop = function ( callback ) {\n\n\t\tonAnimationFrameCallback = callback;\n\t\txr.setAnimationLoop( callback );\n\n\t\t( callback === null ) ? animation.stop() : animation.start();\n\n\t};\n\n\txr.addEventListener( 'sessionstart', onXRSessionStart );\n\txr.addEventListener( 'sessionend', onXRSessionEnd );\n\n\t// Rendering\n\n\tthis.render = function ( scene, camera ) {\n\n\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( _isContextLost === true ) return;\n\n\t\t// update scene graph\n\n\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t// update camera matrices and frustum\n\n\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\tif ( xr.enabled === true && xr.isPresenting === true ) {\n\n\t\t\tif ( xr.cameraAutoUpdate === true ) xr.updateCamera( camera );\n\n\t\t\tcamera = xr.getCamera(); // use XR camera for rendering\n\n\t\t}\n\n\t\t//\n\t\tif ( scene.isScene === true ) scene.onBeforeRender( _this, scene, camera, _currentRenderTarget );\n\n\t\tcurrentRenderState = renderStates.get( scene, renderStateStack.length );\n\t\tcurrentRenderState.init();\n\n\t\trenderStateStack.push( currentRenderState );\n\n\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t_frustum.setFromProjectionMatrix( _projScreenMatrix );\n\n\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t_clippingEnabled = clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\tcurrentRenderList = renderLists.get( scene, renderListStack.length );\n\t\tcurrentRenderList.init();\n\n\t\trenderListStack.push( currentRenderList );\n\n\t\tprojectObject( scene, camera, 0, _this.sortObjects );\n\n\t\tcurrentRenderList.finish();\n\n\t\tif ( _this.sortObjects === true ) {\n\n\t\t\tcurrentRenderList.sort( _opaqueSort, _transparentSort );\n\n\t\t}\n\n\t\t//\n\n\t\tif ( _clippingEnabled === true ) clipping.beginShadows();\n\n\t\tconst shadowsArray = currentRenderState.state.shadowsArray;\n\n\t\tshadowMap.render( shadowsArray, scene, camera );\n\n\t\tif ( _clippingEnabled === true ) clipping.endShadows();\n\n\t\t//\n\n\t\tif ( this.info.autoReset === true ) this.info.reset();\n\n\t\t//\n\n\t\tbackground.render( currentRenderList, scene );\n\n\t\t// render scene\n\n\t\tcurrentRenderState.setupLights( _this.physicallyCorrectLights );\n\n\t\tif ( camera.isArrayCamera ) {\n\n\t\t\tconst cameras = camera.cameras;\n\n\t\t\tfor ( let i = 0, l = cameras.length; i < l; i ++ ) {\n\n\t\t\t\tconst camera2 = cameras[ i ];\n\n\t\t\t\trenderScene( currentRenderList, scene, camera2, camera2.viewport );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\trenderScene( currentRenderList, scene, camera );\n\n\t\t}\n\n\t\t//\n\n\t\tif ( _currentRenderTarget !== null ) {\n\n\t\t\t// resolve multisample renderbuffers to a single-sample texture if necessary\n\n\t\t\ttextures.updateMultisampleRenderTarget( _currentRenderTarget );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\ttextures.updateRenderTargetMipmap( _currentRenderTarget );\n\n\t\t}\n\n\t\t//\n\n\t\tif ( scene.isScene === true ) scene.onAfterRender( _this, scene, camera );\n\n\t\t// _gl.finish();\n\n\t\tbindingStates.resetDefaultState();\n\t\t_currentMaterialId = - 1;\n\t\t_currentCamera = null;\n\n\t\trenderStateStack.pop();\n\n\t\tif ( renderStateStack.length > 0 ) {\n\n\t\t\tcurrentRenderState = renderStateStack[ renderStateStack.length - 1 ];\n\n\t\t} else {\n\n\t\t\tcurrentRenderState = null;\n\n\t\t}\n\n\t\trenderListStack.pop();\n\n\t\tif ( renderListStack.length > 0 ) {\n\n\t\t\tcurrentRenderList = renderListStack[ renderListStack.length - 1 ];\n\n\t\t} else {\n\n\t\t\tcurrentRenderList = null;\n\n\t\t}\n\n\t};\n\n\tfunction projectObject( object, camera, groupOrder, sortObjects ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tconst visible = object.layers.test( camera.layers );\n\n\t\tif ( visible ) {\n\n\t\t\tif ( object.isGroup ) {\n\n\t\t\t\tgroupOrder = object.renderOrder;\n\n\t\t\t} else if ( object.isLOD ) {\n\n\t\t\t\tif ( object.autoUpdate === true ) object.update( camera );\n\n\t\t\t} else if ( object.isLight ) {\n\n\t\t\t\tcurrentRenderState.pushLight( object );\n\n\t\t\t\tif ( object.castShadow ) {\n\n\t\t\t\t\tcurrentRenderState.pushShadow( object );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\tif ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {\n\n\t\t\t\t\tif ( sortObjects ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld )\n\t\t\t\t\t\t\t.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst geometry = objects.update( object );\n\t\t\t\t\tconst material = object.material;\n\n\t\t\t\t\tif ( material.visible ) {\n\n\t\t\t\t\t\tcurrentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t// update skeleton only once in a frame\n\n\t\t\t\t\tif ( object.skeleton.frame !== info.render.frame ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\t\t\t\t\t\tobject.skeleton.frame = info.render.frame;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {\n\n\t\t\t\t\tif ( sortObjects ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld )\n\t\t\t\t\t\t\t.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst geometry = objects.update( object );\n\t\t\t\t\tconst material = object.material;\n\n\t\t\t\t\tif ( Array.isArray( material ) ) {\n\n\t\t\t\t\t\tconst groups = geometry.groups;\n\n\t\t\t\t\t\tfor ( let i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tconst group = groups[ i ];\n\t\t\t\t\t\t\tconst groupMaterial = material[ group.materialIndex ];\n\n\t\t\t\t\t\t\tif ( groupMaterial && groupMaterial.visible ) {\n\n\t\t\t\t\t\t\t\tcurrentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( material.visible ) {\n\n\t\t\t\t\t\tcurrentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst children = object.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tprojectObject( children[ i ], camera, groupOrder, sortObjects );\n\n\t\t}\n\n\t}\n\n\tfunction renderScene( currentRenderList, scene, camera, viewport ) {\n\n\t\tconst opaqueObjects = currentRenderList.opaque;\n\t\tconst transmissiveObjects = currentRenderList.transmissive;\n\t\tconst transparentObjects = currentRenderList.transparent;\n\n\t\tcurrentRenderState.setupLightsView( camera );\n\n\t\tif ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, scene, camera );\n\n\t\tif ( viewport ) state.viewport( _currentViewport.copy( viewport ) );\n\n\t\tif ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera );\n\t\tif ( transmissiveObjects.length > 0 ) renderObjects( transmissiveObjects, scene, camera );\n\t\tif ( transparentObjects.length > 0 ) renderObjects( transparentObjects, scene, camera );\n\n\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\tstate.buffers.depth.setTest( true );\n\t\tstate.buffers.depth.setMask( true );\n\t\tstate.buffers.color.setMask( true );\n\n\t\tstate.setPolygonOffset( false );\n\n\t}\n\n\tfunction renderTransmissionPass( opaqueObjects, scene, camera ) {\n\n\t\tconst isWebGL2 = capabilities.isWebGL2;\n\n\t\tif ( _transmissionRenderTarget === null ) {\n\n\t\t\t_transmissionRenderTarget = new WebGLRenderTarget( 1, 1, {\n\t\t\t\tgenerateMipmaps: true,\n\t\t\t\ttype: extensions.has( 'EXT_color_buffer_half_float' ) ? HalfFloatType : UnsignedByteType,\n\t\t\t\tminFilter: LinearMipmapLinearFilter,\n\t\t\t\tsamples: ( isWebGL2 && _antialias === true ) ? 4 : 0\n\t\t\t} );\n\n\t\t}\n\n\t\t_this.getDrawingBufferSize( _vector2 );\n\n\t\tif ( isWebGL2 ) {\n\n\t\t\t_transmissionRenderTarget.setSize( _vector2.x, _vector2.y );\n\n\t\t} else {\n\n\t\t\t_transmissionRenderTarget.setSize( floorPowerOfTwo( _vector2.x ), floorPowerOfTwo( _vector2.y ) );\n\n\t\t}\n\n\t\t//\n\n\t\tconst currentRenderTarget = _this.getRenderTarget();\n\t\t_this.setRenderTarget( _transmissionRenderTarget );\n\t\t_this.clear();\n\n\t\t// Turn off the features which can affect the frag color for opaque objects pass.\n\t\t// Otherwise they are applied twice in opaque objects pass and transmission objects pass.\n\t\tconst currentToneMapping = _this.toneMapping;\n\t\t_this.toneMapping = NoToneMapping;\n\n\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t_this.toneMapping = currentToneMapping;\n\n\t\ttextures.updateMultisampleRenderTarget( _transmissionRenderTarget );\n\t\ttextures.updateRenderTargetMipmap( _transmissionRenderTarget );\n\n\t\t_this.setRenderTarget( currentRenderTarget );\n\n\t}\n\n\tfunction renderObjects( renderList, scene, camera ) {\n\n\t\tconst overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;\n\n\t\tfor ( let i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\tconst renderItem = renderList[ i ];\n\n\t\t\tconst object = renderItem.object;\n\t\t\tconst geometry = renderItem.geometry;\n\t\t\tconst material = overrideMaterial === null ? renderItem.material : overrideMaterial;\n\t\t\tconst group = renderItem.group;\n\n\t\t\tif ( object.layers.test( camera.layers ) ) {\n\n\t\t\t\trenderObject( object, scene, camera, geometry, material, group );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tfunction renderObject( object, scene, camera, geometry, material, group ) {\n\n\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\tmaterial.onBeforeRender( _this, scene, camera, geometry, object, group );\n\n\t\tif ( material.transparent === true && material.side === DoubleSide ) {\n\n\t\t\tmaterial.side = BackSide;\n\t\t\tmaterial.needsUpdate = true;\n\t\t\t_this.renderBufferDirect( camera, scene, geometry, material, object, group );\n\n\t\t\tmaterial.side = FrontSide;\n\t\t\tmaterial.needsUpdate = true;\n\t\t\t_this.renderBufferDirect( camera, scene, geometry, material, object, group );\n\n\t\t\tmaterial.side = DoubleSide;\n\n\t\t} else {\n\n\t\t\t_this.renderBufferDirect( camera, scene, geometry, material, object, group );\n\n\t\t}\n\n\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\t}\n\n\tfunction getProgram( material, scene, object ) {\n\n\t\tif ( scene.isScene !== true ) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...\n\n\t\tconst materialProperties = properties.get( material );\n\n\t\tconst lights = currentRenderState.state.lights;\n\t\tconst shadowsArray = currentRenderState.state.shadowsArray;\n\n\t\tconst lightsStateVersion = lights.state.version;\n\n\t\tconst parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, object );\n\t\tconst programCacheKey = programCache.getProgramCacheKey( parameters );\n\n\t\tlet programs = materialProperties.programs;\n\n\t\t// always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change\n\n\t\tmaterialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;\n\t\tmaterialProperties.fog = scene.fog;\n\t\tmaterialProperties.envMap = ( material.isMeshStandardMaterial ? cubeuvmaps : cubemaps ).get( material.envMap || materialProperties.environment );\n\n\t\tif ( programs === undefined ) {\n\n\t\t\t// new material\n\n\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tprograms = new Map();\n\t\t\tmaterialProperties.programs = programs;\n\n\t\t}\n\n\t\tlet program = programs.get( programCacheKey );\n\n\t\tif ( program !== undefined ) {\n\n\t\t\t// early out if program and light state is identical\n\n\t\t\tif ( materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion ) {\n\n\t\t\t\tupdateCommonMaterialProperties( material, parameters );\n\n\t\t\t\treturn program;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tparameters.uniforms = programCache.getUniforms( material );\n\n\t\t\tmaterial.onBuild( object, parameters, _this );\n\n\t\t\tmaterial.onBeforeCompile( parameters, _this );\n\n\t\t\tprogram = programCache.acquireProgram( parameters, programCacheKey );\n\t\t\tprograms.set( programCacheKey, program );\n\n\t\t\tmaterialProperties.uniforms = parameters.uniforms;\n\n\t\t}\n\n\t\tconst uniforms = materialProperties.uniforms;\n\n\t\tif ( ( ! material.isShaderMaterial && ! material.isRawShaderMaterial ) || material.clipping === true ) {\n\n\t\t\tuniforms.clippingPlanes = clipping.uniform;\n\n\t\t}\n\n\t\tupdateCommonMaterialProperties( material, parameters );\n\n\t\t// store the light setup it was created for\n\n\t\tmaterialProperties.needsLights = materialNeedsLights( material );\n\t\tmaterialProperties.lightsStateVersion = lightsStateVersion;\n\n\t\tif ( materialProperties.needsLights ) {\n\n\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\tuniforms.ambientLightColor.value = lights.state.ambient;\n\t\t\tuniforms.lightProbe.value = lights.state.probe;\n\t\t\tuniforms.directionalLights.value = lights.state.directional;\n\t\t\tuniforms.directionalLightShadows.value = lights.state.directionalShadow;\n\t\t\tuniforms.spotLights.value = lights.state.spot;\n\t\t\tuniforms.spotLightShadows.value = lights.state.spotShadow;\n\t\t\tuniforms.rectAreaLights.value = lights.state.rectArea;\n\t\t\tuniforms.ltc_1.value = lights.state.rectAreaLTC1;\n\t\t\tuniforms.ltc_2.value = lights.state.rectAreaLTC2;\n\t\t\tuniforms.pointLights.value = lights.state.point;\n\t\t\tuniforms.pointLightShadows.value = lights.state.pointShadow;\n\t\t\tuniforms.hemisphereLights.value = lights.state.hemi;\n\n\t\t\tuniforms.directionalShadowMap.value = lights.state.directionalShadowMap;\n\t\t\tuniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;\n\t\t\tuniforms.spotShadowMap.value = lights.state.spotShadowMap;\n\t\t\tuniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix;\n\t\t\tuniforms.pointShadowMap.value = lights.state.pointShadowMap;\n\t\t\tuniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix;\n\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t}\n\n\t\tconst progUniforms = program.getUniforms();\n\t\tconst uniformsList = WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\tmaterialProperties.currentProgram = program;\n\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\treturn program;\n\n\t}\n\n\tfunction updateCommonMaterialProperties( material, parameters ) {\n\n\t\tconst materialProperties = properties.get( material );\n\n\t\tmaterialProperties.outputEncoding = parameters.outputEncoding;\n\t\tmaterialProperties.instancing = parameters.instancing;\n\t\tmaterialProperties.skinning = parameters.skinning;\n\t\tmaterialProperties.morphTargets = parameters.morphTargets;\n\t\tmaterialProperties.morphNormals = parameters.morphNormals;\n\t\tmaterialProperties.morphColors = parameters.morphColors;\n\t\tmaterialProperties.morphTargetsCount = parameters.morphTargetsCount;\n\t\tmaterialProperties.numClippingPlanes = parameters.numClippingPlanes;\n\t\tmaterialProperties.numIntersection = parameters.numClipIntersection;\n\t\tmaterialProperties.vertexAlphas = parameters.vertexAlphas;\n\t\tmaterialProperties.vertexTangents = parameters.vertexTangents;\n\t\tmaterialProperties.toneMapping = parameters.toneMapping;\n\n\t}\n\n\tfunction setProgram( camera, scene, geometry, material, object ) {\n\n\t\tif ( scene.isScene !== true ) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...\n\n\t\ttextures.resetTextureUnits();\n\n\t\tconst fog = scene.fog;\n\t\tconst environment = material.isMeshStandardMaterial ? scene.environment : null;\n\t\tconst encoding = ( _currentRenderTarget === null ) ? _this.outputEncoding : ( _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.encoding : LinearEncoding );\n\t\tconst envMap = ( material.isMeshStandardMaterial ? cubeuvmaps : cubemaps ).get( material.envMap || environment );\n\t\tconst vertexAlphas = material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4;\n\t\tconst vertexTangents = !! material.normalMap && !! geometry.attributes.tangent;\n\t\tconst morphTargets = !! geometry.morphAttributes.position;\n\t\tconst morphNormals = !! geometry.morphAttributes.normal;\n\t\tconst morphColors = !! geometry.morphAttributes.color;\n\t\tconst toneMapping = material.toneMapped ? _this.toneMapping : NoToneMapping;\n\n\t\tconst morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;\n\t\tconst morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;\n\n\t\tconst materialProperties = properties.get( material );\n\t\tconst lights = currentRenderState.state.lights;\n\n\t\tif ( _clippingEnabled === true ) {\n\n\t\t\tif ( _localClippingEnabled === true || camera !== _currentCamera ) {\n\n\t\t\t\tconst useCache =\n\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t// (#8465, #8379)\n\t\t\t\tclipping.setState( material, camera, useCache );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tlet needsProgramChange = false;\n\n\t\tif ( material.version === materialProperties.__version ) {\n\n\t\t\tif ( materialProperties.needsLights && ( materialProperties.lightsStateVersion !== lights.state.version ) ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.outputEncoding !== encoding ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( object.isInstancedMesh && materialProperties.instancing === false ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( ! object.isInstancedMesh && materialProperties.instancing === true ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( object.isSkinnedMesh && materialProperties.skinning === false ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( ! object.isSkinnedMesh && materialProperties.skinning === true ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.envMap !== envMap ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( material.fog === true && materialProperties.fog !== fog ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t( materialProperties.numClippingPlanes !== clipping.numPlanes ||\n\t\t\t\tmaterialProperties.numIntersection !== clipping.numIntersection ) ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.vertexAlphas !== vertexAlphas ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.vertexTangents !== vertexTangents ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.morphTargets !== morphTargets ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.morphNormals !== morphNormals ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.morphColors !== morphColors ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( materialProperties.toneMapping !== toneMapping ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t} else if ( capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount ) {\n\n\t\t\t\tneedsProgramChange = true;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tneedsProgramChange = true;\n\t\t\tmaterialProperties.__version = material.version;\n\n\t\t}\n\n\t\t//\n\n\t\tlet program = materialProperties.currentProgram;\n\n\t\tif ( needsProgramChange === true ) {\n\n\t\t\tprogram = getProgram( material, scene, object );\n\n\t\t}\n\n\t\tlet refreshProgram = false;\n\t\tlet refreshMaterial = false;\n\t\tlet refreshLights = false;\n\n\t\tconst p_uniforms = program.getUniforms(),\n\t\t\tm_uniforms = materialProperties.uniforms;\n\n\t\tif ( state.useProgram( program.program ) ) {\n\n\t\t\trefreshProgram = true;\n\t\t\trefreshMaterial = true;\n\t\t\trefreshLights = true;\n\n\t\t}\n\n\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t_currentMaterialId = material.id;\n\n\t\t\trefreshMaterial = true;\n\n\t\t}\n\n\t\tif ( refreshProgram || _currentCamera !== camera ) {\n\n\t\t\tp_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );\n\n\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t}\n\n\t\t\tif ( _currentCamera !== camera ) {\n\n\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t}\n\n\t\t\t// load material specific uniforms\n\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\tmaterial.isMeshToonMaterial ||\n\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\tconst uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\tmaterial.isMeshToonMaterial ||\n\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\tmaterial.isShaderMaterial ) {\n\n\t\t\t\tp_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true );\n\n\t\t\t}\n\n\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\tmaterial.isMeshToonMaterial ||\n\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\tmaterial.isShadowMaterial ||\n\t\t\t\tobject.isSkinnedMesh ) {\n\n\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// skinning and morph target uniforms must be set even if material didn't change\n\t\t// auto-setting of texture unit for bone and morph texture must go before other textures\n\t\t// otherwise textures used for skinning and morphing can take over texture units reserved for other material textures\n\n\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\tconst skeleton = object.skeleton;\n\n\t\t\tif ( skeleton ) {\n\n\t\t\t\tif ( capabilities.floatVertexTextures ) {\n\n\t\t\t\t\tif ( skeleton.boneTexture === null ) skeleton.computeBoneTexture();\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures );\n\t\t\t\t\tp_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: SkinnedMesh can only be used with WebGL 2. With WebGL 1 OES_texture_float and vertex textures support is required.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst morphAttributes = geometry.morphAttributes;\n\n\t\tif ( morphAttributes.position !== undefined || morphAttributes.normal !== undefined || ( morphAttributes.color !== undefined && capabilities.isWebGL2 === true ) ) {\n\n\t\t\tmorphtargets.update( object, geometry, material, program );\n\n\t\t}\n\n\n\t\tif ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) {\n\n\t\t\tmaterialProperties.receiveShadow = object.receiveShadow;\n\t\t\tp_uniforms.setValue( _gl, 'receiveShadow', object.receiveShadow );\n\n\t\t}\n\n\t\tif ( refreshMaterial ) {\n\n\t\t\tp_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );\n\n\t\t\tif ( materialProperties.needsLights ) {\n\n\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t// values\n\t\t\t\t//\n\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t// the GL state when required\n\n\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t}\n\n\t\t\t// refresh uniforms common to several materials\n\n\t\t\tif ( fog && material.fog === true ) {\n\n\t\t\t\tmaterials.refreshFogUniforms( m_uniforms, fog );\n\n\t\t\t}\n\n\t\t\tmaterials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget );\n\n\t\t\tWebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );\n\n\t\t}\n\n\t\tif ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {\n\n\t\t\tWebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );\n\t\t\tmaterial.uniformsNeedUpdate = false;\n\n\t\t}\n\n\t\tif ( material.isSpriteMaterial ) {\n\n\t\t\tp_uniforms.setValue( _gl, 'center', object.center );\n\n\t\t}\n\n\t\t// common matrices\n\n\t\tp_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );\n\t\tp_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );\n\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\treturn program;\n\n\t}\n\n\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\tuniforms.ambientLightColor.needsUpdate = value;\n\t\tuniforms.lightProbe.needsUpdate = value;\n\n\t\tuniforms.directionalLights.needsUpdate = value;\n\t\tuniforms.directionalLightShadows.needsUpdate = value;\n\t\tuniforms.pointLights.needsUpdate = value;\n\t\tuniforms.pointLightShadows.needsUpdate = value;\n\t\tuniforms.spotLights.needsUpdate = value;\n\t\tuniforms.spotLightShadows.needsUpdate = value;\n\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t}\n\n\tfunction materialNeedsLights( material ) {\n\n\t\treturn material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial ||\n\t\t\tmaterial.isMeshStandardMaterial || material.isShadowMaterial ||\n\t\t\t( material.isShaderMaterial && material.lights === true );\n\n\t}\n\n\tthis.getActiveCubeFace = function () {\n\n\t\treturn _currentActiveCubeFace;\n\n\t};\n\n\tthis.getActiveMipmapLevel = function () {\n\n\t\treturn _currentActiveMipmapLevel;\n\n\t};\n\n\tthis.getRenderTarget = function () {\n\n\t\treturn _currentRenderTarget;\n\n\t};\n\n\tthis.setRenderTargetTextures = function ( renderTarget, colorTexture, depthTexture ) {\n\n\t\tproperties.get( renderTarget.texture ).__webglTexture = colorTexture;\n\t\tproperties.get( renderTarget.depthTexture ).__webglTexture = depthTexture;\n\n\t\tconst renderTargetProperties = properties.get( renderTarget );\n\t\trenderTargetProperties.__hasExternalTextures = true;\n\n\t\tif ( renderTargetProperties.__hasExternalTextures ) {\n\n\t\t\trenderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;\n\n\t\t\tif ( ! renderTargetProperties.__autoAllocateDepthBuffer ) {\n\n\t\t\t\t// The multisample_render_to_texture extension doesn't work properly if there\n\t\t\t\t// are midframe flushes and an external depth buffer. Disable use of the extension.\n\t\t\t\tif ( extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided' );\n\t\t\t\t\trenderTargetProperties.__useRenderToTexture = false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tthis.setRenderTargetFramebuffer = function ( renderTarget, defaultFramebuffer ) {\n\n\t\tconst renderTargetProperties = properties.get( renderTarget );\n\t\trenderTargetProperties.__webglFramebuffer = defaultFramebuffer;\n\t\trenderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined;\n\n\t};\n\n\tthis.setRenderTarget = function ( renderTarget, activeCubeFace = 0, activeMipmapLevel = 0 ) {\n\n\t\t_currentRenderTarget = renderTarget;\n\t\t_currentActiveCubeFace = activeCubeFace;\n\t\t_currentActiveMipmapLevel = activeMipmapLevel;\n\n\t\tlet useDefaultFramebuffer = true;\n\n\t\tif ( renderTarget ) {\n\n\t\t\tconst renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tif ( renderTargetProperties.__useDefaultFramebuffer !== undefined ) {\n\n\t\t\t\t// We need to make sure to rebind the framebuffer.\n\t\t\t\tstate.bindFramebuffer( 36160, null );\n\t\t\t\tuseDefaultFramebuffer = false;\n\n\t\t\t} else if ( renderTargetProperties.__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t} else if ( renderTargetProperties.__hasExternalTextures ) {\n\n\t\t\t\t// Color and depth texture must be rebound in order for the swapchain to update.\n\t\t\t\ttextures.rebindTextures( renderTarget, properties.get( renderTarget.texture ).__webglTexture, properties.get( renderTarget.depthTexture ).__webglTexture );\n\n\t\t\t}\n\n\t\t}\n\n\t\tlet framebuffer = null;\n\t\tlet isCube = false;\n\t\tlet isRenderTarget3D = false;\n\n\t\tif ( renderTarget ) {\n\n\t\t\tconst texture = renderTarget.texture;\n\n\t\t\tif ( texture.isData3DTexture || texture.isDataArrayTexture ) {\n\n\t\t\t\tisRenderTarget3D = true;\n\n\t\t\t}\n\n\t\t\tconst __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( renderTarget.isWebGLCubeRenderTarget ) {\n\n\t\t\t\tframebuffer = __webglFramebuffer[ activeCubeFace ];\n\t\t\t\tisCube = true;\n\n\t\t\t} else if ( ( capabilities.isWebGL2 && renderTarget.samples > 0 ) && textures.useMultisampledRTT( renderTarget ) === false ) {\n\n\t\t\t\tframebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = __webglFramebuffer;\n\n\t\t\t}\n\n\t\t\t_currentViewport.copy( renderTarget.viewport );\n\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t} else {\n\n\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor();\n\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor();\n\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t}\n\n\t\tconst framebufferBound = state.bindFramebuffer( 36160, framebuffer );\n\n\t\tif ( framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer ) {\n\n\t\t\tstate.drawBuffers( renderTarget, framebuffer );\n\n\t\t}\n\n\t\tstate.viewport( _currentViewport );\n\t\tstate.scissor( _currentScissor );\n\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\tif ( isCube ) {\n\n\t\t\tconst textureProperties = properties.get( renderTarget.texture );\n\t\t\t_gl.framebufferTexture2D( 36160, 36064, 34069 + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel );\n\n\t\t} else if ( isRenderTarget3D ) {\n\n\t\t\tconst textureProperties = properties.get( renderTarget.texture );\n\t\t\tconst layer = activeCubeFace || 0;\n\t\t\t_gl.framebufferTextureLayer( 36160, 36064, textureProperties.__webglTexture, activeMipmapLevel || 0, layer );\n\n\t\t}\n\n\t\t_currentMaterialId = - 1; // reset current material to ensure correct uniform bindings\n\n\t};\n\n\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex ) {\n\n\t\tif ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tlet framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\tif ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) {\n\n\t\t\tframebuffer = framebuffer[ activeCubeFaceIndex ];\n\n\t\t}\n\n\t\tif ( framebuffer ) {\n\n\t\t\tstate.bindFramebuffer( 36160, framebuffer );\n\n\t\t\ttry {\n\n\t\t\t\tconst texture = renderTarget.texture;\n\t\t\t\tconst textureFormat = texture.format;\n\t\t\t\tconst textureType = texture.type;\n\n\t\t\t\tif ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( 35739 ) ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tconst halfFloatSupportedByExt = ( textureType === HalfFloatType ) && ( extensions.has( 'EXT_color_buffer_half_float' ) || ( capabilities.isWebGL2 && extensions.has( 'EXT_color_buffer_float' ) ) );\n\n\t\t\t\tif ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( 35738 ) && // Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.has( 'OES_texture_float' ) || extensions.has( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t! halfFloatSupportedByExt ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );\n\n\t\t\t\t}\n\n\t\t\t} finally {\n\n\t\t\t\t// restore framebuffer of current render target if necessary\n\n\t\t\t\tconst framebuffer = ( _currentRenderTarget !== null ) ? properties.get( _currentRenderTarget ).__webglFramebuffer : null;\n\t\t\t\tstate.bindFramebuffer( 36160, framebuffer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tthis.copyFramebufferToTexture = function ( position, texture, level = 0 ) {\n\n\t\tconst levelScale = Math.pow( 2, - level );\n\t\tconst width = Math.floor( texture.image.width * levelScale );\n\t\tconst height = Math.floor( texture.image.height * levelScale );\n\n\t\ttextures.setTexture2D( texture, 0 );\n\n\t\t_gl.copyTexSubImage2D( 3553, level, 0, 0, position.x, position.y, width, height );\n\n\t\tstate.unbindTexture();\n\n\t};\n\n\tthis.copyTextureToTexture = function ( position, srcTexture, dstTexture, level = 0 ) {\n\n\t\tconst width = srcTexture.image.width;\n\t\tconst height = srcTexture.image.height;\n\t\tconst glFormat = utils.convert( dstTexture.format );\n\t\tconst glType = utils.convert( dstTexture.type );\n\n\t\ttextures.setTexture2D( dstTexture, 0 );\n\n\t\t// As another texture upload may have changed pixelStorei\n\t\t// parameters, make sure they are correct for the dstTexture\n\t\t_gl.pixelStorei( 37440, dstTexture.flipY );\n\t\t_gl.pixelStorei( 37441, dstTexture.premultiplyAlpha );\n\t\t_gl.pixelStorei( 3317, dstTexture.unpackAlignment );\n\n\t\tif ( srcTexture.isDataTexture ) {\n\n\t\t\t_gl.texSubImage2D( 3553, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );\n\n\t\t} else {\n\n\t\t\tif ( srcTexture.isCompressedTexture ) {\n\n\t\t\t\t_gl.compressedTexSubImage2D( 3553, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texSubImage2D( 3553, level, position.x, position.y, glFormat, glType, srcTexture.image );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Generate mipmaps only when copying level 0\n\t\tif ( level === 0 && dstTexture.generateMipmaps ) _gl.generateMipmap( 3553 );\n\n\t\tstate.unbindTexture();\n\n\t};\n\n\tthis.copyTextureToTexture3D = function ( sourceBox, position, srcTexture, dstTexture, level = 0 ) {\n\n\t\tif ( _this.isWebGL1Renderer ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst width = sourceBox.max.x - sourceBox.min.x + 1;\n\t\tconst height = sourceBox.max.y - sourceBox.min.y + 1;\n\t\tconst depth = sourceBox.max.z - sourceBox.min.z + 1;\n\t\tconst glFormat = utils.convert( dstTexture.format );\n\t\tconst glType = utils.convert( dstTexture.type );\n\t\tlet glTarget;\n\n\t\tif ( dstTexture.isData3DTexture ) {\n\n\t\t\ttextures.setTexture3D( dstTexture, 0 );\n\t\t\tglTarget = 32879;\n\n\t\t} else if ( dstTexture.isDataArrayTexture ) {\n\n\t\t\ttextures.setTexture2DArray( dstTexture, 0 );\n\t\t\tglTarget = 35866;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\t_gl.pixelStorei( 37440, dstTexture.flipY );\n\t\t_gl.pixelStorei( 37441, dstTexture.premultiplyAlpha );\n\t\t_gl.pixelStorei( 3317, dstTexture.unpackAlignment );\n\n\t\tconst unpackRowLen = _gl.getParameter( 3314 );\n\t\tconst unpackImageHeight = _gl.getParameter( 32878 );\n\t\tconst unpackSkipPixels = _gl.getParameter( 3316 );\n\t\tconst unpackSkipRows = _gl.getParameter( 3315 );\n\t\tconst unpackSkipImages = _gl.getParameter( 32877 );\n\n\t\tconst image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ 0 ] : srcTexture.image;\n\n\t\t_gl.pixelStorei( 3314, image.width );\n\t\t_gl.pixelStorei( 32878, image.height );\n\t\t_gl.pixelStorei( 3316, sourceBox.min.x );\n\t\t_gl.pixelStorei( 3315, sourceBox.min.y );\n\t\t_gl.pixelStorei( 32877, sourceBox.min.z );\n\n\t\tif ( srcTexture.isDataTexture || srcTexture.isData3DTexture ) {\n\n\t\t\t_gl.texSubImage3D( glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image.data );\n\n\t\t} else {\n\n\t\t\tif ( srcTexture.isCompressedTexture ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.' );\n\t\t\t\t_gl.compressedTexSubImage3D( glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texSubImage3D( glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image );\n\n\t\t\t}\n\n\t\t}\n\n\t\t_gl.pixelStorei( 3314, unpackRowLen );\n\t\t_gl.pixelStorei( 32878, unpackImageHeight );\n\t\t_gl.pixelStorei( 3316, unpackSkipPixels );\n\t\t_gl.pixelStorei( 3315, unpackSkipRows );\n\t\t_gl.pixelStorei( 32877, unpackSkipImages );\n\n\t\t// Generate mipmaps only when copying level 0\n\t\tif ( level === 0 && dstTexture.generateMipmaps ) _gl.generateMipmap( glTarget );\n\n\t\tstate.unbindTexture();\n\n\t};\n\n\tthis.initTexture = function ( texture ) {\n\n\t\ttextures.setTexture2D( texture, 0 );\n\n\t\tstate.unbindTexture();\n\n\t};\n\n\tthis.resetState = function () {\n\n\t\t_currentActiveCubeFace = 0;\n\t\t_currentActiveMipmapLevel = 0;\n\t\t_currentRenderTarget = null;\n\n\t\tstate.reset();\n\t\tbindingStates.reset();\n\n\t};\n\n\tif ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {\n\n\t\t__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) );\n\n\t}\n\n}\n\nclass WebGL1Renderer extends WebGLRenderer {}\n\nWebGL1Renderer.prototype.isWebGL1Renderer = true;\n\nclass FogExp2 {\n\n\tconstructor( color, density = 0.00025 ) {\n\n\t\tthis.isFogExp2 = true;\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = density;\n\n\t}\n\n\tclone() {\n\n\t\treturn new FogExp2( this.color, this.density );\n\n\t}\n\n\ttoJSON( /* meta */ ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t}\n\n}\n\nclass Fog {\n\n\tconstructor( color, near = 1, far = 1000 ) {\n\n\t\tthis.isFog = true;\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = near;\n\t\tthis.far = far;\n\n\t}\n\n\tclone() {\n\n\t\treturn new Fog( this.color, this.near, this.far );\n\n\t}\n\n\ttoJSON( /* meta */ ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t}\n\n}\n\nclass Scene extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isScene = true;\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.environment = null;\n\t\tthis.fog = null;\n\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t\tif ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {\n\n\t\t\t__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) );\n\n\t\t}\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.environment !== null ) this.environment = source.environment.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t}\n\n}\n\nclass InterleavedBuffer {\n\n\tconstructor( array, stride ) {\n\n\t\tthis.isInterleavedBuffer = true;\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.usage = StaticDrawUsage;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.version = 0;\n\n\t\tthis.uuid = generateUUID();\n\n\t}\n\n\tonUploadCallback() {}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) this.version ++;\n\n\t}\n\n\tsetUsage( value ) {\n\n\t\tthis.usage = value;\n\n\t\treturn this;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.array = new source.array.constructor( source.array );\n\t\tthis.count = source.count;\n\t\tthis.stride = source.stride;\n\t\tthis.usage = source.usage;\n\n\t\treturn this;\n\n\t}\n\n\tcopyAt( index1, attribute, index2 ) {\n\n\t\tindex1 *= this.stride;\n\t\tindex2 *= attribute.stride;\n\n\t\tfor ( let i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tset( value, offset = 0 ) {\n\n\t\tthis.array.set( value, offset );\n\n\t\treturn this;\n\n\t}\n\n\tclone( data ) {\n\n\t\tif ( data.arrayBuffers === undefined ) {\n\n\t\t\tdata.arrayBuffers = {};\n\n\t\t}\n\n\t\tif ( this.array.buffer._uuid === undefined ) {\n\n\t\t\tthis.array.buffer._uuid = generateUUID();\n\n\t\t}\n\n\t\tif ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {\n\n\t\t\tdata.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer;\n\n\t\t}\n\n\t\tconst array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] );\n\n\t\tconst ib = new this.constructor( array, this.stride );\n\t\tib.setUsage( this.usage );\n\n\t\treturn ib;\n\n\t}\n\n\tonUpload( callback ) {\n\n\t\tthis.onUploadCallback = callback;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( data ) {\n\n\t\tif ( data.arrayBuffers === undefined ) {\n\n\t\t\tdata.arrayBuffers = {};\n\n\t\t}\n\n\t\t// generate UUID for array buffer if necessary\n\n\t\tif ( this.array.buffer._uuid === undefined ) {\n\n\t\t\tthis.array.buffer._uuid = generateUUID();\n\n\t\t}\n\n\t\tif ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {\n\n\t\t\tdata.arrayBuffers[ this.array.buffer._uuid ] = Array.prototype.slice.call( new Uint32Array( this.array.buffer ) );\n\n\t\t}\n\n\t\t//\n\n\t\treturn {\n\t\t\tuuid: this.uuid,\n\t\t\tbuffer: this.array.buffer._uuid,\n\t\t\ttype: this.array.constructor.name,\n\t\t\tstride: this.stride\n\t\t};\n\n\t}\n\n}\n\nconst _vector$6 = /*@__PURE__*/ new Vector3();\n\nclass InterleavedBufferAttribute {\n\n\tconstructor( interleavedBuffer, itemSize, offset, normalized = false ) {\n\n\t\tthis.isInterleavedBufferAttribute = true;\n\n\t\tthis.name = '';\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\tget count() {\n\n\t\treturn this.data.count;\n\n\t}\n\n\tget array() {\n\n\t\treturn this.data.array;\n\n\t}\n\n\tset needsUpdate( value ) {\n\n\t\tthis.data.needsUpdate = value;\n\n\t}\n\n\tapplyMatrix4( m ) {\n\n\t\tfor ( let i = 0, l = this.data.count; i < l; i ++ ) {\n\n\t\t\t_vector$6.fromBufferAttribute( this, i );\n\n\t\t\t_vector$6.applyMatrix4( m );\n\n\t\t\tthis.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tapplyNormalMatrix( m ) {\n\n\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t_vector$6.fromBufferAttribute( this, i );\n\n\t\t\t_vector$6.applyNormalMatrix( m );\n\n\t\t\tthis.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttransformDirection( m ) {\n\n\t\tfor ( let i = 0, l = this.count; i < l; i ++ ) {\n\n\t\t\t_vector$6.fromBufferAttribute( this, i );\n\n\t\t\t_vector$6.transformDirection( m );\n\n\t\t\tthis.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetX( index, x ) {\n\n\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\treturn this;\n\n\t}\n\n\tsetY( index, y ) {\n\n\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetZ( index, z ) {\n\n\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetW( index, w ) {\n\n\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\treturn this;\n\n\t}\n\n\tgetX( index ) {\n\n\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t}\n\n\tgetY( index ) {\n\n\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t}\n\n\tgetZ( index ) {\n\n\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t}\n\n\tgetW( index ) {\n\n\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t}\n\n\tsetXY( index, x, y ) {\n\n\t\tindex = index * this.data.stride + this.offset;\n\n\t\tthis.data.array[ index + 0 ] = x;\n\t\tthis.data.array[ index + 1 ] = y;\n\n\t\treturn this;\n\n\t}\n\n\tsetXYZ( index, x, y, z ) {\n\n\t\tindex = index * this.data.stride + this.offset;\n\n\t\tthis.data.array[ index + 0 ] = x;\n\t\tthis.data.array[ index + 1 ] = y;\n\t\tthis.data.array[ index + 2 ] = z;\n\n\t\treturn this;\n\n\t}\n\n\tsetXYZW( index, x, y, z, w ) {\n\n\t\tindex = index * this.data.stride + this.offset;\n\n\t\tthis.data.array[ index + 0 ] = x;\n\t\tthis.data.array[ index + 1 ] = y;\n\t\tthis.data.array[ index + 2 ] = z;\n\t\tthis.data.array[ index + 3 ] = w;\n\n\t\treturn this;\n\n\t}\n\n\tclone( data ) {\n\n\t\tif ( data === undefined ) {\n\n\t\t\tconsole.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.' );\n\n\t\t\tconst array = [];\n\n\t\t\tfor ( let i = 0; i < this.count; i ++ ) {\n\n\t\t\t\tconst index = i * this.data.stride + this.offset;\n\n\t\t\t\tfor ( let j = 0; j < this.itemSize; j ++ ) {\n\n\t\t\t\t\tarray.push( this.data.array[ index + j ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized );\n\n\t\t} else {\n\n\t\t\tif ( data.interleavedBuffers === undefined ) {\n\n\t\t\t\tdata.interleavedBuffers = {};\n\n\t\t\t}\n\n\t\t\tif ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {\n\n\t\t\t\tdata.interleavedBuffers[ this.data.uuid ] = this.data.clone( data );\n\n\t\t\t}\n\n\t\t\treturn new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized );\n\n\t\t}\n\n\t}\n\n\ttoJSON( data ) {\n\n\t\tif ( data === undefined ) {\n\n\t\t\tconsole.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.' );\n\n\t\t\tconst array = [];\n\n\t\t\tfor ( let i = 0; i < this.count; i ++ ) {\n\n\t\t\t\tconst index = i * this.data.stride + this.offset;\n\n\t\t\t\tfor ( let j = 0; j < this.itemSize; j ++ ) {\n\n\t\t\t\t\tarray.push( this.data.array[ index + j ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// deinterleave data and save it as an ordinary buffer attribute for now\n\n\t\t\treturn {\n\t\t\t\titemSize: this.itemSize,\n\t\t\t\ttype: this.array.constructor.name,\n\t\t\t\tarray: array,\n\t\t\t\tnormalized: this.normalized\n\t\t\t};\n\n\t\t} else {\n\n\t\t\t// save as true interlaved attribtue\n\n\t\t\tif ( data.interleavedBuffers === undefined ) {\n\n\t\t\t\tdata.interleavedBuffers = {};\n\n\t\t\t}\n\n\t\t\tif ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {\n\n\t\t\t\tdata.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data );\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tisInterleavedBufferAttribute: true,\n\t\t\t\titemSize: this.itemSize,\n\t\t\t\tdata: this.data.uuid,\n\t\t\t\toffset: this.offset,\n\t\t\t\tnormalized: this.normalized\n\t\t\t};\n\n\t\t}\n\n\t}\n\n}\n\nclass SpriteMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isSpriteMaterial = true;\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.transparent = true;\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.rotation = source.rotation;\n\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nlet _geometry;\n\nconst _intersectPoint = /*@__PURE__*/ new Vector3();\nconst _worldScale = /*@__PURE__*/ new Vector3();\nconst _mvPosition = /*@__PURE__*/ new Vector3();\n\nconst _alignedPosition = /*@__PURE__*/ new Vector2();\nconst _rotatedPosition = /*@__PURE__*/ new Vector2();\nconst _viewWorldMatrix = /*@__PURE__*/ new Matrix4();\n\nconst _vA = /*@__PURE__*/ new Vector3();\nconst _vB = /*@__PURE__*/ new Vector3();\nconst _vC = /*@__PURE__*/ new Vector3();\n\nconst _uvA = /*@__PURE__*/ new Vector2();\nconst _uvB = /*@__PURE__*/ new Vector2();\nconst _uvC = /*@__PURE__*/ new Vector2();\n\nclass Sprite extends Object3D {\n\n\tconstructor( material ) {\n\n\t\tsuper();\n\n\t\tthis.isSprite = true;\n\n\t\tthis.type = 'Sprite';\n\n\t\tif ( _geometry === undefined ) {\n\n\t\t\t_geometry = new BufferGeometry();\n\n\t\t\tconst float32Array = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0, 0,\n\t\t\t\t0.5, - 0.5, 0, 1, 0,\n\t\t\t\t0.5, 0.5, 0, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 0, 1\n\t\t\t] );\n\n\t\t\tconst interleavedBuffer = new InterleavedBuffer( float32Array, 5 );\n\n\t\t\t_geometry.setIndex( [ 0, 1, 2,\t0, 2, 3 ] );\n\t\t\t_geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) );\n\t\t\t_geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) );\n\n\t\t}\n\n\t\tthis.geometry = _geometry;\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t\tthis.center = new Vector2( 0.5, 0.5 );\n\n\t}\n\n\traycast( raycaster, intersects ) {\n\n\t\tif ( raycaster.camera === null ) {\n\n\t\t\tconsole.error( 'THREE.Sprite: \"Raycaster.camera\" needs to be set in order to raycast against sprites.' );\n\n\t\t}\n\n\t\t_worldScale.setFromMatrixScale( this.matrixWorld );\n\n\t\t_viewWorldMatrix.copy( raycaster.camera.matrixWorld );\n\t\tthis.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld );\n\n\t\t_mvPosition.setFromMatrixPosition( this.modelViewMatrix );\n\n\t\tif ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) {\n\n\t\t\t_worldScale.multiplyScalar( - _mvPosition.z );\n\n\t\t}\n\n\t\tconst rotation = this.material.rotation;\n\t\tlet sin, cos;\n\n\t\tif ( rotation !== 0 ) {\n\n\t\t\tcos = Math.cos( rotation );\n\t\t\tsin = Math.sin( rotation );\n\n\t\t}\n\n\t\tconst center = this.center;\n\n\t\ttransformVertex( _vA.set( - 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );\n\t\ttransformVertex( _vB.set( 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );\n\t\ttransformVertex( _vC.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );\n\n\t\t_uvA.set( 0, 0 );\n\t\t_uvB.set( 1, 0 );\n\t\t_uvC.set( 1, 1 );\n\n\t\t// check first triangle\n\t\tlet intersect = raycaster.ray.intersectTriangle( _vA, _vB, _vC, false, _intersectPoint );\n\n\t\tif ( intersect === null ) {\n\n\t\t\t// check second triangle\n\t\t\ttransformVertex( _vB.set( - 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );\n\t\t\t_uvB.set( 0, 1 );\n\n\t\t\tintersect = raycaster.ray.intersectTriangle( _vA, _vC, _vB, false, _intersectPoint );\n\t\t\tif ( intersect === null ) {\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst distance = raycaster.ray.origin.distanceTo( _intersectPoint );\n\n\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\tintersects.push( {\n\n\t\t\tdistance: distance,\n\t\t\tpoint: _intersectPoint.clone(),\n\t\t\tuv: Triangle.getUV( _intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ),\n\t\t\tface: null,\n\t\t\tobject: this\n\n\t\t} );\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tif ( source.center !== undefined ) this.center.copy( source.center );\n\n\t\tthis.material = source.material;\n\n\t\treturn this;\n\n\t}\n\n}\n\nfunction transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {\n\n\t// compute position in camera space\n\t_alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );\n\n\t// to check if rotation is not zero\n\tif ( sin !== undefined ) {\n\n\t\t_rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y );\n\t\t_rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y );\n\n\t} else {\n\n\t\t_rotatedPosition.copy( _alignedPosition );\n\n\t}\n\n\n\tvertexPosition.copy( mvPosition );\n\tvertexPosition.x += _rotatedPosition.x;\n\tvertexPosition.y += _rotatedPosition.y;\n\n\t// transform to world space\n\tvertexPosition.applyMatrix4( _viewWorldMatrix );\n\n}\n\nconst _v1$2 = /*@__PURE__*/ new Vector3();\nconst _v2$1 = /*@__PURE__*/ new Vector3();\n\nclass LOD extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis._currentLevel = 0;\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t},\n\t\t\tisLOD: {\n\t\t\t\tvalue: true,\n\t\t\t}\n\t\t} );\n\n\t\tthis.autoUpdate = true;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source, false );\n\n\t\tconst levels = source.levels;\n\n\t\tfor ( let i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\tconst level = levels[ i ];\n\n\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t}\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\n\t\treturn this;\n\n\t}\n\n\taddLevel( object, distance = 0 ) {\n\n\t\tdistance = Math.abs( distance );\n\n\t\tconst levels = this.levels;\n\n\t\tlet l;\n\n\t\tfor ( l = 0; l < levels.length; l ++ ) {\n\n\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\tthis.add( object );\n\n\t\treturn this;\n\n\t}\n\n\tgetCurrentLevel() {\n\n\t\treturn this._currentLevel;\n\n\t}\n\n\tgetObjectForDistance( distance ) {\n\n\t\tconst levels = this.levels;\n\n\t\tif ( levels.length > 0 ) {\n\n\t\t\tlet i, l;\n\n\t\t\tfor ( i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\traycast( raycaster, intersects ) {\n\n\t\tconst levels = this.levels;\n\n\t\tif ( levels.length > 0 ) {\n\n\t\t\t_v1$2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\tconst distance = raycaster.ray.origin.distanceTo( _v1$2 );\n\n\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t}\n\n\t}\n\n\tupdate( camera ) {\n\n\t\tconst levels = this.levels;\n\n\t\tif ( levels.length > 1 ) {\n\n\t\t\t_v1$2.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t_v2$1.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\tconst distance = _v1$2.distanceTo( _v2$1 ) / camera.zoom;\n\n\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\tlet i, l;\n\n\t\t\tfor ( i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._currentLevel = i - 1;\n\n\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tif ( this.autoUpdate === false ) data.object.autoUpdate = false;\n\n\t\tdata.object.levels = [];\n\n\t\tconst levels = this.levels;\n\n\t\tfor ( let i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\tconst level = levels[ i ];\n\n\t\t\tdata.object.levels.push( {\n\t\t\t\tobject: level.object.uuid,\n\t\t\t\tdistance: level.distance\n\t\t\t} );\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n}\n\nconst _basePosition = /*@__PURE__*/ new Vector3();\n\nconst _skinIndex = /*@__PURE__*/ new Vector4();\nconst _skinWeight = /*@__PURE__*/ new Vector4();\n\nconst _vector$5 = /*@__PURE__*/ new Vector3();\nconst _matrix = /*@__PURE__*/ new Matrix4();\n\nclass SkinnedMesh extends Mesh {\n\n\tconstructor( geometry, material ) {\n\n\t\tsuper( geometry, material );\n\n\t\tthis.isSkinnedMesh = true;\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = 'attached';\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.bindMode = source.bindMode;\n\t\tthis.bindMatrix.copy( source.bindMatrix );\n\t\tthis.bindMatrixInverse.copy( source.bindMatrixInverse );\n\n\t\tthis.skeleton = source.skeleton;\n\n\t\treturn this;\n\n\t}\n\n\tbind( skeleton, bindMatrix ) {\n\n\t\tthis.skeleton = skeleton;\n\n\t\tif ( bindMatrix === undefined ) {\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t}\n\n\t\tthis.bindMatrix.copy( bindMatrix );\n\t\tthis.bindMatrixInverse.copy( bindMatrix ).invert();\n\n\t}\n\n\tpose() {\n\n\t\tthis.skeleton.pose();\n\n\t}\n\n\tnormalizeSkinWeights() {\n\n\t\tconst vector = new Vector4();\n\n\t\tconst skinWeight = this.geometry.attributes.skinWeight;\n\n\t\tfor ( let i = 0, l = skinWeight.count; i < l; i ++ ) {\n\n\t\t\tvector.fromBufferAttribute( skinWeight, i );\n\n\t\t\tconst scale = 1.0 / vector.manhattanLength();\n\n\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\tvector.multiplyScalar( scale );\n\n\t\t\t} else {\n\n\t\t\t\tvector.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t}\n\n\t\t\tskinWeight.setXYZW( i, vector.x, vector.y, vector.z, vector.w );\n\n\t\t}\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t\tif ( this.bindMode === 'attached' ) {\n\n\t\t\tthis.bindMatrixInverse.copy( this.matrixWorld ).invert();\n\n\t\t} else if ( this.bindMode === 'detached' ) {\n\n\t\t\tthis.bindMatrixInverse.copy( this.bindMatrix ).invert();\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode );\n\n\t\t}\n\n\t}\n\n\tboneTransform( index, target ) {\n\n\t\tconst skeleton = this.skeleton;\n\t\tconst geometry = this.geometry;\n\n\t\t_skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );\n\t\t_skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );\n\n\t\t_basePosition.copy( target ).applyMatrix4( this.bindMatrix );\n\n\t\ttarget.set( 0, 0, 0 );\n\n\t\tfor ( let i = 0; i < 4; i ++ ) {\n\n\t\t\tconst weight = _skinWeight.getComponent( i );\n\n\t\t\tif ( weight !== 0 ) {\n\n\t\t\t\tconst boneIndex = _skinIndex.getComponent( i );\n\n\t\t\t\t_matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );\n\n\t\t\t\ttarget.addScaledVector( _vector$5.copy( _basePosition ).applyMatrix4( _matrix ), weight );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn target.applyMatrix4( this.bindMatrixInverse );\n\n\t}\n\n}\n\nclass Bone extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isBone = true;\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n}\n\nclass DataTexture extends Texture {\n\n\tconstructor( data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding ) {\n\n\t\tsuper( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.isDataTexture = true;\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n}\n\nconst _offsetMatrix = /*@__PURE__*/ new Matrix4();\nconst _identityMatrix = /*@__PURE__*/ new Matrix4();\n\nclass Skeleton {\n\n\tconstructor( bones = [], boneInverses = [] ) {\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.bones = bones.slice( 0 );\n\t\tthis.boneInverses = boneInverses;\n\t\tthis.boneMatrices = null;\n\n\t\tthis.boneTexture = null;\n\t\tthis.boneTextureSize = 0;\n\n\t\tthis.frame = - 1;\n\n\t\tthis.init();\n\n\t}\n\n\tinit() {\n\n\t\tconst bones = this.bones;\n\t\tconst boneInverses = this.boneInverses;\n\n\t\tthis.boneMatrices = new Float32Array( bones.length * 16 );\n\n\t\t// calculate inverse bone matrices if necessary\n\n\t\tif ( boneInverses.length === 0 ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\t// handle special case\n\n\t\t\tif ( bones.length !== boneInverses.length ) {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton: Number of inverse bone matrices does not match amount of bones.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( let i = 0, il = this.bones.length; i < il; i ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tcalculateInverses() {\n\n\t\tthis.boneInverses.length = 0;\n\n\t\tfor ( let i = 0, il = this.bones.length; i < il; i ++ ) {\n\n\t\t\tconst inverse = new Matrix4();\n\n\t\t\tif ( this.bones[ i ] ) {\n\n\t\t\t\tinverse.copy( this.bones[ i ].matrixWorld ).invert();\n\n\t\t\t}\n\n\t\t\tthis.boneInverses.push( inverse );\n\n\t\t}\n\n\t}\n\n\tpose() {\n\n\t\t// recover the bind-time world matrices\n\n\t\tfor ( let i = 0, il = this.bones.length; i < il; i ++ ) {\n\n\t\t\tconst bone = this.bones[ i ];\n\n\t\t\tif ( bone ) {\n\n\t\t\t\tbone.matrixWorld.copy( this.boneInverses[ i ] ).invert();\n\n\t\t\t}\n\n\t\t}\n\n\t\t// compute the local matrices, positions, rotations and scales\n\n\t\tfor ( let i = 0, il = this.bones.length; i < il; i ++ ) {\n\n\t\t\tconst bone = this.bones[ i ];\n\n\t\t\tif ( bone ) {\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tbone.matrix.copy( bone.parent.matrixWorld ).invert();\n\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tupdate() {\n\n\t\tconst bones = this.bones;\n\t\tconst boneInverses = this.boneInverses;\n\t\tconst boneMatrices = this.boneMatrices;\n\t\tconst boneTexture = this.boneTexture;\n\n\t\t// flatten bone matrices to array\n\n\t\tfor ( let i = 0, il = bones.length; i < il; i ++ ) {\n\n\t\t\t// compute the offset between the current and the original transform\n\n\t\t\tconst matrix = bones[ i ] ? bones[ i ].matrixWorld : _identityMatrix;\n\n\t\t\t_offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] );\n\t\t\t_offsetMatrix.toArray( boneMatrices, i * 16 );\n\n\t\t}\n\n\t\tif ( boneTexture !== null ) {\n\n\t\t\tboneTexture.needsUpdate = true;\n\n\t\t}\n\n\t}\n\n\tclone() {\n\n\t\treturn new Skeleton( this.bones, this.boneInverses );\n\n\t}\n\n\tcomputeBoneTexture() {\n\n\t\t// layout (1 matrix = 4 pixels)\n\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\t\tlet size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\tsize = ceilPowerOfTwo( size );\n\t\tsize = Math.max( size, 4 );\n\n\t\tconst boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel\n\t\tboneMatrices.set( this.boneMatrices ); // copy current values\n\n\t\tconst boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType );\n\t\tboneTexture.needsUpdate = true;\n\n\t\tthis.boneMatrices = boneMatrices;\n\t\tthis.boneTexture = boneTexture;\n\t\tthis.boneTextureSize = size;\n\n\t\treturn this;\n\n\t}\n\n\tgetBoneByName( name ) {\n\n\t\tfor ( let i = 0, il = this.bones.length; i < il; i ++ ) {\n\n\t\t\tconst bone = this.bones[ i ];\n\n\t\t\tif ( bone.name === name ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn undefined;\n\n\t}\n\n\tdispose( ) {\n\n\t\tif ( this.boneTexture !== null ) {\n\n\t\t\tthis.boneTexture.dispose();\n\n\t\t\tthis.boneTexture = null;\n\n\t\t}\n\n\t}\n\n\tfromJSON( json, bones ) {\n\n\t\tthis.uuid = json.uuid;\n\n\t\tfor ( let i = 0, l = json.bones.length; i < l; i ++ ) {\n\n\t\t\tconst uuid = json.bones[ i ];\n\t\t\tlet bone = bones[ uuid ];\n\n\t\t\tif ( bone === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton: No bone found with UUID:', uuid );\n\t\t\t\tbone = new Bone();\n\n\t\t\t}\n\n\t\t\tthis.bones.push( bone );\n\t\t\tthis.boneInverses.push( new Matrix4().fromArray( json.boneInverses[ i ] ) );\n\n\t\t}\n\n\t\tthis.init();\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = {\n\t\t\tmetadata: {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'Skeleton',\n\t\t\t\tgenerator: 'Skeleton.toJSON'\n\t\t\t},\n\t\t\tbones: [],\n\t\t\tboneInverses: []\n\t\t};\n\n\t\tdata.uuid = this.uuid;\n\n\t\tconst bones = this.bones;\n\t\tconst boneInverses = this.boneInverses;\n\n\t\tfor ( let i = 0, l = bones.length; i < l; i ++ ) {\n\n\t\t\tconst bone = bones[ i ];\n\t\t\tdata.bones.push( bone.uuid );\n\n\t\t\tconst boneInverse = boneInverses[ i ];\n\t\t\tdata.boneInverses.push( boneInverse.toArray() );\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n}\n\nclass InstancedBufferAttribute extends BufferAttribute {\n\n\tconstructor( array, itemSize, normalized, meshPerAttribute = 1 ) {\n\n\t\tif ( typeof normalized === 'number' ) {\n\n\t\t\tmeshPerAttribute = normalized;\n\n\t\t\tnormalized = false;\n\n\t\t\tconsole.error( 'THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.' );\n\n\t\t}\n\n\t\tsuper( array, itemSize, normalized );\n\n\t\tthis.isInstancedBufferAttribute = true;\n\n\t\tthis.meshPerAttribute = meshPerAttribute;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.meshPerAttribute = this.meshPerAttribute;\n\n\t\tdata.isInstancedBufferAttribute = true;\n\n\t\treturn data;\n\n\t}\n\n}\n\nconst _instanceLocalMatrix = /*@__PURE__*/ new Matrix4();\nconst _instanceWorldMatrix = /*@__PURE__*/ new Matrix4();\n\nconst _instanceIntersects = [];\n\nconst _mesh = /*@__PURE__*/ new Mesh();\n\nclass InstancedMesh extends Mesh {\n\n\tconstructor( geometry, material, count ) {\n\n\t\tsuper( geometry, material );\n\n\t\tthis.isInstancedMesh = true;\n\n\t\tthis.instanceMatrix = new InstancedBufferAttribute( new Float32Array( count * 16 ), 16 );\n\t\tthis.instanceColor = null;\n\n\t\tthis.count = count;\n\n\t\tthis.frustumCulled = false;\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.instanceMatrix.copy( source.instanceMatrix );\n\n\t\tif ( source.instanceColor !== null ) this.instanceColor = source.instanceColor.clone();\n\n\t\tthis.count = source.count;\n\n\t\treturn this;\n\n\t}\n\n\tgetColorAt( index, color ) {\n\n\t\tcolor.fromArray( this.instanceColor.array, index * 3 );\n\n\t}\n\n\tgetMatrixAt( index, matrix ) {\n\n\t\tmatrix.fromArray( this.instanceMatrix.array, index * 16 );\n\n\t}\n\n\traycast( raycaster, intersects ) {\n\n\t\tconst matrixWorld = this.matrixWorld;\n\t\tconst raycastTimes = this.count;\n\n\t\t_mesh.geometry = this.geometry;\n\t\t_mesh.material = this.material;\n\n\t\tif ( _mesh.material === undefined ) return;\n\n\t\tfor ( let instanceId = 0; instanceId < raycastTimes; instanceId ++ ) {\n\n\t\t\t// calculate the world matrix for each instance\n\n\t\t\tthis.getMatrixAt( instanceId, _instanceLocalMatrix );\n\n\t\t\t_instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix );\n\n\t\t\t// the mesh represents this single instance\n\n\t\t\t_mesh.matrixWorld = _instanceWorldMatrix;\n\n\t\t\t_mesh.raycast( raycaster, _instanceIntersects );\n\n\t\t\t// process the result of raycast\n\n\t\t\tfor ( let i = 0, l = _instanceIntersects.length; i < l; i ++ ) {\n\n\t\t\t\tconst intersect = _instanceIntersects[ i ];\n\t\t\t\tintersect.instanceId = instanceId;\n\t\t\t\tintersect.object = this;\n\t\t\t\tintersects.push( intersect );\n\n\t\t\t}\n\n\t\t\t_instanceIntersects.length = 0;\n\n\t\t}\n\n\t}\n\n\tsetColorAt( index, color ) {\n\n\t\tif ( this.instanceColor === null ) {\n\n\t\t\tthis.instanceColor = new InstancedBufferAttribute( new Float32Array( this.instanceMatrix.count * 3 ), 3 );\n\n\t\t}\n\n\t\tcolor.toArray( this.instanceColor.array, index * 3 );\n\n\t}\n\n\tsetMatrixAt( index, matrix ) {\n\n\t\tmatrix.toArray( this.instanceMatrix.array, index * 16 );\n\n\t}\n\n\tupdateMorphTargets() {\n\n\t}\n\n\tdispose() {\n\n\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t}\n\n}\n\nclass LineBasicMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isLineBasicMaterial = true;\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst _start$1 = /*@__PURE__*/ new Vector3();\nconst _end$1 = /*@__PURE__*/ new Vector3();\nconst _inverseMatrix$1 = /*@__PURE__*/ new Matrix4();\nconst _ray$1 = /*@__PURE__*/ new Ray();\nconst _sphere$1 = /*@__PURE__*/ new Sphere();\n\nclass Line extends Object3D {\n\n\tconstructor( geometry = new BufferGeometry(), material = new LineBasicMaterial() ) {\n\n\t\tsuper();\n\n\t\tthis.isLine = true;\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry;\n\t\tthis.material = material;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.material = source.material;\n\t\tthis.geometry = source.geometry;\n\n\t\treturn this;\n\n\t}\n\n\tcomputeLineDistances() {\n\n\t\tconst geometry = this.geometry;\n\n\t\t// we assume non-indexed geometry\n\n\t\tif ( geometry.index === null ) {\n\n\t\t\tconst positionAttribute = geometry.attributes.position;\n\t\t\tconst lineDistances = [ 0 ];\n\n\t\t\tfor ( let i = 1, l = positionAttribute.count; i < l; i ++ ) {\n\n\t\t\t\t_start$1.fromBufferAttribute( positionAttribute, i - 1 );\n\t\t\t\t_end$1.fromBufferAttribute( positionAttribute, i );\n\n\t\t\t\tlineDistances[ i ] = lineDistances[ i - 1 ];\n\t\t\t\tlineDistances[ i ] += _start$1.distanceTo( _end$1 );\n\n\t\t\t}\n\n\t\t\tgeometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\traycast( raycaster, intersects ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst matrixWorld = this.matrixWorld;\n\t\tconst threshold = raycaster.params.Line.threshold;\n\t\tconst drawRange = geometry.drawRange;\n\n\t\t// Checking boundingSphere distance to ray\n\n\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t_sphere$1.copy( geometry.boundingSphere );\n\t\t_sphere$1.applyMatrix4( matrixWorld );\n\t\t_sphere$1.radius += threshold;\n\n\t\tif ( raycaster.ray.intersectsSphere( _sphere$1 ) === false ) return;\n\n\t\t//\n\n\t\t_inverseMatrix$1.copy( matrixWorld ).invert();\n\t\t_ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 );\n\n\t\tconst localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\tconst localThresholdSq = localThreshold * localThreshold;\n\n\t\tconst vStart = new Vector3();\n\t\tconst vEnd = new Vector3();\n\t\tconst interSegment = new Vector3();\n\t\tconst interRay = new Vector3();\n\t\tconst step = this.isLineSegments ? 2 : 1;\n\n\t\tconst index = geometry.index;\n\t\tconst attributes = geometry.attributes;\n\t\tconst positionAttribute = attributes.position;\n\n\t\tif ( index !== null ) {\n\n\t\t\tconst start = Math.max( 0, drawRange.start );\n\t\t\tconst end = Math.min( index.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( let i = start, l = end - 1; i < l; i += step ) {\n\n\t\t\t\tconst a = index.getX( i );\n\t\t\t\tconst b = index.getX( i + 1 );\n\n\t\t\t\tvStart.fromBufferAttribute( positionAttribute, a );\n\t\t\t\tvEnd.fromBufferAttribute( positionAttribute, b );\n\n\t\t\t\tconst distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\tif ( distSq > localThresholdSq ) continue;\n\n\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\tconst distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\tindex: i,\n\t\t\t\t\tface: null,\n\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst start = Math.max( 0, drawRange.start );\n\t\t\tconst end = Math.min( positionAttribute.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( let i = start, l = end - 1; i < l; i += step ) {\n\n\t\t\t\tvStart.fromBufferAttribute( positionAttribute, i );\n\t\t\t\tvEnd.fromBufferAttribute( positionAttribute, i + 1 );\n\n\t\t\t\tconst distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\tif ( distSq > localThresholdSq ) continue;\n\n\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\tconst distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\tindex: i,\n\t\t\t\t\tface: null,\n\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tupdateMorphTargets() {\n\n\t\tconst geometry = this.geometry;\n\n\t\tconst morphAttributes = geometry.morphAttributes;\n\t\tconst keys = Object.keys( morphAttributes );\n\n\t\tif ( keys.length > 0 ) {\n\n\t\t\tconst morphAttribute = morphAttributes[ keys[ 0 ] ];\n\n\t\t\tif ( morphAttribute !== undefined ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {\n\n\t\t\t\t\tconst name = morphAttribute[ m ].name || String( m );\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n}\n\nconst _start = /*@__PURE__*/ new Vector3();\nconst _end = /*@__PURE__*/ new Vector3();\n\nclass LineSegments extends Line {\n\n\tconstructor( geometry, material ) {\n\n\t\tsuper( geometry, material );\n\n\t\tthis.isLineSegments = true;\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tcomputeLineDistances() {\n\n\t\tconst geometry = this.geometry;\n\n\t\t// we assume non-indexed geometry\n\n\t\tif ( geometry.index === null ) {\n\n\t\t\tconst positionAttribute = geometry.attributes.position;\n\t\t\tconst lineDistances = [];\n\n\t\t\tfor ( let i = 0, l = positionAttribute.count; i < l; i += 2 ) {\n\n\t\t\t\t_start.fromBufferAttribute( positionAttribute, i );\n\t\t\t\t_end.fromBufferAttribute( positionAttribute, i + 1 );\n\n\t\t\t\tlineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];\n\t\t\t\tlineDistances[ i + 1 ] = lineDistances[ i ] + _start.distanceTo( _end );\n\n\t\t\t}\n\n\t\t\tgeometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass LineLoop extends Line {\n\n\tconstructor( geometry, material ) {\n\n\t\tsuper( geometry, material );\n\n\t\tthis.isLineLoop = true;\n\n\t\tthis.type = 'LineLoop';\n\n\t}\n\n}\n\nclass PointsMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isPointsMaterial = true;\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst _inverseMatrix = /*@__PURE__*/ new Matrix4();\nconst _ray = /*@__PURE__*/ new Ray();\nconst _sphere = /*@__PURE__*/ new Sphere();\nconst _position$2 = /*@__PURE__*/ new Vector3();\n\nclass Points extends Object3D {\n\n\tconstructor( geometry = new BufferGeometry(), material = new PointsMaterial() ) {\n\n\t\tsuper();\n\n\t\tthis.isPoints = true;\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry;\n\t\tthis.material = material;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.material = source.material;\n\t\tthis.geometry = source.geometry;\n\n\t\treturn this;\n\n\t}\n\n\traycast( raycaster, intersects ) {\n\n\t\tconst geometry = this.geometry;\n\t\tconst matrixWorld = this.matrixWorld;\n\t\tconst threshold = raycaster.params.Points.threshold;\n\t\tconst drawRange = geometry.drawRange;\n\n\t\t// Checking boundingSphere distance to ray\n\n\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t_sphere.copy( geometry.boundingSphere );\n\t\t_sphere.applyMatrix4( matrixWorld );\n\t\t_sphere.radius += threshold;\n\n\t\tif ( raycaster.ray.intersectsSphere( _sphere ) === false ) return;\n\n\t\t//\n\n\t\t_inverseMatrix.copy( matrixWorld ).invert();\n\t\t_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );\n\n\t\tconst localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\tconst localThresholdSq = localThreshold * localThreshold;\n\n\t\tconst index = geometry.index;\n\t\tconst attributes = geometry.attributes;\n\t\tconst positionAttribute = attributes.position;\n\n\t\tif ( index !== null ) {\n\n\t\t\tconst start = Math.max( 0, drawRange.start );\n\t\t\tconst end = Math.min( index.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( let i = start, il = end; i < il; i ++ ) {\n\n\t\t\t\tconst a = index.getX( i );\n\n\t\t\t\t_position$2.fromBufferAttribute( positionAttribute, a );\n\n\t\t\t\ttestPoint( _position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconst start = Math.max( 0, drawRange.start );\n\t\t\tconst end = Math.min( positionAttribute.count, ( drawRange.start + drawRange.count ) );\n\n\t\t\tfor ( let i = start, l = end; i < l; i ++ ) {\n\n\t\t\t\t_position$2.fromBufferAttribute( positionAttribute, i );\n\n\t\t\t\ttestPoint( _position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tupdateMorphTargets() {\n\n\t\tconst geometry = this.geometry;\n\n\t\tconst morphAttributes = geometry.morphAttributes;\n\t\tconst keys = Object.keys( morphAttributes );\n\n\t\tif ( keys.length > 0 ) {\n\n\t\t\tconst morphAttribute = morphAttributes[ keys[ 0 ] ];\n\n\t\t\tif ( morphAttribute !== undefined ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {\n\n\t\t\t\t\tconst name = morphAttribute[ m ].name || String( m );\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n}\n\nfunction testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {\n\n\tconst rayPointDistanceSq = _ray.distanceSqToPoint( point );\n\n\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\tconst intersectPoint = new Vector3();\n\n\t\t_ray.closestPointToPoint( point, intersectPoint );\n\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\tconst distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\tintersects.push( {\n\n\t\t\tdistance: distance,\n\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\tpoint: intersectPoint,\n\t\t\tindex: index,\n\t\t\tface: null,\n\t\t\tobject: object\n\n\t\t} );\n\n\t}\n\n}\n\nclass VideoTexture extends Texture {\n\n\tconstructor( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tsuper( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.isVideoTexture = true;\n\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearFilter;\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\n\t\tthis.generateMipmaps = false;\n\n\t\tconst scope = this;\n\n\t\tfunction updateVideo() {\n\n\t\t\tscope.needsUpdate = true;\n\t\t\tvideo.requestVideoFrameCallback( updateVideo );\n\n\t\t}\n\n\t\tif ( 'requestVideoFrameCallback' in video ) {\n\n\t\t\tvideo.requestVideoFrameCallback( updateVideo );\n\n\t\t}\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor( this.image ).copy( this );\n\n\t}\n\n\tupdate() {\n\n\t\tconst video = this.image;\n\t\tconst hasVideoFrameCallback = 'requestVideoFrameCallback' in video;\n\n\t\tif ( hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\tthis.needsUpdate = true;\n\n\t\t}\n\n\t}\n\n}\n\nclass FramebufferTexture extends Texture {\n\n\tconstructor( width, height, format ) {\n\n\t\tsuper( { width, height } );\n\n\t\tthis.isFramebufferTexture = true;\n\n\t\tthis.format = format;\n\n\t\tthis.magFilter = NearestFilter;\n\t\tthis.minFilter = NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n}\n\nclass CompressedTexture extends Texture {\n\n\tconstructor( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tsuper( null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.isCompressedTexture = true;\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n}\n\nclass CanvasTexture extends Texture {\n\n\tconstructor( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tsuper( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.isCanvasTexture = true;\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n}\n\n/**\n * Extensible curve object.\n *\n * Some common of curve methods:\n * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget )\n * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget )\n * .getPoints(), .getSpacedPoints()\n * .getLength()\n * .updateArcLengths()\n *\n * This following curves inherit from THREE.Curve:\n *\n * -- 2D curves --\n * THREE.ArcCurve\n * THREE.CubicBezierCurve\n * THREE.EllipseCurve\n * THREE.LineCurve\n * THREE.QuadraticBezierCurve\n * THREE.SplineCurve\n *\n * -- 3D curves --\n * THREE.CatmullRomCurve3\n * THREE.CubicBezierCurve3\n * THREE.LineCurve3\n * THREE.QuadraticBezierCurve3\n *\n * A series of curves can be represented as a THREE.CurvePath.\n *\n **/\n\nclass Curve {\n\n\tconstructor() {\n\n\t\tthis.type = 'Curve';\n\n\t\tthis.arcLengthDivisions = 200;\n\n\t}\n\n\t// Virtual base class method to overwrite and implement in subclasses\n\t//\t- t [0 .. 1]\n\n\tgetPoint( /* t, optionalTarget */ ) {\n\n\t\tconsole.warn( 'THREE.Curve: .getPoint() not implemented.' );\n\t\treturn null;\n\n\t}\n\n\t// Get point at relative position in curve according to arc length\n\t// - u [0 .. 1]\n\n\tgetPointAt( u, optionalTarget ) {\n\n\t\tconst t = this.getUtoTmapping( u );\n\t\treturn this.getPoint( t, optionalTarget );\n\n\t}\n\n\t// Get sequence of points using getPoint( t )\n\n\tgetPoints( divisions = 5 ) {\n\n\t\tconst points = [];\n\n\t\tfor ( let d = 0; d <= divisions; d ++ ) {\n\n\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t}\n\n\t\treturn points;\n\n\t}\n\n\t// Get sequence of points using getPointAt( u )\n\n\tgetSpacedPoints( divisions = 5 ) {\n\n\t\tconst points = [];\n\n\t\tfor ( let d = 0; d <= divisions; d ++ ) {\n\n\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t}\n\n\t\treturn points;\n\n\t}\n\n\t// Get total curve arc length\n\n\tgetLength() {\n\n\t\tconst lengths = this.getLengths();\n\t\treturn lengths[ lengths.length - 1 ];\n\n\t}\n\n\t// Get list of cumulative segment lengths\n\n\tgetLengths( divisions = this.arcLengthDivisions ) {\n\n\t\tif ( this.cacheArcLengths &&\n\t\t\t( this.cacheArcLengths.length === divisions + 1 ) &&\n\t\t\t! this.needsUpdate ) {\n\n\t\t\treturn this.cacheArcLengths;\n\n\t\t}\n\n\t\tthis.needsUpdate = false;\n\n\t\tconst cache = [];\n\t\tlet current, last = this.getPoint( 0 );\n\t\tlet sum = 0;\n\n\t\tcache.push( 0 );\n\n\t\tfor ( let p = 1; p <= divisions; p ++ ) {\n\n\t\t\tcurrent = this.getPoint( p / divisions );\n\t\t\tsum += current.distanceTo( last );\n\t\t\tcache.push( sum );\n\t\t\tlast = current;\n\n\t\t}\n\n\t\tthis.cacheArcLengths = cache;\n\n\t\treturn cache; // { sums: cache, sum: sum }; Sum is in the last element.\n\n\t}\n\n\tupdateArcLengths() {\n\n\t\tthis.needsUpdate = true;\n\t\tthis.getLengths();\n\n\t}\n\n\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\tgetUtoTmapping( u, distance ) {\n\n\t\tconst arcLengths = this.getLengths();\n\n\t\tlet i = 0;\n\t\tconst il = arcLengths.length;\n\n\t\tlet targetArcLength; // The targeted u distance value to get\n\n\t\tif ( distance ) {\n\n\t\t\ttargetArcLength = distance;\n\n\t\t} else {\n\n\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t}\n\n\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\tlet low = 0, high = il - 1, comparison;\n\n\t\twhile ( low <= high ) {\n\n\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\tlow = i + 1;\n\n\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\thigh = i - 1;\n\n\t\t\t} else {\n\n\t\t\t\thigh = i;\n\t\t\t\tbreak;\n\n\t\t\t\t// DONE\n\n\t\t\t}\n\n\t\t}\n\n\t\ti = high;\n\n\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\treturn i / ( il - 1 );\n\n\t\t}\n\n\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\tconst lengthBefore = arcLengths[ i ];\n\t\tconst lengthAfter = arcLengths[ i + 1 ];\n\n\t\tconst segmentLength = lengthAfter - lengthBefore;\n\n\t\t// determine where we are between the 'before' and 'after' points\n\n\t\tconst segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t// add that fractional amount to t\n\n\t\tconst t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\treturn t;\n\n\t}\n\n\t// Returns a unit vector tangent at t\n\t// In case any sub curve does not implement its tangent derivation,\n\t// 2 points a small delta apart will be used to find its gradient\n\t// which seems to give a reasonable approximation\n\n\tgetTangent( t, optionalTarget ) {\n\n\t\tconst delta = 0.0001;\n\t\tlet t1 = t - delta;\n\t\tlet t2 = t + delta;\n\n\t\t// Capping in case of danger\n\n\t\tif ( t1 < 0 ) t1 = 0;\n\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\tconst pt1 = this.getPoint( t1 );\n\t\tconst pt2 = this.getPoint( t2 );\n\n\t\tconst tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() );\n\n\t\ttangent.copy( pt2 ).sub( pt1 ).normalize();\n\n\t\treturn tangent;\n\n\t}\n\n\tgetTangentAt( u, optionalTarget ) {\n\n\t\tconst t = this.getUtoTmapping( u );\n\t\treturn this.getTangent( t, optionalTarget );\n\n\t}\n\n\tcomputeFrenetFrames( segments, closed ) {\n\n\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\tconst normal = new Vector3();\n\n\t\tconst tangents = [];\n\t\tconst normals = [];\n\t\tconst binormals = [];\n\n\t\tconst vec = new Vector3();\n\t\tconst mat = new Matrix4();\n\n\t\t// compute the tangent vectors for each segment on the curve\n\n\t\tfor ( let i = 0; i <= segments; i ++ ) {\n\n\t\t\tconst u = i / segments;\n\n\t\t\ttangents[ i ] = this.getTangentAt( u, new Vector3() );\n\n\t\t}\n\n\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t// and in the direction of the minimum tangent xyz component\n\n\t\tnormals[ 0 ] = new Vector3();\n\t\tbinormals[ 0 ] = new Vector3();\n\t\tlet min = Number.MAX_VALUE;\n\t\tconst tx = Math.abs( tangents[ 0 ].x );\n\t\tconst ty = Math.abs( tangents[ 0 ].y );\n\t\tconst tz = Math.abs( tangents[ 0 ].z );\n\n\t\tif ( tx <= min ) {\n\n\t\t\tmin = tx;\n\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t}\n\n\t\tif ( ty <= min ) {\n\n\t\t\tmin = ty;\n\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t}\n\n\t\tif ( tz <= min ) {\n\n\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t}\n\n\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\tfor ( let i = 1; i <= segments; i ++ ) {\n\n\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\tvec.normalize();\n\n\t\t\t\tconst theta = Math.acos( clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t}\n\n\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t}\n\n\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\tif ( closed === true ) {\n\n\t\t\tlet theta = Math.acos( clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\ttheta /= segments;\n\n\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\ttheta = - theta;\n\n\t\t\t}\n\n\t\t\tfor ( let i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t// twist a little...\n\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttangents: tangents,\n\t\t\tnormals: normals,\n\t\t\tbinormals: binormals\n\t\t};\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.arcLengthDivisions = source.arcLengthDivisions;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = {\n\t\t\tmetadata: {\n\t\t\t\tversion: 4.5,\n\t\t\t\ttype: 'Curve',\n\t\t\t\tgenerator: 'Curve.toJSON'\n\t\t\t}\n\t\t};\n\n\t\tdata.arcLengthDivisions = this.arcLengthDivisions;\n\t\tdata.type = this.type;\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tthis.arcLengthDivisions = json.arcLengthDivisions;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass EllipseCurve extends Curve {\n\n\tconstructor( aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0 ) {\n\n\t\tsuper();\n\n\t\tthis.isEllipseCurve = true;\n\n\t\tthis.type = 'EllipseCurve';\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation;\n\n\t}\n\n\tgetPoint( t, optionalTarget ) {\n\n\t\tconst point = optionalTarget || new Vector2();\n\n\t\tconst twoPi = Math.PI * 2;\n\t\tlet deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tconst samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst angle = this.aStartAngle + t * deltaAngle;\n\t\tlet x = this.aX + this.xRadius * Math.cos( angle );\n\t\tlet y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tconst cos = Math.cos( this.aRotation );\n\t\t\tconst sin = Math.sin( this.aRotation );\n\n\t\t\tconst tx = x - this.aX;\n\t\t\tconst ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn point.set( x, y );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.aX = source.aX;\n\t\tthis.aY = source.aY;\n\n\t\tthis.xRadius = source.xRadius;\n\t\tthis.yRadius = source.yRadius;\n\n\t\tthis.aStartAngle = source.aStartAngle;\n\t\tthis.aEndAngle = source.aEndAngle;\n\n\t\tthis.aClockwise = source.aClockwise;\n\n\t\tthis.aRotation = source.aRotation;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.aX = this.aX;\n\t\tdata.aY = this.aY;\n\n\t\tdata.xRadius = this.xRadius;\n\t\tdata.yRadius = this.yRadius;\n\n\t\tdata.aStartAngle = this.aStartAngle;\n\t\tdata.aEndAngle = this.aEndAngle;\n\n\t\tdata.aClockwise = this.aClockwise;\n\n\t\tdata.aRotation = this.aRotation;\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.aX = json.aX;\n\t\tthis.aY = json.aY;\n\n\t\tthis.xRadius = json.xRadius;\n\t\tthis.yRadius = json.yRadius;\n\n\t\tthis.aStartAngle = json.aStartAngle;\n\t\tthis.aEndAngle = json.aEndAngle;\n\n\t\tthis.aClockwise = json.aClockwise;\n\n\t\tthis.aRotation = json.aRotation;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass ArcCurve extends EllipseCurve {\n\n\tconstructor( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tsuper( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\tthis.isArcCurve = true;\n\n\t\tthis.type = 'ArcCurve';\n\n\t}\n\n}\n\n/**\n * Centripetal CatmullRom Curve - which is useful for avoiding\n * cusps and self-intersections in non-uniform catmull rom curves.\n * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n *\n * curve.type accepts centripetal(default), chordal and catmullrom\n * curve.tension is used for catmullrom which defaults to 0.5\n */\n\n\n/*\nBased on an optimized c++ solution in\n - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n - http://ideone.com/NoEbVM\n\nThis CubicPoly class could be used for reusing some variables and calculations,\nbut for three.js curve use, it could be possible inlined and flatten into a single function call\nwhich can be placed in CurveUtils.\n*/\n\nfunction CubicPoly() {\n\n\tlet c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t/*\n\t * Compute coefficients for a cubic polynomial\n\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t * such that\n\t * p(0) = x0, p(1) = x1\n\t * and\n\t * p'(0) = t0, p'(1) = t1.\n\t */\n\tfunction init( x0, x1, t0, t1 ) {\n\n\t\tc0 = x0;\n\t\tc1 = t0;\n\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t}\n\n\treturn {\n\n\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t},\n\n\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\tlet t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\tlet t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\tt1 *= dt1;\n\t\t\tt2 *= dt1;\n\n\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t},\n\n\t\tcalc: function ( t ) {\n\n\t\t\tconst t2 = t * t;\n\t\t\tconst t3 = t2 * t;\n\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t}\n\n\t};\n\n}\n\n//\n\nconst tmp = new Vector3();\nconst px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly();\n\nclass CatmullRomCurve3 extends Curve {\n\n\tconstructor( points = [], closed = false, curveType = 'centripetal', tension = 0.5 ) {\n\n\t\tsuper();\n\n\t\tthis.isCatmullRomCurve3 = true;\n\n\t\tthis.type = 'CatmullRomCurve3';\n\n\t\tthis.points = points;\n\t\tthis.closed = closed;\n\t\tthis.curveType = curveType;\n\t\tthis.tension = tension;\n\n\t}\n\n\tgetPoint( t, optionalTarget = new Vector3() ) {\n\n\t\tconst point = optionalTarget;\n\n\t\tconst points = this.points;\n\t\tconst l = points.length;\n\n\t\tconst p = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tlet intPoint = Math.floor( p );\n\t\tlet weight = p - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tlet p0, p3; // 4 points (p1 & p2 defined below)\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tconst p1 = points[ intPoint % l ];\n\t\tconst p2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tconst pow = this.curveType === 'chordal' ? 0.5 : 0.25;\n\t\t\tlet dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tlet dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tlet dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.curveType === 'catmullrom' ) {\n\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension );\n\n\t\t}\n\n\t\tpoint.set(\n\t\t\tpx.calc( weight ),\n\t\t\tpy.calc( weight ),\n\t\t\tpz.calc( weight )\n\t\t);\n\n\t\treturn point;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.points = [];\n\n\t\tfor ( let i = 0, l = source.points.length; i < l; i ++ ) {\n\n\t\t\tconst point = source.points[ i ];\n\n\t\t\tthis.points.push( point.clone() );\n\n\t\t}\n\n\t\tthis.closed = source.closed;\n\t\tthis.curveType = source.curveType;\n\t\tthis.tension = source.tension;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.points = [];\n\n\t\tfor ( let i = 0, l = this.points.length; i < l; i ++ ) {\n\n\t\t\tconst point = this.points[ i ];\n\t\t\tdata.points.push( point.toArray() );\n\n\t\t}\n\n\t\tdata.closed = this.closed;\n\t\tdata.curveType = this.curveType;\n\t\tdata.tension = this.tension;\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.points = [];\n\n\t\tfor ( let i = 0, l = json.points.length; i < l; i ++ ) {\n\n\t\t\tconst point = json.points[ i ];\n\t\t\tthis.points.push( new Vector3().fromArray( point ) );\n\n\t\t}\n\n\t\tthis.closed = json.closed;\n\t\tthis.curveType = json.curveType;\n\t\tthis.tension = json.tension;\n\n\t\treturn this;\n\n\t}\n\n}\n\n/**\n * Bezier Curves formulas obtained from\n * https://en.wikipedia.org/wiki/B%C3%A9zier_curve\n */\n\nfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\tconst v0 = ( p2 - p0 ) * 0.5;\n\tconst v1 = ( p3 - p1 ) * 0.5;\n\tconst t2 = t * t;\n\tconst t3 = t * t2;\n\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n}\n\n//\n\nfunction QuadraticBezierP0( t, p ) {\n\n\tconst k = 1 - t;\n\treturn k * k * p;\n\n}\n\nfunction QuadraticBezierP1( t, p ) {\n\n\treturn 2 * ( 1 - t ) * t * p;\n\n}\n\nfunction QuadraticBezierP2( t, p ) {\n\n\treturn t * t * p;\n\n}\n\nfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\tQuadraticBezierP2( t, p2 );\n\n}\n\n//\n\nfunction CubicBezierP0( t, p ) {\n\n\tconst k = 1 - t;\n\treturn k * k * k * p;\n\n}\n\nfunction CubicBezierP1( t, p ) {\n\n\tconst k = 1 - t;\n\treturn 3 * k * k * t * p;\n\n}\n\nfunction CubicBezierP2( t, p ) {\n\n\treturn 3 * ( 1 - t ) * t * t * p;\n\n}\n\nfunction CubicBezierP3( t, p ) {\n\n\treturn t * t * t * p;\n\n}\n\nfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\tCubicBezierP3( t, p3 );\n\n}\n\nclass CubicBezierCurve extends Curve {\n\n\tconstructor( v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2() ) {\n\n\t\tsuper();\n\n\t\tthis.isCubicBezierCurve = true;\n\n\t\tthis.type = 'CubicBezierCurve';\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tgetPoint( t, optionalTarget = new Vector2() ) {\n\n\t\tconst point = optionalTarget;\n\n\t\tconst v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\tpoint.set(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t\treturn point;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.v0.copy( source.v0 );\n\t\tthis.v1.copy( source.v1 );\n\t\tthis.v2.copy( source.v2 );\n\t\tthis.v3.copy( source.v3 );\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.v0 = this.v0.toArray();\n\t\tdata.v1 = this.v1.toArray();\n\t\tdata.v2 = this.v2.toArray();\n\t\tdata.v3 = this.v3.toArray();\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.v0.fromArray( json.v0 );\n\t\tthis.v1.fromArray( json.v1 );\n\t\tthis.v2.fromArray( json.v2 );\n\t\tthis.v3.fromArray( json.v3 );\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass CubicBezierCurve3 extends Curve {\n\n\tconstructor( v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3() ) {\n\n\t\tsuper();\n\n\t\tthis.isCubicBezierCurve3 = true;\n\n\t\tthis.type = 'CubicBezierCurve3';\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tgetPoint( t, optionalTarget = new Vector3() ) {\n\n\t\tconst point = optionalTarget;\n\n\t\tconst v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\tpoint.set(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t\treturn point;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.v0.copy( source.v0 );\n\t\tthis.v1.copy( source.v1 );\n\t\tthis.v2.copy( source.v2 );\n\t\tthis.v3.copy( source.v3 );\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.v0 = this.v0.toArray();\n\t\tdata.v1 = this.v1.toArray();\n\t\tdata.v2 = this.v2.toArray();\n\t\tdata.v3 = this.v3.toArray();\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.v0.fromArray( json.v0 );\n\t\tthis.v1.fromArray( json.v1 );\n\t\tthis.v2.fromArray( json.v2 );\n\t\tthis.v3.fromArray( json.v3 );\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass LineCurve extends Curve {\n\n\tconstructor( v1 = new Vector2(), v2 = new Vector2() ) {\n\n\t\tsuper();\n\n\t\tthis.isLineCurve = true;\n\n\t\tthis.type = 'LineCurve';\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tgetPoint( t, optionalTarget = new Vector2() ) {\n\n\t\tconst point = optionalTarget;\n\n\t\tif ( t === 1 ) {\n\n\t\t\tpoint.copy( this.v2 );\n\n\t\t} else {\n\n\t\t\tpoint.copy( this.v2 ).sub( this.v1 );\n\t\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\t}\n\n\t\treturn point;\n\n\t}\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\tgetPointAt( u, optionalTarget ) {\n\n\t\treturn this.getPoint( u, optionalTarget );\n\n\t}\n\n\tgetTangent( t, optionalTarget ) {\n\n\t\tconst tangent = optionalTarget || new Vector2();\n\n\t\ttangent.copy( this.v2 ).sub( this.v1 ).normalize();\n\n\t\treturn tangent;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.v1.copy( source.v1 );\n\t\tthis.v2.copy( source.v2 );\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.v1 = this.v1.toArray();\n\t\tdata.v2 = this.v2.toArray();\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.v1.fromArray( json.v1 );\n\t\tthis.v2.fromArray( json.v2 );\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass LineCurve3 extends Curve {\n\n\tconstructor( v1 = new Vector3(), v2 = new Vector3() ) {\n\n\t\tsuper();\n\n\t\tthis.isLineCurve3 = true;\n\n\t\tthis.type = 'LineCurve3';\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\tgetPoint( t, optionalTarget = new Vector3() ) {\n\n\t\tconst point = optionalTarget;\n\n\t\tif ( t === 1 ) {\n\n\t\t\tpoint.copy( this.v2 );\n\n\t\t} else {\n\n\t\t\tpoint.copy( this.v2 ).sub( this.v1 );\n\t\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\t}\n\n\t\treturn point;\n\n\t}\n\t// Line curve is linear, so we can overwrite default getPointAt\n\tgetPointAt( u, optionalTarget ) {\n\n\t\treturn this.getPoint( u, optionalTarget );\n\n\t}\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.v1.copy( source.v1 );\n\t\tthis.v2.copy( source.v2 );\n\n\t\treturn this;\n\n\t}\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.v1 = this.v1.toArray();\n\t\tdata.v2 = this.v2.toArray();\n\n\t\treturn data;\n\n\t}\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.v1.fromArray( json.v1 );\n\t\tthis.v2.fromArray( json.v2 );\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass QuadraticBezierCurve extends Curve {\n\n\tconstructor( v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2() ) {\n\n\t\tsuper();\n\n\t\tthis.isQuadraticBezierCurve = true;\n\n\t\tthis.type = 'QuadraticBezierCurve';\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tgetPoint( t, optionalTarget = new Vector2() ) {\n\n\t\tconst point = optionalTarget;\n\n\t\tconst v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\tpoint.set(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t\treturn point;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.v0.copy( source.v0 );\n\t\tthis.v1.copy( source.v1 );\n\t\tthis.v2.copy( source.v2 );\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.v0 = this.v0.toArray();\n\t\tdata.v1 = this.v1.toArray();\n\t\tdata.v2 = this.v2.toArray();\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.v0.fromArray( json.v0 );\n\t\tthis.v1.fromArray( json.v1 );\n\t\tthis.v2.fromArray( json.v2 );\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass QuadraticBezierCurve3 extends Curve {\n\n\tconstructor( v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3() ) {\n\n\t\tsuper();\n\n\t\tthis.isQuadraticBezierCurve3 = true;\n\n\t\tthis.type = 'QuadraticBezierCurve3';\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tgetPoint( t, optionalTarget = new Vector3() ) {\n\n\t\tconst point = optionalTarget;\n\n\t\tconst v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\tpoint.set(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t\treturn point;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.v0.copy( source.v0 );\n\t\tthis.v1.copy( source.v1 );\n\t\tthis.v2.copy( source.v2 );\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.v0 = this.v0.toArray();\n\t\tdata.v1 = this.v1.toArray();\n\t\tdata.v2 = this.v2.toArray();\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.v0.fromArray( json.v0 );\n\t\tthis.v1.fromArray( json.v1 );\n\t\tthis.v2.fromArray( json.v2 );\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass SplineCurve extends Curve {\n\n\tconstructor( points = [] ) {\n\n\t\tsuper();\n\n\t\tthis.isSplineCurve = true;\n\n\t\tthis.type = 'SplineCurve';\n\n\t\tthis.points = points;\n\n\t}\n\n\tgetPoint( t, optionalTarget = new Vector2() ) {\n\n\t\tconst point = optionalTarget;\n\n\t\tconst points = this.points;\n\t\tconst p = ( points.length - 1 ) * t;\n\n\t\tconst intPoint = Math.floor( p );\n\t\tconst weight = p - intPoint;\n\n\t\tconst p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tconst p1 = points[ intPoint ];\n\t\tconst p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tconst p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\tpoint.set(\n\t\t\tCatmullRom( weight, p0.x, p1.x, p2.x, p3.x ),\n\t\t\tCatmullRom( weight, p0.y, p1.y, p2.y, p3.y )\n\t\t);\n\n\t\treturn point;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.points = [];\n\n\t\tfor ( let i = 0, l = source.points.length; i < l; i ++ ) {\n\n\t\t\tconst point = source.points[ i ];\n\n\t\t\tthis.points.push( point.clone() );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.points = [];\n\n\t\tfor ( let i = 0, l = this.points.length; i < l; i ++ ) {\n\n\t\t\tconst point = this.points[ i ];\n\t\t\tdata.points.push( point.toArray() );\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.points = [];\n\n\t\tfor ( let i = 0, l = json.points.length; i < l; i ++ ) {\n\n\t\t\tconst point = json.points[ i ];\n\t\t\tthis.points.push( new Vector2().fromArray( point ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nvar Curves = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tArcCurve: ArcCurve,\n\tCatmullRomCurve3: CatmullRomCurve3,\n\tCubicBezierCurve: CubicBezierCurve,\n\tCubicBezierCurve3: CubicBezierCurve3,\n\tEllipseCurve: EllipseCurve,\n\tLineCurve: LineCurve,\n\tLineCurve3: LineCurve3,\n\tQuadraticBezierCurve: QuadraticBezierCurve,\n\tQuadraticBezierCurve3: QuadraticBezierCurve3,\n\tSplineCurve: SplineCurve\n});\n\n/**************************************************************\n *\tCurved Path - a curve path is simply a array of connected\n * curves, but retains the api of a curve\n **************************************************************/\n\nclass CurvePath extends Curve {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.type = 'CurvePath';\n\n\t\tthis.curves = [];\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tadd( curve ) {\n\n\t\tthis.curves.push( curve );\n\n\t}\n\n\tclosePath() {\n\n\t\t// Add a line curve if start and end of lines are not connected\n\t\tconst startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\tconst endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t}\n\n\t}\n\n\t// To get accurate point with reference to\n\t// entire path distance at time t,\n\t// following has to be done:\n\n\t// 1. Length of each sub path have to be known\n\t// 2. Locate and identify type of curve\n\t// 3. Get t for the curve\n\t// 4. Return curve.getPointAt(t')\n\n\tgetPoint( t, optionalTarget ) {\n\n\t\tconst d = t * this.getLength();\n\t\tconst curveLengths = this.getCurveLengths();\n\t\tlet i = 0;\n\n\t\t// To think about boundaries points.\n\n\t\twhile ( i < curveLengths.length ) {\n\n\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\tconst diff = curveLengths[ i ] - d;\n\t\t\t\tconst curve = this.curves[ i ];\n\n\t\t\t\tconst segmentLength = curve.getLength();\n\t\t\t\tconst u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\treturn curve.getPointAt( u, optionalTarget );\n\n\t\t\t}\n\n\t\t\ti ++;\n\n\t\t}\n\n\t\treturn null;\n\n\t\t// loop where sum != 0, sum > d , sum+1 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\tpoints.push( points[ 0 ] );\n\n\t\t}\n\n\t\treturn points;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.curves = [];\n\n\t\tfor ( let i = 0, l = source.curves.length; i < l; i ++ ) {\n\n\t\t\tconst curve = source.curves[ i ];\n\n\t\t\tthis.curves.push( curve.clone() );\n\n\t\t}\n\n\t\tthis.autoClose = source.autoClose;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.autoClose = this.autoClose;\n\t\tdata.curves = [];\n\n\t\tfor ( let i = 0, l = this.curves.length; i < l; i ++ ) {\n\n\t\t\tconst curve = this.curves[ i ];\n\t\t\tdata.curves.push( curve.toJSON() );\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.autoClose = json.autoClose;\n\t\tthis.curves = [];\n\n\t\tfor ( let i = 0, l = json.curves.length; i < l; i ++ ) {\n\n\t\t\tconst curve = json.curves[ i ];\n\t\t\tthis.curves.push( new Curves[ curve.type ]().fromJSON( curve ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass Path extends CurvePath {\n\n\tconstructor( points ) {\n\n\t\tsuper();\n\t\tthis.type = 'Path';\n\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.setFromPoints( points );\n\n\t\t}\n\n\t}\n\n\tsetFromPoints( points ) {\n\n\t\tthis.moveTo( points[ 0 ].x, points[ 0 ].y );\n\n\t\tfor ( let i = 1, l = points.length; i < l; i ++ ) {\n\n\t\t\tthis.lineTo( points[ i ].x, points[ i ].y );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tmoveTo( x, y ) {\n\n\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\treturn this;\n\n\t}\n\n\tlineTo( x, y ) {\n\n\t\tconst curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\tthis.curves.push( curve );\n\n\t\tthis.currentPoint.set( x, y );\n\n\t\treturn this;\n\n\t}\n\n\tquadraticCurveTo( aCPx, aCPy, aX, aY ) {\n\n\t\tconst curve = new QuadraticBezierCurve(\n\t\t\tthis.currentPoint.clone(),\n\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\tnew Vector2( aX, aY )\n\t\t);\n\n\t\tthis.curves.push( curve );\n\n\t\tthis.currentPoint.set( aX, aY );\n\n\t\treturn this;\n\n\t}\n\n\tbezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\tconst curve = new CubicBezierCurve(\n\t\t\tthis.currentPoint.clone(),\n\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\tnew Vector2( aX, aY )\n\t\t);\n\n\t\tthis.curves.push( curve );\n\n\t\tthis.currentPoint.set( aX, aY );\n\n\t\treturn this;\n\n\t}\n\n\tsplineThru( pts /*Array of Vector*/ ) {\n\n\t\tconst npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\tconst curve = new SplineCurve( npts );\n\t\tthis.curves.push( curve );\n\n\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\treturn this;\n\n\t}\n\n\tarc( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tconst x0 = this.currentPoint.x;\n\t\tconst y0 = this.currentPoint.y;\n\n\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\treturn this;\n\n\t}\n\n\tabsarc( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\treturn this;\n\n\t}\n\n\tellipse( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tconst x0 = this.currentPoint.x;\n\t\tconst y0 = this.currentPoint.y;\n\n\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\treturn this;\n\n\t}\n\n\tabsellipse( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tconst curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t// if a previous curve is present, attempt to join\n\t\t\tconst firstPoint = curve.getPoint( 0 );\n\n\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.curves.push( curve );\n\n\t\tconst lastPoint = curve.getPoint( 1 );\n\t\tthis.currentPoint.copy( lastPoint );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.currentPoint.copy( source.currentPoint );\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.currentPoint = this.currentPoint.toArray();\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.currentPoint.fromArray( json.currentPoint );\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass LatheGeometry extends BufferGeometry {\n\n\tconstructor( points = [ new Vector2( 0, 0.5 ), new Vector2( 0.5, 0 ), new Vector2( 0, - 0.5 ) ], segments = 12, phiStart = 0, phiLength = Math.PI * 2 ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments );\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = clamp( phiLength, 0, Math.PI * 2 );\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst uvs = [];\n\t\tconst initNormals = [];\n\t\tconst normals = [];\n\n\t\t// helper variables\n\n\t\tconst inverseSegments = 1.0 / segments;\n\t\tconst vertex = new Vector3();\n\t\tconst uv = new Vector2();\n\t\tconst normal = new Vector3();\n\t\tconst curNormal = new Vector3();\n\t\tconst prevNormal = new Vector3();\n\t\tlet dx = 0;\n\t\tlet dy = 0;\n\n\t\t// pre-compute normals for initial \"meridian\"\n\n\t\tfor ( let j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\tswitch ( j ) {\n\n\t\t\t\tcase 0:\t\t\t\t// special handling for 1st vertex on path\n\n\t\t\t\t\tdx = points[ j + 1 ].x - points[ j ].x;\n\t\t\t\t\tdy = points[ j + 1 ].y - points[ j ].y;\n\n\t\t\t\t\tnormal.x = dy * 1.0;\n\t\t\t\t\tnormal.y = - dx;\n\t\t\t\t\tnormal.z = dy * 0.0;\n\n\t\t\t\t\tprevNormal.copy( normal );\n\n\t\t\t\t\tnormal.normalize();\n\n\t\t\t\t\tinitNormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase ( points.length - 1 ):\t// special handling for last Vertex on path\n\n\t\t\t\t\tinitNormals.push( prevNormal.x, prevNormal.y, prevNormal.z );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\t\t\t// default handling for all vertices in between\n\n\t\t\t\t\tdx = points[ j + 1 ].x - points[ j ].x;\n\t\t\t\t\tdy = points[ j + 1 ].y - points[ j ].y;\n\n\t\t\t\t\tnormal.x = dy * 1.0;\n\t\t\t\t\tnormal.y = - dx;\n\t\t\t\t\tnormal.z = dy * 0.0;\n\n\t\t\t\t\tcurNormal.copy( normal );\n\n\t\t\t\t\tnormal.x += prevNormal.x;\n\t\t\t\t\tnormal.y += prevNormal.y;\n\t\t\t\t\tnormal.z += prevNormal.z;\n\n\t\t\t\t\tnormal.normalize();\n\n\t\t\t\t\tinitNormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\tprevNormal.copy( curNormal );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices, uvs and normals\n\n\t\tfor ( let i = 0; i <= segments; i ++ ) {\n\n\t\t\tconst phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tconst sin = Math.sin( phi );\n\t\t\tconst cos = Math.cos( phi );\n\n\t\t\tfor ( let j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// normal\n\n\t\t\t\tconst x = initNormals[ 3 * j + 0 ] * sin;\n\t\t\t\tconst y = initNormals[ 3 * j + 1 ];\n\t\t\t\tconst z = initNormals[ 3 * j + 0 ] * cos;\n\n\t\t\t\tnormals.push( x, y, z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( let i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( let j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tconst base = j + i * points.length;\n\n\t\t\t\tconst a = base;\n\t\t\t\tconst b = base + points.length;\n\t\t\t\tconst c = base + points.length + 1;\n\t\t\t\tconst d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( c, d, b );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new LatheGeometry( data.points, data.segments, data.phiStart, data.phiLength );\n\n\t}\n\n}\n\nclass CapsuleGeometry extends LatheGeometry {\n\n\tconstructor( radius = 1, length = 1, capSegments = 4, radialSegments = 8 ) {\n\n\t\tconst path = new Path();\n\t\tpath.absarc( 0, - length / 2, radius, Math.PI * 1.5, 0 );\n\t\tpath.absarc( 0, length / 2, radius, 0, Math.PI * 0.5 );\n\n\t\tsuper( path.getPoints( capSegments ), radialSegments );\n\n\t\tthis.type = 'CapsuleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: length,\n\t\t\tcapSegments: capSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t};\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new CapsuleGeometry( data.radius, data.length, data.capSegments, data.radialSegments );\n\n\t}\n\n}\n\nclass CircleGeometry extends BufferGeometry {\n\n\tconstructor( radius = 1, segments = 8, thetaStart = 0, thetaLength = Math.PI * 2 ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tsegments = Math.max( 3, segments );\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// helper variables\n\n\t\tconst vertex = new Vector3();\n\t\tconst uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( let s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tconst segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( let i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new CircleGeometry( data.radius, data.segments, data.thetaStart, data.thetaLength );\n\n\t}\n\n}\n\nclass CylinderGeometry extends BufferGeometry {\n\n\tconstructor( radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) {\n\n\t\tsuper();\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tconst scope = this;\n\n\t\tradialSegments = Math.floor( radialSegments );\n\t\theightSegments = Math.floor( heightSegments );\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// helper variables\n\n\t\tlet index = 0;\n\t\tconst indexArray = [];\n\t\tconst halfHeight = height / 2;\n\t\tlet groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tconst normal = new Vector3();\n\t\t\tconst vertex = new Vector3();\n\n\t\t\tlet groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tconst slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( let y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tconst indexRow = [];\n\n\t\t\t\tconst v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tconst radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( let x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tconst u = x / radialSegments;\n\n\t\t\t\t\tconst theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tconst sinTheta = Math.sin( theta );\n\t\t\t\t\tconst cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( let x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( let y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tconst a = indexArray[ y ][ x ];\n\t\t\t\t\tconst b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tconst c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tconst d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\t// save the index of the first center vertex\n\t\t\tconst centerIndexStart = index;\n\n\t\t\tconst uv = new Vector2();\n\t\t\tconst vertex = new Vector3();\n\n\t\t\tlet groupCount = 0;\n\n\t\t\tconst radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tconst sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( let x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\t\t\tconst centerIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( let x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tconst u = x / radialSegments;\n\t\t\t\tconst theta = u * thetaLength + thetaStart;\n\n\t\t\t\tconst cosTheta = Math.cos( theta );\n\t\t\t\tconst sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( let x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tconst c = centerIndexStart + x;\n\t\t\t\tconst i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new CylinderGeometry( data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength );\n\n\t}\n\n}\n\nclass ConeGeometry extends CylinderGeometry {\n\n\tconstructor( radius = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) {\n\n\t\tsuper( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new ConeGeometry( data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength );\n\n\t}\n\n}\n\nclass PolyhedronGeometry extends BufferGeometry {\n\n\tconstructor( vertices = [], indices = [], radius = 1, detail = 0 ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\t// default buffer data\n\n\t\tconst vertexBuffer = [];\n\t\tconst uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tapplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\n\t\tif ( detail === 0 ) {\n\n\t\t\tthis.computeVertexNormals(); // flat normals\n\n\t\t} else {\n\n\t\t\tthis.normalizeNormals(); // smooth normals\n\n\t\t}\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tconst a = new Vector3();\n\t\t\tconst b = new Vector3();\n\t\t\tconst c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( let i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tconst cols = detail + 1;\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tconst v = [];\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( let i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tconst aj = a.clone().lerp( c, i / cols );\n\t\t\t\tconst bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tconst rows = cols - i;\n\n\t\t\t\tfor ( let j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( let i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( let j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tconst k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction applyRadius( radius ) {\n\n\t\t\tconst vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( let i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tconst vertex = new Vector3();\n\n\t\t\tfor ( let i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tconst u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tconst v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( let i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tconst x0 = uvBuffer[ i + 0 ];\n\t\t\t\tconst x1 = uvBuffer[ i + 2 ];\n\t\t\t\tconst x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tconst max = Math.max( x0, x1, x2 );\n\t\t\t\tconst min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tconst stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tconst a = new Vector3();\n\t\t\tconst b = new Vector3();\n\t\t\tconst c = new Vector3();\n\n\t\t\tconst centroid = new Vector3();\n\n\t\t\tconst uvA = new Vector2();\n\t\t\tconst uvB = new Vector2();\n\t\t\tconst uvC = new Vector2();\n\n\t\t\tfor ( let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tconst azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new PolyhedronGeometry( data.vertices, data.indices, data.radius, data.details );\n\n\t}\n\n}\n\nclass DodecahedronGeometry extends PolyhedronGeometry {\n\n\tconstructor( radius = 1, detail = 0 ) {\n\n\t\tconst t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tconst r = 1 / t;\n\n\t\tconst vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1,\t- 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t1, - 1, - 1, 1, - 1, 1,\n\t\t\t1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t0, - r, - t, 0, - r, t,\n\t\t\t0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\tr, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tconst indices = [\n\t\t\t3, 11, 7, \t3, 7, 15, \t3, 15, 13,\n\t\t\t7, 19, 17, \t7, 17, 6, \t7, 6, 15,\n\t\t\t17, 4, 8, \t17, 8, 10, \t17, 10, 6,\n\t\t\t8, 0, 16, \t8, 16, 2, \t8, 2, 10,\n\t\t\t0, 12, 1, \t0, 1, 18, \t0, 18, 16,\n\t\t\t6, 10, 2, \t6, 2, 13, \t6, 13, 15,\n\t\t\t2, 16, 18, \t2, 18, 3, \t2, 3, 13,\n\t\t\t18, 1, 9, \t18, 9, 11, \t18, 11, 3,\n\t\t\t4, 14, 12, \t4, 12, 0, \t4, 0, 8,\n\t\t\t11, 9, 5, \t11, 5, 19, \t11, 19, 7,\n\t\t\t19, 5, 14, \t19, 14, 4, \t19, 4, 17,\n\t\t\t1, 12, 14, \t1, 14, 5, \t1, 5, 9\n\t\t];\n\n\t\tsuper( vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new DodecahedronGeometry( data.radius, data.detail );\n\n\t}\n\n}\n\nconst _v0 = new Vector3();\nconst _v1$1 = new Vector3();\nconst _normal = new Vector3();\nconst _triangle = new Triangle();\n\nclass EdgesGeometry extends BufferGeometry {\n\n\tconstructor( geometry = null, thresholdAngle = 1 ) {\n\n\t\tsuper();\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tgeometry: geometry,\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tif ( geometry !== null ) {\n\n\t\t\tconst precisionPoints = 4;\n\t\t\tconst precision = Math.pow( 10, precisionPoints );\n\t\t\tconst thresholdDot = Math.cos( DEG2RAD * thresholdAngle );\n\n\t\t\tconst indexAttr = geometry.getIndex();\n\t\t\tconst positionAttr = geometry.getAttribute( 'position' );\n\t\t\tconst indexCount = indexAttr ? indexAttr.count : positionAttr.count;\n\n\t\t\tconst indexArr = [ 0, 0, 0 ];\n\t\t\tconst vertKeys = [ 'a', 'b', 'c' ];\n\t\t\tconst hashes = new Array( 3 );\n\n\t\t\tconst edgeData = {};\n\t\t\tconst vertices = [];\n\t\t\tfor ( let i = 0; i < indexCount; i += 3 ) {\n\n\t\t\t\tif ( indexAttr ) {\n\n\t\t\t\t\tindexArr[ 0 ] = indexAttr.getX( i );\n\t\t\t\t\tindexArr[ 1 ] = indexAttr.getX( i + 1 );\n\t\t\t\t\tindexArr[ 2 ] = indexAttr.getX( i + 2 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tindexArr[ 0 ] = i;\n\t\t\t\t\tindexArr[ 1 ] = i + 1;\n\t\t\t\t\tindexArr[ 2 ] = i + 2;\n\n\t\t\t\t}\n\n\t\t\t\tconst { a, b, c } = _triangle;\n\t\t\t\ta.fromBufferAttribute( positionAttr, indexArr[ 0 ] );\n\t\t\t\tb.fromBufferAttribute( positionAttr, indexArr[ 1 ] );\n\t\t\t\tc.fromBufferAttribute( positionAttr, indexArr[ 2 ] );\n\t\t\t\t_triangle.getNormal( _normal );\n\n\t\t\t\t// create hashes for the edge from the vertices\n\t\t\t\thashes[ 0 ] = `${ Math.round( a.x * precision ) },${ Math.round( a.y * precision ) },${ Math.round( a.z * precision ) }`;\n\t\t\t\thashes[ 1 ] = `${ Math.round( b.x * precision ) },${ Math.round( b.y * precision ) },${ Math.round( b.z * precision ) }`;\n\t\t\t\thashes[ 2 ] = `${ Math.round( c.x * precision ) },${ Math.round( c.y * precision ) },${ Math.round( c.z * precision ) }`;\n\n\t\t\t\t// skip degenerate triangles\n\t\t\t\tif ( hashes[ 0 ] === hashes[ 1 ] || hashes[ 1 ] === hashes[ 2 ] || hashes[ 2 ] === hashes[ 0 ] ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\t// iterate over every edge\n\t\t\t\tfor ( let j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t// get the first and next vertex making up the edge\n\t\t\t\t\tconst jNext = ( j + 1 ) % 3;\n\t\t\t\t\tconst vecHash0 = hashes[ j ];\n\t\t\t\t\tconst vecHash1 = hashes[ jNext ];\n\t\t\t\t\tconst v0 = _triangle[ vertKeys[ j ] ];\n\t\t\t\t\tconst v1 = _triangle[ vertKeys[ jNext ] ];\n\n\t\t\t\t\tconst hash = `${ vecHash0 }_${ vecHash1 }`;\n\t\t\t\t\tconst reverseHash = `${ vecHash1 }_${ vecHash0 }`;\n\n\t\t\t\t\tif ( reverseHash in edgeData && edgeData[ reverseHash ] ) {\n\n\t\t\t\t\t\t// if we found a sibling edge add it into the vertex array if\n\t\t\t\t\t\t// it meets the angle threshold and delete the edge from the map.\n\t\t\t\t\t\tif ( _normal.dot( edgeData[ reverseHash ].normal ) <= thresholdDot ) {\n\n\t\t\t\t\t\t\tvertices.push( v0.x, v0.y, v0.z );\n\t\t\t\t\t\t\tvertices.push( v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tedgeData[ reverseHash ] = null;\n\n\t\t\t\t\t} else if ( ! ( hash in edgeData ) ) {\n\n\t\t\t\t\t\t// if we've already got an edge here then skip adding a new one\n\t\t\t\t\t\tedgeData[ hash ] = {\n\n\t\t\t\t\t\t\tindex0: indexArr[ j ],\n\t\t\t\t\t\t\tindex1: indexArr[ jNext ],\n\t\t\t\t\t\t\tnormal: _normal.clone(),\n\n\t\t\t\t\t\t};\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// iterate over all remaining, unmatched edges and add them to the vertex array\n\t\t\tfor ( const key in edgeData ) {\n\n\t\t\t\tif ( edgeData[ key ] ) {\n\n\t\t\t\t\tconst { index0, index1 } = edgeData[ key ];\n\t\t\t\t\t_v0.fromBufferAttribute( positionAttr, index0 );\n\t\t\t\t\t_v1$1.fromBufferAttribute( positionAttr, index1 );\n\n\t\t\t\t\tvertices.push( _v0.x, _v0.y, _v0.z );\n\t\t\t\t\tvertices.push( _v1$1.x, _v1$1.y, _v1$1.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t}\n\n\t}\n\n}\n\nclass Shape extends Path {\n\n\tconstructor( points ) {\n\n\t\tsuper( points );\n\n\t\tthis.uuid = generateUUID();\n\n\t\tthis.type = 'Shape';\n\n\t\tthis.holes = [];\n\n\t}\n\n\tgetPointsHoles( divisions ) {\n\n\t\tconst holesPts = [];\n\n\t\tfor ( let i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t}\n\n\t\treturn holesPts;\n\n\t}\n\n\t// get points of shape and holes (keypoints based on segments parameter)\n\n\textractPoints( divisions ) {\n\n\t\treturn {\n\n\t\t\tshape: this.getPoints( divisions ),\n\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t};\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.holes = [];\n\n\t\tfor ( let i = 0, l = source.holes.length; i < l; i ++ ) {\n\n\t\t\tconst hole = source.holes[ i ];\n\n\t\t\tthis.holes.push( hole.clone() );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.uuid = this.uuid;\n\t\tdata.holes = [];\n\n\t\tfor ( let i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\tconst hole = this.holes[ i ];\n\t\t\tdata.holes.push( hole.toJSON() );\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tsuper.fromJSON( json );\n\n\t\tthis.uuid = json.uuid;\n\t\tthis.holes = [];\n\n\t\tfor ( let i = 0, l = json.holes.length; i < l; i ++ ) {\n\n\t\t\tconst hole = json.holes[ i ];\n\t\t\tthis.holes.push( new Path().fromJSON( hole ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\n/**\n * Port from https://github.com/mapbox/earcut (v2.2.2)\n */\n\nconst Earcut = {\n\n\ttriangulate: function ( data, holeIndices, dim = 2 ) {\n\n\t\tconst hasHoles = holeIndices && holeIndices.length;\n\t\tconst outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length;\n\t\tlet outerNode = linkedList( data, 0, outerLen, dim, true );\n\t\tconst triangles = [];\n\n\t\tif ( ! outerNode || outerNode.next === outerNode.prev ) return triangles;\n\n\t\tlet minX, minY, maxX, maxY, x, y, invSize;\n\n\t\tif ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim );\n\n\t\t// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n\t\tif ( data.length > 80 * dim ) {\n\n\t\t\tminX = maxX = data[ 0 ];\n\t\t\tminY = maxY = data[ 1 ];\n\n\t\t\tfor ( let i = dim; i < outerLen; i += dim ) {\n\n\t\t\t\tx = data[ i ];\n\t\t\t\ty = data[ i + 1 ];\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\n\t\t\t}\n\n\t\t\t// minX, minY and invSize are later used to transform coords into integers for z-order calculation\n\t\t\tinvSize = Math.max( maxX - minX, maxY - minY );\n\t\t\tinvSize = invSize !== 0 ? 1 / invSize : 0;\n\n\t\t}\n\n\t\tearcutLinked( outerNode, triangles, dim, minX, minY, invSize );\n\n\t\treturn triangles;\n\n\t}\n\n};\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList( data, start, end, dim, clockwise ) {\n\n\tlet i, last;\n\n\tif ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) {\n\n\t\tfor ( i = start; i < end; i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );\n\n\t} else {\n\n\t\tfor ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );\n\n\t}\n\n\tif ( last && equals( last, last.next ) ) {\n\n\t\tremoveNode( last );\n\t\tlast = last.next;\n\n\t}\n\n\treturn last;\n\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints( start, end ) {\n\n\tif ( ! start ) return start;\n\tif ( ! end ) end = start;\n\n\tlet p = start,\n\t\tagain;\n\tdo {\n\n\t\tagain = false;\n\n\t\tif ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) {\n\n\t\t\tremoveNode( p );\n\t\t\tp = end = p.prev;\n\t\t\tif ( p === p.next ) break;\n\t\t\tagain = true;\n\n\t\t} else {\n\n\t\t\tp = p.next;\n\n\t\t}\n\n\t} while ( again || p !== end );\n\n\treturn end;\n\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) {\n\n\tif ( ! ear ) return;\n\n\t// interlink polygon nodes in z-order\n\tif ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize );\n\n\tlet stop = ear,\n\t\tprev, next;\n\n\t// iterate through ears, slicing them one by one\n\twhile ( ear.prev !== ear.next ) {\n\n\t\tprev = ear.prev;\n\t\tnext = ear.next;\n\n\t\tif ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) {\n\n\t\t\t// cut off the triangle\n\t\t\ttriangles.push( prev.i / dim );\n\t\t\ttriangles.push( ear.i / dim );\n\t\t\ttriangles.push( next.i / dim );\n\n\t\t\tremoveNode( ear );\n\n\t\t\t// skipping the next vertex leads to less sliver triangles\n\t\t\tear = next.next;\n\t\t\tstop = next.next;\n\n\t\t\tcontinue;\n\n\t\t}\n\n\t\tear = next;\n\n\t\t// if we looped through the whole remaining polygon and can't find any more ears\n\t\tif ( ear === stop ) {\n\n\t\t\t// try filtering points and slicing again\n\t\t\tif ( ! pass ) {\n\n\t\t\t\tearcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 );\n\n\t\t\t\t// if this didn't work, try curing all small self-intersections locally\n\n\t\t\t} else if ( pass === 1 ) {\n\n\t\t\t\tear = cureLocalIntersections( filterPoints( ear ), triangles, dim );\n\t\t\t\tearcutLinked( ear, triangles, dim, minX, minY, invSize, 2 );\n\n\t\t\t\t// as a last resort, try splitting the remaining polygon into two\n\n\t\t\t} else if ( pass === 2 ) {\n\n\t\t\t\tsplitEarcut( ear, triangles, dim, minX, minY, invSize );\n\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar( ear ) {\n\n\tconst a = ear.prev,\n\t\tb = ear,\n\t\tc = ear.next;\n\n\tif ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear\n\n\t// now make sure we don't have other points inside the potential ear\n\tlet p = ear.next.next;\n\n\twhile ( p !== ear.prev ) {\n\n\t\tif ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&\n\t\t\tarea( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.next;\n\n\t}\n\n\treturn true;\n\n}\n\nfunction isEarHashed( ear, minX, minY, invSize ) {\n\n\tconst a = ear.prev,\n\t\tb = ear,\n\t\tc = ear.next;\n\n\tif ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear\n\n\t// triangle bbox; min & max are calculated like this for speed\n\tconst minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ),\n\t\tminTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ),\n\t\tmaxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ),\n\t\tmaxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y );\n\n\t// z-order range for the current triangle bbox;\n\tconst minZ = zOrder( minTX, minTY, minX, minY, invSize ),\n\t\tmaxZ = zOrder( maxTX, maxTY, minX, minY, invSize );\n\n\tlet p = ear.prevZ,\n\t\tn = ear.nextZ;\n\n\t// look for points inside the triangle in both directions\n\twhile ( p && p.z >= minZ && n && n.z <= maxZ ) {\n\n\t\tif ( p !== ear.prev && p !== ear.next &&\n\t\t\tpointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&\n\t\t\tarea( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.prevZ;\n\n\t\tif ( n !== ear.prev && n !== ear.next &&\n\t\t\tpointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) &&\n\t\t\tarea( n.prev, n, n.next ) >= 0 ) return false;\n\t\tn = n.nextZ;\n\n\t}\n\n\t// look for remaining points in decreasing z-order\n\twhile ( p && p.z >= minZ ) {\n\n\t\tif ( p !== ear.prev && p !== ear.next &&\n\t\t\tpointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&\n\t\t\tarea( p.prev, p, p.next ) >= 0 ) return false;\n\t\tp = p.prevZ;\n\n\t}\n\n\t// look for remaining points in increasing z-order\n\twhile ( n && n.z <= maxZ ) {\n\n\t\tif ( n !== ear.prev && n !== ear.next &&\n\t\t\tpointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) &&\n\t\t\tarea( n.prev, n, n.next ) >= 0 ) return false;\n\t\tn = n.nextZ;\n\n\t}\n\n\treturn true;\n\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections( start, triangles, dim ) {\n\n\tlet p = start;\n\tdo {\n\n\t\tconst a = p.prev,\n\t\t\tb = p.next.next;\n\n\t\tif ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) {\n\n\t\t\ttriangles.push( a.i / dim );\n\t\t\ttriangles.push( p.i / dim );\n\t\t\ttriangles.push( b.i / dim );\n\n\t\t\t// remove two nodes involved\n\t\t\tremoveNode( p );\n\t\t\tremoveNode( p.next );\n\n\t\t\tp = start = b;\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\treturn filterPoints( p );\n\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut( start, triangles, dim, minX, minY, invSize ) {\n\n\t// look for a valid diagonal that divides the polygon into two\n\tlet a = start;\n\tdo {\n\n\t\tlet b = a.next.next;\n\t\twhile ( b !== a.prev ) {\n\n\t\t\tif ( a.i !== b.i && isValidDiagonal( a, b ) ) {\n\n\t\t\t\t// split the polygon in two by the diagonal\n\t\t\t\tlet c = splitPolygon( a, b );\n\n\t\t\t\t// filter colinear points around the cuts\n\t\t\t\ta = filterPoints( a, a.next );\n\t\t\t\tc = filterPoints( c, c.next );\n\n\t\t\t\t// run earcut on each half\n\t\t\t\tearcutLinked( a, triangles, dim, minX, minY, invSize );\n\t\t\t\tearcutLinked( c, triangles, dim, minX, minY, invSize );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tb = b.next;\n\n\t\t}\n\n\t\ta = a.next;\n\n\t} while ( a !== start );\n\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles( data, holeIndices, outerNode, dim ) {\n\n\tconst queue = [];\n\tlet i, len, start, end, list;\n\n\tfor ( i = 0, len = holeIndices.length; i < len; i ++ ) {\n\n\t\tstart = holeIndices[ i ] * dim;\n\t\tend = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length;\n\t\tlist = linkedList( data, start, end, dim, false );\n\t\tif ( list === list.next ) list.steiner = true;\n\t\tqueue.push( getLeftmost( list ) );\n\n\t}\n\n\tqueue.sort( compareX );\n\n\t// process holes from left to right\n\tfor ( i = 0; i < queue.length; i ++ ) {\n\n\t\teliminateHole( queue[ i ], outerNode );\n\t\touterNode = filterPoints( outerNode, outerNode.next );\n\n\t}\n\n\treturn outerNode;\n\n}\n\nfunction compareX( a, b ) {\n\n\treturn a.x - b.x;\n\n}\n\n// find a bridge between vertices that connects hole with an outer ring and link it\nfunction eliminateHole( hole, outerNode ) {\n\n\touterNode = findHoleBridge( hole, outerNode );\n\tif ( outerNode ) {\n\n\t\tconst b = splitPolygon( outerNode, hole );\n\n\t\t// filter collinear points around the cuts\n\t\tfilterPoints( outerNode, outerNode.next );\n\t\tfilterPoints( b, b.next );\n\n\t}\n\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge( hole, outerNode ) {\n\n\tlet p = outerNode;\n\tconst hx = hole.x;\n\tconst hy = hole.y;\n\tlet qx = - Infinity, m;\n\n\t// find a segment intersected by a ray from the hole's leftmost point to the left;\n\t// segment's endpoint with lesser x will be potential connection point\n\tdo {\n\n\t\tif ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) {\n\n\t\t\tconst x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y );\n\t\t\tif ( x <= hx && x > qx ) {\n\n\t\t\t\tqx = x;\n\t\t\t\tif ( x === hx ) {\n\n\t\t\t\t\tif ( hy === p.y ) return p;\n\t\t\t\t\tif ( hy === p.next.y ) return p.next;\n\n\t\t\t\t}\n\n\t\t\t\tm = p.x < p.next.x ? p : p.next;\n\n\t\t\t}\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== outerNode );\n\n\tif ( ! m ) return null;\n\n\tif ( hx === qx ) return m; // hole touches outer segment; pick leftmost endpoint\n\n\t// look for points inside the triangle of hole point, segment intersection and endpoint;\n\t// if there are no points found, we have a valid connection;\n\t// otherwise choose the point of the minimum angle with the ray as connection point\n\n\tconst stop = m,\n\t\tmx = m.x,\n\t\tmy = m.y;\n\tlet tanMin = Infinity, tan;\n\n\tp = m;\n\n\tdo {\n\n\t\tif ( hx >= p.x && p.x >= mx && hx !== p.x &&\n\t\t\t\tpointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) {\n\n\t\t\ttan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential\n\n\t\t\tif ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) {\n\n\t\t\t\tm = p;\n\t\t\t\ttanMin = tan;\n\n\t\t\t}\n\n\t\t}\n\n\t\tp = p.next;\n\n\t} while ( p !== stop );\n\n\treturn m;\n\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector( m, p ) {\n\n\treturn area( m.prev, m, p.prev ) < 0 && area( p.next, m, m.next ) < 0;\n\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve( start, minX, minY, invSize ) {\n\n\tlet p = start;\n\tdo {\n\n\t\tif ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize );\n\t\tp.prevZ = p.prev;\n\t\tp.nextZ = p.next;\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\tp.prevZ.nextZ = null;\n\tp.prevZ = null;\n\n\tsortLinked( p );\n\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked( list ) {\n\n\tlet i, p, q, e, tail, numMerges, pSize, qSize,\n\t\tinSize = 1;\n\n\tdo {\n\n\t\tp = list;\n\t\tlist = null;\n\t\ttail = null;\n\t\tnumMerges = 0;\n\n\t\twhile ( p ) {\n\n\t\t\tnumMerges ++;\n\t\t\tq = p;\n\t\t\tpSize = 0;\n\t\t\tfor ( i = 0; i < inSize; i ++ ) {\n\n\t\t\t\tpSize ++;\n\t\t\t\tq = q.nextZ;\n\t\t\t\tif ( ! q ) break;\n\n\t\t\t}\n\n\t\t\tqSize = inSize;\n\n\t\t\twhile ( pSize > 0 || ( qSize > 0 && q ) ) {\n\n\t\t\t\tif ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) {\n\n\t\t\t\t\te = p;\n\t\t\t\t\tp = p.nextZ;\n\t\t\t\t\tpSize --;\n\n\t\t\t\t} else {\n\n\t\t\t\t\te = q;\n\t\t\t\t\tq = q.nextZ;\n\t\t\t\t\tqSize --;\n\n\t\t\t\t}\n\n\t\t\t\tif ( tail ) tail.nextZ = e;\n\t\t\t\telse list = e;\n\n\t\t\t\te.prevZ = tail;\n\t\t\t\ttail = e;\n\n\t\t\t}\n\n\t\t\tp = q;\n\n\t\t}\n\n\t\ttail.nextZ = null;\n\t\tinSize *= 2;\n\n\t} while ( numMerges > 1 );\n\n\treturn list;\n\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder( x, y, minX, minY, invSize ) {\n\n\t// coords are transformed into non-negative 15-bit integer range\n\tx = 32767 * ( x - minX ) * invSize;\n\ty = 32767 * ( y - minY ) * invSize;\n\n\tx = ( x | ( x << 8 ) ) & 0x00FF00FF;\n\tx = ( x | ( x << 4 ) ) & 0x0F0F0F0F;\n\tx = ( x | ( x << 2 ) ) & 0x33333333;\n\tx = ( x | ( x << 1 ) ) & 0x55555555;\n\n\ty = ( y | ( y << 8 ) ) & 0x00FF00FF;\n\ty = ( y | ( y << 4 ) ) & 0x0F0F0F0F;\n\ty = ( y | ( y << 2 ) ) & 0x33333333;\n\ty = ( y | ( y << 1 ) ) & 0x55555555;\n\n\treturn x | ( y << 1 );\n\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost( start ) {\n\n\tlet p = start,\n\t\tleftmost = start;\n\tdo {\n\n\t\tif ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p;\n\t\tp = p.next;\n\n\t} while ( p !== start );\n\n\treturn leftmost;\n\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) {\n\n\treturn ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 &&\n\t\t\t( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 &&\n\t\t\t( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0;\n\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal( a, b ) {\n\n\treturn a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // doesn't intersect other edges\n\t\t( locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ) && // locally visible\n\t\t( area( a.prev, a, b.prev ) || area( a, b.prev, b ) ) || // does not create opposite-facing sectors\n\t\tequals( a, b ) && area( a.prev, a, a.next ) > 0 && area( b.prev, b, b.next ) > 0 ); // special zero-length case\n\n}\n\n// signed area of a triangle\nfunction area( p, q, r ) {\n\n\treturn ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y );\n\n}\n\n// check if two points are equal\nfunction equals( p1, p2 ) {\n\n\treturn p1.x === p2.x && p1.y === p2.y;\n\n}\n\n// check if two segments intersect\nfunction intersects( p1, q1, p2, q2 ) {\n\n\tconst o1 = sign( area( p1, q1, p2 ) );\n\tconst o2 = sign( area( p1, q1, q2 ) );\n\tconst o3 = sign( area( p2, q2, p1 ) );\n\tconst o4 = sign( area( p2, q2, q1 ) );\n\n\tif ( o1 !== o2 && o3 !== o4 ) return true; // general case\n\n\tif ( o1 === 0 && onSegment( p1, p2, q1 ) ) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n\tif ( o2 === 0 && onSegment( p1, q2, q1 ) ) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n\tif ( o3 === 0 && onSegment( p2, p1, q2 ) ) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n\tif ( o4 === 0 && onSegment( p2, q1, q2 ) ) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n\treturn false;\n\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment( p, q, r ) {\n\n\treturn q.x <= Math.max( p.x, r.x ) && q.x >= Math.min( p.x, r.x ) && q.y <= Math.max( p.y, r.y ) && q.y >= Math.min( p.y, r.y );\n\n}\n\nfunction sign( num ) {\n\n\treturn num > 0 ? 1 : num < 0 ? - 1 : 0;\n\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon( a, b ) {\n\n\tlet p = a;\n\tdo {\n\n\t\tif ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n\t\t\t\tintersects( p, p.next, a, b ) ) return true;\n\t\tp = p.next;\n\n\t} while ( p !== a );\n\n\treturn false;\n\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside( a, b ) {\n\n\treturn area( a.prev, a, a.next ) < 0 ?\n\t\tarea( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 :\n\t\tarea( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0;\n\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside( a, b ) {\n\n\tlet p = a,\n\t\tinside = false;\n\tconst px = ( a.x + b.x ) / 2,\n\t\tpy = ( a.y + b.y ) / 2;\n\tdo {\n\n\t\tif ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y &&\n\t\t\t\t( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) )\n\t\t\tinside = ! inside;\n\t\tp = p.next;\n\n\t} while ( p !== a );\n\n\treturn inside;\n\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon( a, b ) {\n\n\tconst a2 = new Node( a.i, a.x, a.y ),\n\t\tb2 = new Node( b.i, b.x, b.y ),\n\t\tan = a.next,\n\t\tbp = b.prev;\n\n\ta.next = b;\n\tb.prev = a;\n\n\ta2.next = an;\n\tan.prev = a2;\n\n\tb2.next = a2;\n\ta2.prev = b2;\n\n\tbp.next = b2;\n\tb2.prev = bp;\n\n\treturn b2;\n\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode( i, x, y, last ) {\n\n\tconst p = new Node( i, x, y );\n\n\tif ( ! last ) {\n\n\t\tp.prev = p;\n\t\tp.next = p;\n\n\t} else {\n\n\t\tp.next = last.next;\n\t\tp.prev = last;\n\t\tlast.next.prev = p;\n\t\tlast.next = p;\n\n\t}\n\n\treturn p;\n\n}\n\nfunction removeNode( p ) {\n\n\tp.next.prev = p.prev;\n\tp.prev.next = p.next;\n\n\tif ( p.prevZ ) p.prevZ.nextZ = p.nextZ;\n\tif ( p.nextZ ) p.nextZ.prevZ = p.prevZ;\n\n}\n\nfunction Node( i, x, y ) {\n\n\t// vertex index in coordinates array\n\tthis.i = i;\n\n\t// vertex coordinates\n\tthis.x = x;\n\tthis.y = y;\n\n\t// previous and next vertex nodes in a polygon ring\n\tthis.prev = null;\n\tthis.next = null;\n\n\t// z-order curve value\n\tthis.z = null;\n\n\t// previous and next nodes in z-order\n\tthis.prevZ = null;\n\tthis.nextZ = null;\n\n\t// indicates whether this is a steiner point\n\tthis.steiner = false;\n\n}\n\nfunction signedArea( data, start, end, dim ) {\n\n\tlet sum = 0;\n\tfor ( let i = start, j = end - dim; i < end; i += dim ) {\n\n\t\tsum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] );\n\t\tj = i;\n\n\t}\n\n\treturn sum;\n\n}\n\nclass ShapeUtils {\n\n\t// calculate area of the contour polygon\n\n\tstatic area( contour ) {\n\n\t\tconst n = contour.length;\n\t\tlet a = 0.0;\n\n\t\tfor ( let p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t}\n\n\t\treturn a * 0.5;\n\n\t}\n\n\tstatic isClockWise( pts ) {\n\n\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t}\n\n\tstatic triangulateShape( contour, holes ) {\n\n\t\tconst vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ]\n\t\tconst holeIndices = []; // array of hole indices\n\t\tconst faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ]\n\n\t\tremoveDupEndPts( contour );\n\t\taddContour( vertices, contour );\n\n\t\t//\n\n\t\tlet holeIndex = contour.length;\n\n\t\tholes.forEach( removeDupEndPts );\n\n\t\tfor ( let i = 0; i < holes.length; i ++ ) {\n\n\t\t\tholeIndices.push( holeIndex );\n\t\t\tholeIndex += holes[ i ].length;\n\t\t\taddContour( vertices, holes[ i ] );\n\n\t\t}\n\n\t\t//\n\n\t\tconst triangles = Earcut.triangulate( vertices, holeIndices );\n\n\t\t//\n\n\t\tfor ( let i = 0; i < triangles.length; i += 3 ) {\n\n\t\t\tfaces.push( triangles.slice( i, i + 3 ) );\n\n\t\t}\n\n\t\treturn faces;\n\n\t}\n\n}\n\nfunction removeDupEndPts( points ) {\n\n\tconst l = points.length;\n\n\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\tpoints.pop();\n\n\t}\n\n}\n\nfunction addContour( vertices, contour ) {\n\n\tfor ( let i = 0; i < contour.length; i ++ ) {\n\n\t\tvertices.push( contour[ i ].x );\n\t\tvertices.push( contour[ i ].y );\n\n\t}\n\n}\n\n/**\n * Creates extruded geometry from a path shape.\n *\n * parameters = {\n *\n * curveSegments: , // number of points on the curves\n * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n * depth: , // Depth to extrude the shape\n *\n * bevelEnabled: , // turn on bevel\n * bevelThickness: , // how deep into the original shape bevel goes\n * bevelSize: , // how far from shape outline (including bevelOffset) is bevel\n * bevelOffset: , // how far from shape outline does bevel start\n * bevelSegments: , // number of bevel layers\n *\n * extrudePath: // curve to extrude shape along\n *\n * UVGenerator: // object that provides UV generator functions\n *\n * }\n */\n\nclass ExtrudeGeometry extends BufferGeometry {\n\n\tconstructor( shapes = new Shape( [ new Vector2( 0.5, 0.5 ), new Vector2( - 0.5, 0.5 ), new Vector2( - 0.5, - 0.5 ), new Vector2( 0.5, - 0.5 ) ] ), options = {} ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\toptions: options\n\t\t};\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tconst scope = this;\n\n\t\tconst verticesArray = [];\n\t\tconst uvArray = [];\n\n\t\tfor ( let i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\tconst shape = shapes[ i ];\n\t\t\taddShape( shape );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );\n\n\t\tthis.computeVertexNormals();\n\n\t\t// functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tconst placeholder = [];\n\n\t\t\t// options\n\n\t\t\tconst curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\t\t\tconst steps = options.steps !== undefined ? options.steps : 1;\n\t\t\tlet depth = options.depth !== undefined ? options.depth : 1;\n\n\t\t\tlet bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;\n\t\t\tlet bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2;\n\t\t\tlet bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1;\n\t\t\tlet bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0;\n\t\t\tlet bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\t\tconst extrudePath = options.extrudePath;\n\n\t\t\tconst uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator;\n\n\t\t\t// deprecated options\n\n\t\t\tif ( options.amount !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' );\n\t\t\t\tdepth = options.amount;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tlet extrudePts, extrudeByPath = false;\n\t\t\tlet splineTube, binormal, normal, position2;\n\n\t\t\tif ( extrudePath ) {\n\n\t\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\t\textrudeByPath = true;\n\t\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t\t// SETUP TNB variables\n\n\t\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\t\tsplineTube = extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\t\tbinormal = new Vector3();\n\t\t\t\tnormal = new Vector3();\n\t\t\t\tposition2 = new Vector3();\n\n\t\t\t}\n\n\t\t\t// Safeguards if bevels are not enabled\n\n\t\t\tif ( ! bevelEnabled ) {\n\n\t\t\t\tbevelSegments = 0;\n\t\t\t\tbevelThickness = 0;\n\t\t\t\tbevelSize = 0;\n\t\t\t\tbevelOffset = 0;\n\n\t\t\t}\n\n\t\t\t// Variables initialization\n\n\t\t\tconst shapePoints = shape.extractPoints( curveSegments );\n\n\t\t\tlet vertices = shapePoints.shape;\n\t\t\tconst holes = shapePoints.holes;\n\n\t\t\tconst reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\t\tif ( reverse ) {\n\n\t\t\t\tvertices = vertices.reverse();\n\n\t\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\t\tfor ( let h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tconst ahole = holes[ h ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tconst faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t\t/* Vertices */\n\n\t\t\tconst contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\t\tfor ( let h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tconst ahole = holes[ h ];\n\n\t\t\t\tvertices = vertices.concat( ahole );\n\n\t\t\t}\n\n\n\t\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\t\tif ( ! vec ) console.error( 'THREE.ExtrudeGeometry: vec does not exist' );\n\n\t\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t\t}\n\n\t\t\tconst vlen = vertices.length, flen = faces.length;\n\n\n\t\t\t// Find directions for point movement\n\n\n\t\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t\t//\n\t\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\t\tlet v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt\n\n\t\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\t\tconst v_prev_x = inPt.x - inPrev.x,\n\t\t\t\t\tv_prev_y = inPt.y - inPrev.y;\n\t\t\t\tconst v_next_x = inNext.x - inPt.x,\n\t\t\t\t\tv_next_y = inNext.y - inPt.y;\n\n\t\t\t\tconst v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t\t// check for collinear edges\n\t\t\t\tconst collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not collinear\n\n\t\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\t\tconst v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\t\tconst v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\t\tconst ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\t\tconst ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\t\tconst ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\t\tconst ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\t\tconst sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t\t// but prevent crazy spikes\n\t\t\t\t\tconst v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\t\treturn new Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\t\tlet direction_eq = false; // assumes: opposite\n\n\t\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t\t}\n\n\n\t\t\tconst contourMovements = [];\n\n\t\t\tfor ( let i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t\t}\n\n\t\t\tconst holesMovements = [];\n\t\t\tlet oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\t\tfor ( let h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tconst ahole = holes[ h ];\n\n\t\t\t\toneHoleMovements = [];\n\n\t\t\t\tfor ( let i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t\t// (j)---(i)---(k)\n\t\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t\t}\n\n\t\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t\t}\n\n\n\t\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\t\tfor ( let b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\t\tconst t = b / bevelSegments;\n\t\t\t\tconst z = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\t\tconst bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset;\n\n\t\t\t\t// contract shape\n\n\t\t\t\tfor ( let i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst vert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t\t// expand holes\n\n\t\t\t\tfor ( let h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tconst ahole = holes[ h ];\n\t\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\t\tfor ( let i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tconst vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst bs = bevelSize + bevelOffset;\n\n\t\t\t// Back facing vertices\n\n\t\t\tfor ( let i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tconst vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Add stepped vertices...\n\t\t\t// Including front facing vertices\n\n\t\t\tfor ( let s = 1; s <= steps; s ++ ) {\n\n\t\t\t\tfor ( let i = 0; i < vlen; i ++ ) {\n\n\t\t\t\t\tconst vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, depth / steps * s );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// Add bevel segments planes\n\n\t\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\t\tfor ( let b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\t\tconst t = b / bevelSegments;\n\t\t\t\tconst z = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\t\tconst bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset;\n\n\t\t\t\t// contract shape\n\n\t\t\t\tfor ( let i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst vert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\t\tv( vert.x, vert.y, depth + z );\n\n\t\t\t\t}\n\n\t\t\t\t// expand holes\n\n\t\t\t\tfor ( let h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tconst ahole = holes[ h ];\n\t\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\t\tfor ( let i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tconst vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\t\tv( vert.x, vert.y, depth + z );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t/* Faces */\n\n\t\t\t// Top and bottom faces\n\n\t\t\tbuildLidFaces();\n\n\t\t\t// Sides faces\n\n\t\t\tbuildSideFaces();\n\n\n\t\t\t///// Internal functions\n\n\t\t\tfunction buildLidFaces() {\n\n\t\t\t\tconst start = verticesArray.length / 3;\n\n\t\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\t\tlet layer = 0; // steps + 1\n\t\t\t\t\tlet offset = vlen * layer;\n\n\t\t\t\t\t// Bottom faces\n\n\t\t\t\t\tfor ( let i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\t\tconst face = faces[ i ];\n\t\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t\t// Top faces\n\n\t\t\t\t\tfor ( let i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\t\tconst face = faces[ i ];\n\t\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Bottom faces\n\n\t\t\t\t\tfor ( let i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\t\tconst face = faces[ i ];\n\t\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Top faces\n\n\t\t\t\t\tfor ( let i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\t\tconst face = faces[ i ];\n\t\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tscope.addGroup( start, verticesArray.length / 3 - start, 0 );\n\n\t\t\t}\n\n\t\t\t// Create faces for the z-sides of the shape\n\n\t\t\tfunction buildSideFaces() {\n\n\t\t\t\tconst start = verticesArray.length / 3;\n\t\t\t\tlet layeroffset = 0;\n\t\t\t\tsidewalls( contour, layeroffset );\n\t\t\t\tlayeroffset += contour.length;\n\n\t\t\t\tfor ( let h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tconst ahole = holes[ h ];\n\t\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t\t//, true\n\t\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t\t}\n\n\n\t\t\t\tscope.addGroup( start, verticesArray.length / 3 - start, 1 );\n\n\n\t\t\t}\n\n\t\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\t\tlet i = contour.length;\n\n\t\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\t\tconst j = i;\n\t\t\t\t\tlet k = i - 1;\n\t\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\t\tfor ( let s = 0, sl = ( steps + bevelSegments * 2 ); s < sl; s ++ ) {\n\n\t\t\t\t\t\tconst slen1 = vlen * s;\n\t\t\t\t\t\tconst slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\t\tconst a = layeroffset + j + slen1,\n\t\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\t\tf4( a, b, c, d );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction v( x, y, z ) {\n\n\t\t\t\tplaceholder.push( x );\n\t\t\t\tplaceholder.push( y );\n\t\t\t\tplaceholder.push( z );\n\n\t\t\t}\n\n\n\t\t\tfunction f3( a, b, c ) {\n\n\t\t\t\taddVertex( a );\n\t\t\t\taddVertex( b );\n\t\t\t\taddVertex( c );\n\n\t\t\t\tconst nextIndex = verticesArray.length / 3;\n\t\t\t\tconst uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );\n\n\t\t\t\taddUV( uvs[ 0 ] );\n\t\t\t\taddUV( uvs[ 1 ] );\n\t\t\t\taddUV( uvs[ 2 ] );\n\n\t\t\t}\n\n\t\t\tfunction f4( a, b, c, d ) {\n\n\t\t\t\taddVertex( a );\n\t\t\t\taddVertex( b );\n\t\t\t\taddVertex( d );\n\n\t\t\t\taddVertex( b );\n\t\t\t\taddVertex( c );\n\t\t\t\taddVertex( d );\n\n\n\t\t\t\tconst nextIndex = verticesArray.length / 3;\n\t\t\t\tconst uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );\n\n\t\t\t\taddUV( uvs[ 0 ] );\n\t\t\t\taddUV( uvs[ 1 ] );\n\t\t\t\taddUV( uvs[ 3 ] );\n\n\t\t\t\taddUV( uvs[ 1 ] );\n\t\t\t\taddUV( uvs[ 2 ] );\n\t\t\t\taddUV( uvs[ 3 ] );\n\n\t\t\t}\n\n\t\t\tfunction addVertex( index ) {\n\n\t\t\t\tverticesArray.push( placeholder[ index * 3 + 0 ] );\n\t\t\t\tverticesArray.push( placeholder[ index * 3 + 1 ] );\n\t\t\t\tverticesArray.push( placeholder[ index * 3 + 2 ] );\n\n\t\t\t}\n\n\n\t\t\tfunction addUV( vector2 ) {\n\n\t\t\t\tuvArray.push( vector2.x );\n\t\t\t\tuvArray.push( vector2.y );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tconst shapes = this.parameters.shapes;\n\t\tconst options = this.parameters.options;\n\n\t\treturn toJSON$1( shapes, options, data );\n\n\t}\n\n\tstatic fromJSON( data, shapes ) {\n\n\t\tconst geometryShapes = [];\n\n\t\tfor ( let j = 0, jl = data.shapes.length; j < jl; j ++ ) {\n\n\t\t\tconst shape = shapes[ data.shapes[ j ] ];\n\n\t\t\tgeometryShapes.push( shape );\n\n\t\t}\n\n\t\tconst extrudePath = data.options.extrudePath;\n\n\t\tif ( extrudePath !== undefined ) {\n\n\t\t\tdata.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath );\n\n\t\t}\n\n\t\treturn new ExtrudeGeometry( geometryShapes, data.options );\n\n\t}\n\n}\n\nconst WorldUVGenerator = {\n\n\tgenerateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {\n\n\t\tconst a_x = vertices[ indexA * 3 ];\n\t\tconst a_y = vertices[ indexA * 3 + 1 ];\n\t\tconst b_x = vertices[ indexB * 3 ];\n\t\tconst b_y = vertices[ indexB * 3 + 1 ];\n\t\tconst c_x = vertices[ indexC * 3 ];\n\t\tconst c_y = vertices[ indexC * 3 + 1 ];\n\n\t\treturn [\n\t\t\tnew Vector2( a_x, a_y ),\n\t\t\tnew Vector2( b_x, b_y ),\n\t\t\tnew Vector2( c_x, c_y )\n\t\t];\n\n\t},\n\n\tgenerateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {\n\n\t\tconst a_x = vertices[ indexA * 3 ];\n\t\tconst a_y = vertices[ indexA * 3 + 1 ];\n\t\tconst a_z = vertices[ indexA * 3 + 2 ];\n\t\tconst b_x = vertices[ indexB * 3 ];\n\t\tconst b_y = vertices[ indexB * 3 + 1 ];\n\t\tconst b_z = vertices[ indexB * 3 + 2 ];\n\t\tconst c_x = vertices[ indexC * 3 ];\n\t\tconst c_y = vertices[ indexC * 3 + 1 ];\n\t\tconst c_z = vertices[ indexC * 3 + 2 ];\n\t\tconst d_x = vertices[ indexD * 3 ];\n\t\tconst d_y = vertices[ indexD * 3 + 1 ];\n\t\tconst d_z = vertices[ indexD * 3 + 2 ];\n\n\t\tif ( Math.abs( a_y - b_y ) < Math.abs( a_x - b_x ) ) {\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a_x, 1 - a_z ),\n\t\t\t\tnew Vector2( b_x, 1 - b_z ),\n\t\t\t\tnew Vector2( c_x, 1 - c_z ),\n\t\t\t\tnew Vector2( d_x, 1 - d_z )\n\t\t\t];\n\n\t\t} else {\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a_y, 1 - a_z ),\n\t\t\t\tnew Vector2( b_y, 1 - b_z ),\n\t\t\t\tnew Vector2( c_y, 1 - c_z ),\n\t\t\t\tnew Vector2( d_y, 1 - d_z )\n\t\t\t];\n\n\t\t}\n\n\t}\n\n};\n\nfunction toJSON$1( shapes, options, data ) {\n\n\tdata.shapes = [];\n\n\tif ( Array.isArray( shapes ) ) {\n\n\t\tfor ( let i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\tconst shape = shapes[ i ];\n\n\t\t\tdata.shapes.push( shape.uuid );\n\n\t\t}\n\n\t} else {\n\n\t\tdata.shapes.push( shapes.uuid );\n\n\t}\n\n\tdata.options = Object.assign( {}, options );\n\n\tif ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON();\n\n\treturn data;\n\n}\n\nclass IcosahedronGeometry extends PolyhedronGeometry {\n\n\tconstructor( radius = 1, detail = 0 ) {\n\n\t\tconst t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tconst vertices = [\n\t\t\t- 1, t, 0, \t1, t, 0, \t- 1, - t, 0, \t1, - t, 0,\n\t\t\t0, - 1, t, \t0, 1, t,\t0, - 1, - t, \t0, 1, - t,\n\t\t\tt, 0, - 1, \tt, 0, 1, \t- t, 0, - 1, \t- t, 0, 1\n\t\t];\n\n\t\tconst indices = [\n\t\t\t0, 11, 5, \t0, 5, 1, \t0, 1, 7, \t0, 7, 10, \t0, 10, 11,\n\t\t\t1, 5, 9, \t5, 11, 4,\t11, 10, 2,\t10, 7, 6,\t7, 1, 8,\n\t\t\t3, 9, 4, \t3, 4, 2,\t3, 2, 6,\t3, 6, 8,\t3, 8, 9,\n\t\t\t4, 9, 5, \t2, 4, 11,\t6, 2, 10,\t8, 6, 7,\t9, 8, 1\n\t\t];\n\n\t\tsuper( vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new IcosahedronGeometry( data.radius, data.detail );\n\n\t}\n\n}\n\nclass OctahedronGeometry extends PolyhedronGeometry {\n\n\tconstructor( radius = 1, detail = 0 ) {\n\n\t\tconst vertices = [\n\t\t\t1, 0, 0, \t- 1, 0, 0,\t0, 1, 0,\n\t\t\t0, - 1, 0, \t0, 0, 1,\t0, 0, - 1\n\t\t];\n\n\t\tconst indices = [\n\t\t\t0, 2, 4,\t0, 4, 3,\t0, 3, 5,\n\t\t\t0, 5, 2,\t1, 2, 5,\t1, 5, 3,\n\t\t\t1, 3, 4,\t1, 4, 2\n\t\t];\n\n\t\tsuper( vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new OctahedronGeometry( data.radius, data.detail );\n\n\t}\n\n}\n\nclass RingGeometry extends BufferGeometry {\n\n\tconstructor( innerRadius = 0.5, outerRadius = 1, thetaSegments = 8, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2 ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthetaSegments = Math.max( 3, thetaSegments );\n\t\tphiSegments = Math.max( 1, phiSegments );\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// some helper variables\n\n\t\tlet radius = innerRadius;\n\t\tconst radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tconst vertex = new Vector3();\n\t\tconst uv = new Vector2();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( let j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( let i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tconst segment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( let j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tconst thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( let i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tconst segment = i + thetaSegmentLevel;\n\n\t\t\t\tconst a = segment;\n\t\t\t\tconst b = segment + thetaSegments + 1;\n\t\t\t\tconst c = segment + thetaSegments + 2;\n\t\t\t\tconst d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new RingGeometry( data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength );\n\n\t}\n\n}\n\nclass ShapeGeometry extends BufferGeometry {\n\n\tconstructor( shapes = new Shape( [ new Vector2( 0, 0.5 ), new Vector2( - 0.5, - 0.5 ), new Vector2( 0.5, - 0.5 ) ] ), curveSegments = 12 ) {\n\n\t\tsuper();\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// helper variables\n\n\t\tlet groupStart = 0;\n\t\tlet groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( let i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tconst indexOffset = vertices.length / 3;\n\t\t\tconst points = shape.extractPoints( curveSegments );\n\n\t\t\tlet shapeVertices = points.shape;\n\t\t\tconst shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tconst shapeHole = shapeHoles[ i ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( let i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tconst shapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( let i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tconst vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( let i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tconst face = faces[ i ];\n\n\t\t\t\tconst a = face[ 0 ] + indexOffset;\n\t\t\t\tconst b = face[ 1 ] + indexOffset;\n\t\t\t\tconst c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tconst shapes = this.parameters.shapes;\n\n\t\treturn toJSON( shapes, data );\n\n\t}\n\n\tstatic fromJSON( data, shapes ) {\n\n\t\tconst geometryShapes = [];\n\n\t\tfor ( let j = 0, jl = data.shapes.length; j < jl; j ++ ) {\n\n\t\t\tconst shape = shapes[ data.shapes[ j ] ];\n\n\t\t\tgeometryShapes.push( shape );\n\n\t\t}\n\n\t\treturn new ShapeGeometry( geometryShapes, data.curveSegments );\n\n\t}\n\n}\n\nfunction toJSON( shapes, data ) {\n\n\tdata.shapes = [];\n\n\tif ( Array.isArray( shapes ) ) {\n\n\t\tfor ( let i = 0, l = shapes.length; i < l; i ++ ) {\n\n\t\t\tconst shape = shapes[ i ];\n\n\t\t\tdata.shapes.push( shape.uuid );\n\n\t\t}\n\n\t} else {\n\n\t\tdata.shapes.push( shapes.uuid );\n\n\t}\n\n\treturn data;\n\n}\n\nclass SphereGeometry extends BufferGeometry {\n\n\tconstructor( radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI ) {\n\n\t\tsuper();\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) );\n\n\t\tconst thetaEnd = Math.min( thetaStart + thetaLength, Math.PI );\n\n\t\tlet index = 0;\n\t\tconst grid = [];\n\n\t\tconst vertex = new Vector3();\n\t\tconst normal = new Vector3();\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( let iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tconst verticesRow = [];\n\n\t\t\tconst v = iy / heightSegments;\n\n\t\t\t// special case for the poles\n\n\t\t\tlet uOffset = 0;\n\n\t\t\tif ( iy == 0 && thetaStart == 0 ) {\n\n\t\t\t\tuOffset = 0.5 / widthSegments;\n\n\t\t\t} else if ( iy == heightSegments && thetaEnd == Math.PI ) {\n\n\t\t\t\tuOffset = - 0.5 / widthSegments;\n\n\t\t\t}\n\n\t\t\tfor ( let ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tconst u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.copy( vertex ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u + uOffset, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( let iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( let ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tconst a = grid[ iy ][ ix + 1 ];\n\t\t\t\tconst b = grid[ iy ][ ix ];\n\t\t\t\tconst c = grid[ iy + 1 ][ ix ];\n\t\t\t\tconst d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new SphereGeometry( data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength );\n\n\t}\n\n}\n\nclass TetrahedronGeometry extends PolyhedronGeometry {\n\n\tconstructor( radius = 1, detail = 0 ) {\n\n\t\tconst vertices = [\n\t\t\t1, 1, 1, \t- 1, - 1, 1, \t- 1, 1, - 1, \t1, - 1, - 1\n\t\t];\n\n\t\tconst indices = [\n\t\t\t2, 1, 0, \t0, 3, 2,\t1, 3, 0,\t2, 3, 1\n\t\t];\n\n\t\tsuper( vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new TetrahedronGeometry( data.radius, data.detail );\n\n\t}\n\n}\n\nclass TorusGeometry extends BufferGeometry {\n\n\tconstructor( radius = 1, tube = 0.4, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2 ) {\n\n\t\tsuper();\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradialSegments = Math.floor( radialSegments );\n\t\ttubularSegments = Math.floor( tubularSegments );\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// helper variables\n\n\t\tconst center = new Vector3();\n\t\tconst vertex = new Vector3();\n\t\tconst normal = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( let j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( let i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tconst u = i / tubularSegments * arc;\n\t\t\t\tconst v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( let j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( let i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tconst a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tconst b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tconst c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tconst d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new TorusGeometry( data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc );\n\n\t}\n\n}\n\nclass TorusKnotGeometry extends BufferGeometry {\n\n\tconstructor( radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3 ) {\n\n\t\tsuper();\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\ttubularSegments = Math.floor( tubularSegments );\n\t\tradialSegments = Math.floor( radialSegments );\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// helper variables\n\n\t\tconst vertex = new Vector3();\n\t\tconst normal = new Vector3();\n\n\t\tconst P1 = new Vector3();\n\t\tconst P2 = new Vector3();\n\n\t\tconst B = new Vector3();\n\t\tconst T = new Vector3();\n\t\tconst N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( let i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segment\n\n\t\t\tconst u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( let j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tconst v = j / radialSegments * Math.PI * 2;\n\t\t\t\tconst cx = - tube * Math.cos( v );\n\t\t\t\tconst cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectors, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( let j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( let i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tconst a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tconst b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tconst c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tconst d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tconst cu = Math.cos( u );\n\t\t\tconst su = Math.sin( u );\n\t\t\tconst quOverP = q / p * u;\n\t\t\tconst cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\treturn new TorusKnotGeometry( data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q );\n\n\t}\n\n}\n\nclass TubeGeometry extends BufferGeometry {\n\n\tconstructor( path = new QuadraticBezierCurve3( new Vector3( - 1, - 1, 0 ), new Vector3( - 1, 1, 0 ), new Vector3( 1, 1, 0 ) ), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false ) {\n\n\t\tsuper();\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tconst frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tconst vertex = new Vector3();\n\t\tconst normal = new Vector3();\n\t\tconst uv = new Vector2();\n\t\tlet P = new Vector3();\n\n\t\t// buffer\n\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\t\tconst indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( let i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tP = path.getPointAt( i / tubularSegments, P );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tconst N = frames.normals[ i ];\n\t\t\tconst B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( let j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tconst v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tconst sin = Math.sin( v );\n\t\t\t\tconst cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( let j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( let i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tconst a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tconst b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tconst c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tconst d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( let i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( let j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON();\n\n\t\tdata.path = this.parameters.path.toJSON();\n\n\t\treturn data;\n\n\t}\n\n\tstatic fromJSON( data ) {\n\n\t\t// This only works for built-in curves (e.g. CatmullRomCurve3).\n\t\t// User defined curves or instances of CurvePath will not be deserialized.\n\t\treturn new TubeGeometry(\n\t\t\tnew Curves[ data.path.type ]().fromJSON( data.path ),\n\t\t\tdata.tubularSegments,\n\t\t\tdata.radius,\n\t\t\tdata.radialSegments,\n\t\t\tdata.closed\n\t\t);\n\n\t}\n\n}\n\nclass WireframeGeometry extends BufferGeometry {\n\n\tconstructor( geometry = null ) {\n\n\t\tsuper();\n\t\tthis.type = 'WireframeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tgeometry: geometry\n\t\t};\n\n\t\tif ( geometry !== null ) {\n\n\t\t\t// buffer\n\n\t\t\tconst vertices = [];\n\t\t\tconst edges = new Set();\n\n\t\t\t// helper variables\n\n\t\t\tconst start = new Vector3();\n\t\t\tconst end = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tconst position = geometry.attributes.position;\n\t\t\t\tconst indices = geometry.index;\n\t\t\t\tlet groups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgroups = [ { start: 0, count: indices.count, materialIndex: 0 } ];\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\t\tfor ( let o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tconst group = groups[ o ];\n\n\t\t\t\t\tconst groupStart = group.start;\n\t\t\t\t\tconst groupCount = group.count;\n\n\t\t\t\t\tfor ( let i = groupStart, l = ( groupStart + groupCount ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( let j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tconst index1 = indices.getX( i + j );\n\t\t\t\t\t\t\tconst index2 = indices.getX( i + ( j + 1 ) % 3 );\n\n\t\t\t\t\t\t\tstart.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\t\tend.fromBufferAttribute( position, index2 );\n\n\t\t\t\t\t\t\tif ( isUniqueEdge( start, end, edges ) === true ) {\n\n\t\t\t\t\t\t\t\tvertices.push( start.x, start.y, start.z );\n\t\t\t\t\t\t\t\tvertices.push( end.x, end.y, end.z );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tconst position = geometry.attributes.position;\n\n\t\t\t\tfor ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( let j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tconst index1 = 3 * i + j;\n\t\t\t\t\t\tconst index2 = 3 * i + ( ( j + 1 ) % 3 );\n\n\t\t\t\t\t\tstart.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tend.fromBufferAttribute( position, index2 );\n\n\t\t\t\t\t\tif ( isUniqueEdge( start, end, edges ) === true ) {\n\n\t\t\t\t\t\t\tvertices.push( start.x, start.y, start.z );\n\t\t\t\t\t\t\tvertices.push( end.x, end.y, end.z );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// build geometry\n\n\t\t\tthis.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t}\n\n\t}\n\n}\n\nfunction isUniqueEdge( start, end, edges ) {\n\n\tconst hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`;\n\tconst hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge\n\n\tif ( edges.has( hash1 ) === true || edges.has( hash2 ) === true ) {\n\n\t\treturn false;\n\n\t} else {\n\n\t\tedges.add( hash1 );\n\t\tedges.add( hash2 );\n\t\treturn true;\n\n\t}\n\n}\n\nvar Geometries = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tBoxGeometry: BoxGeometry,\n\tBoxBufferGeometry: BoxGeometry,\n\tCapsuleGeometry: CapsuleGeometry,\n\tCapsuleBufferGeometry: CapsuleGeometry,\n\tCircleGeometry: CircleGeometry,\n\tCircleBufferGeometry: CircleGeometry,\n\tConeGeometry: ConeGeometry,\n\tConeBufferGeometry: ConeGeometry,\n\tCylinderGeometry: CylinderGeometry,\n\tCylinderBufferGeometry: CylinderGeometry,\n\tDodecahedronGeometry: DodecahedronGeometry,\n\tDodecahedronBufferGeometry: DodecahedronGeometry,\n\tEdgesGeometry: EdgesGeometry,\n\tExtrudeGeometry: ExtrudeGeometry,\n\tExtrudeBufferGeometry: ExtrudeGeometry,\n\tIcosahedronGeometry: IcosahedronGeometry,\n\tIcosahedronBufferGeometry: IcosahedronGeometry,\n\tLatheGeometry: LatheGeometry,\n\tLatheBufferGeometry: LatheGeometry,\n\tOctahedronGeometry: OctahedronGeometry,\n\tOctahedronBufferGeometry: OctahedronGeometry,\n\tPlaneGeometry: PlaneGeometry,\n\tPlaneBufferGeometry: PlaneGeometry,\n\tPolyhedronGeometry: PolyhedronGeometry,\n\tPolyhedronBufferGeometry: PolyhedronGeometry,\n\tRingGeometry: RingGeometry,\n\tRingBufferGeometry: RingGeometry,\n\tShapeGeometry: ShapeGeometry,\n\tShapeBufferGeometry: ShapeGeometry,\n\tSphereGeometry: SphereGeometry,\n\tSphereBufferGeometry: SphereGeometry,\n\tTetrahedronGeometry: TetrahedronGeometry,\n\tTetrahedronBufferGeometry: TetrahedronGeometry,\n\tTorusGeometry: TorusGeometry,\n\tTorusBufferGeometry: TorusGeometry,\n\tTorusKnotGeometry: TorusKnotGeometry,\n\tTorusKnotBufferGeometry: TorusKnotGeometry,\n\tTubeGeometry: TubeGeometry,\n\tTubeBufferGeometry: TubeGeometry,\n\tWireframeGeometry: WireframeGeometry\n});\n\nclass ShadowMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isShadowMaterial = true;\n\n\t\tthis.type = 'ShadowMaterial';\n\n\t\tthis.color = new Color( 0x000000 );\n\t\tthis.transparent = true;\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass RawShaderMaterial extends ShaderMaterial {\n\n\tconstructor( parameters ) {\n\n\t\tsuper( parameters );\n\n\t\tthis.isRawShaderMaterial = true;\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n}\n\nclass MeshStandardMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshStandardMaterial = true;\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 1.0;\n\t\tthis.metalness = 0.0;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalMapType = TangentSpaceNormalMap;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.flatShading = false;\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalMapType = source.normalMapType;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.flatShading = source.flatShading;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass MeshPhysicalMaterial extends MeshStandardMaterial {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshPhysicalMaterial = true;\n\n\t\tthis.defines = {\n\n\t\t\t'STANDARD': '',\n\t\t\t'PHYSICAL': ''\n\n\t\t};\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.clearcoatMap = null;\n\t\tthis.clearcoatRoughness = 0.0;\n\t\tthis.clearcoatRoughnessMap = null;\n\t\tthis.clearcoatNormalScale = new Vector2( 1, 1 );\n\t\tthis.clearcoatNormalMap = null;\n\n\t\tthis.ior = 1.5;\n\n\t\tObject.defineProperty( this, 'reflectivity', {\n\t\t\tget: function () {\n\n\t\t\t\treturn ( clamp( 2.5 * ( this.ior - 1 ) / ( this.ior + 1 ), 0, 1 ) );\n\n\t\t\t},\n\t\t\tset: function ( reflectivity ) {\n\n\t\t\t\tthis.ior = ( 1 + 0.4 * reflectivity ) / ( 1 - 0.4 * reflectivity );\n\n\t\t\t}\n\t\t} );\n\n\t\tthis.iridescenceMap = null;\n\t\tthis.iridescenceIOR = 1.3;\n\t\tthis.iridescenceThicknessRange = [ 100, 400 ];\n\t\tthis.iridescenceThicknessMap = null;\n\n\t\tthis.sheenColor = new Color( 0x000000 );\n\t\tthis.sheenColorMap = null;\n\t\tthis.sheenRoughness = 1.0;\n\t\tthis.sheenRoughnessMap = null;\n\n\t\tthis.transmissionMap = null;\n\n\t\tthis.thickness = 0;\n\t\tthis.thicknessMap = null;\n\t\tthis.attenuationDistance = 0.0;\n\t\tthis.attenuationColor = new Color( 1, 1, 1 );\n\n\t\tthis.specularIntensity = 1.0;\n\t\tthis.specularIntensityMap = null;\n\t\tthis.specularColor = new Color( 1, 1, 1 );\n\t\tthis.specularColorMap = null;\n\n\t\tthis._sheen = 0.0;\n\t\tthis._clearcoat = 0;\n\t\tthis._iridescence = 0;\n\t\tthis._transmission = 0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tget sheen() {\n\n\t\treturn this._sheen;\n\n\t}\n\n\tset sheen( value ) {\n\n\t\tif ( this._sheen > 0 !== value > 0 ) {\n\n\t\t\tthis.version ++;\n\n\t\t}\n\n\t\tthis._sheen = value;\n\n\t}\n\n\tget clearcoat() {\n\n\t\treturn this._clearcoat;\n\n\t}\n\n\tset clearcoat( value ) {\n\n\t\tif ( this._clearcoat > 0 !== value > 0 ) {\n\n\t\t\tthis.version ++;\n\n\t\t}\n\n\t\tthis._clearcoat = value;\n\n\t}\n\n\tget iridescence() {\n\n\t\treturn this._iridescence;\n\n\t}\n\n\tset iridescence( value ) {\n\n\t\tif ( this._iridescence > 0 !== value > 0 ) {\n\n\t\t\tthis.version ++;\n\n\t\t}\n\n\t\tthis._iridescence = value;\n\n\t}\n\n\tget transmission() {\n\n\t\treturn this._transmission;\n\n\t}\n\n\tset transmission( value ) {\n\n\t\tif ( this._transmission > 0 !== value > 0 ) {\n\n\t\t\tthis.version ++;\n\n\t\t}\n\n\t\tthis._transmission = value;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.defines = {\n\n\t\t\t'STANDARD': '',\n\t\t\t'PHYSICAL': ''\n\n\t\t};\n\n\t\tthis.clearcoat = source.clearcoat;\n\t\tthis.clearcoatMap = source.clearcoatMap;\n\t\tthis.clearcoatRoughness = source.clearcoatRoughness;\n\t\tthis.clearcoatRoughnessMap = source.clearcoatRoughnessMap;\n\t\tthis.clearcoatNormalMap = source.clearcoatNormalMap;\n\t\tthis.clearcoatNormalScale.copy( source.clearcoatNormalScale );\n\n\t\tthis.ior = source.ior;\n\n\t\tthis.iridescence = source.iridescence;\n\t\tthis.iridescenceMap = source.iridescenceMap;\n\t\tthis.iridescenceIOR = source.iridescenceIOR;\n\t\tthis.iridescenceThicknessRange = [ ...source.iridescenceThicknessRange ];\n\t\tthis.iridescenceThicknessMap = source.iridescenceThicknessMap;\n\n\t\tthis.sheen = source.sheen;\n\t\tthis.sheenColor.copy( source.sheenColor );\n\t\tthis.sheenColorMap = source.sheenColorMap;\n\t\tthis.sheenRoughness = source.sheenRoughness;\n\t\tthis.sheenRoughnessMap = source.sheenRoughnessMap;\n\n\t\tthis.transmission = source.transmission;\n\t\tthis.transmissionMap = source.transmissionMap;\n\n\t\tthis.thickness = source.thickness;\n\t\tthis.thicknessMap = source.thicknessMap;\n\t\tthis.attenuationDistance = source.attenuationDistance;\n\t\tthis.attenuationColor.copy( source.attenuationColor );\n\n\t\tthis.specularIntensity = source.specularIntensity;\n\t\tthis.specularIntensityMap = source.specularIntensityMap;\n\t\tthis.specularColor.copy( source.specularColor );\n\t\tthis.specularColorMap = source.specularColorMap;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass MeshPhongMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshPhongMaterial = true;\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalMapType = TangentSpaceNormalMap;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.flatShading = false;\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalMapType = source.normalMapType;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.flatShading = source.flatShading;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass MeshToonMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshToonMaterial = true;\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\t\tthis.gradientMap = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalMapType = TangentSpaceNormalMap;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalMapType = source.normalMapType;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass MeshNormalMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshNormalMaterial = true;\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalMapType = TangentSpaceNormalMap;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.flatShading = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalMapType = source.normalMapType;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.flatShading = source.flatShading;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass MeshLambertMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshLambertMaterial = true;\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass MeshMatcapMaterial extends Material {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isMeshMatcapMaterial = true;\n\n\t\tthis.defines = { 'MATCAP': '' };\n\n\t\tthis.type = 'MeshMatcapMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.matcap = null;\n\n\t\tthis.map = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalMapType = TangentSpaceNormalMap;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.flatShading = false;\n\n\t\tthis.fog = true;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.defines = { 'MATCAP': '' };\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.matcap = source.matcap;\n\n\t\tthis.map = source.map;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalMapType = source.normalMapType;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.flatShading = source.flatShading;\n\n\t\tthis.fog = source.fog;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass LineDashedMaterial extends LineBasicMaterial {\n\n\tconstructor( parameters ) {\n\n\t\tsuper();\n\n\t\tthis.isLineDashedMaterial = true;\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst materialLib = {\n\tShadowMaterial,\n\tSpriteMaterial,\n\tRawShaderMaterial,\n\tShaderMaterial,\n\tPointsMaterial,\n\tMeshPhysicalMaterial,\n\tMeshStandardMaterial,\n\tMeshPhongMaterial,\n\tMeshToonMaterial,\n\tMeshNormalMaterial,\n\tMeshLambertMaterial,\n\tMeshDepthMaterial,\n\tMeshDistanceMaterial,\n\tMeshBasicMaterial,\n\tMeshMatcapMaterial,\n\tLineDashedMaterial,\n\tLineBasicMaterial,\n\tMaterial\n};\n\nMaterial.fromType = function ( type ) {\n\n\treturn new materialLib[ type ]();\n\n};\n\nconst AnimationUtils = {\n\n\t// same as Array.prototype.slice, but also works on typed arrays\n\tarraySlice: function ( array, from, to ) {\n\n\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t// in ios9 array.subarray(from, undefined) will return empty array\n\t\t\t// but array.subarray(from) or array.subarray(from, len) is correct\n\t\t\treturn new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );\n\n\t\t}\n\n\t\treturn array.slice( from, to );\n\n\t},\n\n\t// converts an array to a specific type\n\tconvertArray: function ( array, type, forceClone ) {\n\n\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\treturn new type( array ); // create typed array\n\n\t\t}\n\n\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t},\n\n\tisTypedArray: function ( object ) {\n\n\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t! ( object instanceof DataView );\n\n\t},\n\n\t// returns an array by which times and values can be sorted\n\tgetKeyframeOrder: function ( times ) {\n\n\t\tfunction compareTime( i, j ) {\n\n\t\t\treturn times[ i ] - times[ j ];\n\n\t\t}\n\n\t\tconst n = times.length;\n\t\tconst result = new Array( n );\n\t\tfor ( let i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\tresult.sort( compareTime );\n\n\t\treturn result;\n\n\t},\n\n\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\tsortedArray: function ( values, stride, order ) {\n\n\t\tconst nValues = values.length;\n\t\tconst result = new values.constructor( nValues );\n\n\t\tfor ( let i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\tconst srcOffset = order[ i ] * stride;\n\n\t\t\tfor ( let j = 0; j !== stride; ++ j ) {\n\n\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn result;\n\n\t},\n\n\t// function for parsing AOS keyframe formats\n\tflattenJSON: function ( jsonKeys, times, values, valuePropertyName ) {\n\n\t\tlet i = 1, key = jsonKeys[ 0 ];\n\n\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t}\n\n\t\tif ( key === undefined ) return; // no data\n\n\t\tlet value = key[ valuePropertyName ];\n\t\tif ( value === undefined ) return; // no data\n\n\t\tif ( Array.isArray( value ) ) {\n\n\t\t\tdo {\n\n\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t}\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t} while ( key !== undefined );\n\n\t\t} else if ( value.toArray !== undefined ) {\n\n\t\t\t// ...assume THREE.Math-ish\n\n\t\t\tdo {\n\n\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t}\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t} while ( key !== undefined );\n\n\t\t} else {\n\n\t\t\t// otherwise push as-is\n\n\t\t\tdo {\n\n\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t}\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t} while ( key !== undefined );\n\n\t\t}\n\n\t},\n\n\tsubclip: function ( sourceClip, name, startFrame, endFrame, fps = 30 ) {\n\n\t\tconst clip = sourceClip.clone();\n\n\t\tclip.name = name;\n\n\t\tconst tracks = [];\n\n\t\tfor ( let i = 0; i < clip.tracks.length; ++ i ) {\n\n\t\t\tconst track = clip.tracks[ i ];\n\t\t\tconst valueSize = track.getValueSize();\n\n\t\t\tconst times = [];\n\t\t\tconst values = [];\n\n\t\t\tfor ( let j = 0; j < track.times.length; ++ j ) {\n\n\t\t\t\tconst frame = track.times[ j ] * fps;\n\n\t\t\t\tif ( frame < startFrame || frame >= endFrame ) continue;\n\n\t\t\t\ttimes.push( track.times[ j ] );\n\n\t\t\t\tfor ( let k = 0; k < valueSize; ++ k ) {\n\n\t\t\t\t\tvalues.push( track.values[ j * valueSize + k ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( times.length === 0 ) continue;\n\n\t\t\ttrack.times = AnimationUtils.convertArray( times, track.times.constructor );\n\t\t\ttrack.values = AnimationUtils.convertArray( values, track.values.constructor );\n\n\t\t\ttracks.push( track );\n\n\t\t}\n\n\t\tclip.tracks = tracks;\n\n\t\t// find minimum .times value across all tracks in the trimmed clip\n\n\t\tlet minStartTime = Infinity;\n\n\t\tfor ( let i = 0; i < clip.tracks.length; ++ i ) {\n\n\t\t\tif ( minStartTime > clip.tracks[ i ].times[ 0 ] ) {\n\n\t\t\t\tminStartTime = clip.tracks[ i ].times[ 0 ];\n\n\t\t\t}\n\n\t\t}\n\n\t\t// shift all tracks such that clip begins at t=0\n\n\t\tfor ( let i = 0; i < clip.tracks.length; ++ i ) {\n\n\t\t\tclip.tracks[ i ].shift( - 1 * minStartTime );\n\n\t\t}\n\n\t\tclip.resetDuration();\n\n\t\treturn clip;\n\n\t},\n\n\tmakeClipAdditive: function ( targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30 ) {\n\n\t\tif ( fps <= 0 ) fps = 30;\n\n\t\tconst numTracks = referenceClip.tracks.length;\n\t\tconst referenceTime = referenceFrame / fps;\n\n\t\t// Make each track's values relative to the values at the reference frame\n\t\tfor ( let i = 0; i < numTracks; ++ i ) {\n\n\t\t\tconst referenceTrack = referenceClip.tracks[ i ];\n\t\t\tconst referenceTrackType = referenceTrack.ValueTypeName;\n\n\t\t\t// Skip this track if it's non-numeric\n\t\t\tif ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) continue;\n\n\t\t\t// Find the track in the target clip whose name and type matches the reference track\n\t\t\tconst targetTrack = targetClip.tracks.find( function ( track ) {\n\n\t\t\t\treturn track.name === referenceTrack.name\n\t\t\t\t\t&& track.ValueTypeName === referenceTrackType;\n\n\t\t\t} );\n\n\t\t\tif ( targetTrack === undefined ) continue;\n\n\t\t\tlet referenceOffset = 0;\n\t\t\tconst referenceValueSize = referenceTrack.getValueSize();\n\n\t\t\tif ( referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {\n\n\t\t\t\treferenceOffset = referenceValueSize / 3;\n\n\t\t\t}\n\n\t\t\tlet targetOffset = 0;\n\t\t\tconst targetValueSize = targetTrack.getValueSize();\n\n\t\t\tif ( targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {\n\n\t\t\t\ttargetOffset = targetValueSize / 3;\n\n\t\t\t}\n\n\t\t\tconst lastIndex = referenceTrack.times.length - 1;\n\t\t\tlet referenceValue;\n\n\t\t\t// Find the value to subtract out of the track\n\t\t\tif ( referenceTime <= referenceTrack.times[ 0 ] ) {\n\n\t\t\t\t// Reference frame is earlier than the first keyframe, so just use the first keyframe\n\t\t\t\tconst startIndex = referenceOffset;\n\t\t\t\tconst endIndex = referenceValueSize - referenceOffset;\n\t\t\t\treferenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex, endIndex );\n\n\t\t\t} else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) {\n\n\t\t\t\t// Reference frame is after the last keyframe, so just use the last keyframe\n\t\t\t\tconst startIndex = lastIndex * referenceValueSize + referenceOffset;\n\t\t\t\tconst endIndex = startIndex + referenceValueSize - referenceOffset;\n\t\t\t\treferenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex, endIndex );\n\n\t\t\t} else {\n\n\t\t\t\t// Interpolate to the reference value\n\t\t\t\tconst interpolant = referenceTrack.createInterpolant();\n\t\t\t\tconst startIndex = referenceOffset;\n\t\t\t\tconst endIndex = referenceValueSize - referenceOffset;\n\t\t\t\tinterpolant.evaluate( referenceTime );\n\t\t\t\treferenceValue = AnimationUtils.arraySlice( interpolant.resultBuffer, startIndex, endIndex );\n\n\t\t\t}\n\n\t\t\t// Conjugate the quaternion\n\t\t\tif ( referenceTrackType === 'quaternion' ) {\n\n\t\t\t\tconst referenceQuat = new Quaternion().fromArray( referenceValue ).normalize().conjugate();\n\t\t\t\treferenceQuat.toArray( referenceValue );\n\n\t\t\t}\n\n\t\t\t// Subtract the reference value from all of the track values\n\n\t\t\tconst numTimes = targetTrack.times.length;\n\t\t\tfor ( let j = 0; j < numTimes; ++ j ) {\n\n\t\t\t\tconst valueStart = j * targetValueSize + targetOffset;\n\n\t\t\t\tif ( referenceTrackType === 'quaternion' ) {\n\n\t\t\t\t\t// Multiply the conjugate for quaternion track types\n\t\t\t\t\tQuaternion.multiplyQuaternionsFlat(\n\t\t\t\t\t\ttargetTrack.values,\n\t\t\t\t\t\tvalueStart,\n\t\t\t\t\t\treferenceValue,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\ttargetTrack.values,\n\t\t\t\t\t\tvalueStart\n\t\t\t\t\t);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconst valueEnd = targetValueSize - targetOffset * 2;\n\n\t\t\t\t\t// Subtract each value for all other numeric track types\n\t\t\t\t\tfor ( let k = 0; k < valueEnd; ++ k ) {\n\n\t\t\t\t\t\ttargetTrack.values[ valueStart + k ] -= referenceValue[ k ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\ttargetClip.blendMode = AdditiveAnimationBlendMode;\n\n\t\treturn targetClip;\n\n\t}\n\n};\n\n/**\n * Abstract base class of interpolants over parametric samples.\n *\n * The parameter domain is one dimensional, typically the time or a path\n * along a curve defined by the data.\n *\n * The sample values can have any dimensionality and derived classes may\n * apply special interpretations to the data.\n *\n * This class provides the interval seek in a Template Method, deferring\n * the actual interpolation to derived classes.\n *\n * Time complexity is O(1) for linear access crossing at most two points\n * and O(log N) for random access, where N is the number of positions.\n *\n * References:\n *\n * \t\thttp://www.oodesign.com/template-method-pattern.html\n *\n */\n\nclass Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t\tthis.settings = null;\n\t\tthis.DefaultSettings_ = {};\n\n\t}\n\n\tevaluate( t ) {\n\n\t\tconst pp = this.parameterPositions;\n\t\tlet i1 = this._cachedIndex,\n\t\t\tt1 = pp[ i1 ],\n\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\tvalidate_interval: {\n\n\t\t\tseek: {\n\n\t\t\t\tlet right;\n\n\t\t\t\tlinear_scan: {\n\n\t\t\t\t\t//- See http://jsperf.com/comparison-to-undefined/3\n\t\t\t\t\t//- slower code:\n\t\t\t\t\t//-\n\t\t\t\t\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\tfor ( let giveUpAt = i1 + 2; ; ) {\n\n\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t//- slower code:\n\t\t\t\t\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\tconst t1global = pp[ 1 ];\n\n\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\tfor ( let giveUpAt = i1 - 2; ; ) {\n\n\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\treturn this.copySampleValue_( 0 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t} // linear scan\n\n\t\t\t\t// binary search\n\n\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\tconst mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t// check boundary cases, again\n\n\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\treturn this.copySampleValue_( 0 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t\t\t}\n\n\t\t\t} // seek\n\n\t\t\tthis._cachedIndex = i1;\n\n\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t} // validate_interval\n\n\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t}\n\n\tgetSettings_() {\n\n\t\treturn this.settings || this.DefaultSettings_;\n\n\t}\n\n\tcopySampleValue_( index ) {\n\n\t\t// copies a sample value to the result buffer\n\n\t\tconst result = this.resultBuffer,\n\t\t\tvalues = this.sampleValues,\n\t\t\tstride = this.valueSize,\n\t\t\toffset = index * stride;\n\n\t\tfor ( let i = 0; i !== stride; ++ i ) {\n\n\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n\t// Template methods for derived classes:\n\n\tinterpolate_( /* i1, t0, t, t1 */ ) {\n\n\t\tthrow new Error( 'call to abstract method' );\n\t\t// implementations shall return this.resultBuffer\n\n\t}\n\n\tintervalChanged_( /* i1, t0, t1 */ ) {\n\n\t\t// empty\n\n\t}\n\n}\n\n/**\n * Fast and simple cubic spline interpolant.\n *\n * It was derived from a Hermitian construction setting the first derivative\n * at each sample position to the linear slope between neighboring positions\n * over their parameter interval.\n */\n\nclass CubicInterpolant extends Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tsuper( parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = - 0;\n\t\tthis._offsetPrev = - 0;\n\t\tthis._weightNext = - 0;\n\t\tthis._offsetNext = - 0;\n\n\t\tthis.DefaultSettings_ = {\n\n\t\t\tendingStart: ZeroCurvatureEnding,\n\t\t\tendingEnd: ZeroCurvatureEnding\n\n\t\t};\n\n\t}\n\n\tintervalChanged_( i1, t0, t1 ) {\n\n\t\tconst pp = this.parameterPositions;\n\t\tlet iPrev = i1 - 2,\n\t\t\tiNext = i1 + 1,\n\n\t\t\ttPrev = pp[ iPrev ],\n\t\t\ttNext = pp[ iNext ];\n\n\t\tif ( tPrev === undefined ) {\n\n\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\tiPrev = i1;\n\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\tiPrev = i1;\n\t\t\t\t\ttPrev = t1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( tNext === undefined ) {\n\n\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\tiNext = i1;\n\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\tiNext = 1;\n\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\ttNext = t0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst halfDt = ( t1 - t0 ) * 0.5,\n\t\t\tstride = this.valueSize;\n\n\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\tthis._offsetPrev = iPrev * stride;\n\t\tthis._offsetNext = iNext * stride;\n\n\t}\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = this.resultBuffer,\n\t\t\tvalues = this.sampleValues,\n\t\t\tstride = this.valueSize,\n\n\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\tpp = p * p,\n\t\t\tppp = pp * p;\n\n\t\t// evaluate polynomials\n\n\t\tconst sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\tconst s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1;\n\t\tconst s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\tconst sN = wN * ppp - wN * pp;\n\n\t\t// combine data linearly\n\n\t\tfor ( let i = 0; i !== stride; ++ i ) {\n\n\t\t\tresult[ i ] =\n\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n}\n\nclass LinearInterpolant extends Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tsuper( parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = this.resultBuffer,\n\t\t\tvalues = this.sampleValues,\n\t\t\tstride = this.valueSize,\n\n\t\t\toffset1 = i1 * stride,\n\t\t\toffset0 = offset1 - stride,\n\n\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\tweight0 = 1 - weight1;\n\n\t\tfor ( let i = 0; i !== stride; ++ i ) {\n\n\t\t\tresult[ i ] =\n\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n}\n\n/**\n *\n * Interpolant that evaluates to the sample value at the position preceding\n * the parameter.\n */\n\nclass DiscreteInterpolant extends Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tsuper( parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tinterpolate_( i1 /*, t0, t, t1 */ ) {\n\n\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t}\n\n}\n\nclass KeyframeTrack {\n\n\tconstructor( name, times, values, interpolation ) {\n\n\t\tif ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' );\n\t\tif ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name );\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t}\n\n\t// Serialization (in static context, because of constructor invocation\n\t// and automatic invocation of .toJSON):\n\n\tstatic toJSON( track ) {\n\n\t\tconst trackType = track.constructor;\n\n\t\tlet json;\n\n\t\t// derived classes can define a static toJSON method\n\t\tif ( trackType.toJSON !== this.toJSON ) {\n\n\t\t\tjson = trackType.toJSON( track );\n\n\t\t} else {\n\n\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\tjson = {\n\n\t\t\t\t'name': track.name,\n\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t};\n\n\t\t\tconst interpolation = track.getInterpolation();\n\n\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t}\n\n\t\t}\n\n\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\treturn json;\n\n\t}\n\n\tInterpolantFactoryMethodDiscrete( result ) {\n\n\t\treturn new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result );\n\n\t}\n\n\tInterpolantFactoryMethodLinear( result ) {\n\n\t\treturn new LinearInterpolant( this.times, this.values, this.getValueSize(), result );\n\n\t}\n\n\tInterpolantFactoryMethodSmooth( result ) {\n\n\t\treturn new CubicInterpolant( this.times, this.values, this.getValueSize(), result );\n\n\t}\n\n\tsetInterpolation( interpolation ) {\n\n\t\tlet factoryMethod;\n\n\t\tswitch ( interpolation ) {\n\n\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\tbreak;\n\n\t\t\tcase InterpolateLinear:\n\n\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\tbreak;\n\n\t\t\tcase InterpolateSmooth:\n\n\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\tif ( factoryMethod === undefined ) {\n\n\t\t\tconst message = 'unsupported interpolation for ' +\n\t\t\t\tthis.ValueTypeName + ' keyframe track named ' + this.name;\n\n\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconsole.warn( 'THREE.KeyframeTrack:', message );\n\t\t\treturn this;\n\n\t\t}\n\n\t\tthis.createInterpolant = factoryMethod;\n\n\t\treturn this;\n\n\t}\n\n\tgetInterpolation() {\n\n\t\tswitch ( this.createInterpolant ) {\n\n\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\treturn InterpolateLinear;\n\n\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\treturn InterpolateSmooth;\n\n\t\t}\n\n\t}\n\n\tgetValueSize() {\n\n\t\treturn this.values.length / this.times.length;\n\n\t}\n\n\t// move all keyframes either forwards or backwards in time\n\tshift( timeOffset ) {\n\n\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\tconst times = this.times;\n\n\t\t\tfor ( let i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\tscale( timeScale ) {\n\n\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\tconst times = this.times;\n\n\t\t\tfor ( let i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\ttrim( startTime, endTime ) {\n\n\t\tconst times = this.times,\n\t\t\tnKeys = times.length;\n\n\t\tlet from = 0,\n\t\t\tto = nKeys - 1;\n\n\t\twhile ( from !== nKeys && times[ from ] < startTime ) {\n\n\t\t\t++ from;\n\n\t\t}\n\n\t\twhile ( to !== - 1 && times[ to ] > endTime ) {\n\n\t\t\t-- to;\n\n\t\t}\n\n\t\t++ to; // inclusive -> exclusive bound\n\n\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\tif ( from >= to ) {\n\n\t\t\t\tto = Math.max( to, 1 );\n\t\t\t\tfrom = to - 1;\n\n\t\t\t}\n\n\t\t\tconst stride = this.getValueSize();\n\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\tthis.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\tvalidate() {\n\n\t\tlet valid = true;\n\n\t\tconst valueSize = this.getValueSize();\n\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\tconsole.error( 'THREE.KeyframeTrack: Invalid value size in track.', this );\n\t\t\tvalid = false;\n\n\t\t}\n\n\t\tconst times = this.times,\n\t\t\tvalues = this.values,\n\n\t\t\tnKeys = times.length;\n\n\t\tif ( nKeys === 0 ) {\n\n\t\t\tconsole.error( 'THREE.KeyframeTrack: Track is empty.', this );\n\t\t\tvalid = false;\n\n\t\t}\n\n\t\tlet prevTime = null;\n\n\t\tfor ( let i = 0; i !== nKeys; i ++ ) {\n\n\t\t\tconst currTime = times[ i ];\n\n\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\tconsole.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime );\n\t\t\t\tvalid = false;\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\tconsole.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime );\n\t\t\t\tvalid = false;\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tprevTime = currTime;\n\n\t\t}\n\n\t\tif ( values !== undefined ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\tfor ( let i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\tconst value = values[ i ];\n\n\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i, value );\n\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn valid;\n\n\t}\n\n\t// removes equivalent sequential keys as common in morph target sequences\n\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\toptimize() {\n\n\t\t// times or values may be shared with other tracks, so overwriting is unsafe\n\t\tconst times = AnimationUtils.arraySlice( this.times ),\n\t\t\tvalues = AnimationUtils.arraySlice( this.values ),\n\t\t\tstride = this.getValueSize(),\n\n\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\tlastIndex = times.length - 1;\n\n\t\tlet writeIndex = 1;\n\n\t\tfor ( let i = 1; i < lastIndex; ++ i ) {\n\n\t\t\tlet keep = false;\n\n\t\t\tconst time = times[ i ];\n\t\t\tconst timeNext = times[ i + 1 ];\n\n\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\tif ( time !== timeNext && ( i !== 1 || time !== times[ 0 ] ) ) {\n\n\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\tconst offset = i * stride,\n\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\tfor ( let j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\tconst value = values[ offset + j ];\n\n\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tkeep = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// in-place compaction\n\n\t\t\tif ( keep ) {\n\n\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\tconst readOffset = i * stride,\n\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\tfor ( let j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// flush last keyframe (compaction looks ahead)\n\n\t\tif ( lastIndex > 0 ) {\n\n\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\tfor ( let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j ) {\n\n\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t}\n\n\t\t\t++ writeIndex;\n\n\t\t}\n\n\t\tif ( writeIndex !== times.length ) {\n\n\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t} else {\n\n\t\t\tthis.times = times;\n\t\t\tthis.values = values;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\tconst times = AnimationUtils.arraySlice( this.times, 0 );\n\t\tconst values = AnimationUtils.arraySlice( this.values, 0 );\n\n\t\tconst TypedKeyframeTrack = this.constructor;\n\t\tconst track = new TypedKeyframeTrack( this.name, times, values );\n\n\t\t// Interpolant argument to constructor is not saved, so copy the factory method directly.\n\t\ttrack.createInterpolant = this.createInterpolant;\n\n\t\treturn track;\n\n\t}\n\n}\n\nKeyframeTrack.prototype.TimeBufferType = Float32Array;\nKeyframeTrack.prototype.ValueBufferType = Float32Array;\nKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;\n\n/**\n * A Track of Boolean keyframe values.\n */\nclass BooleanKeyframeTrack extends KeyframeTrack {}\n\nBooleanKeyframeTrack.prototype.ValueTypeName = 'bool';\nBooleanKeyframeTrack.prototype.ValueBufferType = Array;\nBooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;\nBooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;\nBooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;\n\n/**\n * A Track of keyframe values that represent color.\n */\nclass ColorKeyframeTrack extends KeyframeTrack {}\n\nColorKeyframeTrack.prototype.ValueTypeName = 'color';\n\n/**\n * A Track of numeric keyframe values.\n */\nclass NumberKeyframeTrack extends KeyframeTrack {}\n\nNumberKeyframeTrack.prototype.ValueTypeName = 'number';\n\n/**\n * Spherical linear unit quaternion interpolant.\n */\n\nclass QuaternionLinearInterpolant extends Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tsuper( parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = this.resultBuffer,\n\t\t\tvalues = this.sampleValues,\n\t\t\tstride = this.valueSize,\n\n\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\tlet offset = i1 * stride;\n\n\t\tfor ( let end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\tQuaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha );\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n}\n\n/**\n * A Track of quaternion keyframe values.\n */\nclass QuaternionKeyframeTrack extends KeyframeTrack {\n\n\tInterpolantFactoryMethodLinear( result ) {\n\n\t\treturn new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result );\n\n\t}\n\n}\n\nQuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion';\n// ValueBufferType is inherited\nQuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;\nQuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;\n\n/**\n * A Track that interpolates Strings\n */\nclass StringKeyframeTrack extends KeyframeTrack {}\n\nStringKeyframeTrack.prototype.ValueTypeName = 'string';\nStringKeyframeTrack.prototype.ValueBufferType = Array;\nStringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;\nStringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;\nStringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;\n\n/**\n * A Track of vectored keyframe values.\n */\nclass VectorKeyframeTrack extends KeyframeTrack {}\n\nVectorKeyframeTrack.prototype.ValueTypeName = 'vector';\n\nclass AnimationClip {\n\n\tconstructor( name, duration = - 1, tracks, blendMode = NormalAnimationBlendMode ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = duration;\n\t\tthis.blendMode = blendMode;\n\n\t\tthis.uuid = generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t}\n\n\n\tstatic parse( json ) {\n\n\t\tconst tracks = [],\n\t\t\tjsonTracks = json.tracks,\n\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\tfor ( let i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\ttracks.push( parseKeyframeTrack( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t}\n\n\t\tconst clip = new this( json.name, json.duration, tracks, json.blendMode );\n\t\tclip.uuid = json.uuid;\n\n\t\treturn clip;\n\n\t}\n\n\tstatic toJSON( clip ) {\n\n\t\tconst tracks = [],\n\t\t\tclipTracks = clip.tracks;\n\n\t\tconst json = {\n\n\t\t\t'name': clip.name,\n\t\t\t'duration': clip.duration,\n\t\t\t'tracks': tracks,\n\t\t\t'uuid': clip.uuid,\n\t\t\t'blendMode': clip.blendMode\n\n\t\t};\n\n\t\tfor ( let i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t}\n\n\t\treturn json;\n\n\t}\n\n\tstatic CreateFromMorphTargetSequence( name, morphTargetSequence, fps, noLoop ) {\n\n\t\tconst numMorphTargets = morphTargetSequence.length;\n\t\tconst tracks = [];\n\n\t\tfor ( let i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\tlet times = [];\n\t\t\tlet values = [];\n\n\t\t\ttimes.push(\n\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\ti,\n\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\tconst order = AnimationUtils.getKeyframeOrder( times );\n\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t// last frame as well for perfect loop.\n\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t}\n\n\t\t\ttracks.push(\n\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\ttimes, values\n\t\t\t\t).scale( 1.0 / fps ) );\n\n\t\t}\n\n\t\treturn new this( name, - 1, tracks );\n\n\t}\n\n\tstatic findByName( objectOrClipArray, name ) {\n\n\t\tlet clipArray = objectOrClipArray;\n\n\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\tconst o = objectOrClipArray;\n\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t}\n\n\t\tfor ( let i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\treturn clipArray[ i ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\tstatic CreateClipsFromMorphTargetSequences( morphTargets, fps, noLoop ) {\n\n\t\tconst animationToMorphTargets = {};\n\n\t\t// tested with https://regex101.com/ on trick sequences\n\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\tconst pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t// sort morph target names into animation groups based\n\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\tfor ( let i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\tconst morphTarget = morphTargets[ i ];\n\t\t\tconst parts = morphTarget.name.match( pattern );\n\n\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\tconst name = parts[ 1 ];\n\n\t\t\t\tlet animationMorphTargets = animationToMorphTargets[ name ];\n\n\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t}\n\n\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst clips = [];\n\n\t\tfor ( const name in animationToMorphTargets ) {\n\n\t\t\tclips.push( this.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t}\n\n\t\treturn clips;\n\n\t}\n\n\t// parse the animation.hierarchy format\n\tstatic parseAnimation( animation, bones ) {\n\n\t\tif ( ! animation ) {\n\n\t\t\tconsole.error( 'THREE.AnimationClip: No animation in JSONLoader data.' );\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t// only return track if there are actually keys.\n\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\tconst times = [];\n\t\t\t\tconst values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( animationKeys, times, values, propertyName );\n\n\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tconst tracks = [];\n\n\t\tconst clipName = animation.name || 'default';\n\t\tconst fps = animation.fps || 30;\n\t\tconst blendMode = animation.blendMode;\n\n\t\t// automatic length determination in AnimationClip.\n\t\tlet duration = animation.length || - 1;\n\n\t\tconst hierarchyTracks = animation.hierarchy || [];\n\n\t\tfor ( let h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\tconst animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t// skip empty tracks\n\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t// process morph targets\n\t\t\tif ( animationKeys[ 0 ].morphTargets ) {\n\n\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\tconst morphTargetNames = {};\n\n\t\t\t\tlet k;\n\n\t\t\t\tfor ( k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\tif ( animationKeys[ k ].morphTargets ) {\n\n\t\t\t\t\t\tfor ( let m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t// the morphTarget is named.\n\t\t\t\tfor ( const morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\tconst times = [];\n\t\t\t\t\tconst values = [];\n\n\t\t\t\t\tfor ( let m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\tconst animationKey = animationKeys[ k ];\n\n\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t}\n\n\t\t\t\tduration = morphTargetNames.length * fps;\n\n\t\t\t} else {\n\n\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\tconst boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\taddNonemptyTrack(\n\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\taddNonemptyTrack(\n\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\taddNonemptyTrack(\n\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( tracks.length === 0 ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst clip = new this( clipName, duration, tracks, blendMode );\n\n\t\treturn clip;\n\n\t}\n\n\tresetDuration() {\n\n\t\tconst tracks = this.tracks;\n\t\tlet duration = 0;\n\n\t\tfor ( let i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\tconst track = this.tracks[ i ];\n\n\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t}\n\n\t\tthis.duration = duration;\n\n\t\treturn this;\n\n\t}\n\n\ttrim() {\n\n\t\tfor ( let i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tvalidate() {\n\n\t\tlet valid = true;\n\n\t\tfor ( let i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\tvalid = valid && this.tracks[ i ].validate();\n\n\t\t}\n\n\t\treturn valid;\n\n\t}\n\n\toptimize() {\n\n\t\tfor ( let i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\tthis.tracks[ i ].optimize();\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\tconst tracks = [];\n\n\t\tfor ( let i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\ttracks.push( this.tracks[ i ].clone() );\n\n\t\t}\n\n\t\treturn new this.constructor( this.name, this.duration, tracks, this.blendMode );\n\n\t}\n\n\ttoJSON() {\n\n\t\treturn this.constructor.toJSON( this );\n\n\t}\n\n}\n\nfunction getTrackTypeForValueTypeName( typeName ) {\n\n\tswitch ( typeName.toLowerCase() ) {\n\n\t\tcase 'scalar':\n\t\tcase 'double':\n\t\tcase 'float':\n\t\tcase 'number':\n\t\tcase 'integer':\n\n\t\t\treturn NumberKeyframeTrack;\n\n\t\tcase 'vector':\n\t\tcase 'vector2':\n\t\tcase 'vector3':\n\t\tcase 'vector4':\n\n\t\t\treturn VectorKeyframeTrack;\n\n\t\tcase 'color':\n\n\t\t\treturn ColorKeyframeTrack;\n\n\t\tcase 'quaternion':\n\n\t\t\treturn QuaternionKeyframeTrack;\n\n\t\tcase 'bool':\n\t\tcase 'boolean':\n\n\t\t\treturn BooleanKeyframeTrack;\n\n\t\tcase 'string':\n\n\t\t\treturn StringKeyframeTrack;\n\n\t}\n\n\tthrow new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName );\n\n}\n\nfunction parseKeyframeTrack( json ) {\n\n\tif ( json.type === undefined ) {\n\n\t\tthrow new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' );\n\n\t}\n\n\tconst trackType = getTrackTypeForValueTypeName( json.type );\n\n\tif ( json.times === undefined ) {\n\n\t\tconst times = [], values = [];\n\n\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\tjson.times = times;\n\t\tjson.values = values;\n\n\t}\n\n\t// derived classes can define a static parse method\n\tif ( trackType.parse !== undefined ) {\n\n\t\treturn trackType.parse( json );\n\n\t} else {\n\n\t\t// by default, we assume a constructor compatible with the base\n\t\treturn new trackType( json.name, json.times, json.values, json.interpolation );\n\n\t}\n\n}\n\nconst Cache = {\n\n\tenabled: false,\n\n\tfiles: {},\n\n\tadd: function ( key, file ) {\n\n\t\tif ( this.enabled === false ) return;\n\n\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\tthis.files[ key ] = file;\n\n\t},\n\n\tget: function ( key ) {\n\n\t\tif ( this.enabled === false ) return;\n\n\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\treturn this.files[ key ];\n\n\t},\n\n\tremove: function ( key ) {\n\n\t\tdelete this.files[ key ];\n\n\t},\n\n\tclear: function () {\n\n\t\tthis.files = {};\n\n\t}\n\n};\n\nclass LoadingManager {\n\n\tconstructor( onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tlet isLoading = false;\n\t\tlet itemsLoaded = 0;\n\t\tlet itemsTotal = 0;\n\t\tlet urlModifier = undefined;\n\t\tconst handlers = [];\n\n\t\t// Refer to #5689 for the reason why we don't set .onStart\n\t\t// in the constructor\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.resolveURL = function ( url ) {\n\n\t\t\tif ( urlModifier ) {\n\n\t\t\t\treturn urlModifier( url );\n\n\t\t\t}\n\n\t\t\treturn url;\n\n\t\t};\n\n\t\tthis.setURLModifier = function ( transform ) {\n\n\t\t\turlModifier = transform;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t\tthis.addHandler = function ( regex, loader ) {\n\n\t\t\thandlers.push( regex, loader );\n\n\t\t\treturn this;\n\n\t\t};\n\n\t\tthis.removeHandler = function ( regex ) {\n\n\t\t\tconst index = handlers.indexOf( regex );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\thandlers.splice( index, 2 );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t};\n\n\t\tthis.getHandler = function ( file ) {\n\n\t\t\tfor ( let i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tconst regex = handlers[ i ];\n\t\t\t\tconst loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.global ) regex.lastIndex = 0; // see #17920\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t};\n\n\t}\n\n}\n\nconst DefaultLoadingManager = new LoadingManager();\n\nclass Loader {\n\n\tconstructor( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.crossOrigin = 'anonymous';\n\t\tthis.withCredentials = false;\n\t\tthis.path = '';\n\t\tthis.resourcePath = '';\n\t\tthis.requestHeader = {};\n\n\t}\n\n\tload( /* url, onLoad, onProgress, onError */ ) {}\n\n\tloadAsync( url, onProgress ) {\n\n\t\tconst scope = this;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tscope.load( url, resolve, onProgress, reject );\n\n\t\t} );\n\n\t}\n\n\tparse( /* data */ ) {}\n\n\tsetCrossOrigin( crossOrigin ) {\n\n\t\tthis.crossOrigin = crossOrigin;\n\t\treturn this;\n\n\t}\n\n\tsetWithCredentials( value ) {\n\n\t\tthis.withCredentials = value;\n\t\treturn this;\n\n\t}\n\n\tsetPath( path ) {\n\n\t\tthis.path = path;\n\t\treturn this;\n\n\t}\n\n\tsetResourcePath( resourcePath ) {\n\n\t\tthis.resourcePath = resourcePath;\n\t\treturn this;\n\n\t}\n\n\tsetRequestHeader( requestHeader ) {\n\n\t\tthis.requestHeader = requestHeader;\n\t\treturn this;\n\n\t}\n\n}\n\nconst loading = {};\n\nclass FileLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tif ( url === undefined ) url = '';\n\n\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\turl = this.manager.resolveURL( url );\n\n\t\tconst cached = Cache.get( url );\n\n\t\tif ( cached !== undefined ) {\n\n\t\t\tthis.manager.itemStart( url );\n\n\t\t\tsetTimeout( () => {\n\n\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\tthis.manager.itemEnd( url );\n\n\t\t\t}, 0 );\n\n\t\t\treturn cached;\n\n\t\t}\n\n\t\t// Check if request is duplicate\n\n\t\tif ( loading[ url ] !== undefined ) {\n\n\t\t\tloading[ url ].push( {\n\n\t\t\t\tonLoad: onLoad,\n\t\t\t\tonProgress: onProgress,\n\t\t\t\tonError: onError\n\n\t\t\t} );\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t// Initialise array for duplicate requests\n\t\tloading[ url ] = [];\n\n\t\tloading[ url ].push( {\n\t\t\tonLoad: onLoad,\n\t\t\tonProgress: onProgress,\n\t\t\tonError: onError,\n\t\t} );\n\n\t\t// create request\n\t\tconst req = new Request( url, {\n\t\t\theaders: new Headers( this.requestHeader ),\n\t\t\tcredentials: this.withCredentials ? 'include' : 'same-origin',\n\t\t\t// An abort controller could be added within a future PR\n\t\t} );\n\n\t\t// record states ( avoid data race )\n\t\tconst mimeType = this.mimeType;\n\t\tconst responseType = this.responseType;\n\n\t\t// start the fetch\n\t\tfetch( req )\n\t\t\t.then( response => {\n\n\t\t\t\tif ( response.status === 200 || response.status === 0 ) {\n\n\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\tif ( response.status === 0 ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Workaround: Checking if response.body === undefined for Alipay browser #23548\n\n\t\t\t\t\tif ( typeof ReadableStream === 'undefined' || response.body === undefined || response.body.getReader === undefined ) {\n\n\t\t\t\t\t\treturn response;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst callbacks = loading[ url ];\n\t\t\t\t\tconst reader = response.body.getReader();\n\t\t\t\t\tconst contentLength = response.headers.get( 'Content-Length' );\n\t\t\t\t\tconst total = contentLength ? parseInt( contentLength ) : 0;\n\t\t\t\t\tconst lengthComputable = total !== 0;\n\t\t\t\t\tlet loaded = 0;\n\n\t\t\t\t\t// periodically read data into the new stream tracking while download progress\n\t\t\t\t\tconst stream = new ReadableStream( {\n\t\t\t\t\t\tstart( controller ) {\n\n\t\t\t\t\t\t\treadData();\n\n\t\t\t\t\t\t\tfunction readData() {\n\n\t\t\t\t\t\t\t\treader.read().then( ( { done, value } ) => {\n\n\t\t\t\t\t\t\t\t\tif ( done ) {\n\n\t\t\t\t\t\t\t\t\t\tcontroller.close();\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tloaded += value.byteLength;\n\n\t\t\t\t\t\t\t\t\t\tconst event = new ProgressEvent( 'progress', { lengthComputable, loaded, total } );\n\t\t\t\t\t\t\t\t\t\tfor ( let i = 0, il = callbacks.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\t\t\t\t\tconst callback = callbacks[ i ];\n\t\t\t\t\t\t\t\t\t\t\tif ( callback.onProgress ) callback.onProgress( event );\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tcontroller.enqueue( value );\n\t\t\t\t\t\t\t\t\t\treadData();\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} );\n\n\t\t\t\t\treturn new Response( stream );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow Error( `fetch for \"${response.url}\" responded with ${response.status}: ${response.statusText}` );\n\n\t\t\t\t}\n\n\t\t\t} )\n\t\t\t.then( response => {\n\n\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\tcase 'arraybuffer':\n\n\t\t\t\t\t\treturn response.arrayBuffer();\n\n\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\treturn response.blob();\n\n\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\treturn response.text()\n\t\t\t\t\t\t\t.then( text => {\n\n\t\t\t\t\t\t\t\tconst parser = new DOMParser();\n\t\t\t\t\t\t\t\treturn parser.parseFromString( text, mimeType );\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\treturn response.json();\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( mimeType === undefined ) {\n\n\t\t\t\t\t\t\treturn response.text();\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// sniff encoding\n\t\t\t\t\t\t\tconst re = /charset=\"?([^;\"\\s]*)\"?/i;\n\t\t\t\t\t\t\tconst exec = re.exec( mimeType );\n\t\t\t\t\t\t\tconst label = exec && exec[ 1 ] ? exec[ 1 ].toLowerCase() : undefined;\n\t\t\t\t\t\t\tconst decoder = new TextDecoder( label );\n\t\t\t\t\t\t\treturn response.arrayBuffer().then( ab => decoder.decode( ab ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} )\n\t\t\t.then( data => {\n\n\t\t\t\t// Add to cache only on HTTP success, so that we do not cache\n\t\t\t\t// error response bodies as proper responses to requests.\n\t\t\t\tCache.add( url, data );\n\n\t\t\t\tconst callbacks = loading[ url ];\n\t\t\t\tdelete loading[ url ];\n\n\t\t\t\tfor ( let i = 0, il = callbacks.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst callback = callbacks[ i ];\n\t\t\t\t\tif ( callback.onLoad ) callback.onLoad( data );\n\n\t\t\t\t}\n\n\t\t\t} )\n\t\t\t.catch( err => {\n\n\t\t\t\t// Abort errors and other errors are handled the same\n\n\t\t\t\tconst callbacks = loading[ url ];\n\n\t\t\t\tif ( callbacks === undefined ) {\n\n\t\t\t\t\t// When onLoad was called and url was deleted in `loading`\n\t\t\t\t\tthis.manager.itemError( url );\n\t\t\t\t\tthrow err;\n\n\t\t\t\t}\n\n\t\t\t\tdelete loading[ url ];\n\n\t\t\t\tfor ( let i = 0, il = callbacks.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst callback = callbacks[ i ];\n\t\t\t\t\tif ( callback.onError ) callback.onError( err );\n\n\t\t\t\t}\n\n\t\t\t\tthis.manager.itemError( url );\n\n\t\t\t} )\n\t\t\t.finally( () => {\n\n\t\t\t\tthis.manager.itemEnd( url );\n\n\t\t\t} );\n\n\t\tthis.manager.itemStart( url );\n\n\t}\n\n\tsetResponseType( value ) {\n\n\t\tthis.responseType = value;\n\t\treturn this;\n\n\t}\n\n\tsetMimeType( value ) {\n\n\t\tthis.mimeType = value;\n\t\treturn this;\n\n\t}\n\n}\n\nclass AnimationLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setPath( this.path );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\t\tloader.load( url, function ( text ) {\n\n\t\t\ttry {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\tif ( onError ) {\n\n\t\t\t\t\tonError( e );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t}\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\tparse( json ) {\n\n\t\tconst animations = [];\n\n\t\tfor ( let i = 0; i < json.length; i ++ ) {\n\n\t\t\tconst clip = AnimationClip.parse( json[ i ] );\n\n\t\t\tanimations.push( clip );\n\n\t\t}\n\n\t\treturn animations;\n\n\t}\n\n}\n\n/**\n * Abstract Base class to block based textures loader (dds, pvr, ...)\n *\n * Sub classes have to implement the parse() method which will be used in load().\n */\n\nclass CompressedTextureLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst images = [];\n\n\t\tconst texture = new CompressedTexture();\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setPath( this.path );\n\t\tloader.setResponseType( 'arraybuffer' );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( scope.withCredentials );\n\n\t\tlet loaded = 0;\n\n\t\tfunction loadTexture( i ) {\n\n\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\tconst texDatas = scope.parse( buffer, true );\n\n\t\t\t\timages[ i ] = {\n\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t};\n\n\t\t\t\tloaded += 1;\n\n\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) texture.minFilter = LinearFilter;\n\n\t\t\t\t\ttexture.image = images;\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t\tif ( Array.isArray( url ) ) {\n\n\t\t\tfor ( let i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tconst texDatas = scope.parse( buffer, true );\n\n\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\tconst faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\tfor ( let f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\timages[ f ] = { mipmaps: [] };\n\n\t\t\t\t\t\tfor ( let i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.image = images;\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t\treturn texture;\n\n\t}\n\n}\n\nclass ImageLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\turl = this.manager.resolveURL( url );\n\n\t\tconst scope = this;\n\n\t\tconst cached = Cache.get( url );\n\n\t\tif ( cached !== undefined ) {\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\tsetTimeout( function () {\n\n\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, 0 );\n\n\t\t\treturn cached;\n\n\t\t}\n\n\t\tconst image = createElementNS( 'img' );\n\n\t\tfunction onImageLoad() {\n\n\t\t\tremoveEventListeners();\n\n\t\t\tCache.add( url, this );\n\n\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\tscope.manager.itemEnd( url );\n\n\t\t}\n\n\t\tfunction onImageError( event ) {\n\n\t\t\tremoveEventListeners();\n\n\t\t\tif ( onError ) onError( event );\n\n\t\t\tscope.manager.itemError( url );\n\t\t\tscope.manager.itemEnd( url );\n\n\t\t}\n\n\t\tfunction removeEventListeners() {\n\n\t\t\timage.removeEventListener( 'load', onImageLoad, false );\n\t\t\timage.removeEventListener( 'error', onImageError, false );\n\n\t\t}\n\n\t\timage.addEventListener( 'load', onImageLoad, false );\n\t\timage.addEventListener( 'error', onImageError, false );\n\n\t\tif ( url.slice( 0, 5 ) !== 'data:' ) {\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t}\n\n\t\tscope.manager.itemStart( url );\n\n\t\timage.src = url;\n\n\t\treturn image;\n\n\t}\n\n}\n\nclass CubeTextureLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( urls, onLoad, onProgress, onError ) {\n\n\t\tconst texture = new CubeTexture();\n\n\t\tconst loader = new ImageLoader( this.manager );\n\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\tloader.setPath( this.path );\n\n\t\tlet loaded = 0;\n\n\t\tfunction loadTexture( i ) {\n\n\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\tloaded ++;\n\n\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, undefined, onError );\n\n\t\t}\n\n\t\tfor ( let i = 0; i < urls.length; ++ i ) {\n\n\t\t\tloadTexture( i );\n\n\t\t}\n\n\t\treturn texture;\n\n\t}\n\n}\n\n/**\n * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n *\n * Sub classes have to implement the parse() method which will be used in load().\n */\n\nclass DataTextureLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst texture = new DataTexture();\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setResponseType( 'arraybuffer' );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setPath( this.path );\n\t\tloader.setWithCredentials( scope.withCredentials );\n\t\tloader.load( url, function ( buffer ) {\n\n\t\t\tconst texData = scope.parse( buffer );\n\n\t\t\tif ( ! texData ) return;\n\n\t\t\tif ( texData.image !== undefined ) {\n\n\t\t\t\ttexture.image = texData.image;\n\n\t\t\t} else if ( texData.data !== undefined ) {\n\n\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t}\n\n\t\t\ttexture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\ttexture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\ttexture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;\n\t\t\ttexture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;\n\n\t\t\ttexture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;\n\n\t\t\tif ( texData.encoding !== undefined ) {\n\n\t\t\t\ttexture.encoding = texData.encoding;\n\n\t\t\t}\n\n\t\t\tif ( texData.flipY !== undefined ) {\n\n\t\t\t\ttexture.flipY = texData.flipY;\n\n\t\t\t}\n\n\t\t\tif ( texData.format !== undefined ) {\n\n\t\t\t\ttexture.format = texData.format;\n\n\t\t\t}\n\n\t\t\tif ( texData.type !== undefined ) {\n\n\t\t\t\ttexture.type = texData.type;\n\n\t\t\t}\n\n\t\t\tif ( texData.mipmaps !== undefined ) {\n\n\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\t\t\t\ttexture.minFilter = LinearMipmapLinearFilter; // presumably...\n\n\t\t\t}\n\n\t\t\tif ( texData.mipmapCount === 1 ) {\n\n\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t}\n\n\t\t\tif ( texData.generateMipmaps !== undefined ) {\n\n\t\t\t\ttexture.generateMipmaps = texData.generateMipmaps;\n\n\t\t\t}\n\n\t\t\ttexture.needsUpdate = true;\n\n\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t}, onProgress, onError );\n\n\n\t\treturn texture;\n\n\t}\n\n}\n\nclass TextureLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst texture = new Texture();\n\n\t\tconst loader = new ImageLoader( this.manager );\n\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\tloader.setPath( this.path );\n\n\t\tloader.load( url, function ( image ) {\n\n\t\t\ttexture.image = image;\n\t\t\ttexture.needsUpdate = true;\n\n\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\tonLoad( texture );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t\treturn texture;\n\n\t}\n\n}\n\nclass Light extends Object3D {\n\n\tconstructor( color, intensity = 1 ) {\n\n\t\tsuper();\n\n\t\tthis.isLight = true;\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity;\n\n\t}\n\n\tdispose() {\n\n\t\t// Empty here in base class; some subclasses override.\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.intensity = source.intensity;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tdata.object.color = this.color.getHex();\n\t\tdata.object.intensity = this.intensity;\n\n\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\treturn data;\n\n\t}\n\n}\n\nclass HemisphereLight extends Light {\n\n\tconstructor( skyColor, groundColor, intensity ) {\n\n\t\tsuper( skyColor, intensity );\n\n\t\tthis.isHemisphereLight = true;\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.groundColor.copy( source.groundColor );\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst _projScreenMatrix$1 = /*@__PURE__*/ new Matrix4();\nconst _lightPositionWorld$1 = /*@__PURE__*/ new Vector3();\nconst _lookTarget$1 = /*@__PURE__*/ new Vector3();\n\nclass LightShadow {\n\n\tconstructor( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.normalBias = 0;\n\t\tthis.radius = 1;\n\t\tthis.blurSamples = 8;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.mapPass = null;\n\t\tthis.matrix = new Matrix4();\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis._frustum = new Frustum();\n\t\tthis._frameExtents = new Vector2( 1, 1 );\n\n\t\tthis._viewportCount = 1;\n\n\t\tthis._viewports = [\n\n\t\t\tnew Vector4( 0, 0, 1, 1 )\n\n\t\t];\n\n\t}\n\n\tgetViewportCount() {\n\n\t\treturn this._viewportCount;\n\n\t}\n\n\tgetFrustum() {\n\n\t\treturn this._frustum;\n\n\t}\n\n\tupdateMatrices( light ) {\n\n\t\tconst shadowCamera = this.camera;\n\t\tconst shadowMatrix = this.matrix;\n\n\t\t_lightPositionWorld$1.setFromMatrixPosition( light.matrixWorld );\n\t\tshadowCamera.position.copy( _lightPositionWorld$1 );\n\n\t\t_lookTarget$1.setFromMatrixPosition( light.target.matrixWorld );\n\t\tshadowCamera.lookAt( _lookTarget$1 );\n\t\tshadowCamera.updateMatrixWorld();\n\n\t\t_projScreenMatrix$1.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\tthis._frustum.setFromProjectionMatrix( _projScreenMatrix$1 );\n\n\t\tshadowMatrix.set(\n\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t);\n\n\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t}\n\n\tgetViewport( viewportIndex ) {\n\n\t\treturn this._viewports[ viewportIndex ];\n\n\t}\n\n\tgetFrameExtents() {\n\n\t\treturn this._frameExtents;\n\n\t}\n\n\tdispose() {\n\n\t\tif ( this.map ) {\n\n\t\t\tthis.map.dispose();\n\n\t\t}\n\n\t\tif ( this.mapPass ) {\n\n\t\t\tthis.mapPass.dispose();\n\n\t\t}\n\n\t}\n\n\tcopy( source ) {\n\n\t\tthis.camera = source.camera.clone();\n\n\t\tthis.bias = source.bias;\n\t\tthis.radius = source.radius;\n\n\t\tthis.mapSize.copy( source.mapSize );\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst object = {};\n\n\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\tif ( this.normalBias !== 0 ) object.normalBias = this.normalBias;\n\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\tdelete object.camera.matrix;\n\n\t\treturn object;\n\n\t}\n\n}\n\nclass SpotLightShadow extends LightShadow {\n\n\tconstructor() {\n\n\t\tsuper( new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t\tthis.isSpotLightShadow = true;\n\n\t\tthis.focus = 1;\n\n\t}\n\n\tupdateMatrices( light ) {\n\n\t\tconst camera = this.camera;\n\n\t\tconst fov = RAD2DEG * 2 * light.angle * this.focus;\n\t\tconst aspect = this.mapSize.width / this.mapSize.height;\n\t\tconst far = light.distance || camera.far;\n\n\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\tcamera.fov = fov;\n\t\t\tcamera.aspect = aspect;\n\t\t\tcamera.far = far;\n\t\t\tcamera.updateProjectionMatrix();\n\n\t\t}\n\n\t\tsuper.updateMatrices( light );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.focus = source.focus;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass SpotLight extends Light {\n\n\tconstructor( color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1 ) {\n\n\t\tsuper( color, intensity );\n\n\t\tthis.isSpotLight = true;\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.distance = distance;\n\t\tthis.angle = angle;\n\t\tthis.penumbra = penumbra;\n\t\tthis.decay = decay; // for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tget power() {\n\n\t\t// compute the light's luminous power (in lumens) from its intensity (in candela)\n\t\t// by convention for a spotlight, luminous power (lm) = π * luminous intensity (cd)\n\t\treturn this.intensity * Math.PI;\n\n\t}\n\n\tset power( power ) {\n\n\t\t// set the light's intensity (in candela) from the desired luminous power (in lumens)\n\t\tthis.intensity = power / Math.PI;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.shadow.dispose();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.distance = source.distance;\n\t\tthis.angle = source.angle;\n\t\tthis.penumbra = source.penumbra;\n\t\tthis.decay = source.decay;\n\n\t\tthis.target = source.target.clone();\n\n\t\tthis.shadow = source.shadow.clone();\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst _projScreenMatrix = /*@__PURE__*/ new Matrix4();\nconst _lightPositionWorld = /*@__PURE__*/ new Vector3();\nconst _lookTarget = /*@__PURE__*/ new Vector3();\n\nclass PointLightShadow extends LightShadow {\n\n\tconstructor() {\n\n\t\tsuper( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t\tthis.isPointLightShadow = true;\n\n\t\tthis._frameExtents = new Vector2( 4, 2 );\n\n\t\tthis._viewportCount = 6;\n\n\t\tthis._viewports = [\n\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t// following orientation:\n\t\t\t//\n\t\t\t// xzXZ\n\t\t\t// y Y\n\t\t\t//\n\t\t\t// X - Positive x direction\n\t\t\t// x - Negative x direction\n\t\t\t// Y - Positive y direction\n\t\t\t// y - Negative y direction\n\t\t\t// Z - Positive z direction\n\t\t\t// z - Negative z direction\n\n\t\t\t// positive X\n\t\t\tnew Vector4( 2, 1, 1, 1 ),\n\t\t\t// negative X\n\t\t\tnew Vector4( 0, 1, 1, 1 ),\n\t\t\t// positive Z\n\t\t\tnew Vector4( 3, 1, 1, 1 ),\n\t\t\t// negative Z\n\t\t\tnew Vector4( 1, 1, 1, 1 ),\n\t\t\t// positive Y\n\t\t\tnew Vector4( 3, 0, 1, 1 ),\n\t\t\t// negative Y\n\t\t\tnew Vector4( 1, 0, 1, 1 )\n\t\t];\n\n\t\tthis._cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tthis._cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t}\n\n\tupdateMatrices( light, viewportIndex = 0 ) {\n\n\t\tconst camera = this.camera;\n\t\tconst shadowMatrix = this.matrix;\n\n\t\tconst far = light.distance || camera.far;\n\n\t\tif ( far !== camera.far ) {\n\n\t\t\tcamera.far = far;\n\t\t\tcamera.updateProjectionMatrix();\n\n\t\t}\n\n\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\tcamera.position.copy( _lightPositionWorld );\n\n\t\t_lookTarget.copy( camera.position );\n\t\t_lookTarget.add( this._cubeDirections[ viewportIndex ] );\n\t\tcamera.up.copy( this._cubeUps[ viewportIndex ] );\n\t\tcamera.lookAt( _lookTarget );\n\t\tcamera.updateMatrixWorld();\n\n\t\tshadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z );\n\n\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\tthis._frustum.setFromProjectionMatrix( _projScreenMatrix );\n\n\t}\n\n}\n\nclass PointLight extends Light {\n\n\tconstructor( color, intensity, distance = 0, decay = 1 ) {\n\n\t\tsuper( color, intensity );\n\n\t\tthis.isPointLight = true;\n\n\t\tthis.type = 'PointLight';\n\n\t\tthis.distance = distance;\n\t\tthis.decay = decay; // for physically correct lights, should be 2.\n\n\t\tthis.shadow = new PointLightShadow();\n\n\t}\n\n\tget power() {\n\n\t\t// compute the light's luminous power (in lumens) from its intensity (in candela)\n\t\t// for an isotropic light source, luminous power (lm) = 4 π luminous intensity (cd)\n\t\treturn this.intensity * 4 * Math.PI;\n\n\t}\n\n\tset power( power ) {\n\n\t\t// set the light's intensity (in candela) from the desired luminous power (in lumens)\n\t\tthis.intensity = power / ( 4 * Math.PI );\n\n\t}\n\n\tdispose() {\n\n\t\tthis.shadow.dispose();\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.distance = source.distance;\n\t\tthis.decay = source.decay;\n\n\t\tthis.shadow = source.shadow.clone();\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass DirectionalLightShadow extends LightShadow {\n\n\tconstructor() {\n\n\t\tsuper( new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t\tthis.isDirectionalLightShadow = true;\n\n\t}\n\n}\n\nclass DirectionalLight extends Light {\n\n\tconstructor( color, intensity ) {\n\n\t\tsuper( color, intensity );\n\n\t\tthis.isDirectionalLight = true;\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tdispose() {\n\n\t\tthis.shadow.dispose();\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.target = source.target.clone();\n\t\tthis.shadow = source.shadow.clone();\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass AmbientLight extends Light {\n\n\tconstructor( color, intensity ) {\n\n\t\tsuper( color, intensity );\n\n\t\tthis.isAmbientLight = true;\n\n\t\tthis.type = 'AmbientLight';\n\n\t}\n\n}\n\nclass RectAreaLight extends Light {\n\n\tconstructor( color, intensity, width = 10, height = 10 ) {\n\n\t\tsuper( color, intensity );\n\n\t\tthis.isRectAreaLight = true;\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t}\n\n\tget power() {\n\n\t\t// compute the light's luminous power (in lumens) from its intensity (in nits)\n\t\treturn this.intensity * this.width * this.height * Math.PI;\n\n\t}\n\n\tset power( power ) {\n\n\t\t// set the light's intensity (in nits) from the desired luminous power (in lumens)\n\t\tthis.intensity = power / ( this.width * this.height * Math.PI );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.width = source.width;\n\t\tthis.height = source.height;\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tdata.object.width = this.width;\n\t\tdata.object.height = this.height;\n\n\t\treturn data;\n\n\t}\n\n}\n\n/**\n * Primary reference:\n * https://graphics.stanford.edu/papers/envmap/envmap.pdf\n *\n * Secondary reference:\n * https://www.ppsloan.org/publications/StupidSH36.pdf\n */\n\n// 3-band SH defined by 9 coefficients\n\nclass SphericalHarmonics3 {\n\n\tconstructor() {\n\n\t\tthis.isSphericalHarmonics3 = true;\n\n\t\tthis.coefficients = [];\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.coefficients.push( new Vector3() );\n\n\t\t}\n\n\t}\n\n\tset( coefficients ) {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.coefficients[ i ].copy( coefficients[ i ] );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tzero() {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.coefficients[ i ].set( 0, 0, 0 );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t// get the radiance in the direction of the normal\n\t// target is a Vector3\n\tgetAt( normal, target ) {\n\n\t\t// normal is assumed to be unit length\n\n\t\tconst x = normal.x, y = normal.y, z = normal.z;\n\n\t\tconst coeff = this.coefficients;\n\n\t\t// band 0\n\t\ttarget.copy( coeff[ 0 ] ).multiplyScalar( 0.282095 );\n\n\t\t// band 1\n\t\ttarget.addScaledVector( coeff[ 1 ], 0.488603 * y );\n\t\ttarget.addScaledVector( coeff[ 2 ], 0.488603 * z );\n\t\ttarget.addScaledVector( coeff[ 3 ], 0.488603 * x );\n\n\t\t// band 2\n\t\ttarget.addScaledVector( coeff[ 4 ], 1.092548 * ( x * y ) );\n\t\ttarget.addScaledVector( coeff[ 5 ], 1.092548 * ( y * z ) );\n\t\ttarget.addScaledVector( coeff[ 6 ], 0.315392 * ( 3.0 * z * z - 1.0 ) );\n\t\ttarget.addScaledVector( coeff[ 7 ], 1.092548 * ( x * z ) );\n\t\ttarget.addScaledVector( coeff[ 8 ], 0.546274 * ( x * x - y * y ) );\n\n\t\treturn target;\n\n\t}\n\n\t// get the irradiance (radiance convolved with cosine lobe) in the direction of the normal\n\t// target is a Vector3\n\t// https://graphics.stanford.edu/papers/envmap/envmap.pdf\n\tgetIrradianceAt( normal, target ) {\n\n\t\t// normal is assumed to be unit length\n\n\t\tconst x = normal.x, y = normal.y, z = normal.z;\n\n\t\tconst coeff = this.coefficients;\n\n\t\t// band 0\n\t\ttarget.copy( coeff[ 0 ] ).multiplyScalar( 0.886227 ); // π * 0.282095\n\n\t\t// band 1\n\t\ttarget.addScaledVector( coeff[ 1 ], 2.0 * 0.511664 * y ); // ( 2 * π / 3 ) * 0.488603\n\t\ttarget.addScaledVector( coeff[ 2 ], 2.0 * 0.511664 * z );\n\t\ttarget.addScaledVector( coeff[ 3 ], 2.0 * 0.511664 * x );\n\n\t\t// band 2\n\t\ttarget.addScaledVector( coeff[ 4 ], 2.0 * 0.429043 * x * y ); // ( π / 4 ) * 1.092548\n\t\ttarget.addScaledVector( coeff[ 5 ], 2.0 * 0.429043 * y * z );\n\t\ttarget.addScaledVector( coeff[ 6 ], 0.743125 * z * z - 0.247708 ); // ( π / 4 ) * 0.315392 * 3\n\t\ttarget.addScaledVector( coeff[ 7 ], 2.0 * 0.429043 * x * z );\n\t\ttarget.addScaledVector( coeff[ 8 ], 0.429043 * ( x * x - y * y ) ); // ( π / 4 ) * 0.546274\n\n\t\treturn target;\n\n\t}\n\n\tadd( sh ) {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.coefficients[ i ].add( sh.coefficients[ i ] );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\taddScaledSH( sh, s ) {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.coefficients[ i ].addScaledVector( sh.coefficients[ i ], s );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tscale( s ) {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.coefficients[ i ].multiplyScalar( s );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tlerp( sh, alpha ) {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tthis.coefficients[ i ].lerp( sh.coefficients[ i ], alpha );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tequals( sh ) {\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tif ( ! this.coefficients[ i ].equals( sh.coefficients[ i ] ) ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\tcopy( sh ) {\n\n\t\treturn this.set( sh.coefficients );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tfromArray( array, offset = 0 ) {\n\n\t\tconst coefficients = this.coefficients;\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tcoefficients[ i ].fromArray( array, offset + ( i * 3 ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\ttoArray( array = [], offset = 0 ) {\n\n\t\tconst coefficients = this.coefficients;\n\n\t\tfor ( let i = 0; i < 9; i ++ ) {\n\n\t\t\tcoefficients[ i ].toArray( array, offset + ( i * 3 ) );\n\n\t\t}\n\n\t\treturn array;\n\n\t}\n\n\t// evaluate the basis functions\n\t// shBasis is an Array[ 9 ]\n\tstatic getBasisAt( normal, shBasis ) {\n\n\t\t// normal is assumed to be unit length\n\n\t\tconst x = normal.x, y = normal.y, z = normal.z;\n\n\t\t// band 0\n\t\tshBasis[ 0 ] = 0.282095;\n\n\t\t// band 1\n\t\tshBasis[ 1 ] = 0.488603 * y;\n\t\tshBasis[ 2 ] = 0.488603 * z;\n\t\tshBasis[ 3 ] = 0.488603 * x;\n\n\t\t// band 2\n\t\tshBasis[ 4 ] = 1.092548 * x * y;\n\t\tshBasis[ 5 ] = 1.092548 * y * z;\n\t\tshBasis[ 6 ] = 0.315392 * ( 3 * z * z - 1 );\n\t\tshBasis[ 7 ] = 1.092548 * x * z;\n\t\tshBasis[ 8 ] = 0.546274 * ( x * x - y * y );\n\n\t}\n\n}\n\nclass LightProbe extends Light {\n\n\tconstructor( sh = new SphericalHarmonics3(), intensity = 1 ) {\n\n\t\tsuper( undefined, intensity );\n\n\t\tthis.isLightProbe = true;\n\n\t\tthis.sh = sh;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.sh.copy( source.sh );\n\n\t\treturn this;\n\n\t}\n\n\tfromJSON( json ) {\n\n\t\tthis.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON();\n\t\tthis.sh.fromArray( json.sh );\n\n\t\treturn this;\n\n\t}\n\n\ttoJSON( meta ) {\n\n\t\tconst data = super.toJSON( meta );\n\n\t\tdata.object.sh = this.sh.toArray();\n\n\t\treturn data;\n\n\t}\n\n}\n\nclass MaterialLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\t\tthis.textures = {};\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst loader = new FileLoader( scope.manager );\n\t\tloader.setPath( scope.path );\n\t\tloader.setRequestHeader( scope.requestHeader );\n\t\tloader.setWithCredentials( scope.withCredentials );\n\t\tloader.load( url, function ( text ) {\n\n\t\t\ttry {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\tif ( onError ) {\n\n\t\t\t\t\tonError( e );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t}\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\tparse( json ) {\n\n\t\tconst textures = this.textures;\n\n\t\tfunction getTexture( name ) {\n\n\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t}\n\n\t\t\treturn textures[ name ];\n\n\t\t}\n\n\t\tconst material = Material.fromType( json.type );\n\n\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\tif ( json.color !== undefined && material.color !== undefined ) material.color.setHex( json.color );\n\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\tif ( json.sheen !== undefined ) material.sheen = json.sheen;\n\t\tif ( json.sheenColor !== undefined ) material.sheenColor = new Color().setHex( json.sheenColor );\n\t\tif ( json.sheenRoughness !== undefined ) material.sheenRoughness = json.sheenRoughness;\n\t\tif ( json.emissive !== undefined && material.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\tif ( json.specular !== undefined && material.specular !== undefined ) material.specular.setHex( json.specular );\n\t\tif ( json.specularIntensity !== undefined ) material.specularIntensity = json.specularIntensity;\n\t\tif ( json.specularColor !== undefined && material.specularColor !== undefined ) material.specularColor.setHex( json.specularColor );\n\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\tif ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat;\n\t\tif ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness;\n\t\tif ( json.iridescence !== undefined ) material.iridescence = json.iridescence;\n\t\tif ( json.iridescenceIOR !== undefined ) material.iridescenceIOR = json.iridescenceIOR;\n\t\tif ( json.iridescenceThicknessRange !== undefined ) material.iridescenceThicknessRange = json.iridescenceThicknessRange;\n\t\tif ( json.transmission !== undefined ) material.transmission = json.transmission;\n\t\tif ( json.thickness !== undefined ) material.thickness = json.thickness;\n\t\tif ( json.attenuationDistance !== undefined ) material.attenuationDistance = json.attenuationDistance;\n\t\tif ( json.attenuationColor !== undefined && material.attenuationColor !== undefined ) material.attenuationColor.setHex( json.attenuationColor );\n\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\tif ( json.flatShading !== undefined ) material.flatShading = json.flatShading;\n\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\tif ( json.combine !== undefined ) material.combine = json.combine;\n\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\tif ( json.shadowSide !== undefined ) material.shadowSide = json.shadowSide;\n\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\n\t\tif ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite;\n\t\tif ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask;\n\t\tif ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc;\n\t\tif ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef;\n\t\tif ( json.stencilFuncMask !== undefined ) material.stencilFuncMask = json.stencilFuncMask;\n\t\tif ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail;\n\t\tif ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail;\n\t\tif ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass;\n\n\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\n\t\tif ( json.rotation !== undefined ) material.rotation = json.rotation;\n\n\t\tif ( json.linewidth !== 1 ) material.linewidth = json.linewidth;\n\t\tif ( json.dashSize !== undefined ) material.dashSize = json.dashSize;\n\t\tif ( json.gapSize !== undefined ) material.gapSize = json.gapSize;\n\t\tif ( json.scale !== undefined ) material.scale = json.scale;\n\n\t\tif ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset;\n\t\tif ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor;\n\t\tif ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits;\n\n\t\tif ( json.dithering !== undefined ) material.dithering = json.dithering;\n\n\t\tif ( json.alphaToCoverage !== undefined ) material.alphaToCoverage = json.alphaToCoverage;\n\t\tif ( json.premultipliedAlpha !== undefined ) material.premultipliedAlpha = json.premultipliedAlpha;\n\n\t\tif ( json.visible !== undefined ) material.visible = json.visible;\n\n\t\tif ( json.toneMapped !== undefined ) material.toneMapped = json.toneMapped;\n\n\t\tif ( json.userData !== undefined ) material.userData = json.userData;\n\n\t\tif ( json.vertexColors !== undefined ) {\n\n\t\t\tif ( typeof json.vertexColors === 'number' ) {\n\n\t\t\t\tmaterial.vertexColors = ( json.vertexColors > 0 ) ? true : false;\n\n\t\t\t} else {\n\n\t\t\t\tmaterial.vertexColors = json.vertexColors;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Shader Material\n\n\t\tif ( json.uniforms !== undefined ) {\n\n\t\t\tfor ( const name in json.uniforms ) {\n\n\t\t\t\tconst uniform = json.uniforms[ name ];\n\n\t\t\t\tmaterial.uniforms[ name ] = {};\n\n\t\t\t\tswitch ( uniform.type ) {\n\n\t\t\t\t\tcase 't':\n\t\t\t\t\t\tmaterial.uniforms[ name ].value = getTexture( uniform.value );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'c':\n\t\t\t\t\t\tmaterial.uniforms[ name ].value = new Color().setHex( uniform.value );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'v2':\n\t\t\t\t\t\tmaterial.uniforms[ name ].value = new Vector2().fromArray( uniform.value );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'v3':\n\t\t\t\t\t\tmaterial.uniforms[ name ].value = new Vector3().fromArray( uniform.value );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'v4':\n\t\t\t\t\t\tmaterial.uniforms[ name ].value = new Vector4().fromArray( uniform.value );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'm3':\n\t\t\t\t\t\tmaterial.uniforms[ name ].value = new Matrix3().fromArray( uniform.value );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'm4':\n\t\t\t\t\t\tmaterial.uniforms[ name ].value = new Matrix4().fromArray( uniform.value );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tmaterial.uniforms[ name ].value = uniform.value;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( json.defines !== undefined ) material.defines = json.defines;\n\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\n\t\tif ( json.extensions !== undefined ) {\n\n\t\t\tfor ( const key in json.extensions ) {\n\n\t\t\t\tmaterial.extensions[ key ] = json.extensions[ key ];\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Deprecated\n\n\t\tif ( json.shading !== undefined ) material.flatShading = json.shading === 1; // THREE.FlatShading\n\n\t\t// for PointsMaterial\n\n\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t// maps\n\n\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\t\tif ( json.matcap !== undefined ) material.matcap = getTexture( json.matcap );\n\n\t\tif ( json.alphaMap !== undefined ) material.alphaMap = getTexture( json.alphaMap );\n\n\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\tif ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType;\n\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\tlet normalScale = json.normalScale;\n\n\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t}\n\n\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t}\n\n\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\t\tif ( json.specularIntensityMap !== undefined ) material.specularIntensityMap = getTexture( json.specularIntensityMap );\n\t\tif ( json.specularColorMap !== undefined ) material.specularColorMap = getTexture( json.specularColorMap );\n\n\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\t\tif ( json.envMapIntensity !== undefined ) material.envMapIntensity = json.envMapIntensity;\n\n\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\t\tif ( json.refractionRatio !== undefined ) material.refractionRatio = json.refractionRatio;\n\n\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\tif ( json.clearcoatMap !== undefined ) material.clearcoatMap = getTexture( json.clearcoatMap );\n\t\tif ( json.clearcoatRoughnessMap !== undefined ) material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap );\n\t\tif ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap );\n\t\tif ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale );\n\n\t\tif ( json.iridescenceMap !== undefined ) material.iridescenceMap = getTexture( json.iridescenceMap );\n\t\tif ( json.iridescenceThicknessMap !== undefined ) material.iridescenceThicknessMap = getTexture( json.iridescenceThicknessMap );\n\n\t\tif ( json.transmissionMap !== undefined ) material.transmissionMap = getTexture( json.transmissionMap );\n\t\tif ( json.thicknessMap !== undefined ) material.thicknessMap = getTexture( json.thicknessMap );\n\n\t\tif ( json.sheenColorMap !== undefined ) material.sheenColorMap = getTexture( json.sheenColorMap );\n\t\tif ( json.sheenRoughnessMap !== undefined ) material.sheenRoughnessMap = getTexture( json.sheenRoughnessMap );\n\n\t\treturn material;\n\n\t}\n\n\tsetTextures( value ) {\n\n\t\tthis.textures = value;\n\t\treturn this;\n\n\t}\n\n}\n\nclass LoaderUtils {\n\n\tstatic decodeText( array ) {\n\n\t\tif ( typeof TextDecoder !== 'undefined' ) {\n\n\t\t\treturn new TextDecoder().decode( array );\n\n\t\t}\n\n\t\t// Avoid the String.fromCharCode.apply(null, array) shortcut, which\n\t\t// throws a \"maximum call stack size exceeded\" error for large arrays.\n\n\t\tlet s = '';\n\n\t\tfor ( let i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t// Implicitly assumes little-endian.\n\t\t\ts += String.fromCharCode( array[ i ] );\n\n\t\t}\n\n\t\ttry {\n\n\t\t\t// merges multi-byte utf-8 characters.\n\n\t\t\treturn decodeURIComponent( escape( s ) );\n\n\t\t} catch ( e ) { // see #16358\n\n\t\t\treturn s;\n\n\t\t}\n\n\t}\n\n\tstatic extractUrlBase( url ) {\n\n\t\tconst index = url.lastIndexOf( '/' );\n\n\t\tif ( index === - 1 ) return './';\n\n\t\treturn url.slice( 0, index + 1 );\n\n\t}\n\n\tstatic resolveURL( url, path ) {\n\n\t\t// Invalid URL\n\t\tif ( typeof url !== 'string' || url === '' ) return '';\n\n\t\t// Host Relative URL\n\t\tif ( /^https?:\\/\\//i.test( path ) && /^\\//.test( url ) ) {\n\n\t\t\tpath = path.replace( /(^https?:\\/\\/[^\\/]+).*/i, '$1' );\n\n\t\t}\n\n\t\t// Absolute URL http://,https://,//\n\t\tif ( /^(https?:)?\\/\\//i.test( url ) ) return url;\n\n\t\t// Data URI\n\t\tif ( /^data:.*,.*$/i.test( url ) ) return url;\n\n\t\t// Blob URL\n\t\tif ( /^blob:.*$/i.test( url ) ) return url;\n\n\t\t// Relative URL\n\t\treturn path + url;\n\n\t}\n\n}\n\nclass InstancedBufferGeometry extends BufferGeometry {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.isInstancedBufferGeometry = true;\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.instanceCount = Infinity;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.instanceCount = source.instanceCount;\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\ttoJSON() {\n\n\t\tconst data = super.toJSON( this );\n\n\t\tdata.instanceCount = this.instanceCount;\n\n\t\tdata.isInstancedBufferGeometry = true;\n\n\t\treturn data;\n\n\t}\n\n}\n\nclass BufferGeometryLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst loader = new FileLoader( scope.manager );\n\t\tloader.setPath( scope.path );\n\t\tloader.setRequestHeader( scope.requestHeader );\n\t\tloader.setWithCredentials( scope.withCredentials );\n\t\tloader.load( url, function ( text ) {\n\n\t\t\ttry {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\tif ( onError ) {\n\n\t\t\t\t\tonError( e );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t}\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\tparse( json ) {\n\n\t\tconst interleavedBufferMap = {};\n\t\tconst arrayBufferMap = {};\n\n\t\tfunction getInterleavedBuffer( json, uuid ) {\n\n\t\t\tif ( interleavedBufferMap[ uuid ] !== undefined ) return interleavedBufferMap[ uuid ];\n\n\t\t\tconst interleavedBuffers = json.interleavedBuffers;\n\t\t\tconst interleavedBuffer = interleavedBuffers[ uuid ];\n\n\t\t\tconst buffer = getArrayBuffer( json, interleavedBuffer.buffer );\n\n\t\t\tconst array = getTypedArray( interleavedBuffer.type, buffer );\n\t\t\tconst ib = new InterleavedBuffer( array, interleavedBuffer.stride );\n\t\t\tib.uuid = interleavedBuffer.uuid;\n\n\t\t\tinterleavedBufferMap[ uuid ] = ib;\n\n\t\t\treturn ib;\n\n\t\t}\n\n\t\tfunction getArrayBuffer( json, uuid ) {\n\n\t\t\tif ( arrayBufferMap[ uuid ] !== undefined ) return arrayBufferMap[ uuid ];\n\n\t\t\tconst arrayBuffers = json.arrayBuffers;\n\t\t\tconst arrayBuffer = arrayBuffers[ uuid ];\n\n\t\t\tconst ab = new Uint32Array( arrayBuffer ).buffer;\n\n\t\t\tarrayBufferMap[ uuid ] = ab;\n\n\t\t\treturn ab;\n\n\t\t}\n\n\t\tconst geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry();\n\n\t\tconst index = json.data.index;\n\n\t\tif ( index !== undefined ) {\n\n\t\t\tconst typedArray = getTypedArray( index.type, index.array );\n\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t}\n\n\t\tconst attributes = json.data.attributes;\n\n\t\tfor ( const key in attributes ) {\n\n\t\t\tconst attribute = attributes[ key ];\n\t\t\tlet bufferAttribute;\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tconst interleavedBuffer = getInterleavedBuffer( json.data, attribute.data );\n\t\t\t\tbufferAttribute = new InterleavedBufferAttribute( interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized );\n\n\t\t\t} else {\n\n\t\t\t\tconst typedArray = getTypedArray( attribute.type, attribute.array );\n\t\t\t\tconst bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute;\n\t\t\t\tbufferAttribute = new bufferAttributeConstr( typedArray, attribute.itemSize, attribute.normalized );\n\n\t\t\t}\n\n\t\t\tif ( attribute.name !== undefined ) bufferAttribute.name = attribute.name;\n\t\t\tif ( attribute.usage !== undefined ) bufferAttribute.setUsage( attribute.usage );\n\n\t\t\tif ( attribute.updateRange !== undefined ) {\n\n\t\t\t\tbufferAttribute.updateRange.offset = attribute.updateRange.offset;\n\t\t\t\tbufferAttribute.updateRange.count = attribute.updateRange.count;\n\n\t\t\t}\n\n\t\t\tgeometry.setAttribute( key, bufferAttribute );\n\n\t\t}\n\n\t\tconst morphAttributes = json.data.morphAttributes;\n\n\t\tif ( morphAttributes ) {\n\n\t\t\tfor ( const key in morphAttributes ) {\n\n\t\t\t\tconst attributeArray = morphAttributes[ key ];\n\n\t\t\t\tconst array = [];\n\n\t\t\t\tfor ( let i = 0, il = attributeArray.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst attribute = attributeArray[ i ];\n\t\t\t\t\tlet bufferAttribute;\n\n\t\t\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\tconst interleavedBuffer = getInterleavedBuffer( json.data, attribute.data );\n\t\t\t\t\t\tbufferAttribute = new InterleavedBufferAttribute( interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconst typedArray = getTypedArray( attribute.type, attribute.array );\n\t\t\t\t\t\tbufferAttribute = new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( attribute.name !== undefined ) bufferAttribute.name = attribute.name;\n\t\t\t\t\tarray.push( bufferAttribute );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.morphAttributes[ key ] = array;\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst morphTargetsRelative = json.data.morphTargetsRelative;\n\n\t\tif ( morphTargetsRelative ) {\n\n\t\t\tgeometry.morphTargetsRelative = true;\n\n\t\t}\n\n\t\tconst groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\tif ( groups !== undefined ) {\n\n\t\t\tfor ( let i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\tconst group = groups[ i ];\n\n\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst boundingSphere = json.data.boundingSphere;\n\n\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\tconst center = new Vector3();\n\n\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t}\n\n\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t}\n\n\t\tif ( json.name ) geometry.name = json.name;\n\t\tif ( json.userData ) geometry.userData = json.userData;\n\n\t\treturn geometry;\n\n\t}\n\n}\n\nclass ObjectLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;\n\t\tthis.resourcePath = this.resourcePath || path;\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setPath( this.path );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\t\tloader.load( url, function ( text ) {\n\n\t\t\tlet json = null;\n\n\t\t\ttry {\n\n\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tconst metadata = json.metadata;\n\n\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tscope.parse( json, onLoad );\n\n\t\t}, onProgress, onError );\n\n\t}\n\n\tasync loadAsync( url, onProgress ) {\n\n\t\tconst scope = this;\n\n\t\tconst path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;\n\t\tthis.resourcePath = this.resourcePath || path;\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setPath( this.path );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\n\t\tconst text = await loader.loadAsync( url, onProgress );\n\n\t\tconst json = JSON.parse( text );\n\n\t\tconst metadata = json.metadata;\n\n\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\tthrow new Error( 'THREE.ObjectLoader: Can\\'t load ' + url );\n\n\t\t}\n\n\t\treturn await scope.parseAsync( json );\n\n\t}\n\n\tparse( json, onLoad ) {\n\n\t\tconst animations = this.parseAnimations( json.animations );\n\t\tconst shapes = this.parseShapes( json.shapes );\n\t\tconst geometries = this.parseGeometries( json.geometries, shapes );\n\n\t\tconst images = this.parseImages( json.images, function () {\n\n\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t} );\n\n\t\tconst textures = this.parseTextures( json.textures, images );\n\t\tconst materials = this.parseMaterials( json.materials, textures );\n\n\t\tconst object = this.parseObject( json.object, geometries, materials, textures, animations );\n\t\tconst skeletons = this.parseSkeletons( json.skeletons, object );\n\n\t\tthis.bindSkeletons( object, skeletons );\n\n\t\t//\n\n\t\tif ( onLoad !== undefined ) {\n\n\t\t\tlet hasImages = false;\n\n\t\t\tfor ( const uuid in images ) {\n\n\t\t\t\tif ( images[ uuid ].data instanceof HTMLImageElement ) {\n\n\t\t\t\t\thasImages = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( hasImages === false ) onLoad( object );\n\n\t\t}\n\n\t\treturn object;\n\n\t}\n\n\tasync parseAsync( json ) {\n\n\t\tconst animations = this.parseAnimations( json.animations );\n\t\tconst shapes = this.parseShapes( json.shapes );\n\t\tconst geometries = this.parseGeometries( json.geometries, shapes );\n\n\t\tconst images = await this.parseImagesAsync( json.images );\n\n\t\tconst textures = this.parseTextures( json.textures, images );\n\t\tconst materials = this.parseMaterials( json.materials, textures );\n\n\t\tconst object = this.parseObject( json.object, geometries, materials, textures, animations );\n\t\tconst skeletons = this.parseSkeletons( json.skeletons, object );\n\n\t\tthis.bindSkeletons( object, skeletons );\n\n\t\treturn object;\n\n\t}\n\n\tparseShapes( json ) {\n\n\t\tconst shapes = {};\n\n\t\tif ( json !== undefined ) {\n\n\t\t\tfor ( let i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\tconst shape = new Shape().fromJSON( json[ i ] );\n\n\t\t\t\tshapes[ shape.uuid ] = shape;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn shapes;\n\n\t}\n\n\tparseSkeletons( json, object ) {\n\n\t\tconst skeletons = {};\n\t\tconst bones = {};\n\n\t\t// generate bone lookup table\n\n\t\tobject.traverse( function ( child ) {\n\n\t\t\tif ( child.isBone ) bones[ child.uuid ] = child;\n\n\t\t} );\n\n\t\t// create skeletons\n\n\t\tif ( json !== undefined ) {\n\n\t\t\tfor ( let i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\tconst skeleton = new Skeleton().fromJSON( json[ i ], bones );\n\n\t\t\t\tskeletons[ skeleton.uuid ] = skeleton;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn skeletons;\n\n\t}\n\n\tparseGeometries( json, shapes ) {\n\n\t\tconst geometries = {};\n\n\t\tif ( json !== undefined ) {\n\n\t\t\tconst bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\tfor ( let i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\tlet geometry;\n\t\t\t\tconst data = json[ i ];\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'BufferGeometry':\n\t\t\t\t\tcase 'InstancedBufferGeometry':\n\n\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: The legacy Geometry type is no longer supported.' );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( data.type in Geometries ) {\n\n\t\t\t\t\t\t\tgeometry = Geometries[ data.type ].fromJSON( data, shapes );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( `THREE.ObjectLoader: Unsupported geometry type \"${ data.type }\"` );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\t\t\t\tif ( geometry.isBufferGeometry === true && data.userData !== undefined ) geometry.userData = data.userData;\n\n\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn geometries;\n\n\t}\n\n\tparseMaterials( json, textures ) {\n\n\t\tconst cache = {}; // MultiMaterial\n\t\tconst materials = {};\n\n\t\tif ( json !== undefined ) {\n\n\t\t\tconst loader = new MaterialLoader();\n\t\t\tloader.setTextures( textures );\n\n\t\t\tfor ( let i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\tconst data = json[ i ];\n\n\t\t\t\tif ( data.type === 'MultiMaterial' ) {\n\n\t\t\t\t\t// Deprecated\n\n\t\t\t\t\tconst array = [];\n\n\t\t\t\t\tfor ( let j = 0; j < data.materials.length; j ++ ) {\n\n\t\t\t\t\t\tconst material = data.materials[ j ];\n\n\t\t\t\t\t\tif ( cache[ material.uuid ] === undefined ) {\n\n\t\t\t\t\t\t\tcache[ material.uuid ] = loader.parse( material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tarray.push( cache[ material.uuid ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tmaterials[ data.uuid ] = array;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( cache[ data.uuid ] === undefined ) {\n\n\t\t\t\t\t\tcache[ data.uuid ] = loader.parse( data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tmaterials[ data.uuid ] = cache[ data.uuid ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn materials;\n\n\t}\n\n\tparseAnimations( json ) {\n\n\t\tconst animations = {};\n\n\t\tif ( json !== undefined ) {\n\n\t\t\tfor ( let i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tconst data = json[ i ];\n\n\t\t\t\tconst clip = AnimationClip.parse( data );\n\n\t\t\t\tanimations[ clip.uuid ] = clip;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn animations;\n\n\t}\n\n\tparseImages( json, onLoad ) {\n\n\t\tconst scope = this;\n\t\tconst images = {};\n\n\t\tlet loader;\n\n\t\tfunction loadImage( url ) {\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn loader.load( url, function () {\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, undefined, function () {\n\n\t\t\t\tscope.manager.itemError( url );\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t} );\n\n\t\t}\n\n\t\tfunction deserializeImage( image ) {\n\n\t\t\tif ( typeof image === 'string' ) {\n\n\t\t\t\tconst url = image;\n\n\t\t\t\tconst path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( url ) ? url : scope.resourcePath + url;\n\n\t\t\t\treturn loadImage( path );\n\n\t\t\t} else {\n\n\t\t\t\tif ( image.data ) {\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdata: getTypedArray( image.type, image.data ),\n\t\t\t\t\t\twidth: image.width,\n\t\t\t\t\t\theight: image.height\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\tconst manager = new LoadingManager( onLoad );\n\n\t\t\tloader = new ImageLoader( manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tfor ( let i = 0, il = json.length; i < il; i ++ ) {\n\n\t\t\t\tconst image = json[ i ];\n\t\t\t\tconst url = image.url;\n\n\t\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\t\t// load array of images e.g CubeTexture\n\n\t\t\t\t\tconst imageArray = [];\n\n\t\t\t\t\tfor ( let j = 0, jl = url.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tconst currentUrl = url[ j ];\n\n\t\t\t\t\t\tconst deserializedImage = deserializeImage( currentUrl );\n\n\t\t\t\t\t\tif ( deserializedImage !== null ) {\n\n\t\t\t\t\t\t\tif ( deserializedImage instanceof HTMLImageElement ) {\n\n\t\t\t\t\t\t\t\timageArray.push( deserializedImage );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// special case: handle array of data textures for cube textures\n\n\t\t\t\t\t\t\t\timageArray.push( new DataTexture( deserializedImage.data, deserializedImage.width, deserializedImage.height ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\timages[ image.uuid ] = new Source( imageArray );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// load single image\n\n\t\t\t\t\tconst deserializedImage = deserializeImage( image.url );\n\t\t\t\t\timages[ image.uuid ] = new Source( deserializedImage );\n\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn images;\n\n\t}\n\n\tasync parseImagesAsync( json ) {\n\n\t\tconst scope = this;\n\t\tconst images = {};\n\n\t\tlet loader;\n\n\t\tasync function deserializeImage( image ) {\n\n\t\t\tif ( typeof image === 'string' ) {\n\n\t\t\t\tconst url = image;\n\n\t\t\t\tconst path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( url ) ? url : scope.resourcePath + url;\n\n\t\t\t\treturn await loader.loadAsync( path );\n\n\t\t\t} else {\n\n\t\t\t\tif ( image.data ) {\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdata: getTypedArray( image.type, image.data ),\n\t\t\t\t\t\twidth: image.width,\n\t\t\t\t\t\theight: image.height\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\tloader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tfor ( let i = 0, il = json.length; i < il; i ++ ) {\n\n\t\t\t\tconst image = json[ i ];\n\t\t\t\tconst url = image.url;\n\n\t\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\t\t// load array of images e.g CubeTexture\n\n\t\t\t\t\tconst imageArray = [];\n\n\t\t\t\t\tfor ( let j = 0, jl = url.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tconst currentUrl = url[ j ];\n\n\t\t\t\t\t\tconst deserializedImage = await deserializeImage( currentUrl );\n\n\t\t\t\t\t\tif ( deserializedImage !== null ) {\n\n\t\t\t\t\t\t\tif ( deserializedImage instanceof HTMLImageElement ) {\n\n\t\t\t\t\t\t\t\timageArray.push( deserializedImage );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// special case: handle array of data textures for cube textures\n\n\t\t\t\t\t\t\t\timageArray.push( new DataTexture( deserializedImage.data, deserializedImage.width, deserializedImage.height ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\timages[ image.uuid ] = new Source( imageArray );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// load single image\n\n\t\t\t\t\tconst deserializedImage = await deserializeImage( image.url );\n\t\t\t\t\timages[ image.uuid ] = new Source( deserializedImage );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn images;\n\n\t}\n\n\tparseTextures( json, images ) {\n\n\t\tfunction parseConstant( value, type ) {\n\n\t\t\tif ( typeof value === 'number' ) return value;\n\n\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\treturn type[ value ];\n\n\t\t}\n\n\t\tconst textures = {};\n\n\t\tif ( json !== undefined ) {\n\n\t\t\tfor ( let i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\tconst data = json[ i ];\n\n\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t}\n\n\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t}\n\n\t\t\t\tconst source = images[ data.image ];\n\t\t\t\tconst image = source.data;\n\n\t\t\t\tlet texture;\n\n\t\t\t\tif ( Array.isArray( image ) ) {\n\n\t\t\t\t\ttexture = new CubeTexture();\n\n\t\t\t\t\tif ( image.length === 6 ) texture.needsUpdate = true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( image && image.data ) {\n\n\t\t\t\t\t\ttexture = new DataTexture();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture = new Texture();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( image ) texture.needsUpdate = true; // textures can have undefined image data\n\n\t\t\t\t}\n\n\t\t\t\ttexture.source = source;\n\n\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING );\n\n\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\tif ( data.center !== undefined ) texture.center.fromArray( data.center );\n\t\t\t\tif ( data.rotation !== undefined ) texture.rotation = data.rotation;\n\n\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );\n\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.format !== undefined ) texture.format = data.format;\n\t\t\t\tif ( data.type !== undefined ) texture.type = data.type;\n\t\t\t\tif ( data.encoding !== undefined ) texture.encoding = data.encoding;\n\n\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );\n\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER );\n\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\tif ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha;\n\t\t\t\tif ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment;\n\n\t\t\t\tif ( data.userData !== undefined ) texture.userData = data.userData;\n\n\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn textures;\n\n\t}\n\n\tparseObject( data, geometries, materials, textures, animations ) {\n\n\t\tlet object;\n\n\t\tfunction getGeometry( name ) {\n\n\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t}\n\n\t\t\treturn geometries[ name ];\n\n\t\t}\n\n\t\tfunction getMaterial( name ) {\n\n\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\n\t\t\t\tconst array = [];\n\n\t\t\t\tfor ( let i = 0, l = name.length; i < l; i ++ ) {\n\n\t\t\t\t\tconst uuid = name[ i ];\n\n\t\t\t\t\tif ( materials[ uuid ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tarray.push( materials[ uuid ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\n\t\t\t}\n\n\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t}\n\n\t\t\treturn materials[ name ];\n\n\t\t}\n\n\t\tfunction getTexture( uuid ) {\n\n\t\t\tif ( textures[ uuid ] === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined texture', uuid );\n\n\t\t\t}\n\n\t\t\treturn textures[ uuid ];\n\n\t\t}\n\n\t\tlet geometry, material;\n\n\t\tswitch ( data.type ) {\n\n\t\t\tcase 'Scene':\n\n\t\t\t\tobject = new Scene();\n\n\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tobject.background = getTexture( data.background );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.environment !== undefined ) {\n\n\t\t\t\t\tobject.environment = getTexture( data.environment );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'AmbientLight':\n\n\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'DirectionalLight':\n\n\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'PointLight':\n\n\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'RectAreaLight':\n\n\t\t\t\tobject = new RectAreaLight( data.color, data.intensity, data.width, data.height );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'SpotLight':\n\n\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'HemisphereLight':\n\n\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'LightProbe':\n\n\t\t\t\tobject = new LightProbe().fromJSON( data );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\tgeometry = getGeometry( data.geometry );\n\t\t\t \tmaterial = getMaterial( data.material );\n\n\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\tif ( data.bindMode !== undefined ) object.bindMode = data.bindMode;\n\t\t\t\tif ( data.bindMatrix !== undefined ) object.bindMatrix.fromArray( data.bindMatrix );\n\t\t\t\tif ( data.skeleton !== undefined ) object.skeleton = data.skeleton;\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'Mesh':\n\n\t\t\t\tgeometry = getGeometry( data.geometry );\n\t\t\t\tmaterial = getMaterial( data.material );\n\n\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'InstancedMesh':\n\n\t\t\t\tgeometry = getGeometry( data.geometry );\n\t\t\t\tmaterial = getMaterial( data.material );\n\t\t\t\tconst count = data.count;\n\t\t\t\tconst instanceMatrix = data.instanceMatrix;\n\t\t\t\tconst instanceColor = data.instanceColor;\n\n\t\t\t\tobject = new InstancedMesh( geometry, material, count );\n\t\t\t\tobject.instanceMatrix = new InstancedBufferAttribute( new Float32Array( instanceMatrix.array ), 16 );\n\t\t\t\tif ( instanceColor !== undefined ) object.instanceColor = new InstancedBufferAttribute( new Float32Array( instanceColor.array ), instanceColor.itemSize );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'LOD':\n\n\t\t\t\tobject = new LOD();\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'Line':\n\n\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'LineLoop':\n\n\t\t\t\tobject = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'LineSegments':\n\n\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'PointCloud':\n\t\t\tcase 'Points':\n\n\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'Sprite':\n\n\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'Group':\n\n\t\t\t\tobject = new Group();\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'Bone':\n\n\t\t\t\tobject = new Bone();\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tobject = new Object3D();\n\n\t\t}\n\n\t\tobject.uuid = data.uuid;\n\n\t\tif ( data.name !== undefined ) object.name = data.name;\n\n\t\tif ( data.matrix !== undefined ) {\n\n\t\t\tobject.matrix.fromArray( data.matrix );\n\n\t\t\tif ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate;\n\t\t\tif ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t} else {\n\n\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t}\n\n\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\tif ( data.shadow ) {\n\n\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\tif ( data.shadow.normalBias !== undefined ) object.shadow.normalBias = data.shadow.normalBias;\n\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t}\n\n\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\tif ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled;\n\t\tif ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder;\n\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\t\tif ( data.layers !== undefined ) object.layers.mask = data.layers;\n\n\t\tif ( data.children !== undefined ) {\n\n\t\t\tconst children = data.children;\n\n\t\t\tfor ( let i = 0; i < children.length; i ++ ) {\n\n\t\t\t\tobject.add( this.parseObject( children[ i ], geometries, materials, textures, animations ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( data.animations !== undefined ) {\n\n\t\t\tconst objectAnimations = data.animations;\n\n\t\t\tfor ( let i = 0; i < objectAnimations.length; i ++ ) {\n\n\t\t\t\tconst uuid = objectAnimations[ i ];\n\n\t\t\t\tobject.animations.push( animations[ uuid ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( data.type === 'LOD' ) {\n\n\t\t\tif ( data.autoUpdate !== undefined ) object.autoUpdate = data.autoUpdate;\n\n\t\t\tconst levels = data.levels;\n\n\t\t\tfor ( let l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tconst level = levels[ l ];\n\t\t\t\tconst child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn object;\n\n\t}\n\n\tbindSkeletons( object, skeletons ) {\n\n\t\tif ( Object.keys( skeletons ).length === 0 ) return;\n\n\t\tobject.traverse( function ( child ) {\n\n\t\t\tif ( child.isSkinnedMesh === true && child.skeleton !== undefined ) {\n\n\t\t\t\tconst skeleton = skeletons[ child.skeleton ];\n\n\t\t\t\tif ( skeleton === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tchild.bind( skeleton, child.bindMatrix );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\t/* DEPRECATED */\n\n\tsetTexturePath( value ) {\n\n\t\tconsole.warn( 'THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().' );\n\t\treturn this.setResourcePath( value );\n\n\t}\n\n}\n\nconst TEXTURE_MAPPING = {\n\tUVMapping: UVMapping,\n\tCubeReflectionMapping: CubeReflectionMapping,\n\tCubeRefractionMapping: CubeRefractionMapping,\n\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\tCubeUVReflectionMapping: CubeUVReflectionMapping\n};\n\nconst TEXTURE_WRAPPING = {\n\tRepeatWrapping: RepeatWrapping,\n\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\tMirroredRepeatWrapping: MirroredRepeatWrapping\n};\n\nconst TEXTURE_FILTER = {\n\tNearestFilter: NearestFilter,\n\tNearestMipmapNearestFilter: NearestMipmapNearestFilter,\n\tNearestMipmapLinearFilter: NearestMipmapLinearFilter,\n\tLinearFilter: LinearFilter,\n\tLinearMipmapNearestFilter: LinearMipmapNearestFilter,\n\tLinearMipmapLinearFilter: LinearMipmapLinearFilter\n};\n\nclass ImageBitmapLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\tthis.isImageBitmapLoader = true;\n\n\t\tif ( typeof createImageBitmap === 'undefined' ) {\n\n\t\t\tconsole.warn( 'THREE.ImageBitmapLoader: createImageBitmap() not supported.' );\n\n\t\t}\n\n\t\tif ( typeof fetch === 'undefined' ) {\n\n\t\t\tconsole.warn( 'THREE.ImageBitmapLoader: fetch() not supported.' );\n\n\t\t}\n\n\t\tthis.options = { premultiplyAlpha: 'none' };\n\n\t}\n\n\tsetOptions( options ) {\n\n\t\tthis.options = options;\n\n\t\treturn this;\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tif ( url === undefined ) url = '';\n\n\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\turl = this.manager.resolveURL( url );\n\n\t\tconst scope = this;\n\n\t\tconst cached = Cache.get( url );\n\n\t\tif ( cached !== undefined ) {\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\tsetTimeout( function () {\n\n\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, 0 );\n\n\t\t\treturn cached;\n\n\t\t}\n\n\t\tconst fetchOptions = {};\n\t\tfetchOptions.credentials = ( this.crossOrigin === 'anonymous' ) ? 'same-origin' : 'include';\n\t\tfetchOptions.headers = this.requestHeader;\n\n\t\tfetch( url, fetchOptions ).then( function ( res ) {\n\n\t\t\treturn res.blob();\n\n\t\t} ).then( function ( blob ) {\n\n\t\t\treturn createImageBitmap( blob, Object.assign( scope.options, { colorSpaceConversion: 'none' } ) );\n\n\t\t} ).then( function ( imageBitmap ) {\n\n\t\t\tCache.add( url, imageBitmap );\n\n\t\t\tif ( onLoad ) onLoad( imageBitmap );\n\n\t\t\tscope.manager.itemEnd( url );\n\n\t\t} ).catch( function ( e ) {\n\n\t\t\tif ( onError ) onError( e );\n\n\t\t\tscope.manager.itemError( url );\n\t\t\tscope.manager.itemEnd( url );\n\n\t\t} );\n\n\t\tscope.manager.itemStart( url );\n\n\t}\n\n}\n\nlet _context;\n\nconst AudioContext = {\n\n\tgetContext: function () {\n\n\t\tif ( _context === undefined ) {\n\n\t\t\t_context = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t}\n\n\t\treturn _context;\n\n\t},\n\n\tsetContext: function ( value ) {\n\n\t\t_context = value;\n\n\t}\n\n};\n\nclass AudioLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tconst loader = new FileLoader( this.manager );\n\t\tloader.setResponseType( 'arraybuffer' );\n\t\tloader.setPath( this.path );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\t\tloader.load( url, function ( buffer ) {\n\n\t\t\ttry {\n\n\t\t\t\t// Create a copy of the buffer. The `decodeAudioData` method\n\t\t\t\t// detaches the buffer when complete, preventing reuse.\n\t\t\t\tconst bufferCopy = buffer.slice( 0 );\n\n\t\t\t\tconst context = AudioContext.getContext();\n\t\t\t\tcontext.decodeAudioData( bufferCopy, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\tif ( onError ) {\n\n\t\t\t\t\tonError( e );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t}\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}\n\n\t\t}, onProgress, onError );\n\n\t}\n\n}\n\nclass HemisphereLightProbe extends LightProbe {\n\n\tconstructor( skyColor, groundColor, intensity = 1 ) {\n\n\t\tsuper( undefined, intensity );\n\n\t\tthis.isHemisphereLightProbe = true;\n\n\t\tconst color1 = new Color().set( skyColor );\n\t\tconst color2 = new Color().set( groundColor );\n\n\t\tconst sky = new Vector3( color1.r, color1.g, color1.b );\n\t\tconst ground = new Vector3( color2.r, color2.g, color2.b );\n\n\t\t// without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI );\n\t\tconst c0 = Math.sqrt( Math.PI );\n\t\tconst c1 = c0 * Math.sqrt( 0.75 );\n\n\t\tthis.sh.coefficients[ 0 ].copy( sky ).add( ground ).multiplyScalar( c0 );\n\t\tthis.sh.coefficients[ 1 ].copy( sky ).sub( ground ).multiplyScalar( c1 );\n\n\t}\n\n}\n\nclass AmbientLightProbe extends LightProbe {\n\n\tconstructor( color, intensity = 1 ) {\n\n\t\tsuper( undefined, intensity );\n\n\t\tthis.isAmbientLightProbe = true;\n\n\t\tconst color1 = new Color().set( color );\n\n\t\t// without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI );\n\t\tthis.sh.coefficients[ 0 ].set( color1.r, color1.g, color1.b ).multiplyScalar( 2 * Math.sqrt( Math.PI ) );\n\n\t}\n\n}\n\nconst _eyeRight = /*@__PURE__*/ new Matrix4();\nconst _eyeLeft = /*@__PURE__*/ new Matrix4();\nconst _projectionMatrix = /*@__PURE__*/ new Matrix4();\n\nclass StereoCamera {\n\n\tconstructor() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t\tthis._cache = {\n\t\t\tfocus: null,\n\t\t\tfov: null,\n\t\t\taspect: null,\n\t\t\tnear: null,\n\t\t\tfar: null,\n\t\t\tzoom: null,\n\t\t\teyeSep: null\n\t\t};\n\n\t}\n\n\tupdate( camera ) {\n\n\t\tconst cache = this._cache;\n\n\t\tconst needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov ||\n\t\t\tcache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near ||\n\t\t\tcache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep;\n\n\t\tif ( needsUpdate ) {\n\n\t\t\tcache.focus = camera.focus;\n\t\t\tcache.fov = camera.fov;\n\t\t\tcache.aspect = camera.aspect * this.aspect;\n\t\t\tcache.near = camera.near;\n\t\t\tcache.far = camera.far;\n\t\t\tcache.zoom = camera.zoom;\n\t\t\tcache.eyeSep = this.eyeSep;\n\n\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t_projectionMatrix.copy( camera.projectionMatrix );\n\t\t\tconst eyeSepHalf = cache.eyeSep / 2;\n\t\t\tconst eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus;\n\t\t\tconst ymax = ( cache.near * Math.tan( DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom;\n\t\t\tlet xmin, xmax;\n\n\t\t\t// translate xOffset\n\n\t\t\t_eyeLeft.elements[ 12 ] = - eyeSepHalf;\n\t\t\t_eyeRight.elements[ 12 ] = eyeSepHalf;\n\n\t\t\t// for left eye\n\n\t\t\txmin = - ymax * cache.aspect + eyeSepOnProjection;\n\t\t\txmax = ymax * cache.aspect + eyeSepOnProjection;\n\n\t\t\t_projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );\n\t\t\t_projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\tthis.cameraL.projectionMatrix.copy( _projectionMatrix );\n\n\t\t\t// for right eye\n\n\t\t\txmin = - ymax * cache.aspect - eyeSepOnProjection;\n\t\t\txmax = ymax * cache.aspect - eyeSepOnProjection;\n\n\t\t\t_projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );\n\t\t\t_projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\tthis.cameraR.projectionMatrix.copy( _projectionMatrix );\n\n\t\t}\n\n\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft );\n\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight );\n\n\t}\n\n}\n\nclass Clock {\n\n\tconstructor( autoStart = true ) {\n\n\t\tthis.autoStart = autoStart;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tstart() {\n\n\t\tthis.startTime = now();\n\n\t\tthis.oldTime = this.startTime;\n\t\tthis.elapsedTime = 0;\n\t\tthis.running = true;\n\n\t}\n\n\tstop() {\n\n\t\tthis.getElapsedTime();\n\t\tthis.running = false;\n\t\tthis.autoStart = false;\n\n\t}\n\n\tgetElapsedTime() {\n\n\t\tthis.getDelta();\n\t\treturn this.elapsedTime;\n\n\t}\n\n\tgetDelta() {\n\n\t\tlet diff = 0;\n\n\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\tthis.start();\n\t\t\treturn 0;\n\n\t\t}\n\n\t\tif ( this.running ) {\n\n\t\t\tconst newTime = now();\n\n\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\tthis.oldTime = newTime;\n\n\t\t\tthis.elapsedTime += diff;\n\n\t\t}\n\n\t\treturn diff;\n\n\t}\n\n}\n\nfunction now() {\n\n\treturn ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732\n\n}\n\nconst _position$1 = /*@__PURE__*/ new Vector3();\nconst _quaternion$1 = /*@__PURE__*/ new Quaternion();\nconst _scale$1 = /*@__PURE__*/ new Vector3();\nconst _orientation$1 = /*@__PURE__*/ new Vector3();\n\nclass AudioListener extends Object3D {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t\tthis.timeDelta = 0;\n\n\t\t// private\n\n\t\tthis._clock = new Clock();\n\n\t}\n\n\tgetInput() {\n\n\t\treturn this.gain;\n\n\t}\n\n\tremoveFilter() {\n\n\t\tif ( this.filter !== null ) {\n\n\t\t\tthis.gain.disconnect( this.filter );\n\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\tthis.gain.connect( this.context.destination );\n\t\t\tthis.filter = null;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetFilter() {\n\n\t\treturn this.filter;\n\n\t}\n\n\tsetFilter( value ) {\n\n\t\tif ( this.filter !== null ) {\n\n\t\t\tthis.gain.disconnect( this.filter );\n\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t} else {\n\n\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t}\n\n\t\tthis.filter = value;\n\t\tthis.gain.connect( this.filter );\n\t\tthis.filter.connect( this.context.destination );\n\n\t\treturn this;\n\n\t}\n\n\tgetMasterVolume() {\n\n\t\treturn this.gain.gain.value;\n\n\t}\n\n\tsetMasterVolume( value ) {\n\n\t\tthis.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );\n\n\t\treturn this;\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t\tconst listener = this.context.listener;\n\t\tconst up = this.up;\n\n\t\tthis.timeDelta = this._clock.getDelta();\n\n\t\tthis.matrixWorld.decompose( _position$1, _quaternion$1, _scale$1 );\n\n\t\t_orientation$1.set( 0, 0, - 1 ).applyQuaternion( _quaternion$1 );\n\n\t\tif ( listener.positionX ) {\n\n\t\t\t// code path for Chrome (see #14393)\n\n\t\t\tconst endTime = this.context.currentTime + this.timeDelta;\n\n\t\t\tlistener.positionX.linearRampToValueAtTime( _position$1.x, endTime );\n\t\t\tlistener.positionY.linearRampToValueAtTime( _position$1.y, endTime );\n\t\t\tlistener.positionZ.linearRampToValueAtTime( _position$1.z, endTime );\n\t\t\tlistener.forwardX.linearRampToValueAtTime( _orientation$1.x, endTime );\n\t\t\tlistener.forwardY.linearRampToValueAtTime( _orientation$1.y, endTime );\n\t\t\tlistener.forwardZ.linearRampToValueAtTime( _orientation$1.z, endTime );\n\t\t\tlistener.upX.linearRampToValueAtTime( up.x, endTime );\n\t\t\tlistener.upY.linearRampToValueAtTime( up.y, endTime );\n\t\t\tlistener.upZ.linearRampToValueAtTime( up.z, endTime );\n\n\t\t} else {\n\n\t\t\tlistener.setPosition( _position$1.x, _position$1.y, _position$1.z );\n\t\t\tlistener.setOrientation( _orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z );\n\n\t\t}\n\n\t}\n\n}\n\nclass Audio extends Object3D {\n\n\tconstructor( listener ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.listener = listener;\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.detune = 0;\n\t\tthis.loop = false;\n\t\tthis.loopStart = 0;\n\t\tthis.loopEnd = 0;\n\t\tthis.offset = 0;\n\t\tthis.duration = undefined;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.source = null;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis._startedAt = 0;\n\t\tthis._progress = 0;\n\t\tthis._connected = false;\n\n\t\tthis.filters = [];\n\n\t}\n\n\tgetOutput() {\n\n\t\treturn this.gain;\n\n\t}\n\n\tsetNodeSource( audioNode ) {\n\n\t\tthis.hasPlaybackControl = false;\n\t\tthis.sourceType = 'audioNode';\n\t\tthis.source = audioNode;\n\t\tthis.connect();\n\n\t\treturn this;\n\n\t}\n\n\tsetMediaElementSource( mediaElement ) {\n\n\t\tthis.hasPlaybackControl = false;\n\t\tthis.sourceType = 'mediaNode';\n\t\tthis.source = this.context.createMediaElementSource( mediaElement );\n\t\tthis.connect();\n\n\t\treturn this;\n\n\t}\n\n\tsetMediaStreamSource( mediaStream ) {\n\n\t\tthis.hasPlaybackControl = false;\n\t\tthis.sourceType = 'mediaStreamNode';\n\t\tthis.source = this.context.createMediaStreamSource( mediaStream );\n\t\tthis.connect();\n\n\t\treturn this;\n\n\t}\n\n\tsetBuffer( audioBuffer ) {\n\n\t\tthis.buffer = audioBuffer;\n\t\tthis.sourceType = 'buffer';\n\n\t\tif ( this.autoplay ) this.play();\n\n\t\treturn this;\n\n\t}\n\n\tplay( delay = 0 ) {\n\n\t\tif ( this.isPlaying === true ) {\n\n\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tthis._startedAt = this.context.currentTime + delay;\n\n\t\tconst source = this.context.createBufferSource();\n\t\tsource.buffer = this.buffer;\n\t\tsource.loop = this.loop;\n\t\tsource.loopStart = this.loopStart;\n\t\tsource.loopEnd = this.loopEnd;\n\t\tsource.onended = this.onEnded.bind( this );\n\t\tsource.start( this._startedAt, this._progress + this.offset, this.duration );\n\n\t\tthis.isPlaying = true;\n\n\t\tthis.source = source;\n\n\t\tthis.setDetune( this.detune );\n\t\tthis.setPlaybackRate( this.playbackRate );\n\n\t\treturn this.connect();\n\n\t}\n\n\tpause() {\n\n\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( this.isPlaying === true ) {\n\n\t\t\t// update current progress\n\n\t\t\tthis._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate;\n\n\t\t\tif ( this.loop === true ) {\n\n\t\t\t\t// ensure _progress does not exceed duration with looped audios\n\n\t\t\t\tthis._progress = this._progress % ( this.duration || this.buffer.duration );\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.source.onended = null;\n\n\t\t\tthis.isPlaying = false;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tstop() {\n\n\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tthis._progress = 0;\n\n\t\tthis.source.stop();\n\t\tthis.source.onended = null;\n\t\tthis.isPlaying = false;\n\n\t\treturn this;\n\n\t}\n\n\tconnect() {\n\n\t\tif ( this.filters.length > 0 ) {\n\n\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\tfor ( let i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t}\n\n\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t} else {\n\n\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t}\n\n\t\tthis._connected = true;\n\n\t\treturn this;\n\n\t}\n\n\tdisconnect() {\n\n\t\tif ( this.filters.length > 0 ) {\n\n\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\tfor ( let i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t}\n\n\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t} else {\n\n\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t}\n\n\t\tthis._connected = false;\n\n\t\treturn this;\n\n\t}\n\n\tgetFilters() {\n\n\t\treturn this.filters;\n\n\t}\n\n\tsetFilters( value ) {\n\n\t\tif ( ! value ) value = [];\n\n\t\tif ( this._connected === true ) {\n\n\t\t\tthis.disconnect();\n\t\t\tthis.filters = value.slice();\n\t\t\tthis.connect();\n\n\t\t} else {\n\n\t\t\tthis.filters = value.slice();\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetDetune( value ) {\n\n\t\tthis.detune = value;\n\n\t\tif ( this.source.detune === undefined ) return; // only set detune when available\n\n\t\tif ( this.isPlaying === true ) {\n\n\t\t\tthis.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetDetune() {\n\n\t\treturn this.detune;\n\n\t}\n\n\tgetFilter() {\n\n\t\treturn this.getFilters()[ 0 ];\n\n\t}\n\n\tsetFilter( filter ) {\n\n\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t}\n\n\tsetPlaybackRate( value ) {\n\n\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tthis.playbackRate = value;\n\n\t\tif ( this.isPlaying === true ) {\n\n\t\t\tthis.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tgetPlaybackRate() {\n\n\t\treturn this.playbackRate;\n\n\t}\n\n\tonEnded() {\n\n\t\tthis.isPlaying = false;\n\n\t}\n\n\tgetLoop() {\n\n\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\treturn false;\n\n\t\t}\n\n\t\treturn this.loop;\n\n\t}\n\n\tsetLoop( value ) {\n\n\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tthis.loop = value;\n\n\t\tif ( this.isPlaying === true ) {\n\n\t\t\tthis.source.loop = this.loop;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetLoopStart( value ) {\n\n\t\tthis.loopStart = value;\n\n\t\treturn this;\n\n\t}\n\n\tsetLoopEnd( value ) {\n\n\t\tthis.loopEnd = value;\n\n\t\treturn this;\n\n\t}\n\n\tgetVolume() {\n\n\t\treturn this.gain.gain.value;\n\n\t}\n\n\tsetVolume( value ) {\n\n\t\tthis.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst _position = /*@__PURE__*/ new Vector3();\nconst _quaternion = /*@__PURE__*/ new Quaternion();\nconst _scale = /*@__PURE__*/ new Vector3();\nconst _orientation = /*@__PURE__*/ new Vector3();\n\nclass PositionalAudio extends Audio {\n\n\tconstructor( listener ) {\n\n\t\tsuper( listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.panningModel = 'HRTF';\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tdisconnect() {\n\n\t\tsuper.disconnect();\n\n\t\tthis.panner.disconnect( this.gain );\n\n\t}\n\n\tgetOutput() {\n\n\t\treturn this.panner;\n\n\t}\n\n\tgetRefDistance() {\n\n\t\treturn this.panner.refDistance;\n\n\t}\n\n\tsetRefDistance( value ) {\n\n\t\tthis.panner.refDistance = value;\n\n\t\treturn this;\n\n\t}\n\n\tgetRolloffFactor() {\n\n\t\treturn this.panner.rolloffFactor;\n\n\t}\n\n\tsetRolloffFactor( value ) {\n\n\t\tthis.panner.rolloffFactor = value;\n\n\t\treturn this;\n\n\t}\n\n\tgetDistanceModel() {\n\n\t\treturn this.panner.distanceModel;\n\n\t}\n\n\tsetDistanceModel( value ) {\n\n\t\tthis.panner.distanceModel = value;\n\n\t\treturn this;\n\n\t}\n\n\tgetMaxDistance() {\n\n\t\treturn this.panner.maxDistance;\n\n\t}\n\n\tsetMaxDistance( value ) {\n\n\t\tthis.panner.maxDistance = value;\n\n\t\treturn this;\n\n\t}\n\n\tsetDirectionalCone( coneInnerAngle, coneOuterAngle, coneOuterGain ) {\n\n\t\tthis.panner.coneInnerAngle = coneInnerAngle;\n\t\tthis.panner.coneOuterAngle = coneOuterAngle;\n\t\tthis.panner.coneOuterGain = coneOuterGain;\n\n\t\treturn this;\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t\tif ( this.hasPlaybackControl === true && this.isPlaying === false ) return;\n\n\t\tthis.matrixWorld.decompose( _position, _quaternion, _scale );\n\n\t\t_orientation.set( 0, 0, 1 ).applyQuaternion( _quaternion );\n\n\t\tconst panner = this.panner;\n\n\t\tif ( panner.positionX ) {\n\n\t\t\t// code path for Chrome and Firefox (see #14393)\n\n\t\t\tconst endTime = this.context.currentTime + this.listener.timeDelta;\n\n\t\t\tpanner.positionX.linearRampToValueAtTime( _position.x, endTime );\n\t\t\tpanner.positionY.linearRampToValueAtTime( _position.y, endTime );\n\t\t\tpanner.positionZ.linearRampToValueAtTime( _position.z, endTime );\n\t\t\tpanner.orientationX.linearRampToValueAtTime( _orientation.x, endTime );\n\t\t\tpanner.orientationY.linearRampToValueAtTime( _orientation.y, endTime );\n\t\t\tpanner.orientationZ.linearRampToValueAtTime( _orientation.z, endTime );\n\n\t\t} else {\n\n\t\t\tpanner.setPosition( _position.x, _position.y, _position.z );\n\t\t\tpanner.setOrientation( _orientation.x, _orientation.y, _orientation.z );\n\n\t\t}\n\n\t}\n\n}\n\nclass AudioAnalyser {\n\n\tconstructor( audio, fftSize = 2048 ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\n\tgetFrequencyData() {\n\n\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\treturn this.data;\n\n\t}\n\n\tgetAverageFrequency() {\n\n\t\tlet value = 0;\n\t\tconst data = this.getFrequencyData();\n\n\t\tfor ( let i = 0; i < data.length; i ++ ) {\n\n\t\t\tvalue += data[ i ];\n\n\t\t}\n\n\t\treturn value / data.length;\n\n\t}\n\n}\n\nclass PropertyMixer {\n\n\tconstructor( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tlet mixFunction,\n\t\t\tmixFunctionAdditive,\n\t\t\tsetIdentity;\n\n\t\t// buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\t\t//\n\t\t// 'add' is used for additive cumulative results\n\t\t//\n\t\t// 'work' is optional and is only present for quaternion types. It is used\n\t\t// to store intermediate quaternion multiplication results\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tmixFunctionAdditive = this._slerpAdditive;\n\t\t\t\tsetIdentity = this._setAdditiveIdentityQuaternion;\n\n\t\t\t\tthis.buffer = new Float64Array( valueSize * 6 );\n\t\t\t\tthis._workIndex = 5;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tmixFunction = this._select;\n\n\t\t\t\t// Use the regular mix function and for additive on these types,\n\t\t\t\t// additive is not relevant for non-numeric types\n\t\t\t\tmixFunctionAdditive = this._select;\n\n\t\t\t\tsetIdentity = this._setAdditiveIdentityOther;\n\n\t\t\t\tthis.buffer = new Array( valueSize * 5 );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\t\t\t\tmixFunctionAdditive = this._lerpAdditive;\n\t\t\t\tsetIdentity = this._setAdditiveIdentityNumeric;\n\n\t\t\t\tthis.buffer = new Float64Array( valueSize * 5 );\n\n\t\t}\n\n\t\tthis._mixBufferRegion = mixFunction;\n\t\tthis._mixBufferRegionAdditive = mixFunctionAdditive;\n\t\tthis._setIdentity = setIdentity;\n\t\tthis._origIndex = 3;\n\t\tthis._addIndex = 4;\n\n\t\tthis.cumulativeWeight = 0;\n\t\tthis.cumulativeWeightAdditive = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\t// accumulate data in the 'incoming' region into 'accu'\n\taccumulate( accuIndex, weight ) {\n\n\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t// the weight and shouldn't have made the call in the first place\n\n\t\tconst buffer = this.buffer,\n\t\t\tstride = this.valueSize,\n\t\t\toffset = accuIndex * stride + stride;\n\n\t\tlet currentWeight = this.cumulativeWeight;\n\n\t\tif ( currentWeight === 0 ) {\n\n\t\t\t// accuN := incoming * weight\n\n\t\t\tfor ( let i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t}\n\n\t\t\tcurrentWeight = weight;\n\n\t\t} else {\n\n\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\tcurrentWeight += weight;\n\t\t\tconst mix = weight / currentWeight;\n\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t}\n\n\t\tthis.cumulativeWeight = currentWeight;\n\n\t}\n\n\t// accumulate data in the 'incoming' region into 'add'\n\taccumulateAdditive( weight ) {\n\n\t\tconst buffer = this.buffer,\n\t\t\tstride = this.valueSize,\n\t\t\toffset = stride * this._addIndex;\n\n\t\tif ( this.cumulativeWeightAdditive === 0 ) {\n\n\t\t\t// add = identity\n\n\t\t\tthis._setIdentity();\n\n\t\t}\n\n\t\t// add := add + incoming * weight\n\n\t\tthis._mixBufferRegionAdditive( buffer, offset, 0, weight, stride );\n\t\tthis.cumulativeWeightAdditive += weight;\n\n\t}\n\n\t// apply the state of 'accu' to the binding when accus differ\n\tapply( accuIndex ) {\n\n\t\tconst stride = this.valueSize,\n\t\t\tbuffer = this.buffer,\n\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\tweight = this.cumulativeWeight,\n\t\t\tweightAdditive = this.cumulativeWeightAdditive,\n\n\t\t\tbinding = this.binding;\n\n\t\tthis.cumulativeWeight = 0;\n\t\tthis.cumulativeWeightAdditive = 0;\n\n\t\tif ( weight < 1 ) {\n\n\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\tconst originalValueOffset = stride * this._origIndex;\n\n\t\t\tthis._mixBufferRegion(\n\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t}\n\n\t\tif ( weightAdditive > 0 ) {\n\n\t\t\t// accuN := accuN + additive accuN\n\n\t\t\tthis._mixBufferRegionAdditive( buffer, offset, this._addIndex * stride, 1, stride );\n\n\t\t}\n\n\t\tfor ( let i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// remember the state of the bound property and copy it to both accus\n\tsaveOriginalState() {\n\n\t\tconst binding = this.binding;\n\n\t\tconst buffer = this.buffer,\n\t\t\tstride = this.valueSize,\n\n\t\t\toriginalValueOffset = stride * this._origIndex;\n\n\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\tfor ( let i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t}\n\n\t\t// Add to identity for additive\n\t\tthis._setIdentity();\n\n\t\tthis.cumulativeWeight = 0;\n\t\tthis.cumulativeWeightAdditive = 0;\n\n\t}\n\n\t// apply the state previously taken via 'saveOriginalState' to the binding\n\trestoreOriginalState() {\n\n\t\tconst originalValueOffset = this.valueSize * 3;\n\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t}\n\n\t_setAdditiveIdentityNumeric() {\n\n\t\tconst startIndex = this._addIndex * this.valueSize;\n\t\tconst endIndex = startIndex + this.valueSize;\n\n\t\tfor ( let i = startIndex; i < endIndex; i ++ ) {\n\n\t\t\tthis.buffer[ i ] = 0;\n\n\t\t}\n\n\t}\n\n\t_setAdditiveIdentityQuaternion() {\n\n\t\tthis._setAdditiveIdentityNumeric();\n\t\tthis.buffer[ this._addIndex * this.valueSize + 3 ] = 1;\n\n\t}\n\n\t_setAdditiveIdentityOther() {\n\n\t\tconst startIndex = this._origIndex * this.valueSize;\n\t\tconst targetIndex = this._addIndex * this.valueSize;\n\n\t\tfor ( let i = 0; i < this.valueSize; i ++ ) {\n\n\t\t\tthis.buffer[ targetIndex + i ] = this.buffer[ startIndex + i ];\n\n\t\t}\n\n\t}\n\n\n\t// mix functions\n\n\t_select( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\tif ( t >= 0.5 ) {\n\n\t\t\tfor ( let i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_slerp( buffer, dstOffset, srcOffset, t ) {\n\n\t\tQuaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t );\n\n\t}\n\n\t_slerpAdditive( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\tconst workOffset = this._workIndex * stride;\n\n\t\t// Store result in intermediate buffer offset\n\t\tQuaternion.multiplyQuaternionsFlat( buffer, workOffset, buffer, dstOffset, buffer, srcOffset );\n\n\t\t// Slerp to the intermediate result\n\t\tQuaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t );\n\n\t}\n\n\t_lerp( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\tconst s = 1 - t;\n\n\t\tfor ( let i = 0; i !== stride; ++ i ) {\n\n\t\t\tconst j = dstOffset + i;\n\n\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t}\n\n\t}\n\n\t_lerpAdditive( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\tfor ( let i = 0; i !== stride; ++ i ) {\n\n\t\t\tconst j = dstOffset + i;\n\n\t\t\tbuffer[ j ] = buffer[ j ] + buffer[ srcOffset + i ] * t;\n\n\t\t}\n\n\t}\n\n}\n\n// Characters [].:/ are reserved for track binding syntax.\nconst _RESERVED_CHARS_RE = '\\\\[\\\\]\\\\.:\\\\/';\nconst _reservedRe = new RegExp( '[' + _RESERVED_CHARS_RE + ']', 'g' );\n\n// Attempts to allow node names from any language. ES5's `\\w` regexp matches\n// only latin characters, and the unicode \\p{L} is not yet supported. So\n// instead, we exclude reserved characters and match everything else.\nconst _wordChar = '[^' + _RESERVED_CHARS_RE + ']';\nconst _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\\\.', '' ) + ']';\n\n// Parent directories, delimited by '/' or ':'. Currently unused, but must\n// be matched to parse the rest of the track name.\nconst _directoryRe = /((?:WC+[\\/:])*)/.source.replace( 'WC', _wordChar );\n\n// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.\nconst _nodeRe = /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot );\n\n// Object on target node, and accessor. May not contain reserved\n// characters. Accessor may contain any character except closing bracket.\nconst _objectRe = /(?:\\.(WC+)(?:\\[(.+)\\])?)?/.source.replace( 'WC', _wordChar );\n\n// Property and accessor. May not contain reserved characters. Accessor may\n// contain any non-bracket characters.\nconst _propertyRe = /\\.(WC+)(?:\\[(.+)\\])?/.source.replace( 'WC', _wordChar );\n\nconst _trackRe = new RegExp( ''\n\t+ '^'\n\t+ _directoryRe\n\t+ _nodeRe\n\t+ _objectRe\n\t+ _propertyRe\n\t+ '$'\n);\n\nconst _supportedObjectNames = [ 'material', 'materials', 'bones' ];\n\nclass Composite {\n\n\tconstructor( targetGroup, path, optionalParsedPath ) {\n\n\t\tconst parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t}\n\n\tgetValue( array, offset ) {\n\n\t\tthis.bind(); // bind all binding\n\n\t\tconst firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t// and only call .getValue on the first\n\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t}\n\n\tsetValue( array, offset ) {\n\n\t\tconst bindings = this._bindings;\n\n\t\tfor ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t}\n\n\t}\n\n\tbind() {\n\n\t\tconst bindings = this._bindings;\n\n\t\tfor ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\tbindings[ i ].bind();\n\n\t\t}\n\n\t}\n\n\tunbind() {\n\n\t\tconst bindings = this._bindings;\n\n\t\tfor ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\tbindings[ i ].unbind();\n\n\t\t}\n\n\t}\n\n}\n\n// Note: This class uses a State pattern on a per-method basis:\n// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n// prototype version of these methods with one that represents\n// the bound state. When the property is not found, the methods\n// become no-ops.\nclass PropertyBinding {\n\n\tconstructor( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath || PropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t\t// initial state of these methods that calls 'bind'\n\t\tthis.getValue = this._getValue_unbound;\n\t\tthis.setValue = this._setValue_unbound;\n\n\t}\n\n\n\tstatic create( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Replaces spaces with underscores and removes unsupported characters from\n\t * node names, to ensure compatibility with parseTrackName().\n\t *\n\t * @param {string} name Node name to be sanitized.\n\t * @return {string}\n\t */\n\tstatic sanitizeNodeName( name ) {\n\n\t\treturn name.replace( /\\s/g, '_' ).replace( _reservedRe, '' );\n\n\t}\n\n\tstatic parseTrackName( trackName ) {\n\n\t\tconst matches = _trackRe.exec( trackName );\n\n\t\tif ( matches === null ) {\n\n\t\t\tthrow new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );\n\n\t\t}\n\n\t\tconst results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ],\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ], // required\n\t\t\tpropertyIndex: matches[ 6 ]\n\t\t};\n\n\t\tconst lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );\n\n\t\tif ( lastDot !== undefined && lastDot !== - 1 ) {\n\n\t\t\tconst objectName = results.nodeName.substring( lastDot + 1 );\n\n\t\t\t// Object names must be checked against an allowlist. Otherwise, there\n\t\t\t// is no way to parse 'foo.bar.baz': 'baz' must be a property, but\n\t\t\t// 'bar' could be the objectName, or part of a nodeName (which can\n\t\t\t// include '.' characters).\n\t\t\tif ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) {\n\n\t\t\t\tresults.nodeName = results.nodeName.substring( 0, lastDot );\n\t\t\t\tresults.objectName = objectName;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t}\n\n\tstatic findNode( root, nodeName ) {\n\n\t\tif ( nodeName === undefined || nodeName === '' || nodeName === '.' || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tconst bone = root.skeleton.getBoneByName( nodeName );\n\n\t\t\tif ( bone !== undefined ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tconst searchNodeSubtree = function ( children ) {\n\n\t\t\t\tfor ( let i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tconst childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tconst subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\t// these are used to \"bind\" a nonexistent property\n\t_getValue_unavailable() {}\n\t_setValue_unavailable() {}\n\n\t// Getters\n\n\t_getValue_direct( buffer, offset ) {\n\n\t\tbuffer[ offset ] = this.targetObject[ this.propertyName ];\n\n\t}\n\n\t_getValue_array( buffer, offset ) {\n\n\t\tconst source = this.resolvedProperty;\n\n\t\tfor ( let i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t}\n\n\t}\n\n\t_getValue_arrayElement( buffer, offset ) {\n\n\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t}\n\n\t_getValue_toArray( buffer, offset ) {\n\n\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t}\n\n\t// Direct\n\n\t_setValue_direct( buffer, offset ) {\n\n\t\tthis.targetObject[ this.propertyName ] = buffer[ offset ];\n\n\t}\n\n\t_setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\tthis.targetObject[ this.propertyName ] = buffer[ offset ];\n\t\tthis.targetObject.needsUpdate = true;\n\n\t}\n\n\t_setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\tthis.targetObject[ this.propertyName ] = buffer[ offset ];\n\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t}\n\n\t// EntireArray\n\n\t_setValue_array( buffer, offset ) {\n\n\t\tconst dest = this.resolvedProperty;\n\n\t\tfor ( let i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t}\n\n\t}\n\n\t_setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\tconst dest = this.resolvedProperty;\n\n\t\tfor ( let i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t}\n\n\t\tthis.targetObject.needsUpdate = true;\n\n\t}\n\n\t_setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\tconst dest = this.resolvedProperty;\n\n\t\tfor ( let i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t}\n\n\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t}\n\n\t// ArrayElement\n\n\t_setValue_arrayElement( buffer, offset ) {\n\n\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t}\n\n\t_setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\tthis.targetObject.needsUpdate = true;\n\n\t}\n\n\t_setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t}\n\n\t// HasToFromArray\n\n\t_setValue_fromArray( buffer, offset ) {\n\n\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t}\n\n\t_setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\tthis.targetObject.needsUpdate = true;\n\n\t}\n\n\t_setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t}\n\n\t_getValue_unbound( targetArray, offset ) {\n\n\t\tthis.bind();\n\t\tthis.getValue( targetArray, offset );\n\n\t}\n\n\t_setValue_unbound( sourceArray, offset ) {\n\n\t\tthis.bind();\n\t\tthis.setValue( sourceArray, offset );\n\n\t}\n\n\t// create getter / setter pair for a property in the scene graph\n\tbind() {\n\n\t\tlet targetObject = this.node;\n\t\tconst parsedPath = this.parsedPath;\n\n\t\tconst objectName = parsedPath.objectName;\n\t\tconst propertyName = parsedPath.propertyName;\n\t\tlet propertyIndex = parsedPath.propertyIndex;\n\n\t\tif ( ! targetObject ) {\n\n\t\t\ttargetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\tthis.node = targetObject;\n\n\t\t}\n\n\t\t// set fail state so we can just 'return' on error\n\t\tthis.getValue = this._getValue_unavailable;\n\t\tthis.setValue = this._setValue_unavailable;\n\n\t\t// ensure there is a value node\n\t\tif ( ! targetObject ) {\n\n\t\t\tconsole.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\\'t found.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( objectName ) {\n\n\t\t\tlet objectIndex = parsedPath.objectIndex;\n\n\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\tswitch ( objectName ) {\n\n\t\t\t\tcase 'materials':\n\n\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'bones':\n\n\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tfor ( let i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t}\n\n\n\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\tconsole.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t}\n\n\t\t}\n\n\t\t// resolve property\n\t\tconst nodeProperty = targetObject[ propertyName ];\n\n\t\tif ( nodeProperty === undefined ) {\n\n\t\t\tconst nodeName = parsedPath.nodeName;\n\n\t\t\tconsole.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName +\n\t\t\t\t'.' + propertyName + ' but it wasn\\'t found.', targetObject );\n\t\t\treturn;\n\n\t\t}\n\n\t\t// determine versioning scheme\n\t\tlet versioning = this.Versioning.None;\n\n\t\tthis.targetObject = targetObject;\n\n\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\tversioning = this.Versioning.NeedsUpdate;\n\n\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\n\t\t}\n\n\t\t// determine how the property gets bound\n\t\tlet bindingType = this.BindingType.Direct;\n\n\t\tif ( propertyIndex !== undefined ) {\n\n\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\tif ( propertyName === 'morphTargetInfluences' ) {\n\n\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\tconsole.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! targetObject.geometry.morphAttributes ) {\n\n\t\t\t\t\tconsole.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tif ( targetObject.morphTargetDictionary[ propertyIndex ] !== undefined ) {\n\n\t\t\t\t\tpropertyIndex = targetObject.morphTargetDictionary[ propertyIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\n\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t} else if ( Array.isArray( nodeProperty ) ) {\n\n\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t} else {\n\n\t\t\tthis.propertyName = propertyName;\n\n\t\t}\n\n\t\t// select getter / setter\n\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t}\n\n\tunbind() {\n\n\t\tthis.node = null;\n\n\t\t// back to the prototype version of getValue / setValue\n\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\tthis.getValue = this._getValue_unbound;\n\t\tthis.setValue = this._setValue_unbound;\n\n\t}\n\n}\n\nPropertyBinding.Composite = Composite;\n\nPropertyBinding.prototype.BindingType = {\n\tDirect: 0,\n\tEntireArray: 1,\n\tArrayElement: 2,\n\tHasFromToArray: 3\n};\n\nPropertyBinding.prototype.Versioning = {\n\tNone: 0,\n\tNeedsUpdate: 1,\n\tMatrixWorldNeedsUpdate: 2\n};\n\nPropertyBinding.prototype.GetterByBindingType = [\n\n\tPropertyBinding.prototype._getValue_direct,\n\tPropertyBinding.prototype._getValue_array,\n\tPropertyBinding.prototype._getValue_arrayElement,\n\tPropertyBinding.prototype._getValue_toArray,\n\n];\n\nPropertyBinding.prototype.SetterByBindingTypeAndVersioning = [\n\n\t[\n\t\t// Direct\n\t\tPropertyBinding.prototype._setValue_direct,\n\t\tPropertyBinding.prototype._setValue_direct_setNeedsUpdate,\n\t\tPropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate,\n\n\t], [\n\n\t\t// EntireArray\n\n\t\tPropertyBinding.prototype._setValue_array,\n\t\tPropertyBinding.prototype._setValue_array_setNeedsUpdate,\n\t\tPropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate,\n\n\t], [\n\n\t\t// ArrayElement\n\t\tPropertyBinding.prototype._setValue_arrayElement,\n\t\tPropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate,\n\t\tPropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate,\n\n\t], [\n\n\t\t// HasToFromArray\n\t\tPropertyBinding.prototype._setValue_fromArray,\n\t\tPropertyBinding.prototype._setValue_fromArray_setNeedsUpdate,\n\t\tPropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate,\n\n\t]\n\n];\n\n/**\n *\n * A group of objects that receives a shared animation state.\n *\n * Usage:\n *\n * - Add objects you would otherwise pass as 'root' to the\n * constructor or the .clipAction method of AnimationMixer.\n *\n * - Instead pass this object as 'root'.\n *\n * - You can also add and remove objects later when the mixer\n * is running.\n *\n * Note:\n *\n * Objects of this class appear as one object to the mixer,\n * so cache control of the individual objects must be done\n * on the group.\n *\n * Limitation:\n *\n * - The animated properties must be compatible among the\n * all objects in the group.\n *\n * - A single property can either be controlled through a\n * target group or directly, but not both.\n */\n\nclass AnimationObjectGroup {\n\n\tconstructor() {\n\n\t\tthis.isAnimationObjectGroup = true;\n\n\t\tthis.uuid = generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0; // threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tconst indices = {};\n\t\tthis._indicesByUUID = indices; // for bookkeeping\n\n\t\tfor ( let i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = []; // inside: string\n\t\tthis._parsedPaths = []; // inside: { we don't care, here }\n\t\tthis._bindings = []; // inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; // inside: indices in these arrays\n\n\t\tconst scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() {\n\n\t\t\t\t\treturn scope._objects.length;\n\n\t\t\t\t},\n\t\t\t\tget inUse() {\n\n\t\t\t\t\treturn this.total - scope.nCachedObjects_;\n\n\t\t\t\t}\n\t\t\t},\n\t\t\tget bindingsPerObject() {\n\n\t\t\t\treturn scope._bindings.length;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tadd() {\n\n\t\tconst objects = this._objects,\n\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\tpaths = this._paths,\n\t\t\tparsedPaths = this._parsedPaths,\n\t\t\tbindings = this._bindings,\n\t\t\tnBindings = bindings.length;\n\n\t\tlet knownObject = undefined,\n\t\t\tnObjects = objects.length,\n\t\t\tnCachedObjects = this.nCachedObjects_;\n\n\t\tfor ( let i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tconst object = arguments[ i ],\n\t\t\t\tuuid = object.uuid;\n\t\t\tlet index = indicesByUUID[ uuid ];\n\n\t\t\tif ( index === undefined ) {\n\n\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\tindex = nObjects ++;\n\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\tobjects.push( object );\n\n\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\tfor ( let j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\tbindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t}\n\n\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\tconst firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\tfor ( let j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\tconst bindingsForPath = bindings[ j ],\n\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ];\n\n\t\t\t\t\tlet binding = bindingsForPath[ index ];\n\n\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\tbinding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t}\n\n\t\t\t} else if ( objects[ index ] !== knownObject ) {\n\n\t\t\t\tconsole.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' +\n\t\t\t\t\t'detected. Clean the caches or recreate your infrastructure when reloading scenes.' );\n\n\t\t\t} // else the object is already where we want it to be\n\n\t\t} // for arguments\n\n\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t}\n\n\tremove() {\n\n\t\tconst objects = this._objects,\n\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\tbindings = this._bindings,\n\t\t\tnBindings = bindings.length;\n\n\t\tlet nCachedObjects = this.nCachedObjects_;\n\n\t\tfor ( let i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tconst object = arguments[ i ],\n\t\t\t\tuuid = object.uuid,\n\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\tconst lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\tfor ( let j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\tconst bindingsForPath = bindings[ j ],\n\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} // for arguments\n\n\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t}\n\n\t// remove & forget\n\tuncache() {\n\n\t\tconst objects = this._objects,\n\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\tbindings = this._bindings,\n\t\t\tnBindings = bindings.length;\n\n\t\tlet nCachedObjects = this.nCachedObjects_,\n\t\t\tnObjects = objects.length;\n\n\t\tfor ( let i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tconst object = arguments[ i ],\n\t\t\t\tuuid = object.uuid,\n\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\tconst firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( let j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tconst bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\tconst lastIndex = -- nObjects,\n\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( let j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tconst bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t}\n\n\t\t\t\t} // cached or active\n\n\t\t\t} // if object is known\n\n\t\t} // for arguments\n\n\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t}\n\n\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\tsubscribe_( path, parsedPath ) {\n\n\t\t// returns an array of bindings for the given path that is changed\n\t\t// according to the contained objects in the group\n\n\t\tconst indicesByPath = this._bindingsIndicesByPath;\n\t\tlet index = indicesByPath[ path ];\n\t\tconst bindings = this._bindings;\n\n\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\tconst paths = this._paths,\n\t\t\tparsedPaths = this._parsedPaths,\n\t\t\tobjects = this._objects,\n\t\t\tnObjects = objects.length,\n\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\tindex = bindings.length;\n\n\t\tindicesByPath[ path ] = index;\n\n\t\tpaths.push( path );\n\t\tparsedPaths.push( parsedPath );\n\t\tbindings.push( bindingsForPath );\n\n\t\tfor ( let i = nCachedObjects, n = objects.length; i !== n; ++ i ) {\n\n\t\t\tconst object = objects[ i ];\n\t\t\tbindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath );\n\n\t\t}\n\n\t\treturn bindingsForPath;\n\n\t}\n\n\tunsubscribe_( path ) {\n\n\t\t// tells the group to forget about a property path and no longer\n\t\t// update the array previously obtained with 'subscribe_'\n\n\t\tconst indicesByPath = this._bindingsIndicesByPath,\n\t\t\tindex = indicesByPath[ path ];\n\n\t\tif ( index !== undefined ) {\n\n\t\t\tconst paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\tbindings[ index ] = lastBindings;\n\t\t\tbindings.pop();\n\n\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\tparsedPaths.pop();\n\n\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\tpaths.pop();\n\n\t\t}\n\n\t}\n\n}\n\nclass AnimationAction {\n\n\tconstructor( mixer, clip, localRoot = null, blendMode = clip.blendMode ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot;\n\t\tthis.blendMode = blendMode;\n\n\t\tconst tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tconst interpolantSettings = {\n\t\t\tendingStart: ZeroCurvatureEnding,\n\t\t\tendingEnd: ZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( let i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tconst interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants; // bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null; // for the memory manager\n\t\tthis._byClipCacheIndex = null; // for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = - 1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; // no. of repetitions when looping\n\n\t\tthis.paused = false; // true -> zero effective time scale\n\t\tthis.enabled = true; // false -> zero effective weight\n\n\t\tthis.clampWhenFinished = false;// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart = true;// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd = true;// clips for start, loop and end\n\n\t}\n\n\t// State & Scheduling\n\n\tplay() {\n\n\t\tthis._mixer._activateAction( this );\n\n\t\treturn this;\n\n\t}\n\n\tstop() {\n\n\t\tthis._mixer._deactivateAction( this );\n\n\t\treturn this.reset();\n\n\t}\n\n\treset() {\n\n\t\tthis.paused = false;\n\t\tthis.enabled = true;\n\n\t\tthis.time = 0; // restart clip\n\t\tthis._loopCount = - 1;// forget previous loops\n\t\tthis._startTime = null;// forget scheduling\n\n\t\treturn this.stopFading().stopWarping();\n\n\t}\n\n\tisRunning() {\n\n\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t}\n\n\t// return true when play has been called\n\tisScheduled() {\n\n\t\treturn this._mixer._isActiveAction( this );\n\n\t}\n\n\tstartAt( time ) {\n\n\t\tthis._startTime = time;\n\n\t\treturn this;\n\n\t}\n\n\tsetLoop( mode, repetitions ) {\n\n\t\tthis.loop = mode;\n\t\tthis.repetitions = repetitions;\n\n\t\treturn this;\n\n\t}\n\n\t// Weight\n\n\t// set the weight stopping any scheduled fading\n\t// although .enabled = false yields an effective weight of zero, this\n\t// method does *not* change .enabled, because it would be confusing\n\tsetEffectiveWeight( weight ) {\n\n\t\tthis.weight = weight;\n\n\t\t// note: same logic as when updated at runtime\n\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\treturn this.stopFading();\n\n\t}\n\n\t// return the weight considering fading and .enabled\n\tgetEffectiveWeight() {\n\n\t\treturn this._effectiveWeight;\n\n\t}\n\n\tfadeIn( duration ) {\n\n\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t}\n\n\tfadeOut( duration ) {\n\n\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t}\n\n\tcrossFadeFrom( fadeOutAction, duration, warp ) {\n\n\t\tfadeOutAction.fadeOut( duration );\n\t\tthis.fadeIn( duration );\n\n\t\tif ( warp ) {\n\n\t\t\tconst fadeInDuration = this._clip.duration,\n\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcrossFadeTo( fadeInAction, duration, warp ) {\n\n\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t}\n\n\tstopFading() {\n\n\t\tconst weightInterpolant = this._weightInterpolant;\n\n\t\tif ( weightInterpolant !== null ) {\n\n\t\t\tthis._weightInterpolant = null;\n\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t// Time Scale Control\n\n\t// set the time scale stopping any scheduled warping\n\t// although .paused = true yields an effective time scale of zero, this\n\t// method does *not* change .paused, because it would be confusing\n\tsetEffectiveTimeScale( timeScale ) {\n\n\t\tthis.timeScale = timeScale;\n\t\tthis._effectiveTimeScale = this.paused ? 0 : timeScale;\n\n\t\treturn this.stopWarping();\n\n\t}\n\n\t// return the time scale considering warping and .paused\n\tgetEffectiveTimeScale() {\n\n\t\treturn this._effectiveTimeScale;\n\n\t}\n\n\tsetDuration( duration ) {\n\n\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\treturn this.stopWarping();\n\n\t}\n\n\tsyncWith( action ) {\n\n\t\tthis.time = action.time;\n\t\tthis.timeScale = action.timeScale;\n\n\t\treturn this.stopWarping();\n\n\t}\n\n\thalt( duration ) {\n\n\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t}\n\n\twarp( startTimeScale, endTimeScale, duration ) {\n\n\t\tconst mixer = this._mixer,\n\t\t\tnow = mixer.time,\n\t\t\ttimeScale = this.timeScale;\n\n\t\tlet interpolant = this._timeScaleInterpolant;\n\n\t\tif ( interpolant === null ) {\n\n\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t}\n\n\t\tconst times = interpolant.parameterPositions,\n\t\t\tvalues = interpolant.sampleValues;\n\n\t\ttimes[ 0 ] = now;\n\t\ttimes[ 1 ] = now + duration;\n\n\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\treturn this;\n\n\t}\n\n\tstopWarping() {\n\n\t\tconst timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\tthis._timeScaleInterpolant = null;\n\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t// Object Accessors\n\n\tgetMixer() {\n\n\t\treturn this._mixer;\n\n\t}\n\n\tgetClip() {\n\n\t\treturn this._clip;\n\n\t}\n\n\tgetRoot() {\n\n\t\treturn this._localRoot || this._mixer._root;\n\n\t}\n\n\t// Interna\n\n\t_update( time, deltaTime, timeDirection, accuIndex ) {\n\n\t\t// called by the mixer\n\n\t\tif ( ! this.enabled ) {\n\n\t\t\t// call ._updateWeight() to update ._effectiveWeight\n\n\t\t\tthis._updateWeight( time );\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst startTime = this._startTime;\n\n\t\tif ( startTime !== null ) {\n\n\t\t\t// check for scheduled start of action\n\n\t\t\tconst timeRunning = ( time - startTime ) * timeDirection;\n\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t}\n\n\t\t\t// start\n\n\t\t\tthis._startTime = null; // unschedule\n\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t}\n\n\t\t// apply time scale and advance time\n\n\t\tdeltaTime *= this._updateTimeScale( time );\n\t\tconst clipTime = this._updateTime( deltaTime );\n\n\t\t// note: _updateTime may disable the action resulting in\n\t\t// an effective weight of 0\n\n\t\tconst weight = this._updateWeight( time );\n\n\t\tif ( weight > 0 ) {\n\n\t\t\tconst interpolants = this._interpolants;\n\t\t\tconst propertyMixers = this._propertyBindings;\n\n\t\t\tswitch ( this.blendMode ) {\n\n\t\t\t\tcase AdditiveAnimationBlendMode:\n\n\t\t\t\t\tfor ( let j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\t\tpropertyMixers[ j ].accumulateAdditive( weight );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase NormalAnimationBlendMode:\n\t\t\t\tdefault:\n\n\t\t\t\t\tfor ( let j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_updateWeight( time ) {\n\n\t\tlet weight = 0;\n\n\t\tif ( this.enabled ) {\n\n\t\t\tweight = this.weight;\n\t\t\tconst interpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\tconst interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis._effectiveWeight = weight;\n\t\treturn weight;\n\n\t}\n\n\t_updateTimeScale( time ) {\n\n\t\tlet timeScale = 0;\n\n\t\tif ( ! this.paused ) {\n\n\t\t\ttimeScale = this.timeScale;\n\n\t\t\tconst interpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\tconst interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis._effectiveTimeScale = timeScale;\n\t\treturn timeScale;\n\n\t}\n\n\t_updateTime( deltaTime ) {\n\n\t\tconst duration = this._clip.duration;\n\t\tconst loop = this.loop;\n\n\t\tlet time = this.time + deltaTime;\n\t\tlet loopCount = this._loopCount;\n\n\t\tconst pingPong = ( loop === LoopPingPong );\n\n\t\tif ( deltaTime === 0 ) {\n\n\t\t\tif ( loopCount === - 1 ) return time;\n\n\t\t\treturn ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time;\n\n\t\t}\n\n\t\tif ( loop === LoopOnce ) {\n\n\t\t\tif ( loopCount === - 1 ) {\n\n\t\t\t\t// just started\n\n\t\t\t\tthis._loopCount = 0;\n\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t}\n\n\t\t\thandle_stop: {\n\n\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\ttime = duration;\n\n\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\ttime = 0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.time = time;\n\n\t\t\t\t\tbreak handle_stop;\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\telse this.enabled = false;\n\n\t\t\t\tthis.time = time;\n\n\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\tdirection: deltaTime < 0 ? - 1 : 1\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\tif ( loopCount === - 1 ) {\n\n\t\t\t\t// just started\n\n\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\tthis._setEndings( true, this.repetitions === 0, pingPong );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\tthis._setEndings( this.repetitions === 0, true, pingPong );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( time >= duration || time < 0 ) {\n\n\t\t\t\t// wrap around\n\n\t\t\t\tconst loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\tconst pending = this.repetitions - loopCount;\n\n\t\t\t\tif ( pending <= 0 ) {\n\n\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\tthis.time = time;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : - 1\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// keep running\n\n\t\t\t\t\tif ( pending === 1 ) {\n\n\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\tconst atStart = deltaTime < 0;\n\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\tthis.time = time;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.time = time;\n\n\t\t\t}\n\n\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\n\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\treturn duration - time;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn time;\n\n\t}\n\n\t_setEndings( atStart, atEnd, pingPong ) {\n\n\t\tconst settings = this._interpolantSettings;\n\n\t\tif ( pingPong ) {\n\n\t\t\tsettings.endingStart = ZeroSlopeEnding;\n\t\t\tsettings.endingEnd = ZeroSlopeEnding;\n\n\t\t} else {\n\n\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\tif ( atStart ) {\n\n\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t} else {\n\n\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t}\n\n\t\t\tif ( atEnd ) {\n\n\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t} else {\n\n\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_scheduleFading( duration, weightNow, weightThen ) {\n\n\t\tconst mixer = this._mixer, now = mixer.time;\n\t\tlet interpolant = this._weightInterpolant;\n\n\t\tif ( interpolant === null ) {\n\n\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t}\n\n\t\tconst times = interpolant.parameterPositions,\n\t\t\tvalues = interpolant.sampleValues;\n\n\t\ttimes[ 0 ] = now;\n\t\tvalues[ 0 ] = weightNow;\n\t\ttimes[ 1 ] = now + duration;\n\t\tvalues[ 1 ] = weightThen;\n\n\t\treturn this;\n\n\t}\n\n}\n\nconst _controlInterpolantsResultBuffer = /*@__PURE__*/ new Float32Array( 1 );\n\n\nclass AnimationMixer extends EventDispatcher {\n\n\tconstructor( root ) {\n\n\t\tsuper();\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\t\tthis.time = 0;\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\t_bindAction( action, prototypeAction ) {\n\n\t\tconst root = action._localRoot || this._root,\n\t\t\ttracks = action._clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tbindings = action._propertyBindings,\n\t\t\tinterpolants = action._interpolants,\n\t\t\trootUuid = root.uuid,\n\t\t\tbindingsByRoot = this._bindingsByRootAndName;\n\n\t\tlet bindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\tif ( bindingsByName === undefined ) {\n\n\t\t\tbindingsByName = {};\n\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t}\n\n\t\tfor ( let i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tconst track = tracks[ i ],\n\t\t\t\ttrackName = track.name;\n\n\t\t\tlet binding = bindingsByName[ trackName ];\n\n\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t++ binding.referenceCount;\n\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t} else {\n\n\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tconst path = prototypeAction && prototypeAction.\n\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t++ binding.referenceCount;\n\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t}\n\n\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t}\n\n\t}\n\n\t_activateAction( action ) {\n\n\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\tconst rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\tthis._bindAction( action,\n\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t}\n\n\t\t\tconst bindings = action._propertyBindings;\n\n\t\t\t// increment reference counts / sort out state\n\t\t\tfor ( let i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tconst binding = bindings[ i ];\n\n\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._lendAction( action );\n\n\t\t}\n\n\t}\n\n\t_deactivateAction( action ) {\n\n\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\tconst bindings = action._propertyBindings;\n\n\t\t\t// decrement reference counts / sort out state\n\t\t\tfor ( let i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tconst binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._takeBackAction( action );\n\n\t\t}\n\n\t}\n\n\t// Memory manager\n\n\t_initMemoryManager() {\n\n\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\tthis._nActiveActions = 0;\n\n\t\tthis._actionsByClip = {};\n\t\t// inside:\n\t\t// {\n\t\t// \tknownActions: Array< AnimationAction > - used as prototypes\n\t\t// \tactionByRoot: AnimationAction - lookup\n\t\t// }\n\n\n\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\tthis._nActiveBindings = 0;\n\n\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\tthis._controlInterpolants = []; // same game as above\n\t\tthis._nActiveControlInterpolants = 0;\n\n\t\tconst scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tactions: {\n\t\t\t\tget total() {\n\n\t\t\t\t\treturn scope._actions.length;\n\n\t\t\t\t},\n\t\t\t\tget inUse() {\n\n\t\t\t\t\treturn scope._nActiveActions;\n\n\t\t\t\t}\n\t\t\t},\n\t\t\tbindings: {\n\t\t\t\tget total() {\n\n\t\t\t\t\treturn scope._bindings.length;\n\n\t\t\t\t},\n\t\t\t\tget inUse() {\n\n\t\t\t\t\treturn scope._nActiveBindings;\n\n\t\t\t\t}\n\t\t\t},\n\t\t\tcontrolInterpolants: {\n\t\t\t\tget total() {\n\n\t\t\t\t\treturn scope._controlInterpolants.length;\n\n\t\t\t\t},\n\t\t\t\tget inUse() {\n\n\t\t\t\t\treturn scope._nActiveControlInterpolants;\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t// Memory management for AnimationAction objects\n\n\t_isActiveAction( action ) {\n\n\t\tconst index = action._cacheIndex;\n\t\treturn index !== null && index < this._nActiveActions;\n\n\t}\n\n\t_addInactiveAction( action, clipUuid, rootUuid ) {\n\n\t\tconst actions = this._actions,\n\t\t\tactionsByClip = this._actionsByClip;\n\n\t\tlet actionsForClip = actionsByClip[ clipUuid ];\n\n\t\tif ( actionsForClip === undefined ) {\n\n\t\t\tactionsForClip = {\n\n\t\t\t\tknownActions: [ action ],\n\t\t\t\tactionByRoot: {}\n\n\t\t\t};\n\n\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t} else {\n\n\t\t\tconst knownActions = actionsForClip.knownActions;\n\n\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\tknownActions.push( action );\n\n\t\t}\n\n\t\taction._cacheIndex = actions.length;\n\t\tactions.push( action );\n\n\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t}\n\n\t_removeInactiveAction( action ) {\n\n\t\tconst actions = this._actions,\n\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\tcacheIndex = action._cacheIndex;\n\n\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\tactions.pop();\n\n\t\taction._cacheIndex = null;\n\n\n\t\tconst clipUuid = action._clip.uuid,\n\t\t\tactionsByClip = this._actionsByClip,\n\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\tlastKnownAction =\n\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\tknownActionsForClip.pop();\n\n\t\taction._byClipCacheIndex = null;\n\n\n\t\tconst actionByRoot = actionsForClip.actionByRoot,\n\t\t\trootUuid = ( action._localRoot || this._root ).uuid;\n\n\t\tdelete actionByRoot[ rootUuid ];\n\n\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t}\n\n\t\tthis._removeInactiveBindingsForAction( action );\n\n\t}\n\n\t_removeInactiveBindingsForAction( action ) {\n\n\t\tconst bindings = action._propertyBindings;\n\n\t\tfor ( let i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\tconst binding = bindings[ i ];\n\n\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_lendAction( action ) {\n\n\t\t// [ active actions | inactive actions ]\n\t\t// [ active actions >| inactive actions ]\n\t\t// s a\n\t\t// <-swap->\n\t\t// a s\n\n\t\tconst actions = this._actions,\n\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\taction._cacheIndex = lastActiveIndex;\n\t\tactions[ lastActiveIndex ] = action;\n\n\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t}\n\n\t_takeBackAction( action ) {\n\n\t\t// [ active actions | inactive actions ]\n\t\t// [ active actions |< inactive actions ]\n\t\t// a s\n\t\t// <-swap->\n\t\t// s a\n\n\t\tconst actions = this._actions,\n\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\taction._cacheIndex = firstInactiveIndex;\n\t\tactions[ firstInactiveIndex ] = action;\n\n\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t}\n\n\t// Memory management for PropertyMixer objects\n\n\t_addInactiveBinding( binding, rootUuid, trackName ) {\n\n\t\tconst bindingsByRoot = this._bindingsByRootAndName,\n\t\t\tbindings = this._bindings;\n\n\t\tlet bindingByName = bindingsByRoot[ rootUuid ];\n\n\t\tif ( bindingByName === undefined ) {\n\n\t\t\tbindingByName = {};\n\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t}\n\n\t\tbindingByName[ trackName ] = binding;\n\n\t\tbinding._cacheIndex = bindings.length;\n\t\tbindings.push( binding );\n\n\t}\n\n\t_removeInactiveBinding( binding ) {\n\n\t\tconst bindings = this._bindings,\n\t\t\tpropBinding = binding.binding,\n\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\ttrackName = propBinding.path,\n\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\tbindings.pop();\n\n\t\tdelete bindingByName[ trackName ];\n\n\t\tif ( Object.keys( bindingByName ).length === 0 ) {\n\n\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t}\n\n\t}\n\n\t_lendBinding( binding ) {\n\n\t\tconst bindings = this._bindings,\n\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\tbinding._cacheIndex = lastActiveIndex;\n\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t}\n\n\t_takeBackBinding( binding ) {\n\n\t\tconst bindings = this._bindings,\n\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t}\n\n\n\t// Memory management of Interpolants for weight and time scale\n\n\t_lendControlInterpolant() {\n\n\t\tconst interpolants = this._controlInterpolants,\n\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++;\n\n\t\tlet interpolant = interpolants[ lastActiveIndex ];\n\n\t\tif ( interpolant === undefined ) {\n\n\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t1, _controlInterpolantsResultBuffer );\n\n\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t}\n\n\t\treturn interpolant;\n\n\t}\n\n\t_takeBackControlInterpolant( interpolant ) {\n\n\t\tconst interpolants = this._controlInterpolants,\n\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t}\n\n\t// return an action for a clip optionally using a custom root target\n\t// object (this method allocates a lot of dynamic memory in case a\n\t// previously unknown clip/root combination is specified)\n\tclipAction( clip, optionalRoot, blendMode ) {\n\n\t\tconst root = optionalRoot || this._root,\n\t\t\trootUuid = root.uuid;\n\n\t\tlet clipObject = typeof clip === 'string' ? AnimationClip.findByName( root, clip ) : clip;\n\n\t\tconst clipUuid = clipObject !== null ? clipObject.uuid : clip;\n\n\t\tconst actionsForClip = this._actionsByClip[ clipUuid ];\n\t\tlet prototypeAction = null;\n\n\t\tif ( blendMode === undefined ) {\n\n\t\t\tif ( clipObject !== null ) {\n\n\t\t\t\tblendMode = clipObject.blendMode;\n\n\t\t\t} else {\n\n\t\t\t\tblendMode = NormalAnimationBlendMode;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\tconst existingAction = actionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\tif ( existingAction !== undefined && existingAction.blendMode === blendMode ) {\n\n\t\t\t\treturn existingAction;\n\n\t\t\t}\n\n\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t// the bindings again but can just copy\n\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t// also, take the clip from the prototype action\n\t\t\tif ( clipObject === null )\n\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t}\n\n\t\t// clip must be known when specified via string\n\t\tif ( clipObject === null ) return null;\n\n\t\t// allocate all resources required to run it\n\t\tconst newAction = new AnimationAction( this, clipObject, optionalRoot, blendMode );\n\n\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t// and make the action known to the memory manager\n\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\treturn newAction;\n\n\t}\n\n\t// get an existing action\n\texistingAction( clip, optionalRoot ) {\n\n\t\tconst root = optionalRoot || this._root,\n\t\t\trootUuid = root.uuid,\n\n\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\t// deactivates all previously scheduled actions\n\tstopAllAction() {\n\n\t\tconst actions = this._actions,\n\t\t\tnActions = this._nActiveActions;\n\n\t\tfor ( let i = nActions - 1; i >= 0; -- i ) {\n\n\t\t\tactions[ i ].stop();\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t// advance the time and update apply the animation\n\tupdate( deltaTime ) {\n\n\t\tdeltaTime *= this.timeScale;\n\n\t\tconst actions = this._actions,\n\t\t\tnActions = this._nActiveActions,\n\n\t\t\ttime = this.time += deltaTime,\n\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t// run active actions\n\n\t\tfor ( let i = 0; i !== nActions; ++ i ) {\n\n\t\t\tconst action = actions[ i ];\n\n\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t}\n\n\t\t// update scene graph\n\n\t\tconst bindings = this._bindings,\n\t\t\tnBindings = this._nActiveBindings;\n\n\t\tfor ( let i = 0; i !== nBindings; ++ i ) {\n\n\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\t// Allows you to seek to a specific time in an animation.\n\tsetTime( timeInSeconds ) {\n\n\t\tthis.time = 0; // Zero out time attribute for AnimationMixer object;\n\t\tfor ( let i = 0; i < this._actions.length; i ++ ) {\n\n\t\t\tthis._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects.\n\n\t\t}\n\n\t\treturn this.update( timeInSeconds ); // Update used to set exact time. Returns \"this\" AnimationMixer object.\n\n\t}\n\n\t// return this mixer's root target object\n\tgetRoot() {\n\n\t\treturn this._root;\n\n\t}\n\n\t// free all resources specific to a particular clip\n\tuncacheClip( clip ) {\n\n\t\tconst actions = this._actions,\n\t\t\tclipUuid = clip.uuid,\n\t\t\tactionsByClip = this._actionsByClip,\n\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t// iteration state and also require updating the state we can\n\t\t\t// just throw away\n\n\t\t\tconst actionsToRemove = actionsForClip.knownActions;\n\n\t\t\tfor ( let i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\tconst action = actionsToRemove[ i ];\n\n\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\tconst cacheIndex = action._cacheIndex,\n\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\taction._cacheIndex = null;\n\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\tactions.pop();\n\n\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t}\n\n\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t}\n\n\t}\n\n\t// free all resources specific to a particular root target object\n\tuncacheRoot( root ) {\n\n\t\tconst rootUuid = root.uuid,\n\t\t\tactionsByClip = this._actionsByClip;\n\n\t\tfor ( const clipUuid in actionsByClip ) {\n\n\t\t\tconst actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\tif ( action !== undefined ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst bindingsByRoot = this._bindingsByRootAndName,\n\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\tif ( bindingByName !== undefined ) {\n\n\t\t\tfor ( const trackName in bindingByName ) {\n\n\t\t\t\tconst binding = bindingByName[ trackName ];\n\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// remove a targeted clip from the cache\n\tuncacheAction( clip, optionalRoot ) {\n\n\t\tconst action = this.existingAction( clip, optionalRoot );\n\n\t\tif ( action !== null ) {\n\n\t\t\tthis._deactivateAction( action );\n\t\t\tthis._removeInactiveAction( action );\n\n\t\t}\n\n\t}\n\n}\n\nclass Uniform {\n\n\tconstructor( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tclone() {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t}\n\n}\n\nclass InstancedInterleavedBuffer extends InterleavedBuffer {\n\n\tconstructor( array, stride, meshPerAttribute = 1 ) {\n\n\t\tsuper( array, stride );\n\n\t\tthis.isInstancedInterleavedBuffer = true;\n\n\t\tthis.meshPerAttribute = meshPerAttribute;\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t}\n\n\tclone( data ) {\n\n\t\tconst ib = super.clone( data );\n\n\t\tib.meshPerAttribute = this.meshPerAttribute;\n\n\t\treturn ib;\n\n\t}\n\n\ttoJSON( data ) {\n\n\t\tconst json = super.toJSON( data );\n\n\t\tjson.isInstancedInterleavedBuffer = true;\n\t\tjson.meshPerAttribute = this.meshPerAttribute;\n\n\t\treturn json;\n\n\t}\n\n}\n\nclass GLBufferAttribute {\n\n\tconstructor( buffer, type, itemSize, elementSize, count ) {\n\n\t\tthis.isGLBufferAttribute = true;\n\n\t\tthis.buffer = buffer;\n\t\tthis.type = type;\n\t\tthis.itemSize = itemSize;\n\t\tthis.elementSize = elementSize;\n\t\tthis.count = count;\n\n\t\tthis.version = 0;\n\n\t}\n\n\tset needsUpdate( value ) {\n\n\t\tif ( value === true ) this.version ++;\n\n\t}\n\n\tsetBuffer( buffer ) {\n\n\t\tthis.buffer = buffer;\n\n\t\treturn this;\n\n\t}\n\n\tsetType( type, elementSize ) {\n\n\t\tthis.type = type;\n\t\tthis.elementSize = elementSize;\n\n\t\treturn this;\n\n\t}\n\n\tsetItemSize( itemSize ) {\n\n\t\tthis.itemSize = itemSize;\n\n\t\treturn this;\n\n\t}\n\n\tsetCount( count ) {\n\n\t\tthis.count = count;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass Raycaster {\n\n\tconstructor( origin, direction, near = 0, far = Infinity ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near;\n\t\tthis.far = far;\n\t\tthis.camera = null;\n\t\tthis.layers = new Layers();\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: { threshold: 1 },\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t}\n\n\tset( origin, direction ) {\n\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.ray.set( origin, direction );\n\n\t}\n\n\tsetFromCamera( coords, camera ) {\n\n\t\tif ( camera.isPerspectiveCamera ) {\n\n\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\t\t\tthis.camera = camera;\n\n\t\t} else if ( camera.isOrthographicCamera ) {\n\n\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\t\t\tthis.camera = camera;\n\n\t\t} else {\n\n\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type: ' + camera.type );\n\n\t\t}\n\n\t}\n\n\tintersectObject( object, recursive = true, intersects = [] ) {\n\n\t\tintersectObject( object, this, intersects, recursive );\n\n\t\tintersects.sort( ascSort );\n\n\t\treturn intersects;\n\n\t}\n\n\tintersectObjects( objects, recursive = true, intersects = [] ) {\n\n\t\tfor ( let i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t}\n\n\t\tintersects.sort( ascSort );\n\n\t\treturn intersects;\n\n\t}\n\n}\n\nfunction ascSort( a, b ) {\n\n\treturn a.distance - b.distance;\n\n}\n\nfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\tif ( object.layers.test( raycaster.layers ) ) {\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t}\n\n\tif ( recursive === true ) {\n\n\t\tconst children = object.children;\n\n\t\tfor ( let i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n *\n * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up.\n * The azimuthal angle (theta) is measured from the positive z-axis.\n */\n\nclass Spherical {\n\n\tconstructor( radius = 1, phi = 0, theta = 0 ) {\n\n\t\tthis.radius = radius;\n\t\tthis.phi = phi; // polar angle\n\t\tthis.theta = theta; // azimuthal angle\n\n\t\treturn this;\n\n\t}\n\n\tset( radius, phi, theta ) {\n\n\t\tthis.radius = radius;\n\t\tthis.phi = phi;\n\t\tthis.theta = theta;\n\n\t\treturn this;\n\n\t}\n\n\tcopy( other ) {\n\n\t\tthis.radius = other.radius;\n\t\tthis.phi = other.phi;\n\t\tthis.theta = other.theta;\n\n\t\treturn this;\n\n\t}\n\n\t// restrict phi to be between EPS and PI-EPS\n\tmakeSafe() {\n\n\t\tconst EPS = 0.000001;\n\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromVector3( v ) {\n\n\t\treturn this.setFromCartesianCoords( v.x, v.y, v.z );\n\n\t}\n\n\tsetFromCartesianCoords( x, y, z ) {\n\n\t\tthis.radius = Math.sqrt( x * x + y * y + z * z );\n\n\t\tif ( this.radius === 0 ) {\n\n\t\t\tthis.theta = 0;\n\t\t\tthis.phi = 0;\n\n\t\t} else {\n\n\t\t\tthis.theta = Math.atan2( x, z );\n\t\t\tthis.phi = Math.acos( clamp( y / this.radius, - 1, 1 ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\n/**\n * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n */\n\nclass Cylindrical {\n\n\tconstructor( radius = 1, theta = 0, y = 0 ) {\n\n\t\tthis.radius = radius; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = theta; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = y; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tset( radius, theta, y ) {\n\n\t\tthis.radius = radius;\n\t\tthis.theta = theta;\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tcopy( other ) {\n\n\t\tthis.radius = other.radius;\n\t\tthis.theta = other.theta;\n\t\tthis.y = other.y;\n\n\t\treturn this;\n\n\t}\n\n\tsetFromVector3( v ) {\n\n\t\treturn this.setFromCartesianCoords( v.x, v.y, v.z );\n\n\t}\n\n\tsetFromCartesianCoords( x, y, z ) {\n\n\t\tthis.radius = Math.sqrt( x * x + z * z );\n\t\tthis.theta = Math.atan2( x, z );\n\t\tthis.y = y;\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nconst _vector$4 = /*@__PURE__*/ new Vector2();\n\nclass Box2 {\n\n\tconstructor( min = new Vector2( + Infinity, + Infinity ), max = new Vector2( - Infinity, - Infinity ) ) {\n\n\t\tthis.isBox2 = true;\n\n\t\tthis.min = min;\n\t\tthis.max = max;\n\n\t}\n\n\tset( min, max ) {\n\n\t\tthis.min.copy( min );\n\t\tthis.max.copy( max );\n\n\t\treturn this;\n\n\t}\n\n\tsetFromPoints( points ) {\n\n\t\tthis.makeEmpty();\n\n\t\tfor ( let i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tsetFromCenterAndSize( center, size ) {\n\n\t\tconst halfSize = _vector$4.copy( size ).multiplyScalar( 0.5 );\n\t\tthis.min.copy( center ).sub( halfSize );\n\t\tthis.max.copy( center ).add( halfSize );\n\n\t\treturn this;\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n\tcopy( box ) {\n\n\t\tthis.min.copy( box.min );\n\t\tthis.max.copy( box.max );\n\n\t\treturn this;\n\n\t}\n\n\tmakeEmpty() {\n\n\t\tthis.min.x = this.min.y = + Infinity;\n\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\treturn this;\n\n\t}\n\n\tisEmpty() {\n\n\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t}\n\n\tgetCenter( target ) {\n\n\t\treturn this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t}\n\n\tgetSize( target ) {\n\n\t\treturn this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min );\n\n\t}\n\n\texpandByPoint( point ) {\n\n\t\tthis.min.min( point );\n\t\tthis.max.max( point );\n\n\t\treturn this;\n\n\t}\n\n\texpandByVector( vector ) {\n\n\t\tthis.min.sub( vector );\n\t\tthis.max.add( vector );\n\n\t\treturn this;\n\n\t}\n\n\texpandByScalar( scalar ) {\n\n\t\tthis.min.addScalar( - scalar );\n\t\tthis.max.addScalar( scalar );\n\n\t\treturn this;\n\n\t}\n\n\tcontainsPoint( point ) {\n\n\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t}\n\n\tcontainsBox( box ) {\n\n\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t}\n\n\tgetParameter( point, target ) {\n\n\t\t// This can potentially have a divide by zero if the box\n\t\t// has a size dimension of 0.\n\n\t\treturn target.set(\n\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t);\n\n\t}\n\n\tintersectsBox( box ) {\n\n\t\t// using 4 splitting planes to rule out intersections\n\n\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t}\n\n\tclampPoint( point, target ) {\n\n\t\treturn target.copy( point ).clamp( this.min, this.max );\n\n\t}\n\n\tdistanceToPoint( point ) {\n\n\t\tconst clampedPoint = _vector$4.copy( point ).clamp( this.min, this.max );\n\t\treturn clampedPoint.sub( point ).length();\n\n\t}\n\n\tintersect( box ) {\n\n\t\tthis.min.max( box.min );\n\t\tthis.max.min( box.max );\n\n\t\treturn this;\n\n\t}\n\n\tunion( box ) {\n\n\t\tthis.min.min( box.min );\n\t\tthis.max.max( box.max );\n\n\t\treturn this;\n\n\t}\n\n\ttranslate( offset ) {\n\n\t\tthis.min.add( offset );\n\t\tthis.max.add( offset );\n\n\t\treturn this;\n\n\t}\n\n\tequals( box ) {\n\n\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t}\n\n}\n\nconst _startP = /*@__PURE__*/ new Vector3();\nconst _startEnd = /*@__PURE__*/ new Vector3();\n\nclass Line3 {\n\n\tconstructor( start = new Vector3(), end = new Vector3() ) {\n\n\t\tthis.start = start;\n\t\tthis.end = end;\n\n\t}\n\n\tset( start, end ) {\n\n\t\tthis.start.copy( start );\n\t\tthis.end.copy( end );\n\n\t\treturn this;\n\n\t}\n\n\tcopy( line ) {\n\n\t\tthis.start.copy( line.start );\n\t\tthis.end.copy( line.end );\n\n\t\treturn this;\n\n\t}\n\n\tgetCenter( target ) {\n\n\t\treturn target.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t}\n\n\tdelta( target ) {\n\n\t\treturn target.subVectors( this.end, this.start );\n\n\t}\n\n\tdistanceSq() {\n\n\t\treturn this.start.distanceToSquared( this.end );\n\n\t}\n\n\tdistance() {\n\n\t\treturn this.start.distanceTo( this.end );\n\n\t}\n\n\tat( t, target ) {\n\n\t\treturn this.delta( target ).multiplyScalar( t ).add( this.start );\n\n\t}\n\n\tclosestPointToPointParameter( point, clampToLine ) {\n\n\t\t_startP.subVectors( point, this.start );\n\t\t_startEnd.subVectors( this.end, this.start );\n\n\t\tconst startEnd2 = _startEnd.dot( _startEnd );\n\t\tconst startEnd_startP = _startEnd.dot( _startP );\n\n\t\tlet t = startEnd_startP / startEnd2;\n\n\t\tif ( clampToLine ) {\n\n\t\t\tt = clamp( t, 0, 1 );\n\n\t\t}\n\n\t\treturn t;\n\n\t}\n\n\tclosestPointToPoint( point, clampToLine, target ) {\n\n\t\tconst t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\treturn this.delta( target ).multiplyScalar( t ).add( this.start );\n\n\t}\n\n\tapplyMatrix4( matrix ) {\n\n\t\tthis.start.applyMatrix4( matrix );\n\t\tthis.end.applyMatrix4( matrix );\n\n\t\treturn this;\n\n\t}\n\n\tequals( line ) {\n\n\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t}\n\n\tclone() {\n\n\t\treturn new this.constructor().copy( this );\n\n\t}\n\n}\n\nconst _vector$3 = /*@__PURE__*/ new Vector3();\n\nclass SpotLightHelper extends Object3D {\n\n\tconstructor( light, color ) {\n\n\t\tsuper();\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.color = color;\n\n\t\tconst geometry = new BufferGeometry();\n\n\t\tconst positions = [\n\t\t\t0, 0, 0, \t0, 0, 1,\n\t\t\t0, 0, 0, \t1, 0, 1,\n\t\t\t0, 0, 0,\t- 1, 0, 1,\n\t\t\t0, 0, 0, \t0, 1, 1,\n\t\t\t0, 0, 0, \t0, - 1, 1\n\t\t];\n\n\t\tfor ( let i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tconst p1 = ( i / l ) * Math.PI * 2;\n\t\t\tconst p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tconst material = new LineBasicMaterial( { fog: false, toneMapped: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tdispose() {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t}\n\n\tupdate() {\n\n\t\tthis.light.updateMatrixWorld();\n\n\t\tconst coneLength = this.light.distance ? this.light.distance : 1000;\n\t\tconst coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t_vector$3.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\tthis.cone.lookAt( _vector$3 );\n\n\t\tif ( this.color !== undefined ) {\n\n\t\t\tthis.cone.material.color.set( this.color );\n\n\t\t} else {\n\n\t\t\tthis.cone.material.color.copy( this.light.color );\n\n\t\t}\n\n\t}\n\n}\n\nconst _vector$2 = /*@__PURE__*/ new Vector3();\nconst _boneMatrix = /*@__PURE__*/ new Matrix4();\nconst _matrixWorldInv = /*@__PURE__*/ new Matrix4();\n\n\nclass SkeletonHelper extends LineSegments {\n\n\tconstructor( object ) {\n\n\t\tconst bones = getBoneList( object );\n\n\t\tconst geometry = new BufferGeometry();\n\n\t\tconst vertices = [];\n\t\tconst colors = [];\n\n\t\tconst color1 = new Color( 0, 0, 1 );\n\t\tconst color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( let i = 0; i < bones.length; i ++ ) {\n\n\t\t\tconst bone = bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tconst material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } );\n\n\t\tsuper( geometry, material );\n\n\t\tthis.isSkeletonHelper = true;\n\n\t\tthis.type = 'SkeletonHelper';\n\n\t\tthis.root = object;\n\t\tthis.bones = bones;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tconst bones = this.bones;\n\n\t\tconst geometry = this.geometry;\n\t\tconst position = geometry.getAttribute( 'position' );\n\n\t\t_matrixWorldInv.copy( this.root.matrixWorld ).invert();\n\n\t\tfor ( let i = 0, j = 0; i < bones.length; i ++ ) {\n\n\t\t\tconst bone = bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t_boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld );\n\t\t\t\t_vector$2.setFromMatrixPosition( _boneMatrix );\n\t\t\t\tposition.setXYZ( j, _vector$2.x, _vector$2.y, _vector$2.z );\n\n\t\t\t\t_boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t_vector$2.setFromMatrixPosition( _boneMatrix );\n\t\t\t\tposition.setXYZ( j + 1, _vector$2.x, _vector$2.y, _vector$2.z );\n\n\t\t\t\tj += 2;\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\n\nfunction getBoneList( object ) {\n\n\tconst boneList = [];\n\n\tif ( object.isBone === true ) {\n\n\t\tboneList.push( object );\n\n\t}\n\n\tfor ( let i = 0; i < object.children.length; i ++ ) {\n\n\t\tboneList.push.apply( boneList, getBoneList( object.children[ i ] ) );\n\n\t}\n\n\treturn boneList;\n\n}\n\nclass PointLightHelper extends Mesh {\n\n\tconstructor( light, sphereSize, color ) {\n\n\t\tconst geometry = new SphereGeometry( sphereSize, 4, 2 );\n\t\tconst material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );\n\n\t\tsuper( geometry, material );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.color = color;\n\n\t\tthis.type = 'PointLightHelper';\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\n\t\t/*\n\t// TODO: delete this comment?\n\tconst distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\tconst distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\tconst d = light.distance;\n\n\tif ( d === 0.0 ) {\n\n\t\tthis.lightDistance.visible = false;\n\n\t} else {\n\n\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t}\n\n\tthis.add( this.lightDistance );\n\t*/\n\n\t}\n\n\tdispose() {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t}\n\n\tupdate() {\n\n\t\tif ( this.color !== undefined ) {\n\n\t\t\tthis.material.color.set( this.color );\n\n\t\t} else {\n\n\t\t\tthis.material.color.copy( this.light.color );\n\n\t\t}\n\n\t\t/*\n\t\tconst d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t}\n\n}\n\nconst _vector$1 = /*@__PURE__*/ new Vector3();\nconst _color1 = /*@__PURE__*/ new Color();\nconst _color2 = /*@__PURE__*/ new Color();\n\nclass HemisphereLightHelper extends Object3D {\n\n\tconstructor( light, size, color ) {\n\n\t\tsuper();\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.color = color;\n\n\t\tconst geometry = new OctahedronGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tthis.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );\n\t\tif ( this.color === undefined ) this.material.vertexColors = true;\n\n\t\tconst position = geometry.getAttribute( 'position' );\n\t\tconst colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, this.material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tdispose() {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t}\n\n\tupdate() {\n\n\t\tconst mesh = this.children[ 0 ];\n\n\t\tif ( this.color !== undefined ) {\n\n\t\t\tthis.material.color.set( this.color );\n\n\t\t} else {\n\n\t\t\tconst colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\t_color1.copy( this.light.color );\n\t\t\t_color2.copy( this.light.groundColor );\n\n\t\t\tfor ( let i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tconst color = ( i < ( l / 2 ) ) ? _color1 : _color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t}\n\n\t\tmesh.lookAt( _vector$1.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t}\n\n}\n\nclass GridHelper extends LineSegments {\n\n\tconstructor( size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888 ) {\n\n\t\tcolor1 = new Color( color1 );\n\t\tcolor2 = new Color( color2 );\n\n\t\tconst center = divisions / 2;\n\t\tconst step = size / divisions;\n\t\tconst halfSize = size / 2;\n\n\t\tconst vertices = [], colors = [];\n\n\t\tfor ( let i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tconst color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tconst geometry = new BufferGeometry();\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tconst material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );\n\n\t\tsuper( geometry, material );\n\n\t\tthis.type = 'GridHelper';\n\n\t}\n\n}\n\nclass PolarGridHelper extends LineSegments {\n\n\tconstructor( radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888 ) {\n\n\t\tcolor1 = new Color( color1 );\n\t\tcolor2 = new Color( color2 );\n\n\t\tconst vertices = [];\n\t\tconst colors = [];\n\n\t\t// create the radials\n\n\t\tfor ( let i = 0; i <= radials; i ++ ) {\n\n\t\t\tconst v = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tconst x = Math.sin( v ) * radius;\n\t\t\tconst z = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tconst color = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( let i = 0; i <= circles; i ++ ) {\n\n\t\t\tconst color = ( i & 1 ) ? color1 : color2;\n\n\t\t\tconst r = radius - ( radius / circles * i );\n\n\t\t\tfor ( let j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tlet v = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tlet x = Math.sin( v ) * r;\n\t\t\t\tlet z = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst geometry = new BufferGeometry();\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tconst material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );\n\n\t\tsuper( geometry, material );\n\n\t\tthis.type = 'PolarGridHelper';\n\n\t}\n\n}\n\nconst _v1 = /*@__PURE__*/ new Vector3();\nconst _v2 = /*@__PURE__*/ new Vector3();\nconst _v3 = /*@__PURE__*/ new Vector3();\n\nclass DirectionalLightHelper extends Object3D {\n\n\tconstructor( light, size, color ) {\n\n\t\tsuper();\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.color = color;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tlet geometry = new BufferGeometry();\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\tsize, size, 0,\n\t\t\tsize, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tconst material = new LineBasicMaterial( { fog: false, toneMapped: false } );\n\n\t\tthis.lightPlane = new Line( geometry, material );\n\t\tthis.add( this.lightPlane );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.targetLine = new Line( geometry, material );\n\t\tthis.add( this.targetLine );\n\n\t\tthis.update();\n\n\t}\n\n\tdispose() {\n\n\t\tthis.lightPlane.geometry.dispose();\n\t\tthis.lightPlane.material.dispose();\n\t\tthis.targetLine.geometry.dispose();\n\t\tthis.targetLine.material.dispose();\n\n\t}\n\n\tupdate() {\n\n\t\t_v1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t_v2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t_v3.subVectors( _v2, _v1 );\n\n\t\tthis.lightPlane.lookAt( _v2 );\n\n\t\tif ( this.color !== undefined ) {\n\n\t\t\tthis.lightPlane.material.color.set( this.color );\n\t\t\tthis.targetLine.material.color.set( this.color );\n\n\t\t} else {\n\n\t\t\tthis.lightPlane.material.color.copy( this.light.color );\n\t\t\tthis.targetLine.material.color.copy( this.light.color );\n\n\t\t}\n\n\t\tthis.targetLine.lookAt( _v2 );\n\t\tthis.targetLine.scale.z = _v3.length();\n\n\t}\n\n}\n\nconst _vector = /*@__PURE__*/ new Vector3();\nconst _camera = /*@__PURE__*/ new Camera();\n\n/**\n *\t- shows frustum, line of sight and up of the camera\n *\t- suitable for fast updates\n * \t- based on frustum visualization in lightgl.js shadowmap example\n *\t\thttps://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html\n */\n\nclass CameraHelper extends LineSegments {\n\n\tconstructor( camera ) {\n\n\t\tconst geometry = new BufferGeometry();\n\t\tconst material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true, toneMapped: false } );\n\n\t\tconst vertices = [];\n\t\tconst colors = [];\n\n\t\tconst pointMap = {};\n\n\t\t// colors\n\n\t\tconst colorFrustum = new Color( 0xffaa00 );\n\t\tconst colorCone = new Color( 0xff0000 );\n\t\tconst colorUp = new Color( 0x00aaff );\n\t\tconst colorTarget = new Color( 0xffffff );\n\t\tconst colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( 'n1', 'n2', colorFrustum );\n\t\taddLine( 'n2', 'n4', colorFrustum );\n\t\taddLine( 'n4', 'n3', colorFrustum );\n\t\taddLine( 'n3', 'n1', colorFrustum );\n\n\t\t// far\n\n\t\taddLine( 'f1', 'f2', colorFrustum );\n\t\taddLine( 'f2', 'f4', colorFrustum );\n\t\taddLine( 'f4', 'f3', colorFrustum );\n\t\taddLine( 'f3', 'f1', colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( 'n1', 'f1', colorFrustum );\n\t\taddLine( 'n2', 'f2', colorFrustum );\n\t\taddLine( 'n3', 'f3', colorFrustum );\n\t\taddLine( 'n4', 'f4', colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( 'p', 'n1', colorCone );\n\t\taddLine( 'p', 'n2', colorCone );\n\t\taddLine( 'p', 'n3', colorCone );\n\t\taddLine( 'p', 'n4', colorCone );\n\n\t\t// up\n\n\t\taddLine( 'u1', 'u2', colorUp );\n\t\taddLine( 'u2', 'u3', colorUp );\n\t\taddLine( 'u3', 'u1', colorUp );\n\n\t\t// target\n\n\t\taddLine( 'c', 't', colorTarget );\n\t\taddLine( 'p', 'c', colorCross );\n\n\t\t// cross\n\n\t\taddLine( 'cn1', 'cn2', colorCross );\n\t\taddLine( 'cn3', 'cn4', colorCross );\n\n\t\taddLine( 'cf1', 'cf2', colorCross );\n\t\taddLine( 'cf3', 'cf4', colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tsuper( geometry, material );\n\n\t\tthis.type = 'CameraHelper';\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tupdate() {\n\n\t\tconst geometry = this.geometry;\n\t\tconst pointMap = this.pointMap;\n\n\t\tconst w = 1, h = 1;\n\n\t\t// we need just camera projection matrix inverse\n\t\t// world matrix must be identity\n\n\t\t_camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse );\n\n\t\t// center / target\n\n\t\tsetPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 );\n\t\tsetPoint( 't', pointMap, geometry, _camera, 0, 0, 1 );\n\n\t\t// near\n\n\t\tsetPoint( 'n1', pointMap, geometry, _camera, - w, - h, - 1 );\n\t\tsetPoint( 'n2', pointMap, geometry, _camera, w, - h, - 1 );\n\t\tsetPoint( 'n3', pointMap, geometry, _camera, - w, h, - 1 );\n\t\tsetPoint( 'n4', pointMap, geometry, _camera, w, h, - 1 );\n\n\t\t// far\n\n\t\tsetPoint( 'f1', pointMap, geometry, _camera, - w, - h, 1 );\n\t\tsetPoint( 'f2', pointMap, geometry, _camera, w, - h, 1 );\n\t\tsetPoint( 'f3', pointMap, geometry, _camera, - w, h, 1 );\n\t\tsetPoint( 'f4', pointMap, geometry, _camera, w, h, 1 );\n\n\t\t// up\n\n\t\tsetPoint( 'u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, - 1 );\n\t\tsetPoint( 'u2', pointMap, geometry, _camera, - w * 0.7, h * 1.1, - 1 );\n\t\tsetPoint( 'u3', pointMap, geometry, _camera, 0, h * 2, - 1 );\n\n\t\t// cross\n\n\t\tsetPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 );\n\t\tsetPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 );\n\t\tsetPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 );\n\t\tsetPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 );\n\n\t\tsetPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 );\n\t\tsetPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 );\n\t\tsetPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 );\n\t\tsetPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 );\n\n\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t}\n\n}\n\n\nfunction setPoint( point, pointMap, geometry, camera, x, y, z ) {\n\n\t_vector.set( x, y, z ).unproject( camera );\n\n\tconst points = pointMap[ point ];\n\n\tif ( points !== undefined ) {\n\n\t\tconst position = geometry.getAttribute( 'position' );\n\n\t\tfor ( let i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\tposition.setXYZ( points[ i ], _vector.x, _vector.y, _vector.z );\n\n\t\t}\n\n\t}\n\n}\n\nconst _box = /*@__PURE__*/ new Box3();\n\nclass BoxHelper extends LineSegments {\n\n\tconstructor( object, color = 0xffff00 ) {\n\n\t\tconst indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tconst positions = new Float32Array( 8 * 3 );\n\n\t\tconst geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tsuper( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );\n\n\t\tthis.object = object;\n\t\tthis.type = 'BoxHelper';\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tupdate( object ) {\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.BoxHelper: .update() has no longer arguments.' );\n\n\t\t}\n\n\t\tif ( this.object !== undefined ) {\n\n\t\t\t_box.setFromObject( this.object );\n\n\t\t}\n\n\t\tif ( _box.isEmpty() ) return;\n\n\t\tconst min = _box.min;\n\t\tconst max = _box.max;\n\n\t\t/*\n\t\t\t5____4\n\t\t1/___0/|\n\t\t| 6__|_7\n\t\t2/___3/\n\n\t\t0: max.x, max.y, max.z\n\t\t1: min.x, max.y, max.z\n\t\t2: min.x, min.y, max.z\n\t\t3: max.x, min.y, max.z\n\t\t4: max.x, max.y, min.z\n\t\t5: min.x, max.y, min.z\n\t\t6: min.x, min.y, min.z\n\t\t7: max.x, min.y, min.z\n\t\t*/\n\n\t\tconst position = this.geometry.attributes.position;\n\t\tconst array = position.array;\n\n\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\tposition.needsUpdate = true;\n\n\t\tthis.geometry.computeBoundingSphere();\n\n\n\t}\n\n\tsetFromObject( object ) {\n\n\t\tthis.object = object;\n\t\tthis.update();\n\n\t\treturn this;\n\n\t}\n\n\tcopy( source, recursive ) {\n\n\t\tsuper.copy( source, recursive );\n\n\t\tthis.object = source.object;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass Box3Helper extends LineSegments {\n\n\tconstructor( box, color = 0xffff00 ) {\n\n\t\tconst indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\n\t\tconst positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ];\n\n\t\tconst geometry = new BufferGeometry();\n\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tsuper( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );\n\n\t\tthis.box = box;\n\n\t\tthis.type = 'Box3Helper';\n\n\t\tthis.geometry.computeBoundingSphere();\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tconst box = this.box;\n\n\t\tif ( box.isEmpty() ) return;\n\n\t\tbox.getCenter( this.position );\n\n\t\tbox.getSize( this.scale );\n\n\t\tthis.scale.multiplyScalar( 0.5 );\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\nclass PlaneHelper extends Line {\n\n\tconstructor( plane, size = 1, hex = 0xffff00 ) {\n\n\t\tconst color = hex;\n\n\t\tconst positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ];\n\n\t\tconst geometry = new BufferGeometry();\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\t\tgeometry.computeBoundingSphere();\n\n\t\tsuper( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );\n\n\t\tthis.type = 'PlaneHelper';\n\n\t\tthis.plane = plane;\n\n\t\tthis.size = size;\n\n\t\tconst positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ];\n\n\t\tconst geometry2 = new BufferGeometry();\n\t\tgeometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) );\n\t\tgeometry2.computeBoundingSphere();\n\n\t\tthis.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) );\n\n\t}\n\n\tupdateMatrixWorld( force ) {\n\n\t\tlet scale = - this.plane.constant;\n\n\t\tif ( Math.abs( scale ) < 1e-8 ) scale = 1e-8; // sign does not matter\n\n\t\tthis.scale.set( 0.5 * this.size, 0.5 * this.size, scale );\n\n\t\tthis.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here\n\n\t\tthis.lookAt( this.plane.normal );\n\n\t\tsuper.updateMatrixWorld( force );\n\n\t}\n\n}\n\nconst _axis = /*@__PURE__*/ new Vector3();\nlet _lineGeometry, _coneGeometry;\n\nclass ArrowHelper extends Object3D {\n\n\t// dir is assumed to be normalized\n\n\tconstructor( dir = new Vector3( 0, 0, 1 ), origin = new Vector3( 0, 0, 0 ), length = 1, color = 0xffff00, headLength = length * 0.2, headWidth = headLength * 0.2 ) {\n\n\t\tsuper();\n\n\t\tthis.type = 'ArrowHelper';\n\n\t\tif ( _lineGeometry === undefined ) {\n\n\t\t\t_lineGeometry = new BufferGeometry();\n\t\t\t_lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\t_coneGeometry = new CylinderGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\t_coneGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color, toneMapped: false } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tsetDirection( dir ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t} else {\n\n\t\t\t_axis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\tconst radians = Math.acos( dir.y );\n\n\t\t\tthis.quaternion.setFromAxisAngle( _axis, radians );\n\n\t\t}\n\n\t}\n\n\tsetLength( length, headLength = length * 0.2, headWidth = headLength * 0.2 ) {\n\n\t\tthis.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 ); // see #17458\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t}\n\n\tsetColor( color ) {\n\n\t\tthis.line.material.color.set( color );\n\t\tthis.cone.material.color.set( color );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source, false );\n\n\t\tthis.line.copy( source.line );\n\t\tthis.cone.copy( source.cone );\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass AxesHelper extends LineSegments {\n\n\tconstructor( size = 1 ) {\n\n\t\tconst vertices = [\n\t\t\t0, 0, 0,\tsize, 0, 0,\n\t\t\t0, 0, 0,\t0, size, 0,\n\t\t\t0, 0, 0,\t0, 0, size\n\t\t];\n\n\t\tconst colors = [\n\t\t\t1, 0, 0,\t1, 0.6, 0,\n\t\t\t0, 1, 0,\t0.6, 1, 0,\n\t\t\t0, 0, 1,\t0, 0.6, 1\n\t\t];\n\n\t\tconst geometry = new BufferGeometry();\n\t\tgeometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tconst material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );\n\n\t\tsuper( geometry, material );\n\n\t\tthis.type = 'AxesHelper';\n\n\t}\n\n\tsetColors( xAxisColor, yAxisColor, zAxisColor ) {\n\n\t\tconst color = new Color();\n\t\tconst array = this.geometry.attributes.color.array;\n\n\t\tcolor.set( xAxisColor );\n\t\tcolor.toArray( array, 0 );\n\t\tcolor.toArray( array, 3 );\n\n\t\tcolor.set( yAxisColor );\n\t\tcolor.toArray( array, 6 );\n\t\tcolor.toArray( array, 9 );\n\n\t\tcolor.set( zAxisColor );\n\t\tcolor.toArray( array, 12 );\n\t\tcolor.toArray( array, 15 );\n\n\t\tthis.geometry.attributes.color.needsUpdate = true;\n\n\t\treturn this;\n\n\t}\n\n\tdispose() {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t}\n\n}\n\nclass ShapePath {\n\n\tconstructor() {\n\n\t\tthis.type = 'ShapePath';\n\n\t\tthis.color = new Color();\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tmoveTo( x, y ) {\n\n\t\tthis.currentPath = new Path();\n\t\tthis.subPaths.push( this.currentPath );\n\t\tthis.currentPath.moveTo( x, y );\n\n\t\treturn this;\n\n\t}\n\n\tlineTo( x, y ) {\n\n\t\tthis.currentPath.lineTo( x, y );\n\n\t\treturn this;\n\n\t}\n\n\tquadraticCurveTo( aCPx, aCPy, aX, aY ) {\n\n\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\treturn this;\n\n\t}\n\n\tbezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\treturn this;\n\n\t}\n\n\tsplineThru( pts ) {\n\n\t\tthis.currentPath.splineThru( pts );\n\n\t\treturn this;\n\n\t}\n\n\ttoShapes( isCCW, noHoles ) {\n\n\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\tconst shapes = [];\n\n\t\t\tfor ( let i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\tconst tmpPath = inSubpaths[ i ];\n\n\t\t\t\tconst tmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\tconst polyLen = inPolygon.length;\n\n\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\tlet inside = false;\n\t\t\tfor ( let p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\tlet edgeLowPt = inPolygon[ p ];\n\t\t\t\tlet edgeHighPt = inPolygon[ q ];\n\n\t\t\t\tlet edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\tlet edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconst perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t// continue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tinside;\n\n\t\t}\n\n\t\tconst isClockWise = ShapeUtils.isClockWise;\n\n\t\tconst subPaths = this.subPaths;\n\t\tif ( subPaths.length === 0 ) return [];\n\n\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\tlet solid, tmpPath, tmpShape;\n\t\tconst shapes = [];\n\n\t\tif ( subPaths.length === 1 ) {\n\n\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\ttmpShape = new Shape();\n\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\tshapes.push( tmpShape );\n\t\t\treturn shapes;\n\n\t\t}\n\n\t\tlet holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\tconst betterShapeHoles = [];\n\t\tconst newShapes = [];\n\t\tlet newShapeHoles = [];\n\t\tlet mainIdx = 0;\n\t\tlet tmpPoints;\n\n\t\tnewShapes[ mainIdx ] = undefined;\n\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\tfor ( let i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\ttmpPath = subPaths[ i ];\n\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\tif ( solid ) {\n\n\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t//console.log('cw', i);\n\n\t\t\t} else {\n\n\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t//console.log('ccw', i);\n\n\t\t\t}\n\n\t\t}\n\n\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\tif ( newShapes.length > 1 ) {\n\n\t\t\tlet ambiguous = false;\n\t\t\tlet toChange = 0;\n\n\t\t\tfor ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t}\n\n\t\t\tfor ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\tconst sho = newShapeHoles[ sIdx ];\n\n\t\t\t\tfor ( let hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\tconst ho = sho[ hIdx ];\n\t\t\t\t\tlet hole_unassigned = true;\n\n\t\t\t\t\tfor ( let s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange ++;\n\n\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( toChange > 0 && ambiguous === false ) {\n\n\t\t\t\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t}\n\n\t\t}\n\n\t\tlet tmpHoles;\n\n\t\tfor ( let i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\tshapes.push( tmpShape );\n\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\tfor ( let j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//console.log(\"shape\", shapes);\n\n\t\treturn shapes;\n\n\t}\n\n}\n\n// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf\n\nclass DataUtils {\n\n\t// float32 to float16\n\n\tstatic toHalfFloat( val ) {\n\n\t\tif ( Math.abs( val ) > 65504 ) console.warn( 'THREE.DataUtils.toHalfFloat(): Value out of range.' );\n\n\t\tval = clamp( val, - 65504, 65504 );\n\n\t\t_floatView[ 0 ] = val;\n\t\tconst f = _uint32View[ 0 ];\n\t\tconst e = ( f >> 23 ) & 0x1ff;\n\t\treturn _baseTable[ e ] + ( ( f & 0x007fffff ) >> _shiftTable[ e ] );\n\n\t}\n\n\t// float16 to float32\n\n\tstatic fromHalfFloat( val ) {\n\n\t\tconst m = val >> 10;\n\t\t_uint32View[ 0 ] = _mantissaTable[ _offsetTable[ m ] + ( val & 0x3ff ) ] + _exponentTable[ m ];\n\t\treturn _floatView[ 0 ];\n\n\t}\n\n}\n\n// float32 to float16 helpers\n\nconst _buffer = new ArrayBuffer( 4 );\nconst _floatView = new Float32Array( _buffer );\nconst _uint32View = new Uint32Array( _buffer );\n\nconst _baseTable = new Uint32Array( 512 );\nconst _shiftTable = new Uint32Array( 512 );\n\nfor ( let i = 0; i < 256; ++ i ) {\n\n\tconst e = i - 127;\n\n\t// very small number (0, -0)\n\n\tif ( e < - 27 ) {\n\n\t\t_baseTable[ i ] = 0x0000;\n\t\t_baseTable[ i | 0x100 ] = 0x8000;\n\t\t_shiftTable[ i ] = 24;\n\t\t_shiftTable[ i | 0x100 ] = 24;\n\n\t\t// small number (denorm)\n\n\t} else if ( e < - 14 ) {\n\n\t\t_baseTable[ i ] = 0x0400 >> ( - e - 14 );\n\t\t_baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000;\n\t\t_shiftTable[ i ] = - e - 1;\n\t\t_shiftTable[ i | 0x100 ] = - e - 1;\n\n\t\t// normal number\n\n\t} else if ( e <= 15 ) {\n\n\t\t_baseTable[ i ] = ( e + 15 ) << 10;\n\t\t_baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000;\n\t\t_shiftTable[ i ] = 13;\n\t\t_shiftTable[ i | 0x100 ] = 13;\n\n\t\t// large number (Infinity, -Infinity)\n\n\t} else if ( e < 128 ) {\n\n\t\t_baseTable[ i ] = 0x7c00;\n\t\t_baseTable[ i | 0x100 ] = 0xfc00;\n\t\t_shiftTable[ i ] = 24;\n\t\t_shiftTable[ i | 0x100 ] = 24;\n\n\t\t// stay (NaN, Infinity, -Infinity)\n\n\t} else {\n\n\t\t_baseTable[ i ] = 0x7c00;\n\t\t_baseTable[ i | 0x100 ] = 0xfc00;\n\t\t_shiftTable[ i ] = 13;\n\t\t_shiftTable[ i | 0x100 ] = 13;\n\n\t}\n\n}\n\n// float16 to float32 helpers\n\nconst _mantissaTable = new Uint32Array( 2048 );\nconst _exponentTable = new Uint32Array( 64 );\nconst _offsetTable = new Uint32Array( 64 );\n\nfor ( let i = 1; i < 1024; ++ i ) {\n\n\tlet m = i << 13; // zero pad mantissa bits\n\tlet e = 0; // zero exponent\n\n\t// normalized\n\twhile ( ( m & 0x00800000 ) === 0 ) {\n\n\t\tm <<= 1;\n\t\te -= 0x00800000; // decrement exponent\n\n\t}\n\n\tm &= ~ 0x00800000; // clear leading 1 bit\n\te += 0x38800000; // adjust bias\n\n\t_mantissaTable[ i ] = m | e;\n\n}\n\nfor ( let i = 1024; i < 2048; ++ i ) {\n\n\t_mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 );\n\n}\n\nfor ( let i = 1; i < 31; ++ i ) {\n\n\t_exponentTable[ i ] = i << 23;\n\n}\n\n_exponentTable[ 31 ] = 0x47800000;\n_exponentTable[ 32 ] = 0x80000000;\nfor ( let i = 33; i < 63; ++ i ) {\n\n\t_exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 );\n\n}\n\n_exponentTable[ 63 ] = 0xc7800000;\n\nfor ( let i = 1; i < 64; ++ i ) {\n\n\tif ( i !== 32 ) {\n\n\t\t_offsetTable[ i ] = 1024;\n\n\t}\n\n}\n\n// r133, c5bb5434555a3c3ddd784944a0a124f996fc721b\n\nclass ParametricGeometry extends BufferGeometry {\n\n\tconstructor() {\n\n\t\tconsole.error( 'THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js' );\n\t\tsuper();\n\n\t}\n\n}\n\n// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92\n\nclass TextGeometry extends BufferGeometry {\n\n\tconstructor() {\n\n\t\tconsole.error( 'THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js' );\n\t\tsuper();\n\n\t}\n\n}\n\n// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92\n\nfunction FontLoader() {\n\n\tconsole.error( 'THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js' );\n\n}\n\n// r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92\n\nfunction Font() {\n\n\tconsole.error( 'THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js' );\n\n}\n\n// r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0\n\nfunction ImmediateRenderObject() {\n\n\tconsole.error( 'THREE.ImmediateRenderObject has been removed.' );\n\n}\n\n// r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17\n\nclass WebGLMultisampleRenderTarget extends WebGLRenderTarget {\n\n\tconstructor( width, height, options ) {\n\n\t\tconsole.error( 'THREE.WebGLMultisampleRenderTarget has been removed. Use a normal render target and set the \"samples\" property to greater 0 to enable multisampling.' );\n\t\tsuper( width, height, options );\n\t\tthis.samples = 4;\n\n\t}\n\n}\n\n// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce\n\nclass DataTexture2DArray extends DataArrayTexture {\n\n\tconstructor( data, width, height, depth ) {\n\n\t\tconsole.warn( 'THREE.DataTexture2DArray has been renamed to DataArrayTexture.' );\n\t\tsuper( data, width, height, depth );\n\n\t}\n\n}\n\n// r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce\n\nclass DataTexture3D extends Data3DTexture {\n\n\tconstructor( data, width, height, depth ) {\n\n\t\tconsole.warn( 'THREE.DataTexture3D has been renamed to Data3DTexture.' );\n\t\tsuper( data, width, height, depth );\n\n\t}\n\n}\n\nif ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {\n\n\t__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: {\n\t\trevision: REVISION,\n\t} } ) );\n\n}\n\nif ( typeof window !== 'undefined' ) {\n\n\tif ( window.__THREE__ ) {\n\n\t\tconsole.warn( 'WARNING: Multiple instances of Three.js being imported.' );\n\n\t} else {\n\n\t\twindow.__THREE__ = REVISION;\n\n\t}\n\n}\n\nexport { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AlphaFormat, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightProbe, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BackSide, BasicDepthPacking, BasicShadowMap, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxGeometry as BoxBufferGeometry, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry as CapsuleBufferGeometry, CapsuleGeometry, CatmullRomCurve3, CineonToneMapping, CircleGeometry as CircleBufferGeometry, CircleGeometry, ClampToEdgeWrapping, Clock, Color, ColorKeyframeTrack, ColorManagement, CompressedTexture, CompressedTextureLoader, ConeGeometry as ConeBufferGeometry, ConeGeometry, CubeCamera, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderGeometry as CylinderBufferGeometry, CylinderGeometry, Cylindrical, Data3DTexture, DataArrayTexture, DataTexture, DataTexture2DArray, DataTexture3D, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry as DodecahedronBufferGeometry, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeGeometry as ExtrudeBufferGeometry, ExtrudeGeometry, FileLoader, FlatShading, Float16BufferAttribute, Float32BufferAttribute, Float64BufferAttribute, FloatType, Fog, FogExp2, Font, FontLoader, FramebufferTexture, FrontSide, Frustum, GLBufferAttribute, GLSL1, GLSL3, GreaterDepth, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, HemisphereLightProbe, IcosahedronGeometry as IcosahedronBufferGeometry, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, ImmediateRenderObject, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry as LatheBufferGeometry, LatheGeometry, Layers, LessDepth, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronGeometry as OctahedronBufferGeometry, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, ParametricGeometry, Path, PerspectiveCamera, Plane, PlaneGeometry as PlaneBufferGeometry, PlaneGeometry, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry as PolyhedronBufferGeometry, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingGeometry as RingBufferGeometry, RingGeometry, SRGBColorSpace, Scene, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeGeometry as ShapeBufferGeometry, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, SmoothShading, Source, Sphere, SphereGeometry as SphereBufferGeometry, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronGeometry as TetrahedronBufferGeometry, TetrahedronGeometry, TextGeometry, Texture, TextureLoader, TorusGeometry as TorusBufferGeometry, TorusGeometry, TorusKnotGeometry as TorusKnotBufferGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry as TubeBufferGeometry, TubeGeometry, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, VideoTexture, WebGL1Renderer, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLCubeRenderTarget, WebGLMultipleRenderTargets, WebGLMultisampleRenderTarget, WebGLRenderTarget, WebGLRenderer, WebGLUtils, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, _SRGBAFormat, sRGBEncoding };\n","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nif (typeof window !== 'undefined' && window.THREE) {\n let prevRequire = window.require;\n window.require = (x) => {\n if (prevRequire)\n return prevRequire(x);\n else if (x === \"three\")\n return window.THREE;\n };\n}\nexport {};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWlyZS1zaGltLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlcXVpcmUtc2hpbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFNL0UsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRTtJQUNsRCxJQUFJLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO0lBQ2pDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUM5QixJQUFJLFdBQVc7WUFBRSxPQUFPLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNsQyxJQUFJLENBQUMsS0FBSyxPQUFPO1lBQUUsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDO0lBQzdDLENBQUMsQ0FBQTtDQUNEIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nexport class IntSet {\n array = new Array();\n add(value) {\n let contains = this.contains(value);\n this.array[value | 0] = value | 0;\n return !contains;\n }\n contains(value) {\n return this.array[value | 0] != undefined;\n }\n remove(value) {\n this.array[value | 0] = undefined;\n }\n clear() {\n this.array.length = 0;\n }\n}\nexport class StringSet {\n entries = {};\n size = 0;\n add(value) {\n let contains = this.entries[value];\n this.entries[value] = true;\n if (!contains) {\n this.size++;\n return true;\n }\n return false;\n }\n addAll(values) {\n let oldSize = this.size;\n for (var i = 0, n = values.length; i < n; i++)\n this.add(values[i]);\n return oldSize != this.size;\n }\n contains(value) {\n return this.entries[value];\n }\n clear() {\n this.entries = {};\n this.size = 0;\n }\n}\nexport class Color {\n r;\n g;\n b;\n a;\n static WHITE = new Color(1, 1, 1, 1);\n static RED = new Color(1, 0, 0, 1);\n static GREEN = new Color(0, 1, 0, 1);\n static BLUE = new Color(0, 0, 1, 1);\n static MAGENTA = new Color(1, 0, 1, 1);\n constructor(r = 0, g = 0, b = 0, a = 0) {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a;\n }\n set(r, g, b, a) {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a;\n return this.clamp();\n }\n setFromColor(c) {\n this.r = c.r;\n this.g = c.g;\n this.b = c.b;\n this.a = c.a;\n return this;\n }\n setFromString(hex) {\n hex = hex.charAt(0) == '#' ? hex.substr(1) : hex;\n this.r = parseInt(hex.substr(0, 2), 16) / 255;\n this.g = parseInt(hex.substr(2, 2), 16) / 255;\n this.b = parseInt(hex.substr(4, 2), 16) / 255;\n this.a = hex.length != 8 ? 1 : parseInt(hex.substr(6, 2), 16) / 255;\n return this;\n }\n add(r, g, b, a) {\n this.r += r;\n this.g += g;\n this.b += b;\n this.a += a;\n return this.clamp();\n }\n clamp() {\n if (this.r < 0)\n this.r = 0;\n else if (this.r > 1)\n this.r = 1;\n if (this.g < 0)\n this.g = 0;\n else if (this.g > 1)\n this.g = 1;\n if (this.b < 0)\n this.b = 0;\n else if (this.b > 1)\n this.b = 1;\n if (this.a < 0)\n this.a = 0;\n else if (this.a > 1)\n this.a = 1;\n return this;\n }\n static rgba8888ToColor(color, value) {\n color.r = ((value & 0xff000000) >>> 24) / 255;\n color.g = ((value & 0x00ff0000) >>> 16) / 255;\n color.b = ((value & 0x0000ff00) >>> 8) / 255;\n color.a = ((value & 0x000000ff)) / 255;\n }\n static rgb888ToColor(color, value) {\n color.r = ((value & 0x00ff0000) >>> 16) / 255;\n color.g = ((value & 0x0000ff00) >>> 8) / 255;\n color.b = ((value & 0x000000ff)) / 255;\n }\n static fromString(hex) {\n return new Color().setFromString(hex);\n }\n}\nexport class MathUtils {\n static PI = 3.1415927;\n static PI2 = MathUtils.PI * 2;\n static invPI2 = 1 / MathUtils.PI2;\n static radiansToDegrees = 180 / MathUtils.PI;\n static radDeg = MathUtils.radiansToDegrees;\n static degreesToRadians = MathUtils.PI / 180;\n static degRad = MathUtils.degreesToRadians;\n static clamp(value, min, max) {\n if (value < min)\n return min;\n if (value > max)\n return max;\n return value;\n }\n static cosDeg(degrees) {\n return Math.cos(degrees * MathUtils.degRad);\n }\n static sinDeg(degrees) {\n return Math.sin(degrees * MathUtils.degRad);\n }\n static atan2Deg(y, x) {\n return Math.atan2(y, x) * MathUtils.degRad;\n }\n static signum(value) {\n return value > 0 ? 1 : value < 0 ? -1 : 0;\n }\n static toInt(x) {\n return x > 0 ? Math.floor(x) : Math.ceil(x);\n }\n static cbrt(x) {\n let y = Math.pow(Math.abs(x), 1 / 3);\n return x < 0 ? -y : y;\n }\n static randomTriangular(min, max) {\n return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5);\n }\n static randomTriangularWith(min, max, mode) {\n let u = Math.random();\n let d = max - min;\n if (u <= (mode - min) / d)\n return min + Math.sqrt(u * d * (mode - min));\n return max - Math.sqrt((1 - u) * d * (max - mode));\n }\n static isPowerOfTwo(value) {\n return value && (value & (value - 1)) === 0;\n }\n}\nexport class Interpolation {\n apply(start, end, a) {\n return start + (end - start) * this.applyInternal(a);\n }\n}\nexport class Pow extends Interpolation {\n power = 2;\n constructor(power) {\n super();\n this.power = power;\n }\n applyInternal(a) {\n if (a <= 0.5)\n return Math.pow(a * 2, this.power) / 2;\n return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1;\n }\n}\nexport class PowOut extends Pow {\n constructor(power) {\n super(power);\n }\n applyInternal(a) {\n return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1;\n }\n}\nexport class Utils {\n static SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== \"undefined\";\n static arrayCopy(source, sourceStart, dest, destStart, numElements) {\n for (let i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) {\n dest[j] = source[i];\n }\n }\n static arrayFill(array, fromIndex, toIndex, value) {\n for (let i = fromIndex; i < toIndex; i++)\n array[i] = value;\n }\n static setArraySize(array, size, value = 0) {\n let oldSize = array.length;\n if (oldSize == size)\n return array;\n array.length = size;\n if (oldSize < size) {\n for (let i = oldSize; i < size; i++)\n array[i] = value;\n }\n return array;\n }\n static ensureArrayCapacity(array, size, value = 0) {\n if (array.length >= size)\n return array;\n return Utils.setArraySize(array, size, value);\n }\n static newArray(size, defaultValue) {\n let array = new Array(size);\n for (let i = 0; i < size; i++)\n array[i] = defaultValue;\n return array;\n }\n static newFloatArray(size) {\n if (Utils.SUPPORTS_TYPED_ARRAYS)\n return new Float32Array(size);\n else {\n let array = new Array(size);\n for (let i = 0; i < array.length; i++)\n array[i] = 0;\n return array;\n }\n }\n static newShortArray(size) {\n if (Utils.SUPPORTS_TYPED_ARRAYS)\n return new Int16Array(size);\n else {\n let array = new Array(size);\n for (let i = 0; i < array.length; i++)\n array[i] = 0;\n return array;\n }\n }\n static toFloatArray(array) {\n return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;\n }\n static toSinglePrecision(value) {\n return Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value;\n }\n // This function is used to fix WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109\n static webkit602BugfixHelper(alpha, blend) {\n }\n static contains(array, element, identity = true) {\n for (var i = 0; i < array.length; i++)\n if (array[i] == element)\n return true;\n return false;\n }\n static enumValue(type, name) {\n return type[name[0].toUpperCase() + name.slice(1)];\n }\n}\nexport class DebugUtils {\n static logBones(skeleton) {\n for (let i = 0; i < skeleton.bones.length; i++) {\n let bone = skeleton.bones[i];\n console.log(bone.data.name + \", \" + bone.a + \", \" + bone.b + \", \" + bone.c + \", \" + bone.d + \", \" + bone.worldX + \", \" + bone.worldY);\n }\n }\n}\nexport class Pool {\n items = new Array();\n instantiator;\n constructor(instantiator) {\n this.instantiator = instantiator;\n }\n obtain() {\n return this.items.length > 0 ? this.items.pop() : this.instantiator();\n }\n free(item) {\n if (item.reset)\n item.reset();\n this.items.push(item);\n }\n freeAll(items) {\n for (let i = 0; i < items.length; i++)\n this.free(items[i]);\n }\n clear() {\n this.items.length = 0;\n }\n}\nexport class Vector2 {\n x;\n y;\n constructor(x = 0, y = 0) {\n this.x = x;\n this.y = y;\n }\n set(x, y) {\n this.x = x;\n this.y = y;\n return this;\n }\n length() {\n let x = this.x;\n let y = this.y;\n return Math.sqrt(x * x + y * y);\n }\n normalize() {\n let len = this.length();\n if (len != 0) {\n this.x /= len;\n this.y /= len;\n }\n return this;\n }\n}\nexport class TimeKeeper {\n maxDelta = 0.064;\n framesPerSecond = 0;\n delta = 0;\n totalTime = 0;\n lastTime = Date.now() / 1000;\n frameCount = 0;\n frameTime = 0;\n update() {\n let now = Date.now() / 1000;\n this.delta = now - this.lastTime;\n this.frameTime += this.delta;\n this.totalTime += this.delta;\n if (this.delta > this.maxDelta)\n this.delta = this.maxDelta;\n this.lastTime = now;\n this.frameCount++;\n if (this.frameTime > 1) {\n this.framesPerSecond = this.frameCount / this.frameTime;\n this.frameTime = 0;\n this.frameCount = 0;\n }\n }\n}\nexport class WindowedMean {\n values;\n addedValues = 0;\n lastValue = 0;\n mean = 0;\n dirty = true;\n constructor(windowSize = 32) {\n this.values = new Array(windowSize);\n }\n hasEnoughData() {\n return this.addedValues >= this.values.length;\n }\n addValue(value) {\n if (this.addedValues < this.values.length)\n this.addedValues++;\n this.values[this.lastValue++] = value;\n if (this.lastValue > this.values.length - 1)\n this.lastValue = 0;\n this.dirty = true;\n }\n getMean() {\n if (this.hasEnoughData()) {\n if (this.dirty) {\n let mean = 0;\n for (let i = 0; i < this.values.length; i++)\n mean += this.values[i];\n this.mean = mean / this.values.length;\n this.dirty = false;\n }\n return this.mean;\n }\n return 0;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvVXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBUy9FLE1BQU0sT0FBTyxNQUFNO0lBQ2xCLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBc0IsQ0FBQztJQUV4QyxHQUFHLENBQUUsS0FBYTtRQUNqQixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDbEMsT0FBTyxDQUFDLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQsUUFBUSxDQUFFLEtBQWE7UUFDdEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsSUFBSSxTQUFTLENBQUM7SUFDM0MsQ0FBQztJQUVELE1BQU0sQ0FBRSxLQUFhO1FBQ3BCLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsS0FBSztRQUNKLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUN2QixDQUFDO0NBQ0Q7QUFFRCxNQUFNLE9BQU8sU0FBUztJQUNyQixPQUFPLEdBQXVCLEVBQUUsQ0FBQztJQUNqQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBRVQsR0FBRyxDQUFFLEtBQWE7UUFDakIsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2QsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lB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Q0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBRSxPQUFlO1FBQzdCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxNQUFNLENBQUMsUUFBUSxDQUFFLENBQVMsRUFBRSxDQUFTO1FBQ3BDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztJQUM1QyxDQUFDO0lBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBRSxLQUFhO1FBQzNCLE9BQU8sS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxNQUFNLENBQUMsS0FBSyxDQUFFLENBQVM7UUFDdEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxNQUFNLENBQUMsSUFBSSxDQUFFLENBQVM7UUFDckIsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUVELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBRSxHQUFXLEVBQUUsR0FBVztRQUNoRCxPQUFPLFNBQVMs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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Utils } from \"../Utils.js\";\n/** The base class for all attachments. */\nexport class Attachment {\n name;\n constructor(name) {\n if (!name)\n throw new Error(\"name cannot be null.\");\n this.name = name;\n }\n}\n/** Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's\n * {@link Slot#deform}. */\nexport class VertexAttachment extends Attachment {\n static nextID = 0;\n /** The unique ID for this attachment. */\n id = VertexAttachment.nextID++;\n /** The bones which affect the {@link #getVertices()}. The array entries are, for each vertex, the number of bones affecting\n * the vertex followed by that many bone indices, which is the index of the bone in {@link Skeleton#bones}. Will be null\n * if this attachment has no weights. */\n bones = null;\n /** The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are `x,y`\n * entries for each vertex. For a weighted attachment, the values are `x,y,weight` entries for each bone affecting\n * each vertex. */\n vertices = [];\n /** The maximum number of world vertex values that can be output by\n * {@link #computeWorldVertices()} using the `count` parameter. */\n worldVerticesLength = 0;\n /** Timelines for the timeline attachment are also applied to this attachment.\n * May be null if no attachment-specific timelines should be applied. */\n timelineAttachment = this;\n constructor(name) {\n super(name);\n }\n /** Transforms the attachment's local {@link #vertices} to world coordinates. If the slot's {@link Slot#deform} is\n * not empty, it is used to deform the vertices.\n *\n * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine\n * Runtimes Guide.\n * @param start The index of the first {@link #vertices} value to transform. Each vertex has 2 values, x and y.\n * @param count The number of world vertex values to output. Must be <= {@link #worldVerticesLength} - `start`.\n * @param worldVertices The output world vertices. Must have a length >= `offset` + `count` *\n * `stride` / 2.\n * @param offset The `worldVertices` index to begin writing values.\n * @param stride The number of `worldVertices` entries between the value pairs written. */\n computeWorldVertices(slot, start, count, worldVertices, offset, stride) {\n count = offset + (count >> 1) * stride;\n let skeleton = slot.bone.skeleton;\n let deformArray = slot.deform;\n let vertices = this.vertices;\n let bones = this.bones;\n if (!bones) {\n if (deformArray.length > 0)\n vertices = deformArray;\n let bone = slot.bone;\n let x = bone.worldX;\n let y = bone.worldY;\n let a = bone.a, b = bone.b, c = bone.c, d = bone.d;\n for (let v = start, w = offset; w < count; v += 2, w += stride) {\n let vx = vertices[v], vy = vertices[v + 1];\n worldVertices[w] = vx * a + vy * b + x;\n worldVertices[w + 1] = vx * c + vy * d + y;\n }\n return;\n }\n let v = 0, skip = 0;\n for (let i = 0; i < start; i += 2) {\n let n = bones[v];\n v += n + 1;\n skip += n;\n }\n let skeletonBones = skeleton.bones;\n if (deformArray.length == 0) {\n for (let w = offset, b = skip * 3; w < count; w += stride) {\n let wx = 0, wy = 0;\n let n = bones[v++];\n n += v;\n for (; v < n; v++, b += 3) {\n let bone = skeletonBones[bones[v]];\n let vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];\n wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;\n wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;\n }\n worldVertices[w] = wx;\n worldVertices[w + 1] = wy;\n }\n }\n else {\n let deform = deformArray;\n for (let w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) {\n let wx = 0, wy = 0;\n let n = bones[v++];\n n += v;\n for (; v < n; v++, b += 3, f += 2) {\n let bone = skeletonBones[bones[v]];\n let vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];\n wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;\n wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;\n }\n worldVertices[w] = wx;\n worldVertices[w + 1] = wy;\n }\n }\n }\n /** Does not copy id (generated) or name (set on construction). **/\n copyTo(attachment) {\n if (this.bones) {\n attachment.bones = new Array(this.bones.length);\n Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length);\n }\n else\n attachment.bones = null;\n if (this.vertices) {\n attachment.vertices = Utils.newFloatArray(this.vertices.length);\n Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length);\n }\n attachment.worldVerticesLength = this.worldVerticesLength;\n attachment.timelineAttachment = this.timelineAttachment;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXR0YWNobWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdHRhY2htZW50cy9BdHRhY2htZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQW1CLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVyRCwwQ0FBMEM7QUFDMUMsTUFBTSxPQUFnQixVQUFVO0lBQy9CLElBQUksQ0FBUztJQUViLFlBQWEsSUFBWTtRQUN4QixJQUFJLENBQUMsSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNsQixDQUFDO0NBR0Q7QUFFRDswQkFDMEI7QUFDMUIsTUFBTSxPQUFnQixnQkFBaUIsU0FBUSxVQUFVO0lBQ2hELE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRTFCLHlDQUF5QztJQUN6QyxFQUFFLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLENBQUM7SUFFL0I7OzRDQUV3QztJQUN4QyxLQUFLLEdBQXlCLElBQUksQ0FBQztJQUVuQzs7c0JBRWtCO0lBQ2xCLFFBQVEsR0FBb0IsRUFBRSxDQUFDO0lBRS9CO3NFQUNrRTtJQUNsRSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7SUFFeEI7NEVBQ3dFO0lBQ3hFLGtCQUFrQixHQUFlLElBQUksQ0FBQztJQUV0QyxZQUFhLElBQVk7UUFDeEIsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2IsQ0FBQztJQUVEOzs7Ozs7Ozs7OzhGQVUwRjtJQUMxRixvQkFBb0IsQ0FBRSxJQUFVLEVBQUUsS0FBYSxFQUFFLEtBQWEsRUFBRSxhQUE4QixFQUFFLE1BQWMsRUFBRSxNQUFjO1FBQzdILEtBQUssR0FBRyxNQUFNLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFB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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Utils } from \"../Utils.js\";\nexport class Sequence {\n static _nextID = 0;\n id = Sequence.nextID();\n regions;\n start = 0;\n digits = 0;\n /** The index of the region to show for the setup pose. */\n setupIndex = 0;\n constructor(count) {\n this.regions = new Array(count);\n }\n copy() {\n let copy = new Sequence(this.regions.length);\n Utils.arrayCopy(this.regions, 0, copy.regions, 0, this.regions.length);\n copy.start = this.start;\n copy.digits = this.digits;\n copy.setupIndex = this.setupIndex;\n return copy;\n }\n apply(slot, attachment) {\n let index = slot.sequenceIndex;\n if (index == -1)\n index = this.setupIndex;\n if (index >= this.regions.length)\n index = this.regions.length - 1;\n let region = this.regions[index];\n if (attachment.region != region) {\n attachment.region = region;\n attachment.updateRegion();\n }\n }\n getPath(basePath, index) {\n let result = basePath;\n let frame = (this.start + index).toString();\n for (let i = this.digits - frame.length; i > 0; i--)\n result += \"0\";\n result += frame;\n return result;\n }\n static nextID() {\n return Sequence._nextID++;\n }\n}\nexport var SequenceMode;\n(function (SequenceMode) {\n SequenceMode[SequenceMode[\"hold\"] = 0] = \"hold\";\n SequenceMode[SequenceMode[\"once\"] = 1] = \"once\";\n SequenceMode[SequenceMode[\"loop\"] = 2] = \"loop\";\n SequenceMode[SequenceMode[\"pingpong\"] = 3] = \"pingpong\";\n SequenceMode[SequenceMode[\"onceReverse\"] = 4] = \"onceReverse\";\n SequenceMode[SequenceMode[\"loopReverse\"] = 5] = \"loopReverse\";\n SequenceMode[SequenceMode[\"pingpongReverse\"] = 6] = \"pingpongReverse\";\n})(SequenceMode || (SequenceMode = {}));\nexport const SequenceModeValues = [\n SequenceMode.hold,\n SequenceMode.once,\n SequenceMode.loop,\n SequenceMode.pingpong,\n SequenceMode.onceReverse,\n SequenceMode.loopReverse,\n SequenceMode.pingpongReverse\n];\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VxdWVuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXR0YWNobWVudHMvU2VxdWVuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSy9FLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHcEMsTUFBTSxPQUFPLFFBQVE7SUFDWixNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUUzQixFQUFFLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3ZCLE9BQU8sQ0FBa0I7SUFDekIsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNWLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCwwREFBMEQ7SUFDMUQsVUFBVSxHQUFHLENBQUMsQ0FBQztJQUVmLFlBQWEsS0FBYTtRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksS0FBSyxDQUFnQixLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsSUFBSTtRQUNILElBQUksSUFBSSxHQUFHLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0MsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZFLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ2xDLE9BQU8sSUFBSSxDQUFDO0lBQ2IsQ0FBQztJQUVELEtBQUssQ0FBRSxJQUFVLEVBQUUsVUFBNEI7UUFDOUMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUMvQixJQUFJLEtBQUssSUFBSSxDQUFDLENBQUM7WUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUN6QyxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU07WUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2xFLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsSUFBSSxVQUFVLENBQUMsTUFBTSxJQUFJLE1BQU0sRUFBRTtZQUNoQyxVQUFVLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztZQUMzQixVQUFVLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDMUI7SUFDRixDQUFDO0lBRUQsT0FBTyxDQUFFLFFBQWdCLEVBQUUsS0FBYTtRQUN2QyxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUM7UUFDdEIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzVDLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ2xELE1BQU0sSUFBSSxHQUFHLENBQUM7UUFDZixNQUFNLElBQUksS0FBSyxDQUFDO1FBQ2hCLE9BQU8sTUFBTSxDQUFDO0lBQ2YsQ0FBQztJQUVPLE1BQU0sQ0FBQyxNQUFNO1FBQ3BCLE9BQU8sUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNCLENBQUM7O0FBR0YsTUFBTSxDQUFOLElBQVksWUFRWDtBQVJELFdBQVksWUFBWTtJQUN2QiwrQ0FBUSxDQUFBO0lBQ1IsK0NBQVEsQ0FBQTtJQUNSLCtDQUFRLENBQUE7SUFDUix1REFBWSxDQUFBO0lBQ1osNkRBQWUsQ0FBQTtJQUNmLDZEQUFlLENBQUE7SUFDZixxRUFBbUIsQ0FBQTtBQUNwQixDQUFDLEVBUlcsWUFBWSxLQUFaLFlBQVksUUFRdkI7QUFFRCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRztJQUNqQyxZQUFZLENBQUMsSUFBSTtJQUNqQixZQUFZLENBQUMsSUFBSTtJQUNqQixZQUFZLENBQUMsSUFBSTtJQUNqQixZQUFZLENBQUMsUUFBUTtJQUNyQixZQUFZLENBQUMsV0FBVztJQUN4QixZQUFZLENBQUMsV0FBVztJQUN4QixZQUFZLENBQUMsZUFBZTtDQUM1QixDQUFDIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { VertexAttachment } from \"./attachments/Attachment.js\";\nimport { StringSet, Utils, MathUtils } from \"./Utils.js\";\nimport { SequenceMode, SequenceModeValues } from \"./attachments/Sequence.js\";\n/** A simple container for a list of timelines and a name. */\nexport class Animation {\n /** The animation's name, which is unique across all animations in the skeleton. */\n name;\n timelines = [];\n timelineIds = new StringSet();\n /** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */\n duration;\n constructor(name, timelines, duration) {\n if (!name)\n throw new Error(\"name cannot be null.\");\n this.name = name;\n this.setTimelines(timelines);\n this.duration = duration;\n }\n setTimelines(timelines) {\n if (!timelines)\n throw new Error(\"timelines cannot be null.\");\n this.timelines = timelines;\n this.timelineIds.clear();\n for (var i = 0; i < timelines.length; i++)\n this.timelineIds.addAll(timelines[i].getPropertyIds());\n }\n hasTimeline(ids) {\n for (let i = 0; i < ids.length; i++)\n if (this.timelineIds.contains(ids[i]))\n return true;\n return false;\n }\n /** Applies all the animation's timelines to the specified skeleton.\n *\n * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}.\n * @param loop If true, the animation repeats after {@link #getDuration()}.\n * @param events May be null to ignore fired events. */\n apply(skeleton, lastTime, time, loop, events, alpha, blend, direction) {\n if (!skeleton)\n throw new Error(\"skeleton cannot be null.\");\n if (loop && this.duration != 0) {\n time %= this.duration;\n if (lastTime > 0)\n lastTime %= this.duration;\n }\n let timelines = this.timelines;\n for (let i = 0, n = timelines.length; i < n; i++)\n timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction);\n }\n}\n/** Controls how a timeline value is mixed with the setup pose value or current pose value when a timeline's `alpha`\n * < 1.\n *\n * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. */\nexport var MixBlend;\n(function (MixBlend) {\n /** Transitions from the setup value to the timeline value (the current value is not used). Before the first key, the setup\n * value is set. */\n MixBlend[MixBlend[\"setup\"] = 0] = \"setup\";\n /** Transitions from the current value to the timeline value. Before the first key, transitions from the current value to\n * the setup value. Timelines which perform instant transitions, such as {@link DrawOrderTimeline} or\n * {@link AttachmentTimeline}, use the setup value before the first key.\n *\n * `first` is intended for the first animations applied, not for animations layered on top of those. */\n MixBlend[MixBlend[\"first\"] = 1] = \"first\";\n /** Transitions from the current value to the timeline value. No change is made before the first key (the current value is\n * kept until the first key).\n *\n * `replace` is intended for animations layered on top of others, not for the first animations applied. */\n MixBlend[MixBlend[\"replace\"] = 2] = \"replace\";\n /** Transitions from the current value to the current value plus the timeline value. No change is made before the first key\n * (the current value is kept until the first key).\n *\n * `add` is intended for animations layered on top of others, not for the first animations applied. Properties\n * keyed by additive animations must be set manually or by another animation before applying the additive animations, else\n * the property values will increase continually. */\n MixBlend[MixBlend[\"add\"] = 3] = \"add\";\n})(MixBlend || (MixBlend = {}));\n/** Indicates whether a timeline's `alpha` is mixing out over time toward 0 (the setup or current pose value) or\n * mixing in toward 1 (the timeline's value).\n *\n * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. */\nexport var MixDirection;\n(function (MixDirection) {\n MixDirection[MixDirection[\"mixIn\"] = 0] = \"mixIn\";\n MixDirection[MixDirection[\"mixOut\"] = 1] = \"mixOut\";\n})(MixDirection || (MixDirection = {}));\nconst Property = {\n rotate: 0,\n x: 1,\n y: 2,\n scaleX: 3,\n scaleY: 4,\n shearX: 5,\n shearY: 6,\n rgb: 7,\n alpha: 8,\n rgb2: 9,\n attachment: 10,\n deform: 11,\n event: 12,\n drawOrder: 13,\n ikConstraint: 14,\n transformConstraint: 15,\n pathConstraintPosition: 16,\n pathConstraintSpacing: 17,\n pathConstraintMix: 18,\n physicsConstraintInertia: 19,\n physicsConstraintStrength: 20,\n physicsConstraintDamping: 21,\n physicsConstraintMass: 22,\n physicsConstraintWind: 23,\n physicsConstraintGravity: 24,\n physicsConstraintMix: 25,\n physicsConstraintReset: 26,\n sequence: 27,\n};\n/** The interface for all timelines. */\nexport class Timeline {\n propertyIds;\n frames;\n constructor(frameCount, propertyIds) {\n this.propertyIds = propertyIds;\n this.frames = Utils.newFloatArray(frameCount * this.getFrameEntries());\n }\n getPropertyIds() {\n return this.propertyIds;\n }\n getFrameEntries() {\n return 1;\n }\n getFrameCount() {\n return this.frames.length / this.getFrameEntries();\n }\n getDuration() {\n return this.frames[this.frames.length - this.getFrameEntries()];\n }\n static search1(frames, time) {\n let n = frames.length;\n for (let i = 1; i < n; i++)\n if (frames[i] > time)\n return i - 1;\n return n - 1;\n }\n static search(frames, time, step) {\n let n = frames.length;\n for (let i = step; i < n; i += step)\n if (frames[i] > time)\n return i - step;\n return n - step;\n }\n}\n/** The base class for timelines that use interpolation between key frame values. */\nexport class CurveTimeline extends Timeline {\n curves; // type, x, y, ...\n constructor(frameCount, bezierCount, propertyIds) {\n super(frameCount, propertyIds);\n this.curves = Utils.newFloatArray(frameCount + bezierCount * 18 /*BEZIER_SIZE*/);\n this.curves[frameCount - 1] = 1 /*STEPPED*/;\n }\n /** Sets the specified key frame to linear interpolation. */\n setLinear(frame) {\n this.curves[frame] = 0 /*LINEAR*/;\n }\n /** Sets the specified key frame to stepped interpolation. */\n setStepped(frame) {\n this.curves[frame] = 1 /*STEPPED*/;\n }\n /** Shrinks the storage for Bezier curves, for use when bezierCount (specified in the constructor) was larger\n * than the actual number of Bezier curves. */\n shrink(bezierCount) {\n let size = this.getFrameCount() + bezierCount * 18 /*BEZIER_SIZE*/;\n if (this.curves.length > size) {\n let newCurves = Utils.newFloatArray(size);\n Utils.arrayCopy(this.curves, 0, newCurves, 0, size);\n this.curves = newCurves;\n }\n }\n /** Stores the segments for the specified Bezier curve. For timelines that modify multiple values, there may be more than\n * one curve per frame.\n * @param bezier The ordinal of this Bezier curve for this timeline, between 0 and bezierCount - 1 (specified\n * in the constructor), inclusive.\n * @param frame Between 0 and frameCount - 1, inclusive.\n * @param value The index of the value for this frame that this curve is used for.\n * @param time1 The time for the first key.\n * @param value1 The value for the first key.\n * @param cx1 The time for the first Bezier handle.\n * @param cy1 The value for the first Bezier handle.\n * @param cx2 The time of the second Bezier handle.\n * @param cy2 The value for the second Bezier handle.\n * @param time2 The time for the second key.\n * @param value2 The value for the second key. */\n setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) {\n let curves = this.curves;\n let i = this.getFrameCount() + bezier * 18 /*BEZIER_SIZE*/;\n if (value == 0)\n curves[frame] = 2 /*BEZIER*/ + i;\n let tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = (value1 - cy1 * 2 + cy2) * 0.03;\n let dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = ((cy1 - cy2) * 3 - value1 + value2) * 0.006;\n let ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy;\n let dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = (cy1 - value1) * 0.3 + tmpy + dddy * 0.16666667;\n let x = time1 + dx, y = value1 + dy;\n for (let n = i + 18 /*BEZIER_SIZE*/; i < n; i += 2) {\n curves[i] = x;\n curves[i + 1] = y;\n dx += ddx;\n dy += ddy;\n ddx += dddx;\n ddy += dddy;\n x += dx;\n y += dy;\n }\n }\n /** Returns the Bezier interpolated value for the specified time.\n * @param frameIndex The index into {@link #getFrames()} for the values of the frame before time.\n * @param valueOffset The offset from frameIndex to the value this curve is used for.\n * @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */\n getBezierValue(time, frameIndex, valueOffset, i) {\n let curves = this.curves;\n if (curves[i] > time) {\n let x = this.frames[frameIndex], y = this.frames[frameIndex + valueOffset];\n return y + (time - x) / (curves[i] - x) * (curves[i + 1] - y);\n }\n let n = i + 18 /*BEZIER_SIZE*/;\n for (i += 2; i < n; i += 2) {\n if (curves[i] >= time) {\n let x = curves[i - 2], y = curves[i - 1];\n return y + (time - x) / (curves[i] - x) * (curves[i + 1] - y);\n }\n }\n frameIndex += this.getFrameEntries();\n let x = curves[n - 2], y = curves[n - 1];\n return y + (time - x) / (this.frames[frameIndex] - x) * (this.frames[frameIndex + valueOffset] - y);\n }\n}\nexport class CurveTimeline1 extends CurveTimeline {\n constructor(frameCount, bezierCount, propertyId) {\n super(frameCount, bezierCount, [propertyId]);\n }\n getFrameEntries() {\n return 2 /*ENTRIES*/;\n }\n /** Sets the time and value for the specified frame.\n * @param frame Between 0 and frameCount, inclusive.\n * @param time The frame time in seconds. */\n setFrame(frame, time, value) {\n frame <<= 1;\n this.frames[frame] = time;\n this.frames[frame + 1 /*VALUE*/] = value;\n }\n /** Returns the interpolated value for the specified time. */\n getCurveValue(time) {\n let frames = this.frames;\n let i = frames.length - 2;\n for (let ii = 2; ii <= i; ii += 2) {\n if (frames[ii] > time) {\n i = ii - 2;\n break;\n }\n }\n let curveType = this.curves[i >> 1];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i], value = frames[i + 1 /*VALUE*/];\n return value + (time - before) / (frames[i + 2 /*ENTRIES*/] - before) * (frames[i + 2 /*ENTRIES*/ + 1 /*VALUE*/] - value);\n case 1 /*STEPPED*/:\n return frames[i + 1 /*VALUE*/];\n }\n return this.getBezierValue(time, i, 1 /*VALUE*/, curveType - 2 /*BEZIER*/);\n }\n getRelativeValue(time, alpha, blend, current, setup) {\n if (time < this.frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n return setup;\n case MixBlend.first:\n return current + (setup - current) * alpha;\n }\n return current;\n }\n let value = this.getCurveValue(time);\n switch (blend) {\n case MixBlend.setup:\n return setup + value * alpha;\n case MixBlend.first:\n case MixBlend.replace:\n value += setup - current;\n }\n return current + value * alpha;\n }\n getAbsoluteValue(time, alpha, blend, current, setup) {\n if (time < this.frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n return setup;\n case MixBlend.first:\n return current + (setup - current) * alpha;\n }\n return current;\n }\n let value = this.getCurveValue(time);\n if (blend == MixBlend.setup)\n return setup + (value - setup) * alpha;\n return current + (value - current) * alpha;\n }\n getAbsoluteValue2(time, alpha, blend, current, setup, value) {\n if (time < this.frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n return setup;\n case MixBlend.first:\n return current + (setup - current) * alpha;\n }\n return current;\n }\n if (blend == MixBlend.setup)\n return setup + (value - setup) * alpha;\n return current + (value - current) * alpha;\n }\n getScaleValue(time, alpha, blend, direction, current, setup) {\n const frames = this.frames;\n if (time < frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n return setup;\n case MixBlend.first:\n return current + (setup - current) * alpha;\n }\n return current;\n }\n let value = this.getCurveValue(time) * setup;\n if (alpha == 1) {\n if (blend == MixBlend.add)\n return current + value - setup;\n return value;\n }\n // Mixing out uses sign of setup or current pose, else use sign of key.\n if (direction == MixDirection.mixOut) {\n switch (blend) {\n case MixBlend.setup:\n return setup + (Math.abs(value) * MathUtils.signum(setup) - setup) * alpha;\n case MixBlend.first:\n case MixBlend.replace:\n return current + (Math.abs(value) * MathUtils.signum(current) - current) * alpha;\n }\n }\n else {\n let s = 0;\n switch (blend) {\n case MixBlend.setup:\n s = Math.abs(setup) * MathUtils.signum(value);\n return s + (value - s) * alpha;\n case MixBlend.first:\n case MixBlend.replace:\n s = Math.abs(current) * MathUtils.signum(value);\n return s + (value - s) * alpha;\n }\n }\n return current + (value - setup) * alpha;\n }\n}\n/** The base class for a {@link CurveTimeline} which sets two properties. */\nexport class CurveTimeline2 extends CurveTimeline {\n /** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}.\n * @param propertyIds Unique identifiers for the properties the timeline modifies. */\n constructor(frameCount, bezierCount, propertyId1, propertyId2) {\n super(frameCount, bezierCount, [propertyId1, propertyId2]);\n }\n getFrameEntries() {\n return 3 /*ENTRIES*/;\n }\n /** Sets the time and values for the specified frame.\n * @param frame Between 0 and frameCount, inclusive.\n * @param time The frame time in seconds. */\n setFrame(frame, time, value1, value2) {\n frame *= 3 /*ENTRIES*/;\n this.frames[frame] = time;\n this.frames[frame + 1 /*VALUE1*/] = value1;\n this.frames[frame + 2 /*VALUE2*/] = value2;\n }\n}\n/** Changes a bone's local {@link Bone#rotation}. */\nexport class RotateTimeline extends CurveTimeline1 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.rotate + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (bone.active)\n bone.rotation = this.getRelativeValue(time, alpha, blend, bone.rotation, bone.data.rotation);\n }\n}\n/** Changes a bone's local {@link Bone#x} and {@link Bone#y}. */\nexport class TranslateTimeline extends CurveTimeline2 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.x + \"|\" + boneIndex, Property.y + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (!bone.active)\n return;\n let frames = this.frames;\n if (time < frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n bone.x = bone.data.x;\n bone.y = bone.data.y;\n return;\n case MixBlend.first:\n bone.x += (bone.data.x - bone.x) * alpha;\n bone.y += (bone.data.y - bone.y) * alpha;\n }\n return;\n }\n let x = 0, y = 0;\n let i = Timeline.search(frames, time, 3 /*ENTRIES*/);\n let curveType = this.curves[i / 3 /*ENTRIES*/];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n x = frames[i + 1 /*VALUE1*/];\n y = frames[i + 2 /*VALUE2*/];\n let t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before);\n x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t;\n y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t;\n break;\n case 1 /*STEPPED*/:\n x = frames[i + 1 /*VALUE1*/];\n y = frames[i + 2 /*VALUE2*/];\n break;\n default:\n x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/);\n y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n }\n switch (blend) {\n case MixBlend.setup:\n bone.x = bone.data.x + x * alpha;\n bone.y = bone.data.y + y * alpha;\n break;\n case MixBlend.first:\n case MixBlend.replace:\n bone.x += (bone.data.x + x - bone.x) * alpha;\n bone.y += (bone.data.y + y - bone.y) * alpha;\n break;\n case MixBlend.add:\n bone.x += x * alpha;\n bone.y += y * alpha;\n }\n }\n}\n/** Changes a bone's local {@link Bone#x}. */\nexport class TranslateXTimeline extends CurveTimeline1 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.x + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (bone.active)\n bone.x = this.getRelativeValue(time, alpha, blend, bone.x, bone.data.x);\n }\n}\n/** Changes a bone's local {@link Bone#x}. */\nexport class TranslateYTimeline extends CurveTimeline1 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.y + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (bone.active)\n bone.y = this.getRelativeValue(time, alpha, blend, bone.y, bone.data.y);\n }\n}\n/** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. */\nexport class ScaleTimeline extends CurveTimeline2 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.scaleX + \"|\" + boneIndex, Property.scaleY + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (!bone.active)\n return;\n let frames = this.frames;\n if (time < frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n bone.scaleX = bone.data.scaleX;\n bone.scaleY = bone.data.scaleY;\n return;\n case MixBlend.first:\n bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;\n bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;\n }\n return;\n }\n let x, y;\n let i = Timeline.search(frames, time, 3 /*ENTRIES*/);\n let curveType = this.curves[i / 3 /*ENTRIES*/];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n x = frames[i + 1 /*VALUE1*/];\n y = frames[i + 2 /*VALUE2*/];\n let t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before);\n x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t;\n y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t;\n break;\n case 1 /*STEPPED*/:\n x = frames[i + 1 /*VALUE1*/];\n y = frames[i + 2 /*VALUE2*/];\n break;\n default:\n x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/);\n y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n }\n x *= bone.data.scaleX;\n y *= bone.data.scaleY;\n if (alpha == 1) {\n if (blend == MixBlend.add) {\n bone.scaleX += x - bone.data.scaleX;\n bone.scaleY += y - bone.data.scaleY;\n }\n else {\n bone.scaleX = x;\n bone.scaleY = y;\n }\n }\n else {\n let bx = 0, by = 0;\n if (direction == MixDirection.mixOut) {\n switch (blend) {\n case MixBlend.setup:\n bx = bone.data.scaleX;\n by = bone.data.scaleY;\n bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha;\n bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha;\n break;\n case MixBlend.first:\n case MixBlend.replace:\n bx = bone.scaleX;\n by = bone.scaleY;\n bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha;\n bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha;\n break;\n case MixBlend.add:\n bone.scaleX += (x - bone.data.scaleX) * alpha;\n bone.scaleY += (y - bone.data.scaleY) * alpha;\n }\n }\n else {\n switch (blend) {\n case MixBlend.setup:\n bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x);\n by = Math.abs(bone.data.scaleY) * MathUtils.signum(y);\n bone.scaleX = bx + (x - bx) * alpha;\n bone.scaleY = by + (y - by) * alpha;\n break;\n case MixBlend.first:\n case MixBlend.replace:\n bx = Math.abs(bone.scaleX) * MathUtils.signum(x);\n by = Math.abs(bone.scaleY) * MathUtils.signum(y);\n bone.scaleX = bx + (x - bx) * alpha;\n bone.scaleY = by + (y - by) * alpha;\n break;\n case MixBlend.add:\n bone.scaleX += (x - bone.data.scaleX) * alpha;\n bone.scaleY += (y - bone.data.scaleY) * alpha;\n }\n }\n }\n }\n}\n/** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. */\nexport class ScaleXTimeline extends CurveTimeline1 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.scaleX + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (bone.active)\n bone.scaleX = this.getScaleValue(time, alpha, blend, direction, bone.scaleX, bone.data.scaleX);\n }\n}\n/** Changes a bone's local {@link Bone#scaleX)} and {@link Bone#scaleY}. */\nexport class ScaleYTimeline extends CurveTimeline1 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.scaleY + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (bone.active)\n bone.scaleY = this.getScaleValue(time, alpha, blend, direction, bone.scaleX, bone.data.scaleY);\n }\n}\n/** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. */\nexport class ShearTimeline extends CurveTimeline2 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.shearX + \"|\" + boneIndex, Property.shearY + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (!bone.active)\n return;\n let frames = this.frames;\n if (time < frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n bone.shearX = bone.data.shearX;\n bone.shearY = bone.data.shearY;\n return;\n case MixBlend.first:\n bone.shearX += (bone.data.shearX - bone.shearX) * alpha;\n bone.shearY += (bone.data.shearY - bone.shearY) * alpha;\n }\n return;\n }\n let x = 0, y = 0;\n let i = Timeline.search(frames, time, 3 /*ENTRIES*/);\n let curveType = this.curves[i / 3 /*ENTRIES*/];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n x = frames[i + 1 /*VALUE1*/];\n y = frames[i + 2 /*VALUE2*/];\n let t = (time - before) / (frames[i + 3 /*ENTRIES*/] - before);\n x += (frames[i + 3 /*ENTRIES*/ + 1 /*VALUE1*/] - x) * t;\n y += (frames[i + 3 /*ENTRIES*/ + 2 /*VALUE2*/] - y) * t;\n break;\n case 1 /*STEPPED*/:\n x = frames[i + 1 /*VALUE1*/];\n y = frames[i + 2 /*VALUE2*/];\n break;\n default:\n x = this.getBezierValue(time, i, 1 /*VALUE1*/, curveType - 2 /*BEZIER*/);\n y = this.getBezierValue(time, i, 2 /*VALUE2*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n }\n switch (blend) {\n case MixBlend.setup:\n bone.shearX = bone.data.shearX + x * alpha;\n bone.shearY = bone.data.shearY + y * alpha;\n break;\n case MixBlend.first:\n case MixBlend.replace:\n bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;\n bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;\n break;\n case MixBlend.add:\n bone.shearX += x * alpha;\n bone.shearY += y * alpha;\n }\n }\n}\n/** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. */\nexport class ShearXTimeline extends CurveTimeline1 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.shearX + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (bone.active)\n bone.shearX = this.getRelativeValue(time, alpha, blend, bone.shearX, bone.data.shearX);\n }\n}\n/** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. */\nexport class ShearYTimeline extends CurveTimeline1 {\n boneIndex = 0;\n constructor(frameCount, bezierCount, boneIndex) {\n super(frameCount, bezierCount, Property.shearY + \"|\" + boneIndex);\n this.boneIndex = boneIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let bone = skeleton.bones[this.boneIndex];\n if (bone.active)\n bone.shearY = this.getRelativeValue(time, alpha, blend, bone.shearX, bone.data.shearY);\n }\n}\n/** Changes a slot's {@link Slot#color}. */\nexport class RGBATimeline extends CurveTimeline {\n slotIndex = 0;\n constructor(frameCount, bezierCount, slotIndex) {\n super(frameCount, bezierCount, [\n Property.rgb + \"|\" + slotIndex,\n Property.alpha + \"|\" + slotIndex\n ]);\n this.slotIndex = slotIndex;\n }\n getFrameEntries() {\n return 5 /*ENTRIES*/;\n }\n /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */\n setFrame(frame, time, r, g, b, a) {\n frame *= 5 /*ENTRIES*/;\n this.frames[frame] = time;\n this.frames[frame + 1 /*R*/] = r;\n this.frames[frame + 2 /*G*/] = g;\n this.frames[frame + 3 /*B*/] = b;\n this.frames[frame + 4 /*A*/] = a;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let slot = skeleton.slots[this.slotIndex];\n if (!slot.bone.active)\n return;\n let frames = this.frames;\n let color = slot.color;\n if (time < frames[0]) {\n let setup = slot.data.color;\n switch (blend) {\n case MixBlend.setup:\n color.setFromColor(setup);\n return;\n case MixBlend.first:\n color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha);\n }\n return;\n }\n let r = 0, g = 0, b = 0, a = 0;\n let i = Timeline.search(frames, time, 5 /*ENTRIES*/);\n let curveType = this.curves[i / 5 /*ENTRIES*/];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n r = frames[i + 1 /*R*/];\n g = frames[i + 2 /*G*/];\n b = frames[i + 3 /*B*/];\n a = frames[i + 4 /*A*/];\n let t = (time - before) / (frames[i + 5 /*ENTRIES*/] - before);\n r += (frames[i + 5 /*ENTRIES*/ + 1 /*R*/] - r) * t;\n g += (frames[i + 5 /*ENTRIES*/ + 2 /*G*/] - g) * t;\n b += (frames[i + 5 /*ENTRIES*/ + 3 /*B*/] - b) * t;\n a += (frames[i + 5 /*ENTRIES*/ + 4 /*A*/] - a) * t;\n break;\n case 1 /*STEPPED*/:\n r = frames[i + 1 /*R*/];\n g = frames[i + 2 /*G*/];\n b = frames[i + 3 /*B*/];\n a = frames[i + 4 /*A*/];\n break;\n default:\n r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/);\n g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/);\n a = this.getBezierValue(time, i, 4 /*A*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/);\n }\n if (alpha == 1)\n color.set(r, g, b, a);\n else {\n if (blend == MixBlend.setup)\n color.setFromColor(slot.data.color);\n color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);\n }\n }\n}\n/** Changes a slot's {@link Slot#color}. */\nexport class RGBTimeline extends CurveTimeline {\n slotIndex = 0;\n constructor(frameCount, bezierCount, slotIndex) {\n super(frameCount, bezierCount, [\n Property.rgb + \"|\" + slotIndex\n ]);\n this.slotIndex = slotIndex;\n }\n getFrameEntries() {\n return 4 /*ENTRIES*/;\n }\n /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */\n setFrame(frame, time, r, g, b) {\n frame <<= 2;\n this.frames[frame] = time;\n this.frames[frame + 1 /*R*/] = r;\n this.frames[frame + 2 /*G*/] = g;\n this.frames[frame + 3 /*B*/] = b;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let slot = skeleton.slots[this.slotIndex];\n if (!slot.bone.active)\n return;\n let frames = this.frames;\n let color = slot.color;\n if (time < frames[0]) {\n let setup = slot.data.color;\n switch (blend) {\n case MixBlend.setup:\n color.r = setup.r;\n color.g = setup.g;\n color.b = setup.b;\n return;\n case MixBlend.first:\n color.r += (setup.r - color.r) * alpha;\n color.g += (setup.g - color.g) * alpha;\n color.b += (setup.b - color.b) * alpha;\n }\n return;\n }\n let r = 0, g = 0, b = 0;\n let i = Timeline.search(frames, time, 4 /*ENTRIES*/);\n let curveType = this.curves[i >> 2];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n r = frames[i + 1 /*R*/];\n g = frames[i + 2 /*G*/];\n b = frames[i + 3 /*B*/];\n let t = (time - before) / (frames[i + 4 /*ENTRIES*/] - before);\n r += (frames[i + 4 /*ENTRIES*/ + 1 /*R*/] - r) * t;\n g += (frames[i + 4 /*ENTRIES*/ + 2 /*G*/] - g) * t;\n b += (frames[i + 4 /*ENTRIES*/ + 3 /*B*/] - b) * t;\n break;\n case 1 /*STEPPED*/:\n r = frames[i + 1 /*R*/];\n g = frames[i + 2 /*G*/];\n b = frames[i + 3 /*B*/];\n break;\n default:\n r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/);\n g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/);\n }\n if (alpha == 1) {\n color.r = r;\n color.g = g;\n color.b = b;\n }\n else {\n if (blend == MixBlend.setup) {\n let setup = slot.data.color;\n color.r = setup.r;\n color.g = setup.g;\n color.b = setup.b;\n }\n color.r += (r - color.r) * alpha;\n color.g += (g - color.g) * alpha;\n color.b += (b - color.b) * alpha;\n }\n }\n}\n/** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. */\nexport class AlphaTimeline extends CurveTimeline1 {\n slotIndex = 0;\n constructor(frameCount, bezierCount, slotIndex) {\n super(frameCount, bezierCount, Property.alpha + \"|\" + slotIndex);\n this.slotIndex = slotIndex;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let slot = skeleton.slots[this.slotIndex];\n if (!slot.bone.active)\n return;\n let color = slot.color;\n if (time < this.frames[0]) {\n let setup = slot.data.color;\n switch (blend) {\n case MixBlend.setup:\n color.a = setup.a;\n return;\n case MixBlend.first:\n color.a += (setup.a - color.a) * alpha;\n }\n return;\n }\n let a = this.getCurveValue(time);\n if (alpha == 1)\n color.a = a;\n else {\n if (blend == MixBlend.setup)\n color.a = slot.data.color.a;\n color.a += (a - color.a) * alpha;\n }\n }\n}\n/** Changes a slot's {@link Slot#color} and {@link Slot#darkColor} for two color tinting. */\nexport class RGBA2Timeline extends CurveTimeline {\n slotIndex = 0;\n constructor(frameCount, bezierCount, slotIndex) {\n super(frameCount, bezierCount, [\n Property.rgb + \"|\" + slotIndex,\n Property.alpha + \"|\" + slotIndex,\n Property.rgb2 + \"|\" + slotIndex\n ]);\n this.slotIndex = slotIndex;\n }\n getFrameEntries() {\n return 8 /*ENTRIES*/;\n }\n /** Sets the time in seconds, light, and dark colors for the specified key frame. */\n setFrame(frame, time, r, g, b, a, r2, g2, b2) {\n frame <<= 3;\n this.frames[frame] = time;\n this.frames[frame + 1 /*R*/] = r;\n this.frames[frame + 2 /*G*/] = g;\n this.frames[frame + 3 /*B*/] = b;\n this.frames[frame + 4 /*A*/] = a;\n this.frames[frame + 5 /*R2*/] = r2;\n this.frames[frame + 6 /*G2*/] = g2;\n this.frames[frame + 7 /*B2*/] = b2;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let slot = skeleton.slots[this.slotIndex];\n if (!slot.bone.active)\n return;\n let frames = this.frames;\n let light = slot.color, dark = slot.darkColor;\n if (time < frames[0]) {\n let setupLight = slot.data.color, setupDark = slot.data.darkColor;\n switch (blend) {\n case MixBlend.setup:\n light.setFromColor(setupLight);\n dark.r = setupDark.r;\n dark.g = setupDark.g;\n dark.b = setupDark.b;\n return;\n case MixBlend.first:\n light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha);\n dark.r += (setupDark.r - dark.r) * alpha;\n dark.g += (setupDark.g - dark.g) * alpha;\n dark.b += (setupDark.b - dark.b) * alpha;\n }\n return;\n }\n let r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;\n let i = Timeline.search(frames, time, 8 /*ENTRIES*/);\n let curveType = this.curves[i >> 3];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n r = frames[i + 1 /*R*/];\n g = frames[i + 2 /*G*/];\n b = frames[i + 3 /*B*/];\n a = frames[i + 4 /*A*/];\n r2 = frames[i + 5 /*R2*/];\n g2 = frames[i + 6 /*G2*/];\n b2 = frames[i + 7 /*B2*/];\n let t = (time - before) / (frames[i + 8 /*ENTRIES*/] - before);\n r += (frames[i + 8 /*ENTRIES*/ + 1 /*R*/] - r) * t;\n g += (frames[i + 8 /*ENTRIES*/ + 2 /*G*/] - g) * t;\n b += (frames[i + 8 /*ENTRIES*/ + 3 /*B*/] - b) * t;\n a += (frames[i + 8 /*ENTRIES*/ + 4 /*A*/] - a) * t;\n r2 += (frames[i + 8 /*ENTRIES*/ + 5 /*R2*/] - r2) * t;\n g2 += (frames[i + 8 /*ENTRIES*/ + 6 /*G2*/] - g2) * t;\n b2 += (frames[i + 8 /*ENTRIES*/ + 7 /*B2*/] - b2) * t;\n break;\n case 1 /*STEPPED*/:\n r = frames[i + 1 /*R*/];\n g = frames[i + 2 /*G*/];\n b = frames[i + 3 /*B*/];\n a = frames[i + 4 /*A*/];\n r2 = frames[i + 5 /*R2*/];\n g2 = frames[i + 6 /*G2*/];\n b2 = frames[i + 7 /*B2*/];\n break;\n default:\n r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/);\n g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/);\n a = this.getBezierValue(time, i, 4 /*A*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/);\n r2 = this.getBezierValue(time, i, 5 /*R2*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/);\n g2 = this.getBezierValue(time, i, 6 /*G2*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/);\n b2 = this.getBezierValue(time, i, 7 /*B2*/, curveType + 18 /*BEZIER_SIZE*/ * 6 - 2 /*BEZIER*/);\n }\n if (alpha == 1) {\n light.set(r, g, b, a);\n dark.r = r2;\n dark.g = g2;\n dark.b = b2;\n }\n else {\n if (blend == MixBlend.setup) {\n light.setFromColor(slot.data.color);\n let setupDark = slot.data.darkColor;\n dark.r = setupDark.r;\n dark.g = setupDark.g;\n dark.b = setupDark.b;\n }\n light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);\n dark.r += (r2 - dark.r) * alpha;\n dark.g += (g2 - dark.g) * alpha;\n dark.b += (b2 - dark.b) * alpha;\n }\n }\n}\n/** Changes a slot's {@link Slot#color} and {@link Slot#darkColor} for two color tinting. */\nexport class RGB2Timeline extends CurveTimeline {\n slotIndex = 0;\n constructor(frameCount, bezierCount, slotIndex) {\n super(frameCount, bezierCount, [\n Property.rgb + \"|\" + slotIndex,\n Property.rgb2 + \"|\" + slotIndex\n ]);\n this.slotIndex = slotIndex;\n }\n getFrameEntries() {\n return 7 /*ENTRIES*/;\n }\n /** Sets the time in seconds, light, and dark colors for the specified key frame. */\n setFrame(frame, time, r, g, b, r2, g2, b2) {\n frame *= 7 /*ENTRIES*/;\n this.frames[frame] = time;\n this.frames[frame + 1 /*R*/] = r;\n this.frames[frame + 2 /*G*/] = g;\n this.frames[frame + 3 /*B*/] = b;\n this.frames[frame + 4 /*R2*/] = r2;\n this.frames[frame + 5 /*G2*/] = g2;\n this.frames[frame + 6 /*B2*/] = b2;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let slot = skeleton.slots[this.slotIndex];\n if (!slot.bone.active)\n return;\n let frames = this.frames;\n let light = slot.color, dark = slot.darkColor;\n if (time < frames[0]) {\n let setupLight = slot.data.color, setupDark = slot.data.darkColor;\n switch (blend) {\n case MixBlend.setup:\n light.r = setupLight.r;\n light.g = setupLight.g;\n light.b = setupLight.b;\n dark.r = setupDark.r;\n dark.g = setupDark.g;\n dark.b = setupDark.b;\n return;\n case MixBlend.first:\n light.r += (setupLight.r - light.r) * alpha;\n light.g += (setupLight.g - light.g) * alpha;\n light.b += (setupLight.b - light.b) * alpha;\n dark.r += (setupDark.r - dark.r) * alpha;\n dark.g += (setupDark.g - dark.g) * alpha;\n dark.b += (setupDark.b - dark.b) * alpha;\n }\n return;\n }\n let r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;\n let i = Timeline.search(frames, time, 7 /*ENTRIES*/);\n let curveType = this.curves[i / 7 /*ENTRIES*/];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n r = frames[i + 1 /*R*/];\n g = frames[i + 2 /*G*/];\n b = frames[i + 3 /*B*/];\n r2 = frames[i + 4 /*R2*/];\n g2 = frames[i + 5 /*G2*/];\n b2 = frames[i + 6 /*B2*/];\n let t = (time - before) / (frames[i + 7 /*ENTRIES*/] - before);\n r += (frames[i + 7 /*ENTRIES*/ + 1 /*R*/] - r) * t;\n g += (frames[i + 7 /*ENTRIES*/ + 2 /*G*/] - g) * t;\n b += (frames[i + 7 /*ENTRIES*/ + 3 /*B*/] - b) * t;\n r2 += (frames[i + 7 /*ENTRIES*/ + 4 /*R2*/] - r2) * t;\n g2 += (frames[i + 7 /*ENTRIES*/ + 5 /*G2*/] - g2) * t;\n b2 += (frames[i + 7 /*ENTRIES*/ + 6 /*B2*/] - b2) * t;\n break;\n case 1 /*STEPPED*/:\n r = frames[i + 1 /*R*/];\n g = frames[i + 2 /*G*/];\n b = frames[i + 3 /*B*/];\n r2 = frames[i + 4 /*R2*/];\n g2 = frames[i + 5 /*G2*/];\n b2 = frames[i + 6 /*B2*/];\n break;\n default:\n r = this.getBezierValue(time, i, 1 /*R*/, curveType - 2 /*BEZIER*/);\n g = this.getBezierValue(time, i, 2 /*G*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n b = this.getBezierValue(time, i, 3 /*B*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/);\n r2 = this.getBezierValue(time, i, 4 /*R2*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/);\n g2 = this.getBezierValue(time, i, 5 /*G2*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/);\n b2 = this.getBezierValue(time, i, 6 /*B2*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/);\n }\n if (alpha == 1) {\n light.r = r;\n light.g = g;\n light.b = b;\n dark.r = r2;\n dark.g = g2;\n dark.b = b2;\n }\n else {\n if (blend == MixBlend.setup) {\n let setupLight = slot.data.color, setupDark = slot.data.darkColor;\n light.r = setupLight.r;\n light.g = setupLight.g;\n light.b = setupLight.b;\n dark.r = setupDark.r;\n dark.g = setupDark.g;\n dark.b = setupDark.b;\n }\n light.r += (r - light.r) * alpha;\n light.g += (g - light.g) * alpha;\n light.b += (b - light.b) * alpha;\n dark.r += (r2 - dark.r) * alpha;\n dark.g += (g2 - dark.g) * alpha;\n dark.b += (b2 - dark.b) * alpha;\n }\n }\n}\n/** Changes a slot's {@link Slot#attachment}. */\nexport class AttachmentTimeline extends Timeline {\n slotIndex = 0;\n /** The attachment name for each key frame. May contain null values to clear the attachment. */\n attachmentNames;\n constructor(frameCount, slotIndex) {\n super(frameCount, [\n Property.attachment + \"|\" + slotIndex\n ]);\n this.slotIndex = slotIndex;\n this.attachmentNames = new Array(frameCount);\n }\n getFrameCount() {\n return this.frames.length;\n }\n /** Sets the time in seconds and the attachment name for the specified key frame. */\n setFrame(frame, time, attachmentName) {\n this.frames[frame] = time;\n this.attachmentNames[frame] = attachmentName;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let slot = skeleton.slots[this.slotIndex];\n if (!slot.bone.active)\n return;\n if (direction == MixDirection.mixOut) {\n if (blend == MixBlend.setup)\n this.setAttachment(skeleton, slot, slot.data.attachmentName);\n return;\n }\n if (time < this.frames[0]) {\n if (blend == MixBlend.setup || blend == MixBlend.first)\n this.setAttachment(skeleton, slot, slot.data.attachmentName);\n return;\n }\n this.setAttachment(skeleton, slot, this.attachmentNames[Timeline.search1(this.frames, time)]);\n }\n setAttachment(skeleton, slot, attachmentName) {\n slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(this.slotIndex, attachmentName));\n }\n}\n/** Changes a slot's {@link Slot#deform} to deform a {@link VertexAttachment}. */\nexport class DeformTimeline extends CurveTimeline {\n slotIndex = 0;\n /** The attachment that will be deformed. */\n attachment;\n /** The vertices for each key frame. */\n vertices;\n constructor(frameCount, bezierCount, slotIndex, attachment) {\n super(frameCount, bezierCount, [\n Property.deform + \"|\" + slotIndex + \"|\" + attachment.id\n ]);\n this.slotIndex = slotIndex;\n this.attachment = attachment;\n this.vertices = new Array(frameCount);\n }\n getFrameCount() {\n return this.frames.length;\n }\n /** Sets the time in seconds and the vertices for the specified key frame.\n * @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */\n setFrame(frame, time, vertices) {\n this.frames[frame] = time;\n this.vertices[frame] = vertices;\n }\n /** @param value1 Ignored (0 is used for a deform timeline).\n * @param value2 Ignored (1 is used for a deform timeline). */\n setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) {\n let curves = this.curves;\n let i = this.getFrameCount() + bezier * 18 /*BEZIER_SIZE*/;\n if (value == 0)\n curves[frame] = 2 /*BEZIER*/ + i;\n let tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = cy2 * 0.03 - cy1 * 0.06;\n let dddx = ((cx1 - cx2) * 3 - time1 + time2) * 0.006, dddy = (cy1 - cy2 + 0.33333333) * 0.018;\n let ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy;\n let dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = cy1 * 0.3 + tmpy + dddy * 0.16666667;\n let x = time1 + dx, y = dy;\n for (let n = i + 18 /*BEZIER_SIZE*/; i < n; i += 2) {\n curves[i] = x;\n curves[i + 1] = y;\n dx += ddx;\n dy += ddy;\n ddx += dddx;\n ddy += dddy;\n x += dx;\n y += dy;\n }\n }\n getCurvePercent(time, frame) {\n let curves = this.curves;\n let i = curves[frame];\n switch (i) {\n case 0 /*LINEAR*/:\n let x = this.frames[frame];\n return (time - x) / (this.frames[frame + this.getFrameEntries()] - x);\n case 1 /*STEPPED*/:\n return 0;\n }\n i -= 2 /*BEZIER*/;\n if (curves[i] > time) {\n let x = this.frames[frame];\n return curves[i + 1] * (time - x) / (curves[i] - x);\n }\n let n = i + 18 /*BEZIER_SIZE*/;\n for (i += 2; i < n; i += 2) {\n if (curves[i] >= time) {\n let x = curves[i - 2], y = curves[i - 1];\n return y + (time - x) / (curves[i] - x) * (curves[i + 1] - y);\n }\n }\n let x = curves[n - 2], y = curves[n - 1];\n return y + (1 - y) * (time - x) / (this.frames[frame + this.getFrameEntries()] - x);\n }\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n let slot = skeleton.slots[this.slotIndex];\n if (!slot.bone.active)\n return;\n let slotAttachment = slot.getAttachment();\n if (!slotAttachment)\n return;\n if (!(slotAttachment instanceof VertexAttachment) || slotAttachment.timelineAttachment != this.attachment)\n return;\n let deform = slot.deform;\n if (deform.length == 0)\n blend = MixBlend.setup;\n let vertices = this.vertices;\n let vertexCount = vertices[0].length;\n let frames = this.frames;\n if (time < frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n deform.length = 0;\n return;\n case MixBlend.first:\n if (alpha == 1) {\n deform.length = 0;\n return;\n }\n deform.length = vertexCount;\n let vertexAttachment = slotAttachment;\n if (!vertexAttachment.bones) {\n // Unweighted vertex positions.\n let setupVertices = vertexAttachment.vertices;\n for (var i = 0; i < vertexCount; i++)\n deform[i] += (setupVertices[i] - deform[i]) * alpha;\n }\n else {\n // Weighted deform offsets.\n alpha = 1 - alpha;\n for (var i = 0; i < vertexCount; i++)\n deform[i] *= alpha;\n }\n }\n return;\n }\n deform.length = vertexCount;\n if (time >= frames[frames.length - 1]) {\n let lastVertices = vertices[frames.length - 1];\n if (alpha == 1) {\n if (blend == MixBlend.add) {\n let vertexAttachment = slotAttachment;\n if (!vertexAttachment.bones) {\n // Unweighted vertex positions, with alpha.\n let setupVertices = vertexAttachment.vertices;\n for (let i = 0; i < vertexCount; i++)\n deform[i] += lastVertices[i] - setupVertices[i];\n }\n else {\n // Weighted deform offsets, with alpha.\n for (let i = 0; i < vertexCount; i++)\n deform[i] += lastVertices[i];\n }\n }\n else\n Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount);\n }\n else {\n switch (blend) {\n case MixBlend.setup: {\n let vertexAttachment = slotAttachment;\n if (!vertexAttachment.bones) {\n // Unweighted vertex positions, with alpha.\n let setupVertices = vertexAttachment.vertices;\n for (let i = 0; i < vertexCount; i++) {\n let setup = setupVertices[i];\n deform[i] = setup + (lastVertices[i] - setup) * alpha;\n }\n }\n else {\n // Weighted deform offsets, with alpha.\n for (let i = 0; i < vertexCount; i++)\n deform[i] = lastVertices[i] * alpha;\n }\n break;\n }\n case MixBlend.first:\n case MixBlend.replace:\n for (let i = 0; i < vertexCount; i++)\n deform[i] += (lastVertices[i] - deform[i]) * alpha;\n break;\n case MixBlend.add:\n let vertexAttachment = slotAttachment;\n if (!vertexAttachment.bones) {\n // Unweighted vertex positions, with alpha.\n let setupVertices = vertexAttachment.vertices;\n for (let i = 0; i < vertexCount; i++)\n deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;\n }\n else {\n // Weighted deform offsets, with alpha.\n for (let i = 0; i < vertexCount; i++)\n deform[i] += lastVertices[i] * alpha;\n }\n }\n }\n return;\n }\n // Interpolate between the previous frame and the current frame.\n let frame = Timeline.search1(frames, time);\n let percent = this.getCurvePercent(time, frame);\n let prevVertices = vertices[frame];\n let nextVertices = vertices[frame + 1];\n if (alpha == 1) {\n if (blend == MixBlend.add) {\n let vertexAttachment = slotAttachment;\n if (!vertexAttachment.bones) {\n // Unweighted vertex positions, with alpha.\n let setupVertices = vertexAttachment.vertices;\n for (let i = 0; i < vertexCount; i++) {\n let prev = prevVertices[i];\n deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];\n }\n }\n else {\n // Weighted deform offsets, with alpha.\n for (let i = 0; i < vertexCount; i++) {\n let prev = prevVertices[i];\n deform[i] += prev + (nextVertices[i] - prev) * percent;\n }\n }\n }\n else {\n for (let i = 0; i < vertexCount; i++) {\n let prev = prevVertices[i];\n deform[i] = prev + (nextVertices[i] - prev) * percent;\n }\n }\n }\n else {\n switch (blend) {\n case MixBlend.setup: {\n let vertexAttachment = slotAttachment;\n if (!vertexAttachment.bones) {\n // Unweighted vertex positions, with alpha.\n let setupVertices = vertexAttachment.vertices;\n for (let i = 0; i < vertexCount; i++) {\n let prev = prevVertices[i], setup = setupVertices[i];\n deform[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;\n }\n }\n else {\n // Weighted deform offsets, with alpha.\n for (let i = 0; i < vertexCount; i++) {\n let prev = prevVertices[i];\n deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;\n }\n }\n break;\n }\n case MixBlend.first:\n case MixBlend.replace:\n for (let i = 0; i < vertexCount; i++) {\n let prev = prevVertices[i];\n deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha;\n }\n break;\n case MixBlend.add:\n let vertexAttachment = slotAttachment;\n if (!vertexAttachment.bones) {\n // Unweighted vertex positions, with alpha.\n let setupVertices = vertexAttachment.vertices;\n for (let i = 0; i < vertexCount; i++) {\n let prev = prevVertices[i];\n deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;\n }\n }\n else {\n // Weighted deform offsets, with alpha.\n for (let i = 0; i < vertexCount; i++) {\n let prev = prevVertices[i];\n deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;\n }\n }\n }\n }\n }\n}\n/** Fires an {@link Event} when specific animation times are reached. */\nexport class EventTimeline extends Timeline {\n static propertyIds = [\"\" + Property.event];\n /** The event for each key frame. */\n events;\n constructor(frameCount) {\n super(frameCount, EventTimeline.propertyIds);\n this.events = new Array(frameCount);\n }\n getFrameCount() {\n return this.frames.length;\n }\n /** Sets the time in seconds and the event for the specified key frame. */\n setFrame(frame, event) {\n this.frames[frame] = event.time;\n this.events[frame] = event;\n }\n /** Fires events for frames > `lastTime` and <= `time`. */\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n if (!firedEvents)\n return;\n let frames = this.frames;\n let frameCount = this.frames.length;\n if (lastTime > time) { // Apply after lastTime for looped animations.\n this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction);\n lastTime = -1;\n }\n else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.\n return;\n if (time < frames[0])\n return;\n let i = 0;\n if (lastTime < frames[0])\n i = 0;\n else {\n i = Timeline.search1(frames, lastTime) + 1;\n let frameTime = frames[i];\n while (i > 0) { // Fire multiple events with the same frame.\n if (frames[i - 1] != frameTime)\n break;\n i--;\n }\n }\n for (; i < frameCount && time >= frames[i]; i++)\n firedEvents.push(this.events[i]);\n }\n}\n/** Changes a skeleton's {@link Skeleton#drawOrder}. */\nexport class DrawOrderTimeline extends Timeline {\n static propertyIds = [\"\" + Property.drawOrder];\n /** The draw order for each key frame. See {@link #setFrame(int, float, int[])}. */\n drawOrders;\n constructor(frameCount) {\n super(frameCount, DrawOrderTimeline.propertyIds);\n this.drawOrders = new Array(frameCount);\n }\n getFrameCount() {\n return this.frames.length;\n }\n /** Sets the time in seconds and the draw order for the specified key frame.\n * @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose\n * draw order. */\n setFrame(frame, time, drawOrder) {\n this.frames[frame] = time;\n this.drawOrders[frame] = drawOrder;\n }\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n if (direction == MixDirection.mixOut) {\n if (blend == MixBlend.setup)\n Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);\n return;\n }\n if (time < this.frames[0]) {\n if (blend == MixBlend.setup || blend == MixBlend.first)\n Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);\n return;\n }\n let idx = Timeline.search1(this.frames, time);\n let drawOrderToSetupIndex = this.drawOrders[idx];\n if (!drawOrderToSetupIndex)\n Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);\n else {\n let drawOrder = skeleton.drawOrder;\n let slots = skeleton.slots;\n for (let i = 0, n = drawOrderToSetupIndex.length; i < n; i++)\n drawOrder[i] = slots[drawOrderToSetupIndex[i]];\n }\n }\n}\n/** Changes an IK constraint's {@link IkConstraint#mix}, {@link IkConstraint#softness},\n * {@link IkConstraint#bendDirection}, {@link IkConstraint#stretch}, and {@link IkConstraint#compress}. */\nexport class IkConstraintTimeline extends CurveTimeline {\n /** The index of the IK constraint in {@link Skeleton#getIkConstraints()} that will be changed when this timeline is */\n constraintIndex = 0;\n constructor(frameCount, bezierCount, ikConstraintIndex) {\n super(frameCount, bezierCount, [\n Property.ikConstraint + \"|\" + ikConstraintIndex\n ]);\n this.constraintIndex = ikConstraintIndex;\n }\n getFrameEntries() {\n return 6 /*ENTRIES*/;\n }\n /** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */\n setFrame(frame, time, mix, softness, bendDirection, compress, stretch) {\n frame *= 6 /*ENTRIES*/;\n this.frames[frame] = time;\n this.frames[frame + 1 /*MIX*/] = mix;\n this.frames[frame + 2 /*SOFTNESS*/] = softness;\n this.frames[frame + 3 /*BEND_DIRECTION*/] = bendDirection;\n this.frames[frame + 4 /*COMPRESS*/] = compress ? 1 : 0;\n this.frames[frame + 5 /*STRETCH*/] = stretch ? 1 : 0;\n }\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n let constraint = skeleton.ikConstraints[this.constraintIndex];\n if (!constraint.active)\n return;\n let frames = this.frames;\n if (time < frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n constraint.mix = constraint.data.mix;\n constraint.softness = constraint.data.softness;\n constraint.bendDirection = constraint.data.bendDirection;\n constraint.compress = constraint.data.compress;\n constraint.stretch = constraint.data.stretch;\n return;\n case MixBlend.first:\n constraint.mix += (constraint.data.mix - constraint.mix) * alpha;\n constraint.softness += (constraint.data.softness - constraint.softness) * alpha;\n constraint.bendDirection = constraint.data.bendDirection;\n constraint.compress = constraint.data.compress;\n constraint.stretch = constraint.data.stretch;\n }\n return;\n }\n let mix = 0, softness = 0;\n let i = Timeline.search(frames, time, 6 /*ENTRIES*/);\n let curveType = this.curves[i / 6 /*ENTRIES*/];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n mix = frames[i + 1 /*MIX*/];\n softness = frames[i + 2 /*SOFTNESS*/];\n let t = (time - before) / (frames[i + 6 /*ENTRIES*/] - before);\n mix += (frames[i + 6 /*ENTRIES*/ + 1 /*MIX*/] - mix) * t;\n softness += (frames[i + 6 /*ENTRIES*/ + 2 /*SOFTNESS*/] - softness) * t;\n break;\n case 1 /*STEPPED*/:\n mix = frames[i + 1 /*MIX*/];\n softness = frames[i + 2 /*SOFTNESS*/];\n break;\n default:\n mix = this.getBezierValue(time, i, 1 /*MIX*/, curveType - 2 /*BEZIER*/);\n softness = this.getBezierValue(time, i, 2 /*SOFTNESS*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n }\n if (blend == MixBlend.setup) {\n constraint.mix = constraint.data.mix + (mix - constraint.data.mix) * alpha;\n constraint.softness = constraint.data.softness + (softness - constraint.data.softness) * alpha;\n if (direction == MixDirection.mixOut) {\n constraint.bendDirection = constraint.data.bendDirection;\n constraint.compress = constraint.data.compress;\n constraint.stretch = constraint.data.stretch;\n }\n else {\n constraint.bendDirection = frames[i + 3 /*BEND_DIRECTION*/];\n constraint.compress = frames[i + 4 /*COMPRESS*/] != 0;\n constraint.stretch = frames[i + 5 /*STRETCH*/] != 0;\n }\n }\n else {\n constraint.mix += (mix - constraint.mix) * alpha;\n constraint.softness += (softness - constraint.softness) * alpha;\n if (direction == MixDirection.mixIn) {\n constraint.bendDirection = frames[i + 3 /*BEND_DIRECTION*/];\n constraint.compress = frames[i + 4 /*COMPRESS*/] != 0;\n constraint.stretch = frames[i + 5 /*STRETCH*/] != 0;\n }\n }\n }\n}\n/** Changes a transform constraint's {@link TransformConstraint#rotateMix}, {@link TransformConstraint#translateMix},\n * {@link TransformConstraint#scaleMix}, and {@link TransformConstraint#shearMix}. */\nexport class TransformConstraintTimeline extends CurveTimeline {\n /** The index of the transform constraint slot in {@link Skeleton#transformConstraints} that will be changed. */\n constraintIndex = 0;\n constructor(frameCount, bezierCount, transformConstraintIndex) {\n super(frameCount, bezierCount, [\n Property.transformConstraint + \"|\" + transformConstraintIndex\n ]);\n this.constraintIndex = transformConstraintIndex;\n }\n getFrameEntries() {\n return 7 /*ENTRIES*/;\n }\n /** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */\n setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY) {\n let frames = this.frames;\n frame *= 7 /*ENTRIES*/;\n frames[frame] = time;\n frames[frame + 1 /*ROTATE*/] = mixRotate;\n frames[frame + 2 /*X*/] = mixX;\n frames[frame + 3 /*Y*/] = mixY;\n frames[frame + 4 /*SCALEX*/] = mixScaleX;\n frames[frame + 5 /*SCALEY*/] = mixScaleY;\n frames[frame + 6 /*SHEARY*/] = mixShearY;\n }\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n let constraint = skeleton.transformConstraints[this.constraintIndex];\n if (!constraint.active)\n return;\n let frames = this.frames;\n if (time < frames[0]) {\n let data = constraint.data;\n switch (blend) {\n case MixBlend.setup:\n constraint.mixRotate = data.mixRotate;\n constraint.mixX = data.mixX;\n constraint.mixY = data.mixY;\n constraint.mixScaleX = data.mixScaleX;\n constraint.mixScaleY = data.mixScaleY;\n constraint.mixShearY = data.mixShearY;\n return;\n case MixBlend.first:\n constraint.mixRotate += (data.mixRotate - constraint.mixRotate) * alpha;\n constraint.mixX += (data.mixX - constraint.mixX) * alpha;\n constraint.mixY += (data.mixY - constraint.mixY) * alpha;\n constraint.mixScaleX += (data.mixScaleX - constraint.mixScaleX) * alpha;\n constraint.mixScaleY += (data.mixScaleY - constraint.mixScaleY) * alpha;\n constraint.mixShearY += (data.mixShearY - constraint.mixShearY) * alpha;\n }\n return;\n }\n let rotate, x, y, scaleX, scaleY, shearY;\n let i = Timeline.search(frames, time, 7 /*ENTRIES*/);\n let curveType = this.curves[i / 7 /*ENTRIES*/];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n rotate = frames[i + 1 /*ROTATE*/];\n x = frames[i + 2 /*X*/];\n y = frames[i + 3 /*Y*/];\n scaleX = frames[i + 4 /*SCALEX*/];\n scaleY = frames[i + 5 /*SCALEY*/];\n shearY = frames[i + 6 /*SHEARY*/];\n let t = (time - before) / (frames[i + 7 /*ENTRIES*/] - before);\n rotate += (frames[i + 7 /*ENTRIES*/ + 1 /*ROTATE*/] - rotate) * t;\n x += (frames[i + 7 /*ENTRIES*/ + 2 /*X*/] - x) * t;\n y += (frames[i + 7 /*ENTRIES*/ + 3 /*Y*/] - y) * t;\n scaleX += (frames[i + 7 /*ENTRIES*/ + 4 /*SCALEX*/] - scaleX) * t;\n scaleY += (frames[i + 7 /*ENTRIES*/ + 5 /*SCALEY*/] - scaleY) * t;\n shearY += (frames[i + 7 /*ENTRIES*/ + 6 /*SHEARY*/] - shearY) * t;\n break;\n case 1 /*STEPPED*/:\n rotate = frames[i + 1 /*ROTATE*/];\n x = frames[i + 2 /*X*/];\n y = frames[i + 3 /*Y*/];\n scaleX = frames[i + 4 /*SCALEX*/];\n scaleY = frames[i + 5 /*SCALEY*/];\n shearY = frames[i + 6 /*SHEARY*/];\n break;\n default:\n rotate = this.getBezierValue(time, i, 1 /*ROTATE*/, curveType - 2 /*BEZIER*/);\n x = this.getBezierValue(time, i, 2 /*X*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n y = this.getBezierValue(time, i, 3 /*Y*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/);\n scaleX = this.getBezierValue(time, i, 4 /*SCALEX*/, curveType + 18 /*BEZIER_SIZE*/ * 3 - 2 /*BEZIER*/);\n scaleY = this.getBezierValue(time, i, 5 /*SCALEY*/, curveType + 18 /*BEZIER_SIZE*/ * 4 - 2 /*BEZIER*/);\n shearY = this.getBezierValue(time, i, 6 /*SHEARY*/, curveType + 18 /*BEZIER_SIZE*/ * 5 - 2 /*BEZIER*/);\n }\n if (blend == MixBlend.setup) {\n let data = constraint.data;\n constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha;\n constraint.mixX = data.mixX + (x - data.mixX) * alpha;\n constraint.mixY = data.mixY + (y - data.mixY) * alpha;\n constraint.mixScaleX = data.mixScaleX + (scaleX - data.mixScaleX) * alpha;\n constraint.mixScaleY = data.mixScaleY + (scaleY - data.mixScaleY) * alpha;\n constraint.mixShearY = data.mixShearY + (shearY - data.mixShearY) * alpha;\n }\n else {\n constraint.mixRotate += (rotate - constraint.mixRotate) * alpha;\n constraint.mixX += (x - constraint.mixX) * alpha;\n constraint.mixY += (y - constraint.mixY) * alpha;\n constraint.mixScaleX += (scaleX - constraint.mixScaleX) * alpha;\n constraint.mixScaleY += (scaleY - constraint.mixScaleY) * alpha;\n constraint.mixShearY += (shearY - constraint.mixShearY) * alpha;\n }\n }\n}\n/** Changes a path constraint's {@link PathConstraint#position}. */\nexport class PathConstraintPositionTimeline extends CurveTimeline1 {\n /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is\n * applied. */\n constraintIndex = 0;\n constructor(frameCount, bezierCount, pathConstraintIndex) {\n super(frameCount, bezierCount, Property.pathConstraintPosition + \"|\" + pathConstraintIndex);\n this.constraintIndex = pathConstraintIndex;\n }\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n let constraint = skeleton.pathConstraints[this.constraintIndex];\n if (constraint.active)\n constraint.position = this.getAbsoluteValue(time, alpha, blend, constraint.position, constraint.data.position);\n }\n}\n/** Changes a path constraint's {@link PathConstraint#spacing}. */\nexport class PathConstraintSpacingTimeline extends CurveTimeline1 {\n /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is\n * applied. */\n constraintIndex = 0;\n constructor(frameCount, bezierCount, pathConstraintIndex) {\n super(frameCount, bezierCount, Property.pathConstraintSpacing + \"|\" + pathConstraintIndex);\n this.constraintIndex = pathConstraintIndex;\n }\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n let constraint = skeleton.pathConstraints[this.constraintIndex];\n if (constraint.active)\n constraint.spacing = this.getAbsoluteValue(time, alpha, blend, constraint.spacing, constraint.data.spacing);\n }\n}\n/** Changes a transform constraint's {@link PathConstraint#getMixRotate()}, {@link PathConstraint#getMixX()}, and\n * {@link PathConstraint#getMixY()}. */\nexport class PathConstraintMixTimeline extends CurveTimeline {\n /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is\n * applied. */\n constraintIndex = 0;\n constructor(frameCount, bezierCount, pathConstraintIndex) {\n super(frameCount, bezierCount, [\n Property.pathConstraintMix + \"|\" + pathConstraintIndex\n ]);\n this.constraintIndex = pathConstraintIndex;\n }\n getFrameEntries() {\n return 4 /*ENTRIES*/;\n }\n setFrame(frame, time, mixRotate, mixX, mixY) {\n let frames = this.frames;\n frame <<= 2;\n frames[frame] = time;\n frames[frame + 1 /*ROTATE*/] = mixRotate;\n frames[frame + 2 /*X*/] = mixX;\n frames[frame + 3 /*Y*/] = mixY;\n }\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n let constraint = skeleton.pathConstraints[this.constraintIndex];\n if (!constraint.active)\n return;\n let frames = this.frames;\n if (time < frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n constraint.mixRotate = constraint.data.mixRotate;\n constraint.mixX = constraint.data.mixX;\n constraint.mixY = constraint.data.mixY;\n return;\n case MixBlend.first:\n constraint.mixRotate += (constraint.data.mixRotate - constraint.mixRotate) * alpha;\n constraint.mixX += (constraint.data.mixX - constraint.mixX) * alpha;\n constraint.mixY += (constraint.data.mixY - constraint.mixY) * alpha;\n }\n return;\n }\n let rotate, x, y;\n let i = Timeline.search(frames, time, 4 /*ENTRIES*/);\n let curveType = this.curves[i >> 2];\n switch (curveType) {\n case 0 /*LINEAR*/:\n let before = frames[i];\n rotate = frames[i + 1 /*ROTATE*/];\n x = frames[i + 2 /*X*/];\n y = frames[i + 3 /*Y*/];\n let t = (time - before) / (frames[i + 4 /*ENTRIES*/] - before);\n rotate += (frames[i + 4 /*ENTRIES*/ + 1 /*ROTATE*/] - rotate) * t;\n x += (frames[i + 4 /*ENTRIES*/ + 2 /*X*/] - x) * t;\n y += (frames[i + 4 /*ENTRIES*/ + 3 /*Y*/] - y) * t;\n break;\n case 1 /*STEPPED*/:\n rotate = frames[i + 1 /*ROTATE*/];\n x = frames[i + 2 /*X*/];\n y = frames[i + 3 /*Y*/];\n break;\n default:\n rotate = this.getBezierValue(time, i, 1 /*ROTATE*/, curveType - 2 /*BEZIER*/);\n x = this.getBezierValue(time, i, 2 /*X*/, curveType + 18 /*BEZIER_SIZE*/ - 2 /*BEZIER*/);\n y = this.getBezierValue(time, i, 3 /*Y*/, curveType + 18 /*BEZIER_SIZE*/ * 2 - 2 /*BEZIER*/);\n }\n if (blend == MixBlend.setup) {\n let data = constraint.data;\n constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha;\n constraint.mixX = data.mixX + (x - data.mixX) * alpha;\n constraint.mixY = data.mixY + (y - data.mixY) * alpha;\n }\n else {\n constraint.mixRotate += (rotate - constraint.mixRotate) * alpha;\n constraint.mixX += (x - constraint.mixX) * alpha;\n constraint.mixY += (y - constraint.mixY) * alpha;\n }\n }\n}\n/** The base class for most {@link PhysicsConstraint} timelines. */\nexport class PhysicsConstraintTimeline extends CurveTimeline1 {\n /** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be changed when this timeline\n * is applied, or -1 if all physics constraints in the skeleton will be changed. */\n constraintIndex = 0;\n /** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */\n constructor(frameCount, bezierCount, physicsConstraintIndex, property) {\n super(frameCount, bezierCount, property + \"|\" + physicsConstraintIndex);\n this.constraintIndex = physicsConstraintIndex;\n }\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n let constraint;\n if (this.constraintIndex == -1) {\n const value = time >= this.frames[0] ? this.getCurveValue(time) : 0;\n for (const constraint of skeleton.physicsConstraints) {\n if (constraint.active && this.global(constraint.data))\n this.set(constraint, this.getAbsoluteValue2(time, alpha, blend, this.get(constraint), this.setup(constraint), value));\n }\n }\n else {\n constraint = skeleton.physicsConstraints[this.constraintIndex];\n if (constraint.active)\n this.set(constraint, this.getAbsoluteValue(time, alpha, blend, this.get(constraint), this.setup(constraint)));\n }\n }\n}\n/** Changes a physics constraint's {@link PhysicsConstraint#getInertia()}. */\nexport class PhysicsConstraintInertiaTimeline extends PhysicsConstraintTimeline {\n constructor(frameCount, bezierCount, physicsConstraintIndex) {\n super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintInertia);\n }\n setup(constraint) {\n return constraint.data.inertia;\n }\n get(constraint) {\n return constraint.inertia;\n }\n set(constraint, value) {\n constraint.inertia = value;\n }\n global(constraint) {\n return constraint.inertiaGlobal;\n }\n}\n/** Changes a physics constraint's {@link PhysicsConstraint#getStrength()}. */\nexport class PhysicsConstraintStrengthTimeline extends PhysicsConstraintTimeline {\n constructor(frameCount, bezierCount, physicsConstraintIndex) {\n super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintStrength);\n }\n setup(constraint) {\n return constraint.data.strength;\n }\n get(constraint) {\n return constraint.strength;\n }\n set(constraint, value) {\n constraint.strength = value;\n }\n global(constraint) {\n return constraint.strengthGlobal;\n }\n}\n/** Changes a physics constraint's {@link PhysicsConstraint#getDamping()}. */\nexport class PhysicsConstraintDampingTimeline extends PhysicsConstraintTimeline {\n constructor(frameCount, bezierCount, physicsConstraintIndex) {\n super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintDamping);\n }\n setup(constraint) {\n return constraint.data.damping;\n }\n get(constraint) {\n return constraint.damping;\n }\n set(constraint, value) {\n constraint.damping = value;\n }\n global(constraint) {\n return constraint.dampingGlobal;\n }\n}\n/** Changes a physics constraint's {@link PhysicsConstraint#getMassInverse()}. The timeline values are not inverted. */\nexport class PhysicsConstraintMassTimeline extends PhysicsConstraintTimeline {\n constructor(frameCount, bezierCount, physicsConstraintIndex) {\n super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMass);\n }\n setup(constraint) {\n return 1 / constraint.data.massInverse;\n }\n get(constraint) {\n return 1 / constraint.massInverse;\n }\n set(constraint, value) {\n constraint.massInverse = 1 / value;\n }\n global(constraint) {\n return constraint.massGlobal;\n }\n}\n/** Changes a physics constraint's {@link PhysicsConstraint#getWind()}. */\nexport class PhysicsConstraintWindTimeline extends PhysicsConstraintTimeline {\n constructor(frameCount, bezierCount, physicsConstraintIndex) {\n super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintWind);\n }\n setup(constraint) {\n return constraint.data.wind;\n }\n get(constraint) {\n return constraint.wind;\n }\n set(constraint, value) {\n constraint.wind = value;\n }\n global(constraint) {\n return constraint.windGlobal;\n }\n}\n/** Changes a physics constraint's {@link PhysicsConstraint#getGravity()}. */\nexport class PhysicsConstraintGravityTimeline extends PhysicsConstraintTimeline {\n constructor(frameCount, bezierCount, physicsConstraintIndex) {\n super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintGravity);\n }\n setup(constraint) {\n return constraint.data.gravity;\n }\n get(constraint) {\n return constraint.gravity;\n }\n set(constraint, value) {\n constraint.gravity = value;\n }\n global(constraint) {\n return constraint.gravityGlobal;\n }\n}\n/** Changes a physics constraint's {@link PhysicsConstraint#getMix()}. */\nexport class PhysicsConstraintMixTimeline extends PhysicsConstraintTimeline {\n constructor(frameCount, bezierCount, physicsConstraintIndex) {\n super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMix);\n }\n setup(constraint) {\n return constraint.data.mix;\n }\n get(constraint) {\n return constraint.mix;\n }\n set(constraint, value) {\n constraint.mix = value;\n }\n global(constraint) {\n return constraint.mixGlobal;\n }\n}\n/** Resets a physics constraint when specific animation times are reached. */\nexport class PhysicsConstraintResetTimeline extends Timeline {\n static propertyIds = [Property.physicsConstraintReset.toString()];\n /** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be reset when this timeline is\n * applied, or -1 if all physics constraints in the skeleton will be reset. */\n constraintIndex;\n /** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */\n constructor(frameCount, physicsConstraintIndex) {\n super(frameCount, PhysicsConstraintResetTimeline.propertyIds);\n this.constraintIndex = physicsConstraintIndex;\n }\n getFrameCount() {\n return this.frames.length;\n }\n /** Sets the time for the specified frame.\n * @param frame Between 0 and frameCount, inclusive. */\n setFrame(frame, time) {\n this.frames[frame] = time;\n }\n /** Resets the physics constraint when frames > lastTime and <= time. */\n apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) {\n let constraint;\n if (this.constraintIndex != -1) {\n constraint = skeleton.physicsConstraints[this.constraintIndex];\n if (!constraint.active)\n return;\n }\n const frames = this.frames;\n if (lastTime > time) { // Apply after lastTime for looped animations.\n this.apply(skeleton, lastTime, Number.MAX_VALUE, [], alpha, blend, direction);\n lastTime = -1;\n }\n else if (lastTime >= frames[frames.length - 1]) // Last time is after last frame.\n return;\n if (time < frames[0])\n return;\n if (lastTime < frames[0] || time >= frames[Timeline.search1(frames, lastTime) + 1]) {\n if (constraint != null)\n constraint.reset();\n else {\n for (const constraint of skeleton.physicsConstraints) {\n if (constraint.active)\n constraint.reset();\n }\n }\n }\n }\n}\n/** Changes a slot's {@link Slot#getSequenceIndex()} for an attachment's {@link Sequence}. */\nexport class SequenceTimeline extends Timeline {\n static ENTRIES = 3;\n static MODE = 1;\n static DELAY = 2;\n slotIndex;\n attachment;\n constructor(frameCount, slotIndex, attachment) {\n super(frameCount, [\n Property.sequence + \"|\" + slotIndex + \"|\" + attachment.sequence.id\n ]);\n this.slotIndex = slotIndex;\n this.attachment = attachment;\n }\n getFrameEntries() {\n return SequenceTimeline.ENTRIES;\n }\n getSlotIndex() {\n return this.slotIndex;\n }\n getAttachment() {\n return this.attachment;\n }\n /** Sets the time, mode, index, and frame time for the specified frame.\n * @param frame Between 0 and frameCount, inclusive.\n * @param time Seconds between frames. */\n setFrame(frame, time, mode, index, delay) {\n let frames = this.frames;\n frame *= SequenceTimeline.ENTRIES;\n frames[frame] = time;\n frames[frame + SequenceTimeline.MODE] = mode | (index << 4);\n frames[frame + SequenceTimeline.DELAY] = delay;\n }\n apply(skeleton, lastTime, time, events, alpha, blend, direction) {\n let slot = skeleton.slots[this.slotIndex];\n if (!slot.bone.active)\n return;\n let slotAttachment = slot.attachment;\n let attachment = this.attachment;\n if (slotAttachment != attachment) {\n if (!(slotAttachment instanceof VertexAttachment)\n || slotAttachment.timelineAttachment != attachment)\n return;\n }\n let frames = this.frames;\n if (time < frames[0]) {\n if (blend == MixBlend.setup || blend == MixBlend.first)\n slot.sequenceIndex = -1;\n return;\n }\n let i = Timeline.search(frames, time, SequenceTimeline.ENTRIES);\n let before = frames[i];\n let modeAndIndex = frames[i + SequenceTimeline.MODE];\n let delay = frames[i + SequenceTimeline.DELAY];\n if (!this.attachment.sequence)\n return;\n let index = modeAndIndex >> 4, count = this.attachment.sequence.regions.length;\n let mode = SequenceModeValues[modeAndIndex & 0xf];\n if (mode != SequenceMode.hold) {\n index += (((time - before) / delay + 0.00001) | 0);\n switch (mode) {\n case SequenceMode.once:\n index = Math.min(count - 1, index);\n break;\n case SequenceMode.loop:\n index %= count;\n break;\n case SequenceMode.pingpong: {\n let n = (count << 1) - 2;\n index = n == 0 ? 0 : index % n;\n if (index >= count)\n index = n - index;\n break;\n }\n case SequenceMode.onceReverse:\n index = Math.max(count - 1 - index, 0);\n break;\n case SequenceMode.loopReverse:\n index = count - 1 - (index % count);\n break;\n case SequenceMode.pingpongReverse: {\n let n = (count << 1) - 2;\n index = n == 0 ? 0 : (index + count - 1) % n;\n if (index >= count)\n index = n - index;\n }\n }\n }\n slot.sequenceIndex = index;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQW5pbWF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0FuaW1hdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUFFLGdCQUFnQixFQUFjLE1BQU0sNkJBQTZCLENBQUM7QUFNM0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFtQixNQUFNLFlBQVksQ0FBQztBQUcxRSxPQUFPLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFJN0UsNkRBQTZEO0FBQzdELE1BQU0sT0FBTyxTQUFTO0lBQ3JCLG1GQUFtRjtJQUNuRixJQUFJLENBQVM7SUFDYixTQUFTLEdBQW9CLEVBQUUsQ0FBQztJQUNoQyxXQUFXLEdBQWMsSUFBSSxTQUFTLEVBQUUsQ0FBQztJQUV6Qyx1R0FBdUc7SUFDdkcsUUFBUSxDQUFTO0lBRWpCLFlBQWEsSUFBWSxFQUFFLFNBQTBCLEVBQUUsUUFBZ0I7UUFDdEUsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMxQixDQUFDO0lBRUQsWUFBWSxDQUFFLFNBQTBCO1FBQ3ZDLElBQUksQ0FBQyxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQzNCLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMs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QUFDLENBQUM7Z0JBQ3BHLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBLFVBQVUsRUFBRSxTQUFTLEdBQUcsRUFBRSxDQUFBLGVBQWUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBLFVBQVUsQ0FBQyxDQUFDO1NBQ3JHO1FBRUQsSUFBSSxLQUFLLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRTtZQUM1QixJQUFJLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDO1lBQzNCLFVBQVUsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQzFFLFVBQVUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQ3RELFVBQVUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQ3RELFVBQVUsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQzFFLFVBQVUsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQzFFLFVBQVUsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDO1NBQzFFO2FBQU07WUFDTixVQUFVLENBQUMsU0FBUyxJQUFJLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsR0FBRyxLQUFLLENBQUM7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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Animation, MixBlend, AttachmentTimeline, MixDirection, RotateTimeline, DrawOrderTimeline, Timeline, EventTimeline } from \"./Animation.js\";\nimport { StringSet, Pool, Utils, MathUtils } from \"./Utils.js\";\n/** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies\n * multiple animations on top of each other (layering).\n *\n * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */\nexport class AnimationState {\n static _emptyAnimation = new Animation(\"\", [], 0);\n static emptyAnimation() {\n return AnimationState._emptyAnimation;\n }\n /** The AnimationStateData to look up mix durations. */\n data;\n /** The list of tracks that currently have animations, which may contain null entries. */\n tracks = new Array();\n /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower\n * or faster. Defaults to 1.\n *\n * See TrackEntry {@link TrackEntry#timeScale} for affecting a single animation. */\n timeScale = 1;\n unkeyedState = 0;\n events = new Array();\n listeners = new Array();\n queue = new EventQueue(this);\n propertyIDs = new StringSet();\n animationsChanged = false;\n trackEntryPool = new Pool(() => new TrackEntry());\n constructor(data) {\n this.data = data;\n }\n /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */\n update(delta) {\n delta *= this.timeScale;\n let tracks = this.tracks;\n for (let i = 0, n = tracks.length; i < n; i++) {\n let current = tracks[i];\n if (!current)\n continue;\n current.animationLast = current.nextAnimationLast;\n current.trackLast = current.nextTrackLast;\n let currentDelta = delta * current.timeScale;\n if (current.delay > 0) {\n current.delay -= currentDelta;\n if (current.delay > 0)\n continue;\n currentDelta = -current.delay;\n current.delay = 0;\n }\n let next = current.next;\n if (next) {\n // When the next entry's delay is passed, change to the next entry, preserving leftover time.\n let nextTime = current.trackLast - next.delay;\n if (nextTime >= 0) {\n next.delay = 0;\n next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale;\n current.trackTime += currentDelta;\n this.setCurrent(i, next, true);\n while (next.mixingFrom) {\n next.mixTime += delta;\n next = next.mixingFrom;\n }\n continue;\n }\n }\n else if (current.trackLast >= current.trackEnd && !current.mixingFrom) {\n tracks[i] = null;\n this.queue.end(current);\n this.clearNext(current);\n continue;\n }\n if (current.mixingFrom && this.updateMixingFrom(current, delta)) {\n // End mixing from entries once all have completed.\n let from = current.mixingFrom;\n current.mixingFrom = null;\n if (from)\n from.mixingTo = null;\n while (from) {\n this.queue.end(from);\n from = from.mixingFrom;\n }\n }\n current.trackTime += currentDelta;\n }\n this.queue.drain();\n }\n /** Returns true when all mixing from entries are complete. */\n updateMixingFrom(to, delta) {\n let from = to.mixingFrom;\n if (!from)\n return true;\n let finished = this.updateMixingFrom(from, delta);\n from.animationLast = from.nextAnimationLast;\n from.trackLast = from.nextTrackLast;\n // Require mixTime > 0 to ensure the mixing from entry was applied at least once.\n if (to.mixTime > 0 && to.mixTime >= to.mixDuration) {\n // Require totalAlpha == 0 to ensure mixing is complete, unless mixDuration == 0 (the transition is a single frame).\n if (from.totalAlpha == 0 || to.mixDuration == 0) {\n to.mixingFrom = from.mixingFrom;\n if (from.mixingFrom)\n from.mixingFrom.mixingTo = to;\n to.interruptAlpha = from.interruptAlpha;\n this.queue.end(from);\n }\n return finished;\n }\n from.trackTime += delta * from.timeScale;\n to.mixTime += delta;\n return false;\n }\n /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the\n * animation state can be applied to multiple skeletons to pose them identically.\n * @returns True if any animations were applied. */\n apply(skeleton) {\n if (!skeleton)\n throw new Error(\"skeleton cannot be null.\");\n if (this.animationsChanged)\n this._animationsChanged();\n let events = this.events;\n let tracks = this.tracks;\n let applied = false;\n for (let i = 0, n = tracks.length; i < n; i++) {\n let current = tracks[i];\n if (!current || current.delay > 0)\n continue;\n applied = true;\n let blend = i == 0 ? MixBlend.first : current.mixBlend;\n // Apply mixing from entries first.\n let alpha = current.alpha;\n if (current.mixingFrom)\n alpha *= this.applyMixingFrom(current, skeleton, blend);\n else if (current.trackTime >= current.trackEnd && !current.next)\n alpha = 0;\n let attachments = alpha >= current.alphaAttachmentThreshold;\n // Apply current entry.\n let animationLast = current.animationLast, animationTime = current.getAnimationTime(), applyTime = animationTime;\n let applyEvents = events;\n if (current.reverse) {\n applyTime = current.animation.duration - applyTime;\n applyEvents = null;\n }\n let timelines = current.animation.timelines;\n let timelineCount = timelines.length;\n if ((i == 0 && alpha == 1) || blend == MixBlend.add) {\n if (i == 0)\n attachments = true;\n for (let ii = 0; ii < timelineCount; ii++) {\n // Fixes issue #302 on IOS9 where mix, blend sometimes became undefined and caused assets\n // to sometimes stop rendering when using color correction, as their RGBA values become NaN.\n // (https://github.com/pixijs/pixi-spine/issues/302)\n Utils.webkit602BugfixHelper(alpha, blend);\n var timeline = timelines[ii];\n if (timeline instanceof AttachmentTimeline)\n this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, attachments);\n else\n timeline.apply(skeleton, animationLast, applyTime, applyEvents, alpha, blend, MixDirection.mixIn);\n }\n }\n else {\n let timelineMode = current.timelineMode;\n let shortestRotation = current.shortestRotation;\n let firstFrame = !shortestRotation && current.timelinesRotation.length != timelineCount << 1;\n if (firstFrame)\n current.timelinesRotation.length = timelineCount << 1;\n for (let ii = 0; ii < timelineCount; ii++) {\n let timeline = timelines[ii];\n let timelineBlend = timelineMode[ii] == SUBSEQUENT ? blend : MixBlend.setup;\n if (!shortestRotation && timeline instanceof RotateTimeline) {\n this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, current.timelinesRotation, ii << 1, firstFrame);\n }\n else if (timeline instanceof AttachmentTimeline) {\n this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, attachments);\n }\n else {\n // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109\n Utils.webkit602BugfixHelper(alpha, blend);\n timeline.apply(skeleton, animationLast, applyTime, applyEvents, alpha, timelineBlend, MixDirection.mixIn);\n }\n }\n }\n this.queueEvents(current, animationTime);\n events.length = 0;\n current.nextAnimationLast = animationTime;\n current.nextTrackLast = current.trackTime;\n }\n // Set slots attachments to the setup pose, if needed. This occurs if an animation that is mixing out sets attachments so\n // subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or\n // the time is before the first key).\n var setupState = this.unkeyedState + SETUP;\n var slots = skeleton.slots;\n for (var i = 0, n = skeleton.slots.length; i < n; i++) {\n var slot = slots[i];\n if (slot.attachmentState == setupState) {\n var attachmentName = slot.data.attachmentName;\n slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName));\n }\n }\n this.unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot.\n this.queue.drain();\n return applied;\n }\n applyMixingFrom(to, skeleton, blend) {\n let from = to.mixingFrom;\n if (from.mixingFrom)\n this.applyMixingFrom(from, skeleton, blend);\n let mix = 0;\n if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes.\n mix = 1;\n if (blend == MixBlend.first)\n blend = MixBlend.setup;\n }\n else {\n mix = to.mixTime / to.mixDuration;\n if (mix > 1)\n mix = 1;\n if (blend != MixBlend.first)\n blend = from.mixBlend;\n }\n let attachments = mix < from.mixAttachmentThreshold, drawOrder = mix < from.mixDrawOrderThreshold;\n let timelines = from.animation.timelines;\n let timelineCount = timelines.length;\n let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);\n let animationLast = from.animationLast, animationTime = from.getAnimationTime(), applyTime = animationTime;\n let events = null;\n if (from.reverse)\n applyTime = from.animation.duration - applyTime;\n else if (mix < from.eventThreshold)\n events = this.events;\n if (blend == MixBlend.add) {\n for (let i = 0; i < timelineCount; i++)\n timelines[i].apply(skeleton, animationLast, applyTime, events, alphaMix, blend, MixDirection.mixOut);\n }\n else {\n let timelineMode = from.timelineMode;\n let timelineHoldMix = from.timelineHoldMix;\n let shortestRotation = from.shortestRotation;\n let firstFrame = !shortestRotation && from.timelinesRotation.length != timelineCount << 1;\n if (firstFrame)\n from.timelinesRotation.length = timelineCount << 1;\n from.totalAlpha = 0;\n for (let i = 0; i < timelineCount; i++) {\n let timeline = timelines[i];\n let direction = MixDirection.mixOut;\n let timelineBlend;\n let alpha = 0;\n switch (timelineMode[i]) {\n case SUBSEQUENT:\n if (!drawOrder && timeline instanceof DrawOrderTimeline)\n continue;\n timelineBlend = blend;\n alpha = alphaMix;\n break;\n case FIRST:\n timelineBlend = MixBlend.setup;\n alpha = alphaMix;\n break;\n case HOLD_SUBSEQUENT:\n timelineBlend = blend;\n alpha = alphaHold;\n break;\n case HOLD_FIRST:\n timelineBlend = MixBlend.setup;\n alpha = alphaHold;\n break;\n default:\n timelineBlend = MixBlend.setup;\n let holdMix = timelineHoldMix[i];\n alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);\n break;\n }\n from.totalAlpha += alpha;\n if (!shortestRotation && timeline instanceof RotateTimeline)\n this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, from.timelinesRotation, i << 1, firstFrame);\n else if (timeline instanceof AttachmentTimeline)\n this.applyAttachmentTimeline(timeline, skeleton, applyTime, timelineBlend, attachments && alpha >= from.alphaAttachmentThreshold);\n else {\n // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109\n Utils.webkit602BugfixHelper(alpha, blend);\n if (drawOrder && timeline instanceof DrawOrderTimeline && timelineBlend == MixBlend.setup)\n direction = MixDirection.mixIn;\n timeline.apply(skeleton, animationLast, applyTime, events, alpha, timelineBlend, direction);\n }\n }\n }\n if (to.mixDuration > 0)\n this.queueEvents(from, animationTime);\n this.events.length = 0;\n from.nextAnimationLast = animationTime;\n from.nextTrackLast = from.trackTime;\n return mix;\n }\n applyAttachmentTimeline(timeline, skeleton, time, blend, attachments) {\n var slot = skeleton.slots[timeline.slotIndex];\n if (!slot.bone.active)\n return;\n if (time < timeline.frames[0]) { // Time is before first frame.\n if (blend == MixBlend.setup || blend == MixBlend.first)\n this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments);\n }\n else\n this.setAttachment(skeleton, slot, timeline.attachmentNames[Timeline.search1(timeline.frames, time)], attachments);\n // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later.\n if (slot.attachmentState <= this.unkeyedState)\n slot.attachmentState = this.unkeyedState + SETUP;\n }\n setAttachment(skeleton, slot, attachmentName, attachments) {\n slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName));\n if (attachments)\n slot.attachmentState = this.unkeyedState + CURRENT;\n }\n applyRotateTimeline(timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) {\n if (firstFrame)\n timelinesRotation[i] = 0;\n if (alpha == 1) {\n timeline.apply(skeleton, 0, time, null, 1, blend, MixDirection.mixIn);\n return;\n }\n let bone = skeleton.bones[timeline.boneIndex];\n if (!bone.active)\n return;\n let frames = timeline.frames;\n let r1 = 0, r2 = 0;\n if (time < frames[0]) {\n switch (blend) {\n case MixBlend.setup:\n bone.rotation = bone.data.rotation;\n default:\n return;\n case MixBlend.first:\n r1 = bone.rotation;\n r2 = bone.data.rotation;\n }\n }\n else {\n r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;\n r2 = bone.data.rotation + timeline.getCurveValue(time);\n }\n // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.\n let total = 0, diff = r2 - r1;\n diff -= Math.ceil(diff / 360 - 0.5) * 360;\n if (diff == 0) {\n total = timelinesRotation[i];\n }\n else {\n let lastTotal = 0, lastDiff = 0;\n if (firstFrame) {\n lastTotal = 0;\n lastDiff = diff;\n }\n else {\n lastTotal = timelinesRotation[i];\n lastDiff = timelinesRotation[i + 1];\n }\n let loops = lastTotal - lastTotal % 360;\n total = diff + loops;\n let current = diff >= 0, dir = lastTotal >= 0;\n if (Math.abs(lastDiff) <= 90 && MathUtils.signum(lastDiff) != MathUtils.signum(diff)) {\n if (Math.abs(lastTotal - loops) > 180) {\n total += 360 * MathUtils.signum(lastTotal);\n dir = current;\n }\n else if (loops != 0)\n total -= 360 * MathUtils.signum(lastTotal);\n else\n dir = current;\n }\n if (dir != current)\n total += 360 * MathUtils.signum(lastTotal);\n timelinesRotation[i] = total;\n }\n timelinesRotation[i + 1] = diff;\n bone.rotation = r1 + total * alpha;\n }\n queueEvents(entry, animationTime) {\n let animationStart = entry.animationStart, animationEnd = entry.animationEnd;\n let duration = animationEnd - animationStart;\n let trackLastWrapped = entry.trackLast % duration;\n // Queue events before complete.\n let events = this.events;\n let i = 0, n = events.length;\n for (; i < n; i++) {\n let event = events[i];\n if (event.time < trackLastWrapped)\n break;\n if (event.time > animationEnd)\n continue; // Discard events outside animation start/end.\n this.queue.event(entry, event);\n }\n // Queue complete if completed a loop iteration or the animation.\n let complete = false;\n if (entry.loop)\n complete = duration == 0 || trackLastWrapped > entry.trackTime % duration;\n else\n complete = animationTime >= animationEnd && entry.animationLast < animationEnd;\n if (complete)\n this.queue.complete(entry);\n // Queue events after complete.\n for (; i < n; i++) {\n let event = events[i];\n if (event.time < animationStart)\n continue; // Discard events outside animation start/end.\n this.queue.event(entry, event);\n }\n }\n /** Removes all animations from all tracks, leaving skeletons in their current pose.\n *\n * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose,\n * rather than leaving them in their current pose. */\n clearTracks() {\n let oldDrainDisabled = this.queue.drainDisabled;\n this.queue.drainDisabled = true;\n for (let i = 0, n = this.tracks.length; i < n; i++)\n this.clearTrack(i);\n this.tracks.length = 0;\n this.queue.drainDisabled = oldDrainDisabled;\n this.queue.drain();\n }\n /** Removes all animations from the track, leaving skeletons in their current pose.\n *\n * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose,\n * rather than leaving them in their current pose. */\n clearTrack(trackIndex) {\n if (trackIndex >= this.tracks.length)\n return;\n let current = this.tracks[trackIndex];\n if (!current)\n return;\n this.queue.end(current);\n this.clearNext(current);\n let entry = current;\n while (true) {\n let from = entry.mixingFrom;\n if (!from)\n break;\n this.queue.end(from);\n entry.mixingFrom = null;\n entry.mixingTo = null;\n entry = from;\n }\n this.tracks[current.trackIndex] = null;\n this.queue.drain();\n }\n setCurrent(index, current, interrupt) {\n let from = this.expandToIndex(index);\n this.tracks[index] = current;\n current.previous = null;\n if (from) {\n if (interrupt)\n this.queue.interrupt(from);\n current.mixingFrom = from;\n from.mixingTo = current;\n current.mixTime = 0;\n // Store the interrupted mix percentage.\n if (from.mixingFrom && from.mixDuration > 0)\n current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);\n from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in.\n }\n this.queue.start(current);\n }\n /** Sets an animation by name.\n *\n * See {@link #setAnimationWith()}. */\n setAnimation(trackIndex, animationName, loop = false) {\n let animation = this.data.skeletonData.findAnimation(animationName);\n if (!animation)\n throw new Error(\"Animation not found: \" + animationName);\n return this.setAnimationWith(trackIndex, animation, loop);\n }\n /** Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never\n * applied to a skeleton, it is replaced (not mixed from).\n * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its\n * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared.\n * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept\n * after the {@link AnimationStateListener#dispose()} event occurs. */\n setAnimationWith(trackIndex, animation, loop = false) {\n if (!animation)\n throw new Error(\"animation cannot be null.\");\n let interrupt = true;\n let current = this.expandToIndex(trackIndex);\n if (current) {\n if (current.nextTrackLast == -1) {\n // Don't mix from an entry that was never applied.\n this.tracks[trackIndex] = current.mixingFrom;\n this.queue.interrupt(current);\n this.queue.end(current);\n this.clearNext(current);\n current = current.mixingFrom;\n interrupt = false;\n }\n else\n this.clearNext(current);\n }\n let entry = this.trackEntry(trackIndex, animation, loop, current);\n this.setCurrent(trackIndex, entry, interrupt);\n this.queue.drain();\n return entry;\n }\n /** Queues an animation by name.\n *\n * See {@link #addAnimationWith()}. */\n addAnimation(trackIndex, animationName, loop = false, delay = 0) {\n let animation = this.data.skeletonData.findAnimation(animationName);\n if (!animation)\n throw new Error(\"Animation not found: \" + animationName);\n return this.addAnimationWith(trackIndex, animation, loop, delay);\n }\n /** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is\n * equivalent to calling {@link #setAnimationWith()}.\n * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry\n * minus any mix duration (from the {@link AnimationStateData}) plus the specified `delay` (ie the mix\n * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the\n * previous entry is looping, its next loop completion is used instead of its duration.\n * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept\n * after the {@link AnimationStateListener#dispose()} event occurs. */\n addAnimationWith(trackIndex, animation, loop = false, delay = 0) {\n if (!animation)\n throw new Error(\"animation cannot be null.\");\n let last = this.expandToIndex(trackIndex);\n if (last) {\n while (last.next)\n last = last.next;\n }\n let entry = this.trackEntry(trackIndex, animation, loop, last);\n if (!last) {\n this.setCurrent(trackIndex, entry, true);\n this.queue.drain();\n }\n else {\n last.next = entry;\n entry.previous = last;\n if (delay <= 0)\n delay += last.getTrackComplete() - entry.mixDuration;\n }\n entry.delay = delay;\n return entry;\n }\n /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's\n * {@link TrackEntry#mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out.\n *\n * Mixing out is done by setting an empty animation with a mix duration using either {@link #setEmptyAnimation()},\n * {@link #setEmptyAnimations()}, or {@link #addEmptyAnimation()}. Mixing to an empty animation causes\n * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation\n * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of\n * 0 still mixes out over one frame.\n *\n * Mixing in is done by first setting an empty animation, then adding an animation using\n * {@link #addAnimation()} and on the returned track entry, set the\n * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and\n * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the\n * setup pose value if no lower tracks key the property to the value keyed in the new animation. */\n setEmptyAnimation(trackIndex, mixDuration = 0) {\n let entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation(), false);\n entry.mixDuration = mixDuration;\n entry.trackEnd = mixDuration;\n return entry;\n }\n /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's\n * {@link TrackEntry#mixDuration}. If the track is empty, it is equivalent to calling\n * {@link #setEmptyAnimation()}.\n *\n * See {@link #setEmptyAnimation()}.\n * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry\n * minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or\n * before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next\n * loop completion is used instead of its duration.\n * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept\n * after the {@link AnimationStateListener#dispose()} event occurs. */\n addEmptyAnimation(trackIndex, mixDuration = 0, delay = 0) {\n let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation(), false, delay);\n if (delay <= 0)\n entry.delay += entry.mixDuration - mixDuration;\n entry.mixDuration = mixDuration;\n entry.trackEnd = mixDuration;\n return entry;\n }\n /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix\n * duration. */\n setEmptyAnimations(mixDuration = 0) {\n let oldDrainDisabled = this.queue.drainDisabled;\n this.queue.drainDisabled = true;\n for (let i = 0, n = this.tracks.length; i < n; i++) {\n let current = this.tracks[i];\n if (current)\n this.setEmptyAnimation(current.trackIndex, mixDuration);\n }\n this.queue.drainDisabled = oldDrainDisabled;\n this.queue.drain();\n }\n expandToIndex(index) {\n if (index < this.tracks.length)\n return this.tracks[index];\n Utils.ensureArrayCapacity(this.tracks, index + 1, null);\n this.tracks.length = index + 1;\n return null;\n }\n /** @param last May be null. */\n trackEntry(trackIndex, animation, loop, last) {\n let entry = this.trackEntryPool.obtain();\n entry.reset();\n entry.trackIndex = trackIndex;\n entry.animation = animation;\n entry.loop = loop;\n entry.holdPrevious = false;\n entry.reverse = false;\n entry.shortestRotation = false;\n entry.eventThreshold = 0;\n entry.alphaAttachmentThreshold = 0;\n entry.mixAttachmentThreshold = 0;\n entry.mixDrawOrderThreshold = 0;\n entry.animationStart = 0;\n entry.animationEnd = animation.duration;\n entry.animationLast = -1;\n entry.nextAnimationLast = -1;\n entry.delay = 0;\n entry.trackTime = 0;\n entry.trackLast = -1;\n entry.nextTrackLast = -1;\n entry.trackEnd = Number.MAX_VALUE;\n entry.timeScale = 1;\n entry.alpha = 1;\n entry.mixTime = 0;\n entry.mixDuration = !last ? 0 : this.data.getMix(last.animation, animation);\n entry.interruptAlpha = 1;\n entry.totalAlpha = 0;\n entry.mixBlend = MixBlend.replace;\n return entry;\n }\n /** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */\n clearNext(entry) {\n let next = entry.next;\n while (next) {\n this.queue.dispose(next);\n next = next.next;\n }\n entry.next = null;\n }\n _animationsChanged() {\n this.animationsChanged = false;\n this.propertyIDs.clear();\n let tracks = this.tracks;\n for (let i = 0, n = tracks.length; i < n; i++) {\n let entry = tracks[i];\n if (!entry)\n continue;\n while (entry.mixingFrom)\n entry = entry.mixingFrom;\n do {\n if (!entry.mixingTo || entry.mixBlend != MixBlend.add)\n this.computeHold(entry);\n entry = entry.mixingTo;\n } while (entry);\n }\n }\n computeHold(entry) {\n let to = entry.mixingTo;\n let timelines = entry.animation.timelines;\n let timelinesCount = entry.animation.timelines.length;\n let timelineMode = entry.timelineMode;\n timelineMode.length = timelinesCount;\n let timelineHoldMix = entry.timelineHoldMix;\n timelineHoldMix.length = 0;\n let propertyIDs = this.propertyIDs;\n if (to && to.holdPrevious) {\n for (let i = 0; i < timelinesCount; i++)\n timelineMode[i] = propertyIDs.addAll(timelines[i].getPropertyIds()) ? HOLD_FIRST : HOLD_SUBSEQUENT;\n return;\n }\n outer: for (let i = 0; i < timelinesCount; i++) {\n let timeline = timelines[i];\n let ids = timeline.getPropertyIds();\n if (!propertyIDs.addAll(ids))\n timelineMode[i] = SUBSEQUENT;\n else if (!to || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline\n || timeline instanceof EventTimeline || !to.animation.hasTimeline(ids)) {\n timelineMode[i] = FIRST;\n }\n else {\n for (let next = to.mixingTo; next; next = next.mixingTo) {\n if (next.animation.hasTimeline(ids))\n continue;\n if (entry.mixDuration > 0) {\n timelineMode[i] = HOLD_MIX;\n timelineHoldMix[i] = next;\n continue outer;\n }\n break;\n }\n timelineMode[i] = HOLD_FIRST;\n }\n }\n }\n /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */\n getCurrent(trackIndex) {\n if (trackIndex >= this.tracks.length)\n return null;\n return this.tracks[trackIndex];\n }\n /** Adds a listener to receive events for all track entries. */\n addListener(listener) {\n if (!listener)\n throw new Error(\"listener cannot be null.\");\n this.listeners.push(listener);\n }\n /** Removes the listener added with {@link #addListener()}. */\n removeListener(listener) {\n let index = this.listeners.indexOf(listener);\n if (index >= 0)\n this.listeners.splice(index, 1);\n }\n /** Removes all listeners added with {@link #addListener()}. */\n clearListeners() {\n this.listeners.length = 0;\n }\n /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an\n * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery\n * are not wanted because new animations are being set. */\n clearListenerNotifications() {\n this.queue.clear();\n }\n}\n/** Stores settings and other state for the playback of an animation on an {@link AnimationState} track.\n *\n * References to a track entry must not be kept after the {@link AnimationStateListener#dispose()} event occurs. */\nexport class TrackEntry {\n /** The animation to apply for this track entry. */\n animation = null;\n previous = null;\n /** The animation queued to start after this animation, or null. `next` makes up a linked list. */\n next = null;\n /** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no\n * mixing is currently occuring. When mixing from multiple animations, `mixingFrom` makes up a linked list. */\n mixingFrom = null;\n /** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is\n * currently occuring. When mixing to multiple animations, `mixingTo` makes up a linked list. */\n mixingTo = null;\n /** The listener for events generated by this track entry, or null.\n *\n * A track entry returned from {@link AnimationState#setAnimation()} is already the current animation\n * for the track, so the track entry listener {@link AnimationStateListener#start()} will not be called. */\n listener = null;\n /** The index of the track where this track entry is either current or queued.\n *\n * See {@link AnimationState#getCurrent()}. */\n trackIndex = 0;\n /** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its\n * duration. */\n loop = false;\n /** If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead\n * of being mixed out.\n *\n * When mixing between animations that key the same property, if a lower track also keys that property then the value will\n * briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0%\n * while the second animation mixes from 0% to 100%. Setting `holdPrevious` to true applies the first animation\n * at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which\n * keys the property, only when a higher track also keys the property.\n *\n * Snapping will occur if `holdPrevious` is true and this animation does not key all the same properties as the\n * previous animation. */\n holdPrevious = false;\n reverse = false;\n shortestRotation = false;\n /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the\n * `eventThreshold`, event timelines are applied while this animation is being mixed out. Defaults to 0, so event\n * timelines are not applied while this animation is being mixed out. */\n eventThreshold = 0;\n /** When the mix percentage ({@link #mixtime} / {@link #mixDuration}) is less than the\n * `attachmentThreshold`, attachment timelines are applied while this animation is being mixed out. Defaults to\n * 0, so attachment timelines are not applied while this animation is being mixed out. */\n mixAttachmentThreshold = 0;\n /** When {@link #getAlpha()} is greater than alphaAttachmentThreshold, attachment timelines are applied.\n * Defaults to 0, so attachment timelines are always applied. */\n alphaAttachmentThreshold = 0;\n /** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the\n * mixDrawOrderThreshold, draw order timelines are applied while this animation is being mixed out. Defaults to\n * 0, so draw order timelines are not applied while this animation is being mixed out. */\n mixDrawOrderThreshold = 0;\n /** Seconds when this animation starts, both initially and after looping. Defaults to 0.\n *\n * When changing the `animationStart` time, it often makes sense to set {@link #animationLast} to the same\n * value to prevent timeline keys before the start time from triggering. */\n animationStart = 0;\n /** Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will\n * loop back to {@link #animationStart} at this time. Defaults to the animation {@link Animation#duration}. */\n animationEnd = 0;\n /** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this\n * animation is applied, event timelines will fire all events between the `animationLast` time (exclusive) and\n * `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation\n * is applied. */\n animationLast = 0;\n nextAnimationLast = 0;\n /** Seconds to postpone playing the animation. When this track entry is the current track entry, `delay`\n * postpones incrementing the {@link #trackTime}. When this track entry is queued, `delay` is the time from\n * the start of the previous animation to when this track entry will become the current track entry (ie when the previous\n * track entry {@link TrackEntry#trackTime} >= this track entry's `delay`).\n *\n * {@link #timeScale} affects the delay. */\n delay = 0;\n /** Current time in seconds this track entry has been the current track entry. The track time determines\n * {@link #animationTime}. The track time can be set to start the animation at a time other than 0, without affecting\n * looping. */\n trackTime = 0;\n trackLast = 0;\n nextTrackLast = 0;\n /** The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float\n * value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time\n * is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the\n * properties keyed by the animation are set to the setup pose and the track is cleared.\n *\n * It may be desired to use {@link AnimationState#addEmptyAnimation()} rather than have the animation\n * abruptly cease being applied. */\n trackEnd = 0;\n /** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or\n * faster. Defaults to 1.\n *\n * {@link #mixTime} is not affected by track entry time scale, so {@link #mixDuration} may need to be adjusted to\n * match the animation speed.\n *\n * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the\n * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, assuming time scale to be 1. If\n * the time scale is not 1, the delay may need to be adjusted.\n *\n * See AnimationState {@link AnimationState#timeScale} for affecting all animations. */\n timeScale = 0;\n /** Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults\n * to 1, which overwrites the skeleton's current pose with this animation.\n *\n * Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to\n * use alpha on track 0 if the skeleton pose is from the last frame render. */\n alpha = 0;\n /** Seconds from 0 to the {@link #getMixDuration()} when mixing from the previous animation to this animation. May be\n * slightly more than `mixDuration` when the mix is complete. */\n mixTime = 0;\n /** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData\n * {@link AnimationStateData#getMix()} based on the animation before this animation (if any).\n *\n * A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the\n * properties it was animating.\n *\n * The `mixDuration` can be set manually rather than use the value from\n * {@link AnimationStateData#getMix()}. In that case, the `mixDuration` can be set for a new\n * track entry only before {@link AnimationState#update(float)} is first called.\n *\n * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the\n * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, not a mix duration set\n * afterward. */\n _mixDuration = 0;\n interruptAlpha = 0;\n totalAlpha = 0;\n get mixDuration() {\n return this._mixDuration;\n }\n set mixDuration(mixDuration) {\n this._mixDuration = mixDuration;\n if (this.previous != null && this.delay <= 0)\n this.delay += this.previous.getTrackComplete() - mixDuration;\n this.delay = this.delay;\n }\n /** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}, which\n * replaces the values from the lower tracks with the animation values. {@link MixBlend#add} adds the animation values to\n * the values from the lower tracks.\n *\n * The `mixBlend` can be set for a new track entry only before {@link AnimationState#apply()} is first\n * called. */\n mixBlend = MixBlend.replace;\n timelineMode = new Array();\n timelineHoldMix = new Array();\n timelinesRotation = new Array();\n reset() {\n this.next = null;\n this.previous = null;\n this.mixingFrom = null;\n this.mixingTo = null;\n this.animation = null;\n this.listener = null;\n this.timelineMode.length = 0;\n this.timelineHoldMix.length = 0;\n this.timelinesRotation.length = 0;\n }\n /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart}\n * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the\n * `animationStart` time. */\n getAnimationTime() {\n if (this.loop) {\n let duration = this.animationEnd - this.animationStart;\n if (duration == 0)\n return this.animationStart;\n return (this.trackTime % duration) + this.animationStart;\n }\n return Math.min(this.trackTime + this.animationStart, this.animationEnd);\n }\n setAnimationLast(animationLast) {\n this.animationLast = animationLast;\n this.nextAnimationLast = animationLast;\n }\n /** Returns true if at least one loop has been completed.\n *\n * See {@link AnimationStateListener#complete()}. */\n isComplete() {\n return this.trackTime >= this.animationEnd - this.animationStart;\n }\n /** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the\n * long way around when using {@link #alpha} and starting animations on other tracks.\n *\n * Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions:\n * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long\n * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the\n * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */\n resetRotationDirections() {\n this.timelinesRotation.length = 0;\n }\n getTrackComplete() {\n let duration = this.animationEnd - this.animationStart;\n if (duration != 0) {\n if (this.loop)\n return duration * (1 + ((this.trackTime / duration) | 0)); // Completion of next loop.\n if (this.trackTime < duration)\n return duration; // Before duration.\n }\n return this.trackTime; // Next update.\n }\n /** Returns true if this track entry has been applied at least once.\n *

\n * See {@link AnimationState#apply(Skeleton)}. */\n wasApplied() {\n return this.nextTrackLast != -1;\n }\n}\nexport class EventQueue {\n objects = [];\n drainDisabled = false;\n animState;\n constructor(animState) {\n this.animState = animState;\n }\n start(entry) {\n this.objects.push(EventType.start);\n this.objects.push(entry);\n this.animState.animationsChanged = true;\n }\n interrupt(entry) {\n this.objects.push(EventType.interrupt);\n this.objects.push(entry);\n }\n end(entry) {\n this.objects.push(EventType.end);\n this.objects.push(entry);\n this.animState.animationsChanged = true;\n }\n dispose(entry) {\n this.objects.push(EventType.dispose);\n this.objects.push(entry);\n }\n complete(entry) {\n this.objects.push(EventType.complete);\n this.objects.push(entry);\n }\n event(entry, event) {\n this.objects.push(EventType.event);\n this.objects.push(entry);\n this.objects.push(event);\n }\n drain() {\n if (this.drainDisabled)\n return;\n this.drainDisabled = true;\n let objects = this.objects;\n let listeners = this.animState.listeners;\n for (let i = 0; i < objects.length; i += 2) {\n let type = objects[i];\n let entry = objects[i + 1];\n switch (type) {\n case EventType.start:\n if (entry.listener && entry.listener.start)\n entry.listener.start(entry);\n for (let ii = 0; ii < listeners.length; ii++) {\n let listener = listeners[ii];\n if (listener.start)\n listener.start(entry);\n }\n break;\n case EventType.interrupt:\n if (entry.listener && entry.listener.interrupt)\n entry.listener.interrupt(entry);\n for (let ii = 0; ii < listeners.length; ii++) {\n let listener = listeners[ii];\n if (listener.interrupt)\n listener.interrupt(entry);\n }\n break;\n case EventType.end:\n if (entry.listener && entry.listener.end)\n entry.listener.end(entry);\n for (let ii = 0; ii < listeners.length; ii++) {\n let listener = listeners[ii];\n if (listener.end)\n listener.end(entry);\n }\n // Fall through.\n case EventType.dispose:\n if (entry.listener && entry.listener.dispose)\n entry.listener.dispose(entry);\n for (let ii = 0; ii < listeners.length; ii++) {\n let listener = listeners[ii];\n if (listener.dispose)\n listener.dispose(entry);\n }\n this.animState.trackEntryPool.free(entry);\n break;\n case EventType.complete:\n if (entry.listener && entry.listener.complete)\n entry.listener.complete(entry);\n for (let ii = 0; ii < listeners.length; ii++) {\n let listener = listeners[ii];\n if (listener.complete)\n listener.complete(entry);\n }\n break;\n case EventType.event:\n let event = objects[i++ + 2];\n if (entry.listener && entry.listener.event)\n entry.listener.event(entry, event);\n for (let ii = 0; ii < listeners.length; ii++) {\n let listener = listeners[ii];\n if (listener.event)\n listener.event(entry, event);\n }\n break;\n }\n }\n this.clear();\n this.drainDisabled = false;\n }\n clear() {\n this.objects.length = 0;\n }\n}\nexport var EventType;\n(function (EventType) {\n EventType[EventType[\"start\"] = 0] = \"start\";\n EventType[EventType[\"interrupt\"] = 1] = \"interrupt\";\n EventType[EventType[\"end\"] = 2] = \"end\";\n EventType[EventType[\"dispose\"] = 3] = \"dispose\";\n EventType[EventType[\"complete\"] = 4] = \"complete\";\n EventType[EventType[\"event\"] = 5] = \"event\";\n})(EventType || (EventType = {}));\nexport class AnimationStateAdapter {\n start(entry) {\n }\n interrupt(entry) {\n }\n end(entry) {\n }\n dispose(entry) {\n }\n complete(entry) {\n }\n event(entry, event) {\n }\n}\n/** 1. A previously applied timeline has set this property.\n *\n * Result: Mix from the current pose to the timeline pose. */\nexport const SUBSEQUENT = 0;\n/** 1. This is the first timeline to set this property.\n * 2. The next track entry applied after this one does not have a timeline to set this property.\n *\n * Result: Mix from the setup pose to the timeline pose. */\nexport const FIRST = 1;\n/** 1) A previously applied timeline has set this property.
\n * 2) The next track entry to be applied does have a timeline to set this property.
\n * 3) The next track entry after that one does not have a timeline to set this property.
\n * Result: Mix from the current pose to the timeline pose, but do not mix out. This avoids \"dipping\" when crossfading\n * animations that key the same property. A subsequent timeline will set this property using a mix. */\nexport const HOLD_SUBSEQUENT = 2;\n/** 1) This is the first timeline to set this property.
\n * 2) The next track entry to be applied does have a timeline to set this property.
\n * 3) The next track entry after that one does not have a timeline to set this property.
\n * Result: Mix from the setup pose to the timeline pose, but do not mix out. This avoids \"dipping\" when crossfading animations\n * that key the same property. A subsequent timeline will set this property using a mix. */\nexport const HOLD_FIRST = 3;\n/** 1. This is the first timeline to set this property.\n * 2. The next track entry to be applied does have a timeline to set this property.\n * 3. The next track entry after that one does have a timeline to set this property.\n * 4. timelineHoldMix stores the first subsequent track entry that does not have a timeline to set this property.\n *\n * Result: The same as HOLD except the mix percentage from the timelineHoldMix track entry is used. This handles when more than\n * 2 track entries in a row have a timeline that sets the same property.\n *\n * Eg, A -> B -> C -> D where A, B, and C have a timeline setting same property, but D does not. When A is applied, to avoid\n * \"dipping\" A is not mixed out, however D (the first entry that doesn't set the property) mixing in is used to mix out A\n * (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap into\n * place. */\nexport const HOLD_MIX = 4;\nexport const SETUP = 1;\nexport const CURRENT = 2;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQW5pbWF0aW9uU3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQW5pbWF0aW9uU3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSW5KLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFJL0Q7OztvSEFHb0g7QUFDcEgsTUFBTSxPQUFPLGNBQWM7SUFDMUIsTUFBTSxDQUFDLGVBQWUsR0FBRyxJQUFJLFNBQVMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2pELE1BQU0sQ0FBQyxjQUFjO1FBQzVCLE9BQU8sY0FBYyxDQUFDLGVBQWUsQ0FBQztJQUN2QyxDQUFDO0lBRUQsdURBQXVEO0lBQ3ZELElBQUksQ0FBcUI7SUFFekIseUZBQXlGO0lBQ3pGLE1BQU0sR0FBRyxJQUFJLEtBQUssRUFBcUIsQ0FBQztJQUV4Qzs7O3VGQUdtRjtJQUNuRixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsWUFBWSxHQUFHLENBQUMsQ0FBQztJQUVqQixNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQVMsQ0FBQztJQUM1QixTQUFTLEdBQUcsSUFBSSxLQUFLLEVBQTBCLENBQUM7SUFDaEQsS0FBSyxHQUFHLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLFdBQVcsR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO0lBQzlCLGlCQUFpQixHQUFHLEtBQUssQ0FBQztJQUUxQixjQUFjLEdBQUcsSUFBSSxJQUFJLENBQWEsR0FBRyxFQUFFLENBQUMsSUFBSSxV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QVEsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU87d0JBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzVFLEtBQUssSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFO3dCQUM3QyxJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7d0JBQzdCLElBQUksUUFBUSxDQUFDLE9BQU87NEJBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztxQkFDOUM7b0JBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMxQyxNQUFNO2dCQUNQLEtBQUssU0FBUyxDQUFDLFFBQVE7b0JBQ3RCLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLFFBQVE7d0JBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzlFLEtBQUssSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFO3dCQUM3QyxJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7d0JBQzdCLElBQUksUUFBUSxDQUFDLFFBQVE7NEJBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztxQkFDaEQ7b0JBQ0QsTUFBTTtnQkFDUCxLQUFLLFNBQVMsQ0FBQyxLQUFLO29CQUNuQixJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFVLENBQUM7b0JBQ3RDLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUs7d0JBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUMvRSxLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRTt3QkFDN0MsSUFBSSxRQUFRLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO3dCQUM3QixJQUFJLFFBQVEsQ0FBQyxLQUFLOzRCQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO3FCQUNqRDtvQkFDRCxNQUFNO2FBQ1A7U0FDRDtRQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUViLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO0lBQzVCLENBQUM7SUFFRCxLQUFLO1FBQ0osSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7Q0FDRDtBQUVELE1BQU0sQ0FBTixJQUFZLFNBRVg7QUFGRCxXQUFZLFNBQVM7SUFDcEIsMkNBQUssQ0FBQTtJQUFFLG1EQUFTLENBQUE7SUFBRSx1Q0FBRyxDQUFBO0lBQUUsK0NBQU8sQ0FBQTtJQUFFLGlEQUFRLENBQUE7SUFBRSwyQ0FBSyxDQUFBO0FBQ2hELENBQUMsRUFGVyxTQUFTLEtBQVQsU0FBUyxRQUVwQjtBQTZCRCxNQUFNLE9BQWdCLHFCQUFxQjtJQUMxQyxLQUFLLENBQUUsS0FBaUI7SUFDeEIsQ0FBQztJQUVELFNBQVMsQ0FBRSxLQUFpQjtJQUM1QixDQUFDO0lBRUQsR0FBRyxDQUFFLEtBQWlCO0lBQ3RCLENBQUM7SUFFRCxPQUFPLENBQUUsS0FBaUI7SUFDMUIsQ0FBQztJQUVELFFBQVEsQ0FBRSxLQUFpQjtJQUMzQixDQUFDO0lBRUQsS0FBSyxDQUFFLEtBQWlCLEVBQUUsS0FBWTtJQUN0QyxDQUFDO0NBQ0Q7QUFFRDs7NkRBRTZEO0FBQzdELE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFDNUI7OzsyREFHMkQ7QUFDM0QsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQztBQUN2Qjs7OztzR0FJc0c7QUFDdEcsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLENBQUMsQ0FBQztBQUNqQzs7OzsyRkFJMkY7QUFDM0YsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQztBQUM1Qjs7Ozs7Ozs7Ozs7WUFXWTtBQUNaLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFFMUIsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\n/** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed. */\nexport class AnimationStateData {\n /** The SkeletonData to look up animations when they are specified by name. */\n skeletonData;\n animationToMixTime = {};\n /** The mix duration to use when no mix duration has been defined between two animations. */\n defaultMix = 0;\n constructor(skeletonData) {\n if (!skeletonData)\n throw new Error(\"skeletonData cannot be null.\");\n this.skeletonData = skeletonData;\n }\n /** Sets a mix duration by animation name.\n *\n * See {@link #setMixWith()}. */\n setMix(fromName, toName, duration) {\n let from = this.skeletonData.findAnimation(fromName);\n if (!from)\n throw new Error(\"Animation not found: \" + fromName);\n let to = this.skeletonData.findAnimation(toName);\n if (!to)\n throw new Error(\"Animation not found: \" + toName);\n this.setMixWith(from, to, duration);\n }\n /** Sets the mix duration when changing from the specified animation to the other.\n *\n * See {@link TrackEntry#mixDuration}. */\n setMixWith(from, to, duration) {\n if (!from)\n throw new Error(\"from cannot be null.\");\n if (!to)\n throw new Error(\"to cannot be null.\");\n let key = from.name + \".\" + to.name;\n this.animationToMixTime[key] = duration;\n }\n /** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #defaultMix} if\n * no mix duration has been set. */\n getMix(from, to) {\n let key = from.name + \".\" + to.name;\n let value = this.animationToMixTime[key];\n return value === undefined ? this.defaultMix : value;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQW5pbWF0aW9uU3RhdGVEYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0FuaW1hdGlvblN0YXRlRGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFPL0UseUdBQXlHO0FBQ3pHLE1BQU0sT0FBTyxrQkFBa0I7SUFDOUIsOEVBQThFO0lBQzlFLFlBQVksQ0FBZTtJQUUzQixrQkFBa0IsR0FBc0IsRUFBRSxDQUFDO0lBRTNDLDRGQUE0RjtJQUM1RixVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBRWYsWUFBYSxZQUEwQjtRQUN0QyxJQUFJLENBQUMsWUFBWTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O29DQUVnQztJQUNoQyxNQUFNLENBQUUsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsUUFBZ0I7UUFDekQsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixHQUFHLFFBQVEsQ0FBQyxDQUFDO1FBQy9ELElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxFQUFFO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsR0FBRyxNQUFNLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs2Q0FFeUM7SUFDekMsVUFBVSxDQUFFLElBQWUsRUFBRSxFQUFhLEVBQUUsUUFBZ0I7UUFDM0QsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLEVBQUU7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDL0MsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztRQUNwQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDO0lBQ3pDLENBQUM7SUFFRDt3Q0FDb0M7SUFDcEMsTUFBTSxDQUFFLElBQWUsRUFBRSxFQUFhO1FBQ3JDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUFDcEMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLE9BQU8sS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQ3RELENBQUM7Q0FDRCJ9","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Color } from \"../Utils.js\";\nimport { VertexAttachment } from \"./Attachment.js\";\n/** An attachment with vertices that make up a polygon. Can be used for hit detection, creating physics bodies, spawning particle\n * effects, and more.\n *\n * See {@link SkeletonBounds} and [Bounding Boxes](http://esotericsoftware.com/spine-bounding-boxes) in the Spine User\n * Guide. */\nexport class BoundingBoxAttachment extends VertexAttachment {\n color = new Color(1, 1, 1, 1);\n constructor(name) {\n super(name);\n }\n copy() {\n let copy = new BoundingBoxAttachment(this.name);\n this.copyTo(copy);\n copy.color.setFromColor(this.color);\n return copy;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm91bmRpbmdCb3hBdHRhY2htZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F0dGFjaG1lbnRzL0JvdW5kaW5nQm94QXR0YWNobWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNwQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQWMsTUFBTSxpQkFBaUIsQ0FBQztBQUUvRDs7OztZQUlZO0FBQ1osTUFBTSxPQUFPLHFCQUFzQixTQUFRLGdCQUFnQjtJQUMxRCxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFOUIsWUFBYSxJQUFZO1FBQ3hCLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNiLENBQUM7SUFFRCxJQUFJO1FBQ0gsSUFBSSxJQUFJLEdBQUcsSUFBSSxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEMsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0NBQ0QifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Color } from \"../Utils.js\";\nimport { VertexAttachment } from \"./Attachment.js\";\n/** An attachment with vertices that make up a polygon used for clipping the rendering of other attachments. */\nexport class ClippingAttachment extends VertexAttachment {\n /** Clipping is performed between the clipping polygon's slot and the end slot. Returns null if clipping is done until the end of\n * the skeleton's rendering. */\n endSlot = null;\n // Nonessential.\n /** The color of the clipping polygon as it was in Spine. Available only when nonessential data was exported. Clipping polygons\n * are not usually rendered at runtime. */\n color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff\n constructor(name) {\n super(name);\n }\n copy() {\n let copy = new ClippingAttachment(this.name);\n this.copyTo(copy);\n copy.endSlot = this.endSlot;\n copy.color.setFromColor(this.color);\n return copy;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2xpcHBpbmdBdHRhY2htZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F0dGFjaG1lbnRzL0NsaXBwaW5nQXR0YWNobWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNwQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQWMsTUFBTSxpQkFBaUIsQ0FBQztBQUUvRCwrR0FBK0c7QUFDL0csTUFBTSxPQUFPLGtCQUFtQixTQUFRLGdCQUFnQjtJQUN2RDttQ0FDK0I7SUFDL0IsT0FBTyxHQUFvQixJQUFJLENBQUM7SUFFaEMsZ0JBQWdCO0lBQ2hCOzhDQUMwQztJQUMxQyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXO0lBRXpELFlBQWEsSUFBWTtRQUN4QixLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDYixDQUFDO0lBRUQsSUFBSTtRQUNILElBQUksSUFBSSxHQUFHLElBQUksa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwQyxPQUFPLElBQUksQ0FBQztJQUNiLENBQUM7Q0FDRCJ9","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nexport class Texture {\n _image;\n constructor(image) {\n this._image = image;\n }\n getImage() {\n return this._image;\n }\n}\nexport var TextureFilter;\n(function (TextureFilter) {\n TextureFilter[TextureFilter[\"Nearest\"] = 9728] = \"Nearest\";\n TextureFilter[TextureFilter[\"Linear\"] = 9729] = \"Linear\";\n TextureFilter[TextureFilter[\"MipMap\"] = 9987] = \"MipMap\";\n TextureFilter[TextureFilter[\"MipMapNearestNearest\"] = 9984] = \"MipMapNearestNearest\";\n TextureFilter[TextureFilter[\"MipMapLinearNearest\"] = 9985] = \"MipMapLinearNearest\";\n TextureFilter[TextureFilter[\"MipMapNearestLinear\"] = 9986] = \"MipMapNearestLinear\";\n TextureFilter[TextureFilter[\"MipMapLinearLinear\"] = 9987] = \"MipMapLinearLinear\"; // WebGLRenderingContext.LINEAR_MIPMAP_LINEAR\n})(TextureFilter || (TextureFilter = {}));\nexport var TextureWrap;\n(function (TextureWrap) {\n TextureWrap[TextureWrap[\"MirroredRepeat\"] = 33648] = \"MirroredRepeat\";\n TextureWrap[TextureWrap[\"ClampToEdge\"] = 33071] = \"ClampToEdge\";\n TextureWrap[TextureWrap[\"Repeat\"] = 10497] = \"Repeat\"; // WebGLRenderingContext.REPEAT\n})(TextureWrap || (TextureWrap = {}));\nexport class TextureRegion {\n texture;\n u = 0;\n v = 0;\n u2 = 0;\n v2 = 0;\n width = 0;\n height = 0;\n degrees = 0;\n offsetX = 0;\n offsetY = 0;\n originalWidth = 0;\n originalHeight = 0;\n}\nexport class FakeTexture extends Texture {\n setFilters(minFilter, magFilter) { }\n setWraps(uWrap, vWrap) { }\n dispose() { }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGV4dHVyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9UZXh0dXJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUUvRSxNQUFNLE9BQWdCLE9BQU87SUFDbEIsTUFBTSxDQUFpQztJQUVqRCxZQUFhLEtBQXFDO1FBQ2pELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxRQUFRO1FBQ1AsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3BCLENBQUM7Q0FLRDtBQUVELE1BQU0sQ0FBTixJQUFZLGFBUVg7QUFSRCxXQUFZLGFBQWE7SUFDeEIsMERBQWMsQ0FBQTtJQUNkLHdEQUFhLENBQUE7SUFDYix3REFBYSxDQUFBO0lBQ2Isb0ZBQTJCLENBQUE7SUFDM0Isa0ZBQTBCLENBQUE7SUFDMUIsa0ZBQTBCLENBQUE7SUFDMUIsZ0ZBQXlCLENBQUEsQ0FBQyw2Q0FBNkM7QUFDeEUsQ0FBQyxFQVJXLGFBQWEsS0FBYixhQUFhLFFBUXhCO0FBRUQsTUFBTSxDQUFOLElBQVksV0FJWDtBQUpELFdBQVksV0FBVztJQUN0QixxRUFBc0IsQ0FBQTtJQUN0QiwrREFBbUIsQ0FBQTtJQUNuQixxREFBYyxDQUFBLENBQUMsK0JBQStCO0FBQy9DLENBQUMsRUFKVyxXQUFXLEtBQVgsV0FBVyxRQUl0QjtBQUVELE1BQU0sT0FBTyxhQUFhO0lBQ3pCLE9BQU8sQ0FBTTtJQUNiLENBQUMsR0FBRyxDQUFDLENBQUM7SUFBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDZixLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUN0QixPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ1osT0FBTyxHQUFHLENBQUMsQ0FBQztJQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDekIsYUFBYSxHQUFHLENBQUMsQ0FBQztJQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7Q0FDdEM7QUFFRCxNQUFNLE9BQU8sV0FBWSxTQUFRLE9BQU87SUFDdkMsVUFBVSxDQUFFLFNBQXdCLEVBQUUsU0FBd0IsSUFBSSxDQUFDO0lBQ25FLFFBQVEsQ0FBRSxLQUFrQixFQUFFLEtBQWtCLElBQUksQ0FBQztJQUNyRCxPQUFPLEtBQU0sQ0FBQztDQUNkIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { TextureFilter, TextureWrap, TextureRegion } from \"./Texture.js\";\nimport { Utils } from \"./Utils.js\";\nexport class TextureAtlas {\n pages = new Array();\n regions = new Array();\n constructor(atlasText) {\n let reader = new TextureAtlasReader(atlasText);\n let entry = new Array(4);\n let pageFields = {};\n pageFields[\"size\"] = (page) => {\n page.width = parseInt(entry[1]);\n page.height = parseInt(entry[2]);\n };\n pageFields[\"format\"] = () => {\n // page.format = Format[tuple[0]]; we don't need format in WebGL\n };\n pageFields[\"filter\"] = (page) => {\n page.minFilter = Utils.enumValue(TextureFilter, entry[1]);\n page.magFilter = Utils.enumValue(TextureFilter, entry[2]);\n };\n pageFields[\"repeat\"] = (page) => {\n if (entry[1].indexOf('x') != -1)\n page.uWrap = TextureWrap.Repeat;\n if (entry[1].indexOf('y') != -1)\n page.vWrap = TextureWrap.Repeat;\n };\n pageFields[\"pma\"] = (page) => {\n page.pma = entry[1] == \"true\";\n };\n var regionFields = {};\n regionFields[\"xy\"] = (region) => {\n region.x = parseInt(entry[1]);\n region.y = parseInt(entry[2]);\n };\n regionFields[\"size\"] = (region) => {\n region.width = parseInt(entry[1]);\n region.height = parseInt(entry[2]);\n };\n regionFields[\"bounds\"] = (region) => {\n region.x = parseInt(entry[1]);\n region.y = parseInt(entry[2]);\n region.width = parseInt(entry[3]);\n region.height = parseInt(entry[4]);\n };\n regionFields[\"offset\"] = (region) => {\n region.offsetX = parseInt(entry[1]);\n region.offsetY = parseInt(entry[2]);\n };\n regionFields[\"orig\"] = (region) => {\n region.originalWidth = parseInt(entry[1]);\n region.originalHeight = parseInt(entry[2]);\n };\n regionFields[\"offsets\"] = (region) => {\n region.offsetX = parseInt(entry[1]);\n region.offsetY = parseInt(entry[2]);\n region.originalWidth = parseInt(entry[3]);\n region.originalHeight = parseInt(entry[4]);\n };\n regionFields[\"rotate\"] = (region) => {\n let value = entry[1];\n if (value == \"true\")\n region.degrees = 90;\n else if (value != \"false\")\n region.degrees = parseInt(value);\n };\n regionFields[\"index\"] = (region) => {\n region.index = parseInt(entry[1]);\n };\n let line = reader.readLine();\n // Ignore empty lines before first entry.\n while (line && line.trim().length == 0)\n line = reader.readLine();\n // Header entries.\n while (true) {\n if (!line || line.trim().length == 0)\n break;\n if (reader.readEntry(entry, line) == 0)\n break; // Silently ignore all header fields.\n line = reader.readLine();\n }\n // Page and region entries.\n let page = null;\n let names = null;\n let values = null;\n while (true) {\n if (line === null)\n break;\n if (line.trim().length == 0) {\n page = null;\n line = reader.readLine();\n }\n else if (!page) {\n page = new TextureAtlasPage(line.trim());\n while (true) {\n if (reader.readEntry(entry, line = reader.readLine()) == 0)\n break;\n let field = pageFields[entry[0]];\n if (field)\n field(page);\n }\n this.pages.push(page);\n }\n else {\n let region = new TextureAtlasRegion(page, line);\n while (true) {\n let count = reader.readEntry(entry, line = reader.readLine());\n if (count == 0)\n break;\n let field = regionFields[entry[0]];\n if (field)\n field(region);\n else {\n if (!names)\n names = [];\n if (!values)\n values = [];\n names.push(entry[0]);\n let entryValues = [];\n for (let i = 0; i < count; i++)\n entryValues.push(parseInt(entry[i + 1]));\n values.push(entryValues);\n }\n }\n if (region.originalWidth == 0 && region.originalHeight == 0) {\n region.originalWidth = region.width;\n region.originalHeight = region.height;\n }\n if (names && names.length > 0 && values && values.length > 0) {\n region.names = names;\n region.values = values;\n names = null;\n values = null;\n }\n region.u = region.x / page.width;\n region.v = region.y / page.height;\n if (region.degrees == 90) {\n region.u2 = (region.x + region.height) / page.width;\n region.v2 = (region.y + region.width) / page.height;\n }\n else {\n region.u2 = (region.x + region.width) / page.width;\n region.v2 = (region.y + region.height) / page.height;\n }\n this.regions.push(region);\n }\n }\n }\n findRegion(name) {\n for (let i = 0; i < this.regions.length; i++) {\n if (this.regions[i].name == name) {\n return this.regions[i];\n }\n }\n return null;\n }\n setTextures(assetManager, pathPrefix = \"\") {\n for (let page of this.pages)\n page.setTexture(assetManager.get(pathPrefix + page.name));\n }\n dispose() {\n for (let i = 0; i < this.pages.length; i++) {\n this.pages[i].texture?.dispose();\n }\n }\n}\nclass TextureAtlasReader {\n lines;\n index = 0;\n constructor(text) {\n this.lines = text.split(/\\r\\n|\\r|\\n/);\n }\n readLine() {\n if (this.index >= this.lines.length)\n return null;\n return this.lines[this.index++];\n }\n readEntry(entry, line) {\n if (!line)\n return 0;\n line = line.trim();\n if (line.length == 0)\n return 0;\n let colon = line.indexOf(':');\n if (colon == -1)\n return 0;\n entry[0] = line.substr(0, colon).trim();\n for (let i = 1, lastMatch = colon + 1;; i++) {\n let comma = line.indexOf(',', lastMatch);\n if (comma == -1) {\n entry[i] = line.substr(lastMatch).trim();\n return i;\n }\n entry[i] = line.substr(lastMatch, comma - lastMatch).trim();\n lastMatch = comma + 1;\n if (i == 4)\n return 4;\n }\n }\n}\nexport class TextureAtlasPage {\n name;\n minFilter = TextureFilter.Nearest;\n magFilter = TextureFilter.Nearest;\n uWrap = TextureWrap.ClampToEdge;\n vWrap = TextureWrap.ClampToEdge;\n texture = null;\n width = 0;\n height = 0;\n pma = false;\n regions = new Array();\n constructor(name) {\n this.name = name;\n }\n setTexture(texture) {\n this.texture = texture;\n texture.setFilters(this.minFilter, this.magFilter);\n texture.setWraps(this.uWrap, this.vWrap);\n for (let region of this.regions)\n region.texture = texture;\n }\n}\nexport class TextureAtlasRegion extends TextureRegion {\n page;\n name;\n x = 0;\n y = 0;\n offsetX = 0;\n offsetY = 0;\n originalWidth = 0;\n originalHeight = 0;\n index = 0;\n degrees = 0;\n names = null;\n values = null;\n constructor(page, name) {\n super();\n this.page = page;\n this.name = name;\n page.regions.push(this);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGV4dHVyZUF0bGFzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1RleHR1cmVBdGxhcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQVcsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ2xGLE9BQU8sRUFBYyxLQUFLLEVBQWEsTUFBTSxZQUFZLENBQUM7QUFFMUQsTUFBTSxPQUFPLFlBQVk7SUFDeEIsS0FBSyxHQUFHLElBQUksS0FBSyxFQUFvQixDQUFDO0lBQ3RDLE9BQU8sR0FBRyxJQUFJLEtBQUssRUFBc0IsQ0FBQztJQUUxQyxZQUFhLFNBQWlCO1FBQzdCLElBQUksTUFBTSxHQUFHLElBQUksa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0MsSUFBSSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQVMsQ0FBQyxDQUFDLENBQUM7UUFFakMsSUFBSSxVQUFVLEdBQWdELEVBQUUsQ0FBQztRQUNqRSxVQUFVLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFzQixFQUFFLEVBQUU7WUFDL0MsSUFBSyxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakMsSUFBSyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsQ0FBQyxDQUFDO1FBQ0YsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEdBQUcsRUFBRTtZQUMzQixnRUFBZ0U7UUFDakUsQ0FBQyxDQUFDO1FBQ0YsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBc0IsRUFBRSxFQUFFO1lBQ2pELElBQUssQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0QsSUFBSyxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RCxDQUFDLENBQUM7UUFDRixVQUFVLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFzQixFQUFFLEVBQUU7WUFDakQsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFBRSxJQUFLLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7WUFDbEUsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFBRSxJQUFLLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7UUFDbkUsQ0FBQyxDQUFDO1FBQ0YsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBc0IsRUFBRSxFQUFFO1lBQzlDLElBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQztRQUNoQyxDQUFDLENBQUM7UUFFRixJQUFJLFlBQVksR0FBb0QsRUFBRSxDQUFDO1FBQ3ZFLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQTBCLEVBQUUsRUFBRTtZQUNuRCxNQUFNLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QixNQUFNLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQUM7UUFDRixZQUFZLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUEwQixFQUFFLEVBQUU7WUFDckQsTUFBTSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEMsTUFBTSxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDO1FBQ0YsWUFBWSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBMEIsRUFBRSxFQUFFO1lBQ3ZELE1BQU0sQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLENBQUMsQ0FBQztRQUNGLFlBQVksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQTBCLEVBQUUsRUFBRTtZQUN2RCxNQUFNLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQyxNQUFNLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUM7UUFDRixZQUFZLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUEwQixFQUFFLEVBQUU7WUFDckQsTUFBTSxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUMsTUFBTSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDO1FBQ0YsWUFBWSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsTUFBMEIsRUFBRSxFQUFFO1lBQ3hELE1BQU0sQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFD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QUFDLFdBQVcsQ0FBQztJQUM3QyxLQUFLLEdBQWdCLFdBQVcsQ0FBQyxXQUFXLENBQUM7SUFDN0MsT0FBTyxHQUFtQixJQUFJLENBQUM7SUFDL0IsS0FBSyxHQUFXLENBQUMsQ0FBQztJQUNsQixNQUFNLEdBQVcsQ0FBQyxDQUFDO0lBQ25CLEdBQUcsR0FBWSxLQUFLLENBQUM7SUFDckIsT0FBTyxHQUFHLElBQUksS0FBSyxFQUFzQixDQUFDO0lBRTFDLFlBQWEsSUFBWTtRQUN4QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNsQixDQUFDO0lBRUQsVUFBVSxDQUFFLE9BQWdCO1FBQzNCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QyxLQUFLLElBQUksTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPO1lBQzlCLE1BQU0sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzNCLENBQUM7Q0FDRDtBQUVELE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxhQUFhO0lBQ3BELElBQUksQ0FBbUI7SUFDdkIsSUFBSSxDQUFTO0lBQ2IsQ0FBQyxHQUFXLENBQUMsQ0FBQztJQUNkLENBQUMsR0FBVyxDQUFDLENBQUM7SUFDZCxPQUFPLEdBQVcsQ0FBQyxDQUFDO0lBQ3BCLE9BQU8sR0FBVyxDQUFDLENBQUM7SUFDcEIsYUFBYSxHQUFXLENBQUMsQ0FBQztJQUMxQixjQUFjLEdBQVcsQ0FBQyxDQUFDO0lBQzNCLEtBQUssR0FBVyxDQUFDLENBQUM7SUFDbEIsT0FBTyxHQUFXLENBQUMsQ0FBQztJQUNwQixLQUFLLEdBQW9CLElBQUksQ0FBQztJQUM5QixNQUFNLEdBQXNCLElBQUksQ0FBQztJQUVqQyxZQUFhLElBQXNCLEVBQUUsSUFBWTtRQUNoRCxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUM7Q0FDRCJ9","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { TextureAtlasRegion } from \"../TextureAtlas.js\";\nimport { Color, Utils } from \"../Utils.js\";\nimport { VertexAttachment } from \"./Attachment.js\";\n/** An attachment that displays a textured mesh. A mesh has hull vertices and internal vertices within the hull. Holes are not\n * supported. Each vertex has UVs (texture coordinates) and triangles are used to map an image on to the mesh.\n *\n * See [Mesh attachments](http://esotericsoftware.com/spine-meshes) in the Spine User Guide. */\nexport class MeshAttachment extends VertexAttachment {\n region = null;\n /** The name of the texture region for this attachment. */\n path;\n /** The UV pair for each vertex, normalized within the texture region. */\n regionUVs = [];\n /** The UV pair for each vertex, normalized within the entire texture.\n *\n * See {@link #updateUVs}. */\n uvs = [];\n /** Triplets of vertex indices which describe the mesh's triangulation. */\n triangles = [];\n /** The color to tint the mesh. */\n color = new Color(1, 1, 1, 1);\n /** The width of the mesh's image. Available only when nonessential data was exported. */\n width = 0;\n /** The height of the mesh's image. Available only when nonessential data was exported. */\n height = 0;\n /** The number of entries at the beginning of {@link #vertices} that make up the mesh hull. */\n hullLength = 0;\n /** Vertex index pairs describing edges for controling triangulation. Mesh triangles will never cross edges. Only available if\n * nonessential data was exported. Triangulation is not performed at runtime. */\n edges = [];\n parentMesh = null;\n sequence = null;\n tempColor = new Color(0, 0, 0, 0);\n constructor(name, path) {\n super(name);\n this.path = path;\n }\n /** Calculates {@link #uvs} using the {@link #regionUVs} and region. Must be called if the region, the region's properties, or\n * the {@link #regionUVs} are changed. */\n updateRegion() {\n if (!this.region)\n throw new Error(\"Region not set.\");\n let regionUVs = this.regionUVs;\n if (!this.uvs || this.uvs.length != regionUVs.length)\n this.uvs = Utils.newFloatArray(regionUVs.length);\n let uvs = this.uvs;\n let n = this.uvs.length;\n let u = this.region.u, v = this.region.v, width = 0, height = 0;\n if (this.region instanceof TextureAtlasRegion) {\n let region = this.region, page = region.page;\n let textureWidth = page.width, textureHeight = page.height;\n switch (region.degrees) {\n case 90:\n u -= (region.originalHeight - region.offsetY - region.height) / textureWidth;\n v -= (region.originalWidth - region.offsetX - region.width) / textureHeight;\n width = region.originalHeight / textureWidth;\n height = region.originalWidth / textureHeight;\n for (let i = 0; i < n; i += 2) {\n uvs[i] = u + regionUVs[i + 1] * width;\n uvs[i + 1] = v + (1 - regionUVs[i]) * height;\n }\n return;\n case 180:\n u -= (region.originalWidth - region.offsetX - region.width) / textureWidth;\n v -= region.offsetY / textureHeight;\n width = region.originalWidth / textureWidth;\n height = region.originalHeight / textureHeight;\n for (let i = 0; i < n; i += 2) {\n uvs[i] = u + (1 - regionUVs[i]) * width;\n uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height;\n }\n return;\n case 270:\n u -= region.offsetY / textureWidth;\n v -= region.offsetX / textureHeight;\n width = region.originalHeight / textureWidth;\n height = region.originalWidth / textureHeight;\n for (let i = 0; i < n; i += 2) {\n uvs[i] = u + (1 - regionUVs[i + 1]) * width;\n uvs[i + 1] = v + regionUVs[i] * height;\n }\n return;\n }\n u -= region.offsetX / textureWidth;\n v -= (region.originalHeight - region.offsetY - region.height) / textureHeight;\n width = region.originalWidth / textureWidth;\n height = region.originalHeight / textureHeight;\n }\n else if (!this.region) {\n u = v = 0;\n width = height = 1;\n }\n else {\n width = this.region.u2 - u;\n height = this.region.v2 - v;\n }\n for (let i = 0; i < n; i += 2) {\n uvs[i] = u + regionUVs[i] * width;\n uvs[i + 1] = v + regionUVs[i + 1] * height;\n }\n }\n /** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices},\n * {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the\n * parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */\n getParentMesh() {\n return this.parentMesh;\n }\n /** @param parentMesh May be null. */\n setParentMesh(parentMesh) {\n this.parentMesh = parentMesh;\n if (parentMesh) {\n this.bones = parentMesh.bones;\n this.vertices = parentMesh.vertices;\n this.worldVerticesLength = parentMesh.worldVerticesLength;\n this.regionUVs = parentMesh.regionUVs;\n this.triangles = parentMesh.triangles;\n this.hullLength = parentMesh.hullLength;\n this.worldVerticesLength = parentMesh.worldVerticesLength;\n }\n }\n copy() {\n if (this.parentMesh)\n return this.newLinkedMesh();\n let copy = new MeshAttachment(this.name, this.path);\n copy.region = this.region;\n copy.color.setFromColor(this.color);\n this.copyTo(copy);\n copy.regionUVs = new Array(this.regionUVs.length);\n Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length);\n copy.uvs = new Array(this.uvs.length);\n Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, this.uvs.length);\n copy.triangles = new Array(this.triangles.length);\n Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length);\n copy.hullLength = this.hullLength;\n copy.sequence = this.sequence != null ? this.sequence.copy() : null;\n // Nonessential.\n if (this.edges) {\n copy.edges = new Array(this.edges.length);\n Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length);\n }\n copy.width = this.width;\n copy.height = this.height;\n return copy;\n }\n computeWorldVertices(slot, start, count, worldVertices, offset, stride) {\n if (this.sequence != null)\n this.sequence.apply(slot, this);\n super.computeWorldVertices(slot, start, count, worldVertices, offset, stride);\n }\n /** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. **/\n newLinkedMesh() {\n let copy = new MeshAttachment(this.name, this.path);\n copy.region = this.region;\n copy.color.setFromColor(this.color);\n copy.timelineAttachment = this.timelineAttachment;\n copy.setParentMesh(this.parentMesh ? this.parentMesh : this);\n if (copy.region != null)\n copy.updateRegion();\n return copy;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWVzaEF0dGFjaG1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXR0YWNobWVudHMvTWVzaEF0dGFjaG1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxLQUFLLEVBQW1CLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQWMsTUFBTSxpQkFBaUIsQ0FBQztBQUsvRDs7OytGQUcrRjtBQUMvRixNQUFNLE9BQU8sY0FBZSxTQUFRLGdCQUFnQjtJQUNuRCxNQUFNLEdBQXlCLElBQUksQ0FBQztJQUVwQywwREFBMEQ7SUFDMUQsSUFBSSxDQUFTO0lBRWIseUVBQXlFO0lBQ3pFLFNBQVMsR0FBb0IsRUFBRSxDQUFDO0lBRWhDOztpQ0FFNkI7SUFDN0IsR0FBRyxHQUFvQixFQUFFLENBQUM7SUFFMUIsMEVBQTBFO0lBQzFFLFNBQVMsR0FBa0IsRUFBRSxDQUFDO0lBRTlCLGtDQUFrQztJQUNsQyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFOUIseUZBQXlGO0lBQ3pGLEtBQUssR0FBVyxDQUFDLENBQUM7SUFFbEIsMEZBQTBGO0lBQzFGLE1BQU0sR0FBVyxDQUFDLENBQUM7SUFFbkIsOEZBQThGO0lBQzlGLFVBQVUsR0FBVyxDQUFDLENBQUM7SUFFdkI7b0ZBQ2dGO0lBQ2hGLEtBQUssR0FBa0IsRUFBRSxDQUFDO0lBRWxCLFVBQVUsR0FBMEIsSUFBSSxDQUFDO0lBRWpELFFBQVEsR0FBb0IsSUFBSSxDQUFDO0lBRWpDLFNBQVMsR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxD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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Color, Utils } from \"../Utils.js\";\nimport { VertexAttachment } from \"./Attachment.js\";\n/** An attachment whose vertices make up a composite Bezier curve.\n *\n * See {@link PathConstraint} and [Paths](http://esotericsoftware.com/spine-paths) in the Spine User Guide. */\nexport class PathAttachment extends VertexAttachment {\n /** The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve. */\n lengths = [];\n /** If true, the start and end knots are connected. */\n closed = false;\n /** If true, additional calculations are performed to make calculating positions along the path more accurate. If false, fewer\n * calculations are performed but calculating positions along the path is less accurate. */\n constantSpeed = false;\n /** The color of the path as it was in Spine. Available only when nonessential data was exported. Paths are not usually\n * rendered at runtime. */\n color = new Color(1, 1, 1, 1);\n constructor(name) {\n super(name);\n }\n copy() {\n let copy = new PathAttachment(this.name);\n this.copyTo(copy);\n copy.lengths = new Array(this.lengths.length);\n Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length);\n copy.closed = closed;\n copy.constantSpeed = this.constantSpeed;\n copy.color.setFromColor(this.color);\n return copy;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGF0aEF0dGFjaG1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXR0YWNobWVudHMvUGF0aEF0dGFjaG1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBYyxNQUFNLGlCQUFpQixDQUFDO0FBRS9EOzs4R0FFOEc7QUFDOUcsTUFBTSxPQUFPLGNBQWUsU0FBUSxnQkFBZ0I7SUFFbkQsK0dBQStHO0lBQy9HLE9BQU8sR0FBa0IsRUFBRSxDQUFDO0lBRTVCLHNEQUFzRDtJQUN0RCxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBRWY7K0ZBQzJGO0lBQzNGLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFFdEI7OEJBQzBCO0lBQzFCLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUU5QixZQUFhLElBQVk7UUFDeEIsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2IsQ0FBQztJQUVELElBQUk7UUFDSCxJQUFJLElBQUksR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksS0FBSyxDQUFTLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZFLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEMsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0NBQ0QifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Color, MathUtils } from \"../Utils.js\";\nimport { VertexAttachment } from \"./Attachment.js\";\n/** An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be\n * used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a\n * skin.\n *\n * See [Point Attachments](http://esotericsoftware.com/spine-point-attachments) in the Spine User Guide. */\nexport class PointAttachment extends VertexAttachment {\n x = 0;\n y = 0;\n rotation = 0;\n /** The color of the point attachment as it was in Spine. Available only when nonessential data was exported. Point attachments\n * are not usually rendered at runtime. */\n color = new Color(0.38, 0.94, 0, 1);\n constructor(name) {\n super(name);\n }\n computeWorldPosition(bone, point) {\n point.x = this.x * bone.a + this.y * bone.b + bone.worldX;\n point.y = this.x * bone.c + this.y * bone.d + bone.worldY;\n return point;\n }\n computeWorldRotation(bone) {\n const r = this.rotation * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r);\n const x = cos * bone.a + sin * bone.b;\n const y = cos * bone.c + sin * bone.d;\n return MathUtils.atan2Deg(y, x);\n }\n copy() {\n let copy = new PointAttachment(this.name);\n copy.x = this.x;\n copy.y = this.y;\n copy.rotation = this.rotation;\n copy.color.setFromColor(this.color);\n return copy;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUG9pbnRBdHRhY2htZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F0dGFjaG1lbnRzL1BvaW50QXR0YWNobWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLEtBQUssRUFBVyxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDeEQsT0FBTyxFQUFFLGdCQUFnQixFQUFjLE1BQU0saUJBQWlCLENBQUM7QUFFL0Q7Ozs7MkdBSTJHO0FBQzNHLE1BQU0sT0FBTyxlQUFnQixTQUFRLGdCQUFnQjtJQUNwRCxDQUFDLEdBQVcsQ0FBQyxDQUFDO0lBQ2QsQ0FBQyxHQUFXLENBQUMsQ0FBQztJQUNkLFFBQVEsR0FBVyxDQUFDLENBQUM7SUFFckI7OENBQzBDO0lBQzFDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVwQyxZQUFhLElBQVk7UUFDeEIsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2IsQ0FBQztJQUVELG9CQUFvQixDQUFFLElBQVUsRUFBRSxLQUFjO1FBQy9DLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzFELEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzFELE9BQU8sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVELG9CQUFvQixDQUFFLElBQVU7UUFDL0IsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pGLE1BQU0sQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLE9BQU8sU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELElBQUk7UUFDSCxJQUFJLElBQUksR0FBRyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNoQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sSUFBSSxDQUFDO0lBQ2IsQ0FBQztDQUNEIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Color, MathUtils, Utils } from \"../Utils.js\";\nimport { Attachment } from \"./Attachment.js\";\n/** An attachment that displays a textured quadrilateral.\n *\n * See [Region attachments](http://esotericsoftware.com/spine-regions) in the Spine User Guide. */\nexport class RegionAttachment extends Attachment {\n /** The local x translation. */\n x = 0;\n /** The local y translation. */\n y = 0;\n /** The local scaleX. */\n scaleX = 1;\n /** The local scaleY. */\n scaleY = 1;\n /** The local rotation. */\n rotation = 0;\n /** The width of the region attachment in Spine. */\n width = 0;\n /** The height of the region attachment in Spine. */\n height = 0;\n /** The color to tint the region attachment. */\n color = new Color(1, 1, 1, 1);\n /** The name of the texture region for this attachment. */\n path;\n region = null;\n sequence = null;\n /** For each of the 4 vertices, a pair of x,y values that is the local position of the vertex.\n *\n * See {@link #updateOffset()}. */\n offset = Utils.newFloatArray(8);\n uvs = Utils.newFloatArray(8);\n tempColor = new Color(1, 1, 1, 1);\n constructor(name, path) {\n super(name);\n this.path = path;\n }\n /** Calculates the {@link #offset} using the region settings. Must be called after changing region settings. */\n updateRegion() {\n if (!this.region)\n throw new Error(\"Region not set.\");\n let region = this.region;\n let uvs = this.uvs;\n if (region == null) {\n uvs[0] = 0;\n uvs[1] = 0;\n uvs[2] = 0;\n uvs[3] = 1;\n uvs[4] = 1;\n uvs[5] = 1;\n uvs[6] = 1;\n uvs[7] = 0;\n return;\n }\n let regionScaleX = this.width / this.region.originalWidth * this.scaleX;\n let regionScaleY = this.height / this.region.originalHeight * this.scaleY;\n let localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX;\n let localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY;\n let localX2 = localX + this.region.width * regionScaleX;\n let localY2 = localY + this.region.height * regionScaleY;\n let radians = this.rotation * MathUtils.degRad;\n let cos = Math.cos(radians);\n let sin = Math.sin(radians);\n let x = this.x, y = this.y;\n let localXCos = localX * cos + x;\n let localXSin = localX * sin;\n let localYCos = localY * cos + y;\n let localYSin = localY * sin;\n let localX2Cos = localX2 * cos + x;\n let localX2Sin = localX2 * sin;\n let localY2Cos = localY2 * cos + y;\n let localY2Sin = localY2 * sin;\n let offset = this.offset;\n offset[0] = localXCos - localYSin;\n offset[1] = localYCos + localXSin;\n offset[2] = localXCos - localY2Sin;\n offset[3] = localY2Cos + localXSin;\n offset[4] = localX2Cos - localY2Sin;\n offset[5] = localY2Cos + localX2Sin;\n offset[6] = localX2Cos - localYSin;\n offset[7] = localYCos + localX2Sin;\n if (region.degrees == 90) {\n uvs[0] = region.u2;\n uvs[1] = region.v2;\n uvs[2] = region.u;\n uvs[3] = region.v2;\n uvs[4] = region.u;\n uvs[5] = region.v;\n uvs[6] = region.u2;\n uvs[7] = region.v;\n }\n else {\n uvs[0] = region.u;\n uvs[1] = region.v2;\n uvs[2] = region.u;\n uvs[3] = region.v;\n uvs[4] = region.u2;\n uvs[5] = region.v;\n uvs[6] = region.u2;\n uvs[7] = region.v2;\n }\n }\n /** Transforms the attachment's four vertices to world coordinates. If the attachment has a {@link #sequence}, the region may\n * be changed.\n *

\n * See World transforms in the Spine\n * Runtimes Guide.\n * @param worldVertices The output world vertices. Must have a length >= offset + 8.\n * @param offset The worldVertices index to begin writing values.\n * @param stride The number of worldVertices entries between the value pairs written. */\n computeWorldVertices(slot, worldVertices, offset, stride) {\n if (this.sequence != null)\n this.sequence.apply(slot, this);\n let bone = slot.bone;\n let vertexOffset = this.offset;\n let x = bone.worldX, y = bone.worldY;\n let a = bone.a, b = bone.b, c = bone.c, d = bone.d;\n let offsetX = 0, offsetY = 0;\n offsetX = vertexOffset[0];\n offsetY = vertexOffset[1];\n worldVertices[offset] = offsetX * a + offsetY * b + x; // br\n worldVertices[offset + 1] = offsetX * c + offsetY * d + y;\n offset += stride;\n offsetX = vertexOffset[2];\n offsetY = vertexOffset[3];\n worldVertices[offset] = offsetX * a + offsetY * b + x; // bl\n worldVertices[offset + 1] = offsetX * c + offsetY * d + y;\n offset += stride;\n offsetX = vertexOffset[4];\n offsetY = vertexOffset[5];\n worldVertices[offset] = offsetX * a + offsetY * b + x; // ul\n worldVertices[offset + 1] = offsetX * c + offsetY * d + y;\n offset += stride;\n offsetX = vertexOffset[6];\n offsetY = vertexOffset[7];\n worldVertices[offset] = offsetX * a + offsetY * b + x; // ur\n worldVertices[offset + 1] = offsetX * c + offsetY * d + y;\n }\n copy() {\n let copy = new RegionAttachment(this.name, this.path);\n copy.region = this.region;\n copy.x = this.x;\n copy.y = this.y;\n copy.scaleX = this.scaleX;\n copy.scaleY = this.scaleY;\n copy.rotation = this.rotation;\n copy.width = this.width;\n copy.height = this.height;\n Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8);\n Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8);\n copy.color.setFromColor(this.color);\n copy.sequence = this.sequence != null ? this.sequence.copy() : null;\n return copy;\n }\n static X1 = 0;\n static Y1 = 1;\n static C1R = 2;\n static C1G = 3;\n static C1B = 4;\n static C1A = 5;\n static U1 = 6;\n static V1 = 7;\n static X2 = 8;\n static Y2 = 9;\n static C2R = 10;\n static C2G = 11;\n static C2B = 12;\n static C2A = 13;\n static U2 = 14;\n static V2 = 15;\n static X3 = 16;\n static Y3 = 17;\n static C3R = 18;\n static C3G = 19;\n static C3B = 20;\n static C3A = 21;\n static U3 = 22;\n static V3 = 23;\n static X4 = 24;\n static Y4 = 25;\n static C4R = 26;\n static C4G = 27;\n static C4B = 28;\n static C4A = 29;\n static U4 = 30;\n static V4 = 31;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaW9uQXR0YWNobWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdHRhY2htZW50cy9SZWdpb25BdHRhY2htZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUkvRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBbUIsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUs3Qzs7a0dBRWtHO0FBQ2xHLE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxVQUFVO0lBQy9DLCtCQUErQjtJQUMvQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRU4sK0JBQStCO0lBQy9CLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFTix3QkFBd0I7SUFDeEIsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUVYLHdCQUF3QjtJQUN4QixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRVgsMEJBQTBCO0lBQzFCLFFBQVEsR0FBRyxDQUFDLENBQUM7SUFFYixtREFBbUQ7SUFDbkQsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUVWLG9EQUFvRDtJQUNwRCxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRVgsK0NBQStDO0lBQy9DLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUU5QiwwREFBMEQ7SUFDMUQsSUFBSSxDQUFTO0lBRWIsTUFBTSxHQUF5QixJQUFJLENBQUM7SUFDcEMsUUFBUSxHQUFvQixJQUFJLENBQUM7SUFFakM7O3NDQUVrQztJQUNsQyxNQUFNLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVoQyxHQUFHLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU3QixTQUFTLEdBQUcsSUFB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LENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUNmLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ2YsTUFBTSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDaEIsTUFBTSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDaEIsTUFBTSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDaEIsTUFBTSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDaEIsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDZixNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUVmLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ2YsTUFBTSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDZixNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUNoQixNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUNoQixNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUNoQixNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUNoQixNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUNmLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { BoundingBoxAttachment } from \"./attachments/BoundingBoxAttachment.js\";\nimport { ClippingAttachment } from \"./attachments/ClippingAttachment.js\";\nimport { MeshAttachment } from \"./attachments/MeshAttachment.js\";\nimport { PathAttachment } from \"./attachments/PathAttachment.js\";\nimport { PointAttachment } from \"./attachments/PointAttachment.js\";\nimport { RegionAttachment } from \"./attachments/RegionAttachment.js\";\n/** An {@link AttachmentLoader} that configures attachments using texture regions from an {@link TextureAtlas}.\n *\n * See [Loading skeleton data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the\n * Spine Runtimes Guide. */\nexport class AtlasAttachmentLoader {\n atlas;\n constructor(atlas) {\n this.atlas = atlas;\n }\n loadSequence(name, basePath, sequence) {\n let regions = sequence.regions;\n for (let i = 0, n = regions.length; i < n; i++) {\n let path = sequence.getPath(basePath, i);\n let region = this.atlas.findRegion(path);\n if (region == null)\n throw new Error(\"Region not found in atlas: \" + path + \" (sequence: \" + name + \")\");\n regions[i] = region;\n }\n }\n newRegionAttachment(skin, name, path, sequence) {\n let attachment = new RegionAttachment(name, path);\n if (sequence != null) {\n this.loadSequence(name, path, sequence);\n }\n else {\n let region = this.atlas.findRegion(path);\n if (!region)\n throw new Error(\"Region not found in atlas: \" + path + \" (region attachment: \" + name + \")\");\n attachment.region = region;\n }\n return attachment;\n }\n newMeshAttachment(skin, name, path, sequence) {\n let attachment = new MeshAttachment(name, path);\n if (sequence != null) {\n this.loadSequence(name, path, sequence);\n }\n else {\n let region = this.atlas.findRegion(path);\n if (!region)\n throw new Error(\"Region not found in atlas: \" + path + \" (mesh attachment: \" + name + \")\");\n attachment.region = region;\n }\n return attachment;\n }\n newBoundingBoxAttachment(skin, name) {\n return new BoundingBoxAttachment(name);\n }\n newPathAttachment(skin, name) {\n return new PathAttachment(name);\n }\n newPointAttachment(skin, name) {\n return new PointAttachment(name);\n }\n newClippingAttachment(skin, name) {\n return new ClippingAttachment(name);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXRsYXNBdHRhY2htZW50TG9hZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0F0bGFzQXR0YWNobWVudExvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDL0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDekUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFLckU7OzsyQkFHMkI7QUFDM0IsTUFBTSxPQUFPLHFCQUFxQjtJQUNqQyxLQUFLLENBQWU7SUFFcEIsWUFBYSxLQUFtQjtRQUMvQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBRUQsWUFBWSxDQUFFLElBQVksRUFBRSxRQUFnQixFQUFFLFFBQWtCO1FBQy9ELElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7UUFDL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUMvQyxJQUFJLElBQUksR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN6QyxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QyxJQUFJLE1BQU0sSUFBSSxJQUFJO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLEdBQUcsSUFBSSxHQUFHLGNBQWMsR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDeEcsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQztTQUNwQjtJQUNGLENBQUM7SUFFRCxtQkFBbUIsQ0FBRSxJQUFVLEVBQUUsSUFBWSxFQUFFLElBQVksRUFBRSxRQUFrQjtRQUM5RSxJQUFJLFVBQVUsR0FBRyxJQUFJLGdCQUFnQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNsRCxJQUFJLFFBQVEsSUFBSSxJQUFJLEVBQUU7WUFDckIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ3hDO2FBQU07WUFDTixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QyxJQUFJLENBQUMsTUFBTTtnQkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixHQUFHLElBQUksR0FBRyx1QkFBdUIsR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDMUcsVUFBVSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7U0FDM0I7UUFDRCxPQUFPLFVBQVUsQ0FBQztJQUNuQixDQUFDO0lBRUQsaUJBQWlCLENBQUUsSUFBVSxFQUFFLElBQVksRUFBRSxJQUFZLEVBQUUsUUFBa0I7UUFDNUUsSUFBSSxVQUFVLEdBQUcsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hELElBQUksUUFBUSxJQUFJLElBQUksRUFBRTtZQUNyQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7U0FDeEM7YUFBTTtZQUNOLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pDLElBQUksQ0FBQyxNQUFNO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLEdBQUcsSUFBSSxHQUFHLHFCQUFxQixHQUFHLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztZQUN4RyxVQUFVLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztTQUMzQjtRQUNELE9BQU8sVUFBVSxDQUFDO0lBQ25CLENBQUM7SUFFRCx3QkFBd0IsQ0FBRSxJQUFVLEVBQUUsSUFBWTtRQUNqRCxPQUFPLElBQUkscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVELGlCQUFpQixDQUFFLElBQVUsRUFBRSxJQUFZO1FBQzFDLE9BQU8sSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELGtCQUFrQixDQUFFLElBQVUsRUFBRSxJQUFZO1FBQzNDLE9BQU8sSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELHFCQUFxQixDQUFFLElBQVUsRUFBRSxJQUFZO1FBQzlDLE9BQU8sSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNyQyxDQUFDO0NBQ0QifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Color } from \"./Utils.js\";\n/** Stores the setup pose for a {@link Bone}. */\nexport class BoneData {\n /** The index of the bone in {@link Skeleton#getBones()}. */\n index = 0;\n /** The name of the bone, which is unique across all bones in the skeleton. */\n name;\n /** @returns May be null. */\n parent = null;\n /** The bone's length. */\n length = 0;\n /** The local x translation. */\n x = 0;\n /** The local y translation. */\n y = 0;\n /** The local rotation in degrees, counter clockwise. */\n rotation = 0;\n /** The local scaleX. */\n scaleX = 1;\n /** The local scaleY. */\n scaleY = 1;\n /** The local shearX. */\n shearX = 0;\n /** The local shearX. */\n shearY = 0;\n /** The transform mode for how parent world transforms affect this bone. */\n transformMode = TransformMode.Normal;\n /** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#skin} contains this\n * bone.\n * @see Skin#bones */\n skinRequired = false;\n /** The color of the bone as it was in Spine. Available only when nonessential data was exported. Bones are not usually\n * rendered at runtime. */\n color = new Color();\n /** The bone icon as it was in Spine, or null if nonessential data was not exported. */\n icon;\n /** False if the bone was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */\n visible = false;\n constructor(index, name, parent) {\n if (index < 0)\n throw new Error(\"index must be >= 0.\");\n if (!name)\n throw new Error(\"name cannot be null.\");\n this.index = index;\n this.name = name;\n this.parent = parent;\n }\n}\n/** Determines how a bone inherits world transforms from parent bones. */\nexport var TransformMode;\n(function (TransformMode) {\n TransformMode[TransformMode[\"Normal\"] = 0] = \"Normal\";\n TransformMode[TransformMode[\"OnlyTranslation\"] = 1] = \"OnlyTranslation\";\n TransformMode[TransformMode[\"NoRotationOrReflection\"] = 2] = \"NoRotationOrReflection\";\n TransformMode[TransformMode[\"NoScale\"] = 3] = \"NoScale\";\n TransformMode[TransformMode[\"NoScaleOrReflection\"] = 4] = \"NoScaleOrReflection\";\n})(TransformMode || (TransformMode = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm9uZURhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQm9uZURhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFbkMsZ0RBQWdEO0FBQ2hELE1BQU0sT0FBTyxRQUFRO0lBQ3BCLDREQUE0RDtJQUM1RCxLQUFLLEdBQVcsQ0FBQyxDQUFDO0lBRWxCLDhFQUE4RTtJQUM5RSxJQUFJLENBQVM7SUFFYiw0QkFBNEI7SUFDNUIsTUFBTSxHQUFvQixJQUFJLENBQUM7SUFFL0IseUJBQXlCO0lBQ3pCLE1BQU0sR0FBVyxDQUFDLENBQUM7SUFFbkIsK0JBQStCO0lBQy9CLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFTiwrQkFBK0I7SUFDL0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVOLHdEQUF3RDtJQUN4RCxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBRWIsd0JBQXdCO0lBQ3hCLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFWCx3QkFBd0I7SUFDeEIsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUVYLHdCQUF3QjtJQUN4QixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRVgsd0JBQXdCO0lBQ3hCLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFWCwyRUFBMkU7SUFDM0UsYUFBYSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUM7SUFFckM7OzBCQUVzQjtJQUN0QixZQUFZLEdBQUcsS0FBSyxDQUFDO0lBRXJCOzhCQUMwQjtJQUMxQixLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztJQUVwQix1RkFBdUY7SUFDdkYsSUFBSSxDQUFVO0lBRWQsbUhBQW1IO0lBQ25ILE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEIsWUFBYSxLQUFhLEVBQUUsSUFBWSxFQUFFLE1BQXVCO1FBQ2hFLElBQUksS0FBSyxHQUFHLENBQUM7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdEIsQ0FBQztDQUNEO0FBRUQseUVBQXlFO0FBQ3pFLE1BQU0sQ0FBTixJQUFZLGFBQStGO0FBQTNHLFdBQVksYUFBYTtJQUFHLHFEQUFNLENBQUE7SUFBRSx1RUFBZSxDQUFBO0lBQUUscUZBQXNCLENBQUE7SUFBRSx1REFBTyxDQUFBO0lBQUUsK0VBQW1CLENBQUE7QUFBQyxDQUFDLEVBQS9GLGFBQWEsS0FBYixhQUFhLFFBQWtGIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { TransformMode } from \"./BoneData.js\";\nimport { MathUtils } from \"./Utils.js\";\n/** Stores a bone's current pose.\n *\n * A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a\n * local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a\n * constraint or application code modifies the world transform after it was computed from the local transform. */\nexport class Bone {\n /** The bone's setup pose data. */\n data;\n /** The skeleton this bone belongs to. */\n skeleton;\n /** The parent bone, or null if this is the root bone. */\n parent = null;\n /** The immediate children of this bone. */\n children = new Array();\n /** The local x translation. */\n x = 0;\n /** The local y translation. */\n y = 0;\n /** The local rotation in degrees, counter clockwise. */\n rotation = 0;\n /** The local scaleX. */\n scaleX = 0;\n /** The local scaleY. */\n scaleY = 0;\n /** The local shearX. */\n shearX = 0;\n /** The local shearY. */\n shearY = 0;\n /** The applied local x translation. */\n ax = 0;\n /** The applied local y translation. */\n ay = 0;\n /** The applied local rotation in degrees, counter clockwise. */\n arotation = 0;\n /** The applied local scaleX. */\n ascaleX = 0;\n /** The applied local scaleY. */\n ascaleY = 0;\n /** The applied local shearX. */\n ashearX = 0;\n /** The applied local shearY. */\n ashearY = 0;\n /** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */\n a = 0;\n /** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */\n b = 0;\n /** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */\n c = 0;\n /** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */\n d = 0;\n /** The world X position. If changed, {@link #updateAppliedTransform()} should be called. */\n worldY = 0;\n /** The world Y position. If changed, {@link #updateAppliedTransform()} should be called. */\n worldX = 0;\n sorted = false;\n active = false;\n /** @param parent May be null. */\n constructor(data, skeleton, parent) {\n if (!data)\n throw new Error(\"data cannot be null.\");\n if (!skeleton)\n throw new Error(\"skeleton cannot be null.\");\n this.data = data;\n this.skeleton = skeleton;\n this.parent = parent;\n this.setToSetupPose();\n }\n /** Returns false when the bone has not been computed because {@link BoneData#skinRequired} is true and the\n * {@link Skeleton#skin active skin} does not {@link Skin#bones contain} this bone. */\n isActive() {\n return this.active;\n }\n /** Computes the world transform using the parent bone and this bone's local applied transform. */\n update(physics) {\n this.updateWorldTransformWith(this.ax, this.ay, this.arotation, this.ascaleX, this.ascaleY, this.ashearX, this.ashearY);\n }\n /** Computes the world transform using the parent bone and this bone's local transform.\n *\n * See {@link #updateWorldTransformWith()}. */\n updateWorldTransform() {\n this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);\n }\n /** Computes the world transform using the parent bone and the specified local transform. The applied transform is set to the\n * specified local transform. Child bones are not updated.\n *\n * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine\n * Runtimes Guide. */\n updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY) {\n this.ax = x;\n this.ay = y;\n this.arotation = rotation;\n this.ascaleX = scaleX;\n this.ascaleY = scaleY;\n this.ashearX = shearX;\n this.ashearY = shearY;\n let parent = this.parent;\n if (!parent) { // Root bone.\n let skeleton = this.skeleton;\n const sx = skeleton.scaleX, sy = skeleton.scaleY;\n const rx = (rotation + shearX) * MathUtils.degRad;\n const ry = (rotation + 90 + shearY) * MathUtils.degRad;\n this.a = Math.cos(rx) * scaleX * sx;\n this.b = Math.cos(ry) * scaleY * sx;\n this.c = Math.sin(rx) * scaleX * sy;\n this.d = Math.sin(ry) * scaleY * sy;\n this.worldX = x * sx + skeleton.x;\n this.worldY = y * sy + skeleton.y;\n return;\n }\n let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;\n this.worldX = pa * x + pb * y + parent.worldX;\n this.worldY = pc * x + pd * y + parent.worldY;\n switch (this.data.transformMode) {\n case TransformMode.Normal: {\n const rx = (rotation + shearX) * MathUtils.degRad;\n const ry = (rotation + 90 + shearY) * MathUtils.degRad;\n const la = Math.cos(rx) * scaleX;\n const lb = Math.cos(ry) * scaleY;\n const lc = Math.sin(rx) * scaleX;\n const ld = Math.sin(ry) * scaleY;\n this.a = pa * la + pb * lc;\n this.b = pa * lb + pb * ld;\n this.c = pc * la + pd * lc;\n this.d = pc * lb + pd * ld;\n return;\n }\n case TransformMode.OnlyTranslation: {\n const rx = (rotation + shearX) * MathUtils.degRad;\n const ry = (rotation + 90 + shearY) * MathUtils.degRad;\n this.a = Math.cos(rx) * scaleX;\n this.b = Math.cos(ry) * scaleY;\n this.c = Math.sin(rx) * scaleX;\n this.d = Math.sin(ry) * scaleY;\n break;\n }\n case TransformMode.NoRotationOrReflection: {\n let s = pa * pa + pc * pc;\n let prx = 0;\n if (s > 0.0001) {\n s = Math.abs(pa * pd - pb * pc) / s;\n pa /= this.skeleton.scaleX;\n pc /= this.skeleton.scaleY;\n pb = pc * s;\n pd = pa * s;\n prx = Math.atan2(pc, pa) * MathUtils.radDeg;\n }\n else {\n pa = 0;\n pc = 0;\n prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg;\n }\n const rx = (rotation + shearX - prx) * MathUtils.degRad;\n const ry = (rotation + shearY - prx + 90) * MathUtils.degRad;\n const la = Math.cos(rx) * scaleX;\n const lb = Math.cos(ry) * scaleY;\n const lc = Math.sin(rx) * scaleX;\n const ld = Math.sin(ry) * scaleY;\n this.a = pa * la - pb * lc;\n this.b = pa * lb - pb * ld;\n this.c = pc * la + pd * lc;\n this.d = pc * lb + pd * ld;\n break;\n }\n case TransformMode.NoScale:\n case TransformMode.NoScaleOrReflection: {\n rotation *= MathUtils.degRad;\n const cos = Math.cos(rotation), sin = Math.sin(rotation);\n let za = (pa * cos + pb * sin) / this.skeleton.scaleX;\n let zc = (pc * cos + pd * sin) / this.skeleton.scaleY;\n let s = Math.sqrt(za * za + zc * zc);\n if (s > 0.00001)\n s = 1 / s;\n za *= s;\n zc *= s;\n s = Math.sqrt(za * za + zc * zc);\n if (this.data.transformMode == TransformMode.NoScale\n && (pa * pd - pb * pc < 0) != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0))\n s = -s;\n rotation = Math.PI / 2 + Math.atan2(zc, za);\n const zb = Math.cos(rotation) * s;\n const zd = Math.sin(rotation) * s;\n shearX *= MathUtils.degRad;\n shearY = (90 + shearY) * MathUtils.degRad;\n const la = Math.cos(shearX) * scaleX;\n const lb = Math.cos(shearY) * scaleY;\n const lc = Math.sin(shearX) * scaleX;\n const ld = Math.sin(shearY) * scaleY;\n this.a = za * la + zb * lc;\n this.b = za * lb + zb * ld;\n this.c = zc * la + zd * lc;\n this.d = zc * lb + zd * ld;\n break;\n }\n }\n this.a *= this.skeleton.scaleX;\n this.b *= this.skeleton.scaleX;\n this.c *= this.skeleton.scaleY;\n this.d *= this.skeleton.scaleY;\n }\n /** Sets this bone's local transform to the setup pose. */\n setToSetupPose() {\n let data = this.data;\n this.x = data.x;\n this.y = data.y;\n this.rotation = data.rotation;\n this.scaleX = data.scaleX;\n this.scaleY = data.scaleY;\n this.shearX = data.shearX;\n this.shearY = data.shearY;\n }\n /** Computes the applied transform values from the world transform.\n *\n * If the world transform is modified (by a constraint, {@link #rotateWorld(float)}, etc) then this method should be called so\n * the applied transform matches the world transform. The applied transform may be needed by other code (eg to apply other\n * constraints).\n *\n * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after\n * calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */\n updateAppliedTransform() {\n let parent = this.parent;\n if (!parent) {\n this.ax = this.worldX - this.skeleton.x;\n this.ay = this.worldY - this.skeleton.y;\n this.arotation = Math.atan2(this.c, this.a) * MathUtils.radDeg;\n this.ascaleX = Math.sqrt(this.a * this.a + this.c * this.c);\n this.ascaleY = Math.sqrt(this.b * this.b + this.d * this.d);\n this.ashearX = 0;\n this.ashearY = Math.atan2(this.a * this.b + this.c * this.d, this.a * this.d - this.b * this.c) * MathUtils.radDeg;\n return;\n }\n let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;\n let pid = 1 / (pa * pd - pb * pc);\n let ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid;\n let dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY;\n this.ax = (dx * ia - dy * ib);\n this.ay = (dy * id - dx * ic);\n let ra, rb, rc, rd;\n if (this.data.transformMode == TransformMode.OnlyTranslation) {\n ra = this.a;\n rb = this.b;\n rc = this.c;\n rd = this.d;\n }\n else {\n switch (this.data.transformMode) {\n case TransformMode.NoRotationOrReflection: {\n let s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc);\n let sa = pa / this.skeleton.scaleX;\n let sc = pc / this.skeleton.scaleY;\n pb = -sc * s * this.skeleton.scaleX;\n pd = sa * s * this.skeleton.scaleY;\n pid = 1 / (pa * pd - pb * pc);\n ia = pd * pid;\n ib = pb * pid;\n break;\n }\n case TransformMode.NoScale:\n case TransformMode.NoScaleOrReflection:\n let cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation);\n pa = (pa * cos + pb * sin) / this.skeleton.scaleX;\n pc = (pc * cos + pd * sin) / this.skeleton.scaleY;\n let s = Math.sqrt(pa * pa + pc * pc);\n if (s > 0.00001)\n s = 1 / s;\n pa *= s;\n pc *= s;\n s = Math.sqrt(pa * pa + pc * pc);\n if (this.data.transformMode == TransformMode.NoScale && pid < 0 != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0))\n s = -s;\n let r = MathUtils.PI / 2 + Math.atan2(pc, pa);\n pb = Math.cos(r) * s;\n pd = Math.sin(r) * s;\n pid = 1 / (pa * pd - pb * pc);\n ia = pd * pid;\n ib = pb * pid;\n ic = pc * pid;\n id = pa * pid;\n }\n ra = ia * this.a - ib * this.c;\n rb = ia * this.b - ib * this.d;\n rc = id * this.c - ic * this.a;\n rd = id * this.d - ic * this.b;\n }\n this.ashearX = 0;\n this.ascaleX = Math.sqrt(ra * ra + rc * rc);\n if (this.ascaleX > 0.0001) {\n let det = ra * rd - rb * rc;\n this.ascaleY = det / this.ascaleX;\n this.ashearY = -Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg;\n this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg;\n }\n else {\n this.ascaleX = 0;\n this.ascaleY = Math.sqrt(rb * rb + rd * rd);\n this.ashearY = 0;\n this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg;\n }\n }\n /** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */\n getWorldRotationX() {\n return Math.atan2(this.c, this.a) * MathUtils.radDeg;\n }\n /** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */\n getWorldRotationY() {\n return Math.atan2(this.d, this.b) * MathUtils.radDeg;\n }\n /** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */\n getWorldScaleX() {\n return Math.sqrt(this.a * this.a + this.c * this.c);\n }\n /** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */\n getWorldScaleY() {\n return Math.sqrt(this.b * this.b + this.d * this.d);\n }\n /** Transforms a point from world coordinates to the bone's local coordinates. */\n worldToLocal(world) {\n let invDet = 1 / (this.a * this.d - this.b * this.c);\n let x = world.x - this.worldX, y = world.y - this.worldY;\n world.x = x * this.d * invDet - y * this.b * invDet;\n world.y = y * this.a * invDet - x * this.c * invDet;\n return world;\n }\n /** Transforms a point from the bone's local coordinates to world coordinates. */\n localToWorld(local) {\n let x = local.x, y = local.y;\n local.x = x * this.a + y * this.b + this.worldX;\n local.y = x * this.c + y * this.d + this.worldY;\n return local;\n }\n /** Transforms a point from world coordinates to the parent bone's local coordinates. */\n worldToParent(world) {\n if (world == null)\n throw new Error(\"world cannot be null.\");\n return this.parent == null ? world : this.parent.worldToLocal(world);\n }\n /** Transforms a point from the parent bone's coordinates to world coordinates. */\n parentToWorld(world) {\n if (world == null)\n throw new Error(\"world cannot be null.\");\n return this.parent == null ? world : this.parent.localToWorld(world);\n }\n /** Transforms a world rotation to a local rotation. */\n worldToLocalRotation(worldRotation) {\n let sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation);\n return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * MathUtils.radDeg + this.rotation - this.shearX;\n }\n /** Transforms a local rotation to a world rotation. */\n localToWorldRotation(localRotation) {\n localRotation -= this.rotation - this.shearX;\n let sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation);\n return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * MathUtils.radDeg;\n }\n /** Rotates the world transform the specified amount.\n *

\n * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and\n * {@link #update(Physics)} will need to be called on any child bones, recursively. */\n rotateWorld(degrees) {\n degrees *= MathUtils.degRad;\n const sin = Math.sin(degrees), cos = Math.cos(degrees);\n const ra = this.a, rb = this.b;\n this.a = cos * ra - sin * this.c;\n this.b = cos * rb - sin * this.d;\n this.c = sin * ra + cos * this.c;\n this.d = sin * rb + cos * this.d;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm9uZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Cb25lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUUvRSxPQUFPLEVBQVksYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3hELE9BQU8sRUFBRSxTQUFTLEVBQVcsTUFBTSxZQUFZLENBQUM7QUFFaEQ7Ozs7aUhBSWlIO0FBQ2pILE1BQU0sT0FBTyxJQUFJO0lBQ2hCLGtDQUFrQztJQUNsQyxJQUFJLENBQVc7SUFFZix5Q0FBeUM7SUFDekMsUUFBUSxDQUFXO0lBRW5CLHlEQUF5RDtJQUN6RCxNQUFNLEdBQWdCLElBQUksQ0FBQztJQUUzQiwyQ0FBMkM7SUFDM0MsUUFBUSxHQUFHLElBQUksS0FBSyxFQUFRLENBQUM7SUFFN0IsK0JBQStCO0lBQy9CLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFTiwrQkFBK0I7SUFDL0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVOLHdEQUF3RDtJQUN4RCxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBRWIsd0JBQXdCO0lBQ3hCLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFWCx3QkFBd0I7SUFDeEIsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUVYLHdCQUF3QjtJQUN4QixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRVgsd0JBQXdCO0lBQ3hCLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFWCx1Q0FBdUM7SUFDdkMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUVQLHVDQUF1QztJQUN2QyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBRVAsZ0VBQWdFO0lBQ2hFLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFFZCxnQ0FBZ0M7SUFDaEMsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUVaLGdDQUFnQztJQUNoQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBRVosZ0NBQWdDO0lBQ2hDLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFF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LFNBQVMsQ0FBQyxNQUFNLENBQUM7WUFDdkQsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDbEMsT0FBTztTQUNQO1FBRUQsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQzlDLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFFOUMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNoQyxLQUFLLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDMUIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztnQkFDbEQsTUFBTSxFQUFFLEdBQUcsQ0FBQyxRQUFRLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7Z0JBQ3ZELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUNqQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQztnQkFDakMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUM7Z0JBQ2pDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUNqQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO2dCQUMzQixJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsT0FBTzthQUNQO1lBQ0QsS0FBSyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ25DLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7Z0JBQ2xELE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO2dCQUN2RCxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUMvQixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUMvQixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUMvQixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUMvQixNQUFNO2FBQ047WUFDRCxLQUFLLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7Z0JBQzFCLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztnQkFDWixJQUFJLENBQUMsR0FBRyxNQUFNLEVBQUU7b0JBQ2YsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNwQyxFQUFFLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7b0JBQzNCLEVBQUUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztvQkFDM0IsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBQ1osRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBQ1osR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7aUJBQzVDO3FCQUFNO29CQUNOLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBQ1AsRUFBRSxHQUFHLENBQUMsQ0FBQztvQkFDUCxHQUFHLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7aUJBQ2pEO2dCQUNELE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxHQUFHLE1BQU0sR0FBRyxHQUFHLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO2dCQUN4RCxNQUFNLEVBQUUsR0FBRyxDQUFDLFFBQVEsR0FBRyxNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7Z0JBQzdELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUNqQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQztnQkFDakMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUM7Z0JBQ2pDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUNqQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO2dCQUMzQixJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsTUFBTTthQUNOO1lBQ0QsS0FBSyxhQUFhLENBQUMsT0FBTyxDQUFDO1lBQzNCLEtBQUssYUFBYSxDQUFDLG1CQUFtQixDQUFDLENBQUM7Z0JBQ3ZDLFFBQVEsSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDO2dCQUM3QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN6RCxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO2dCQUN0RCxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO2dCQUN0RCxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO2dCQUNyQyxJQUFJLENBQUMsR0FBRyxPQUFPO29CQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMzQixFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNSLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ1IsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7Z0JBQ2pDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksYUFBYSxDQUFDLE9BQU87dUJBQ2hELENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztvQkFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQzlGLFFBQVEsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDNUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2xDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNsQyxNQUFNLElBQUksU0FBUyxDQUFDLE1BQU0sQ0FBQztnQkFDM0IsTUFBTSxHQUFHLENBQUMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7Z0JBQzFDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUNyQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQztnQkFDckMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUM7Z0JBQ3JDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUNyQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO2dCQUMzQixJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsTUFBTTthQUNOO1NBQ0Q7UUFDRCxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQy9CLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDL0IsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztRQUMvQixJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO0lBQ2hDLENBQUM7SUFFRCwwREFBMEQ7SUFDMUQsY0FBYztRQUNiLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNoQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzFCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDMUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQzNCLENBQUM7SUFFRDs7Ozs7OztpSUFPNkg7SUFDN0gsc0JBQXNCO1FBQ3JCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDekIsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNaLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUN4QyxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7WUFDL0QsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1RCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVELElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1lBQ25ILE9BQU87U0FDUDtRQUNELElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDL0QsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDbEMsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztRQUMvRCxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUN2RSxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRTlCLElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ25CLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksYUFBYSxDQUFDLGVBQWUsRUFBRTtZQUM3RCxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNaLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ1osRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDWixFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUNaO2FBQU07WUFDTixRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUNoQyxLQUFLLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO29CQUMxQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7b0JBQzFELElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztvQkFDbkMsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO29CQUNuQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO29CQUNwQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztvQkFDbkMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO29CQUM5QixFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztvQkFDZCxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztvQkFDZCxNQUFNO2lCQUNOO2dCQUNELEtBQUssYUFBYSxDQUFDLE9BQU8sQ0FBQztnQkFDM0IsS0FBSyxhQUFhLENBQUMsbUJBQW1CO29CQUNyQyxJQUFJLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ2pGLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO29CQUNsRCxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztvQkFDbEQsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztvQkFDckMsSUFBSSxDQUFDLEdBQUcsT0FBTzt3QkFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDM0IsRUFBRSxJQUFJLENBQUMsQ0FBQztvQkFDUixFQUFFLElBQUksQ0FBQyxDQUFDO29CQUNSLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO29CQUNqQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLGFBQWEsQ0FBQyxPQUFPLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7d0JBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO29CQUNsSSxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDOUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNyQixFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3JCLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztvQkFDOUIsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7b0JBQ2QsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7b0JBQ2QsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7b0JBQ2QsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7YUFDZjtZQUNELEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUMvQixFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDL0IsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQy9CLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUMvQjtRQUVELElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM1QyxJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxFQUFFO1lBQzFCLElBQUksR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1lBQ3RFLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztTQUN2RDthQUFNO1lBQ04sSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7WUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7U0FDNUQ7SUFDRixDQUFDO0lBR0QscUZBQXFGO0lBQ3JGLGlCQUFpQjtRQUNoQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztJQUN0RCxDQUFDO0lBRUQscUZBQXFGO0lBQ3JGLGlCQUFpQjtRQUNoQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztJQUN0RCxDQUFDO0lBRUQsd0dBQXdHO0lBQ3hHLGNBQWM7UUFDYixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFRCx3R0FBd0c7SUFDeEcsY0FBYztRQUNiLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVELGlGQUFpRjtJQUNqRixZQUFZLENBQUUsS0FBYztRQUMzQixJQUFJLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDekQsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ3BELEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUNwRCxPQUFPLEtBQUssQ0FBQztJQUNkLENBQUM7SUFFRCxpRkFBaUY7SUFDakYsWUFBWSxDQUFFLEtBQWM7UUFDM0IsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM3QixLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDaEQsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ2hELE9BQU8sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVELHdGQUF3RjtJQUN4RixhQUFhLENBQUUsS0FBYztRQUM1QixJQUFJLEtBQUssSUFBSSxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQzVELE9BQU8sSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELGtGQUFrRjtJQUNsRixhQUFhLENBQUUsS0FBYztRQUM1QixJQUFJLEtBQUssSUFBSSxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQzVELE9BQU8sSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELHVEQUF1RDtJQUN2RCxvQkFBb0IsQ0FBRSxhQUFxQjtRQUMxQyxJQUFJLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2pGLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQzlILENBQUM7SUFFRCx1REFBdUQ7SUFDdkQsb0JBQW9CLENBQUUsYUFBcUI7UUFDMUMsYUFBYSxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUM3QyxJQUFJLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2pGLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDaEcsQ0FBQztJQUVEOzs7MEZBR3NGO0lBQ3RGLFdBQVcsQ0FBRSxPQUFlO1FBQzNCLE9BQU8sSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdkQsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDbEMsQ0FBQztDQUNEIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\n/** The base class for all constraint datas. */\nexport class ConstraintData {\n name;\n order;\n skinRequired;\n constructor(name, order, skinRequired) {\n this.name = name;\n this.order = order;\n this.skinRequired = skinRequired;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uc3RyYWludERhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQ29uc3RyYWludERhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLCtDQUErQztBQUMvQyxNQUFNLE9BQWdCLGNBQWM7SUFDZjtJQUFxQjtJQUFzQjtJQUEvRCxZQUFvQixJQUFZLEVBQVMsS0FBYSxFQUFTLFlBQXFCO1FBQWhFLFNBQUksR0FBSixJQUFJLENBQVE7UUFBUyxVQUFLLEdBQUwsS0FBSyxDQUFRO1FBQVMsaUJBQVksR0FBWixZQUFZLENBQVM7SUFBSSxDQUFDO0NBQ3pGIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { TextureAtlas } from \"./TextureAtlas.js\";\nexport class AssetManagerBase {\n pathPrefix = \"\";\n textureLoader;\n downloader;\n assets = {};\n errors = {};\n toLoad = 0;\n loaded = 0;\n constructor(textureLoader, pathPrefix = \"\", downloader = new Downloader()) {\n this.textureLoader = textureLoader;\n this.pathPrefix = pathPrefix;\n this.downloader = downloader;\n }\n start(path) {\n this.toLoad++;\n return this.pathPrefix + path;\n }\n success(callback, path, asset) {\n this.toLoad--;\n this.loaded++;\n this.assets[path] = asset;\n if (callback)\n callback(path, asset);\n }\n error(callback, path, message) {\n this.toLoad--;\n this.loaded++;\n this.errors[path] = message;\n if (callback)\n callback(path, message);\n }\n loadAll() {\n let promise = new Promise((resolve, reject) => {\n let check = () => {\n if (this.isLoadingComplete()) {\n if (this.hasErrors())\n reject(this.errors);\n else\n resolve(this);\n return;\n }\n requestAnimationFrame(check);\n };\n requestAnimationFrame(check);\n });\n return promise;\n }\n setRawDataURI(path, data) {\n this.downloader.rawDataUris[this.pathPrefix + path] = data;\n }\n loadBinary(path, success = () => { }, error = () => { }) {\n path = this.start(path);\n this.downloader.downloadBinary(path, (data) => {\n this.success(success, path, data);\n }, (status, responseText) => {\n this.error(error, path, `Couldn't load binary ${path}: status ${status}, ${responseText}`);\n });\n }\n loadText(path, success = () => { }, error = () => { }) {\n path = this.start(path);\n this.downloader.downloadText(path, (data) => {\n this.success(success, path, data);\n }, (status, responseText) => {\n this.error(error, path, `Couldn't load text ${path}: status ${status}, ${responseText}`);\n });\n }\n loadJson(path, success = () => { }, error = () => { }) {\n path = this.start(path);\n this.downloader.downloadJson(path, (data) => {\n this.success(success, path, data);\n }, (status, responseText) => {\n this.error(error, path, `Couldn't load JSON ${path}: status ${status}, ${responseText}`);\n });\n }\n loadTexture(path, success = () => { }, error = () => { }) {\n path = this.start(path);\n let isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document);\n let isWebWorker = !isBrowser; // && typeof importScripts !== 'undefined';\n if (isWebWorker) {\n fetch(path, { mode: \"cors\" }).then((response) => {\n if (response.ok)\n return response.blob();\n this.error(error, path, `Couldn't load image: ${path}`);\n return null;\n }).then((blob) => {\n return blob ? createImageBitmap(blob, { premultiplyAlpha: \"none\", colorSpaceConversion: \"none\" }) : null;\n }).then((bitmap) => {\n if (bitmap)\n this.success(success, path, this.textureLoader(bitmap));\n });\n }\n else {\n let image = new Image();\n image.crossOrigin = \"anonymous\";\n image.onload = () => {\n this.success(success, path, this.textureLoader(image));\n };\n image.onerror = () => {\n this.error(error, path, `Couldn't load image: ${path}`);\n };\n if (this.downloader.rawDataUris[path])\n path = this.downloader.rawDataUris[path];\n image.src = path;\n }\n }\n loadTextureAtlas(path, success = () => { }, error = () => { }, fileAlias) {\n let index = path.lastIndexOf(\"/\");\n let parent = index >= 0 ? path.substring(0, index + 1) : \"\";\n path = this.start(path);\n this.downloader.downloadText(path, (atlasText) => {\n try {\n let atlas = new TextureAtlas(atlasText);\n let toLoad = atlas.pages.length, abort = false;\n for (let page of atlas.pages) {\n this.loadTexture(!fileAlias ? parent + page.name : fileAlias[page.name], (imagePath, texture) => {\n if (!abort) {\n page.setTexture(texture);\n if (--toLoad == 0)\n this.success(success, path, atlas);\n }\n }, (imagePath, message) => {\n if (!abort)\n this.error(error, path, `Couldn't load texture atlas ${path} page image: ${imagePath}`);\n abort = true;\n });\n }\n }\n catch (e) {\n this.error(error, path, `Couldn't parse texture atlas ${path}: ${e.message}`);\n }\n }, (status, responseText) => {\n this.error(error, path, `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`);\n });\n }\n get(path) {\n return this.assets[this.pathPrefix + path];\n }\n require(path) {\n path = this.pathPrefix + path;\n let asset = this.assets[path];\n if (asset)\n return asset;\n let error = this.errors[path];\n throw Error(\"Asset not found: \" + path + (error ? \"\\n\" + error : \"\"));\n }\n remove(path) {\n path = this.pathPrefix + path;\n let asset = this.assets[path];\n if (asset.dispose)\n asset.dispose();\n delete this.assets[path];\n return asset;\n }\n removeAll() {\n for (let key in this.assets) {\n let asset = this.assets[key];\n if (asset.dispose)\n asset.dispose();\n }\n this.assets = {};\n }\n isLoadingComplete() {\n return this.toLoad == 0;\n }\n getToLoad() {\n return this.toLoad;\n }\n getLoaded() {\n return this.loaded;\n }\n dispose() {\n this.removeAll();\n }\n hasErrors() {\n return Object.keys(this.errors).length > 0;\n }\n getErrors() {\n return this.errors;\n }\n}\nexport class Downloader {\n callbacks = {};\n rawDataUris = {};\n dataUriToString(dataUri) {\n if (!dataUri.startsWith(\"data:\")) {\n throw new Error(\"Not a data URI.\");\n }\n let base64Idx = dataUri.indexOf(\"base64,\");\n if (base64Idx != -1) {\n base64Idx += \"base64,\".length;\n return atob(dataUri.substr(base64Idx));\n }\n else {\n return dataUri.substr(dataUri.indexOf(\",\") + 1);\n }\n }\n base64ToUint8Array(base64) {\n var binary_string = window.atob(base64);\n var len = binary_string.length;\n var bytes = new Uint8Array(len);\n for (var i = 0; i < len; i++) {\n bytes[i] = binary_string.charCodeAt(i);\n }\n return bytes;\n }\n dataUriToUint8Array(dataUri) {\n if (!dataUri.startsWith(\"data:\")) {\n throw new Error(\"Not a data URI.\");\n }\n let base64Idx = dataUri.indexOf(\"base64,\");\n if (base64Idx == -1)\n throw new Error(\"Not a binary data URI.\");\n base64Idx += \"base64,\".length;\n return this.base64ToUint8Array(dataUri.substr(base64Idx));\n }\n downloadText(url, success, error) {\n if (this.start(url, success, error))\n return;\n if (this.rawDataUris[url]) {\n try {\n let dataUri = this.rawDataUris[url];\n this.finish(url, 200, this.dataUriToString(dataUri));\n }\n catch (e) {\n this.finish(url, 400, JSON.stringify(e));\n }\n return;\n }\n let request = new XMLHttpRequest();\n request.overrideMimeType(\"text/html\");\n request.open(\"GET\", url, true);\n let done = () => {\n this.finish(url, request.status, request.responseText);\n };\n request.onload = done;\n request.onerror = done;\n request.send();\n }\n downloadJson(url, success, error) {\n this.downloadText(url, (data) => {\n success(JSON.parse(data));\n }, error);\n }\n downloadBinary(url, success, error) {\n if (this.start(url, success, error))\n return;\n if (this.rawDataUris[url]) {\n try {\n let dataUri = this.rawDataUris[url];\n this.finish(url, 200, this.dataUriToUint8Array(dataUri));\n }\n catch (e) {\n this.finish(url, 400, JSON.stringify(e));\n }\n return;\n }\n let request = new XMLHttpRequest();\n request.open(\"GET\", url, true);\n request.responseType = \"arraybuffer\";\n let onerror = () => {\n this.finish(url, request.status, request.response);\n };\n request.onload = () => {\n if (request.status == 200 || request.status == 0)\n this.finish(url, 200, new Uint8Array(request.response));\n else\n onerror();\n };\n request.onerror = onerror;\n request.send();\n }\n start(url, success, error) {\n let callbacks = this.callbacks[url];\n try {\n if (callbacks)\n return true;\n this.callbacks[url] = callbacks = [];\n }\n finally {\n callbacks.push(success, error);\n }\n }\n finish(url, status, data) {\n let callbacks = this.callbacks[url];\n delete this.callbacks[url];\n let args = status == 200 || status == 0 ? [data] : [status, data];\n for (let i = args.length - 1, n = callbacks.length; i < n; i += 2)\n callbacks[i].apply(null, args);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXNzZXRNYW5hZ2VyQmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Bc3NldE1hbmFnZXJCYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHakQsTUFBTSxPQUFPLGdCQUFnQjtJQUNwQixVQUFVLEdBQVcsRUFBRSxDQUFDO0lBQ3hCLGFBQWEsQ0FBcUQ7SUFDbEUsVUFBVSxDQUFhO0lBQ3ZCLE1BQU0sR0FBbUIsRUFBRSxDQUFDO0lBQzVCLE1BQU0sR0FBc0IsRUFBRSxDQUFDO0lBQy9CLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRW5CLFlBQWEsYUFBaUUsRUFBRSxhQUFxQixFQUFFLEVBQUUsYUFBeUIsSUFBSSxVQUFVLEVBQUU7UUFDakosSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDbkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7SUFDOUIsQ0FBQztJQUVPLEtBQUssQ0FBRSxJQUFZO1FBQzFCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLE9BQU8sSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDL0IsQ0FBQztJQUVPLE9BQU8sQ0FBRSxRQUEyQyxFQUFFLElBQVksRUFBRSxLQUFVO1FBQ3JGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksUUFBUTtZQUFFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVPLEtBQUss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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\n/** Stores the current pose values for an {@link Event}.\n *\n * See Timeline {@link Timeline#apply()},\n * AnimationStateListener {@link AnimationStateListener#event()}, and\n * [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. */\nexport class Event {\n data;\n intValue = 0;\n floatValue = 0;\n stringValue = null;\n time = 0;\n volume = 0;\n balance = 0;\n constructor(time, data) {\n if (!data)\n throw new Error(\"data cannot be null.\");\n this.time = time;\n this.data = data;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXZlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvRXZlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSS9FOzs7O2lGQUlpRjtBQUNqRixNQUFNLE9BQU8sS0FBSztJQUNqQixJQUFJLENBQVk7SUFDaEIsUUFBUSxHQUFXLENBQUMsQ0FBQztJQUNyQixVQUFVLEdBQVcsQ0FBQyxDQUFDO0lBQ3ZCLFdBQVcsR0FBa0IsSUFBSSxDQUFDO0lBQ2xDLElBQUksR0FBVyxDQUFDLENBQUM7SUFDakIsTUFBTSxHQUFXLENBQUMsQ0FBQztJQUNuQixPQUFPLEdBQVcsQ0FBQyxDQUFDO0lBRXBCLFlBQWEsSUFBWSxFQUFFLElBQWU7UUFDekMsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbEIsQ0FBQztDQUNEIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\n/** Stores the setup pose values for an {@link Event}.\n *\n * See [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. */\nexport class EventData {\n name;\n intValue = 0;\n floatValue = 0;\n stringValue = null;\n audioPath = null;\n volume = 0;\n balance = 0;\n constructor(name) {\n this.name = name;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXZlbnREYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0V2ZW50RGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0U7O3FGQUVxRjtBQUNyRixNQUFNLE9BQU8sU0FBUztJQUNyQixJQUFJLENBQVM7SUFDYixRQUFRLEdBQVcsQ0FBQyxDQUFDO0lBQ3JCLFVBQVUsR0FBVyxDQUFDLENBQUM7SUFDdkIsV0FBVyxHQUFrQixJQUFJLENBQUM7SUFDbEMsU0FBUyxHQUFrQixJQUFJLENBQUM7SUFDaEMsTUFBTSxHQUFXLENBQUMsQ0FBQztJQUNuQixPQUFPLEdBQVcsQ0FBQyxDQUFDO0lBRXBCLFlBQWEsSUFBWTtRQUN4QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNsQixDQUFDO0NBQ0QifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { TransformMode } from \"./BoneData.js\";\nimport { MathUtils } from \"./Utils.js\";\n/** Stores the current pose for an IK constraint. An IK constraint adjusts the rotation of 1 or 2 constrained bones so the tip of\n * the last bone is as close to the target bone as possible.\n *\n * See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. */\nexport class IkConstraint {\n /** The IK constraint's setup pose data. */\n data;\n /** The bones that will be modified by this IK constraint. */\n bones;\n /** The bone that is the IK target. */\n target;\n /** Controls the bend direction of the IK bones, either 1 or -1. */\n bendDirection = 0;\n /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */\n compress = false;\n /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained\n * and the parent bone has local nonuniform scale, stretch is not applied. */\n stretch = false;\n /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */\n mix = 1;\n /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */\n softness = 0;\n active = false;\n constructor(data, skeleton) {\n if (!data)\n throw new Error(\"data cannot be null.\");\n if (!skeleton)\n throw new Error(\"skeleton cannot be null.\");\n this.data = data;\n this.mix = data.mix;\n this.softness = data.softness;\n this.bendDirection = data.bendDirection;\n this.compress = data.compress;\n this.stretch = data.stretch;\n this.bones = new Array();\n for (let i = 0; i < data.bones.length; i++) {\n let bone = skeleton.findBone(data.bones[i].name);\n if (!bone)\n throw new Error(`Couldn't find bone ${data.bones[i].name}`);\n this.bones.push(bone);\n }\n let target = skeleton.findBone(data.target.name);\n if (!target)\n throw new Error(`Couldn't find bone ${data.target.name}`);\n this.target = target;\n }\n isActive() {\n return this.active;\n }\n setToSetupPose() {\n const data = this.data;\n this.mix = data.mix;\n this.softness = data.softness;\n this.bendDirection = data.bendDirection;\n this.compress = data.compress;\n this.stretch = data.stretch;\n }\n update(physics) {\n if (this.mix == 0)\n return;\n let target = this.target;\n let bones = this.bones;\n switch (bones.length) {\n case 1:\n this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix);\n break;\n case 2:\n this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.data.uniform, this.softness, this.mix);\n break;\n }\n }\n /** Applies 1 bone IK. The target is specified in the world coordinate system. */\n apply1(bone, targetX, targetY, compress, stretch, uniform, alpha) {\n let p = bone.parent;\n if (!p)\n throw new Error(\"IK bone must have parent.\");\n let pa = p.a, pb = p.b, pc = p.c, pd = p.d;\n let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0;\n switch (bone.data.transformMode) {\n case TransformMode.OnlyTranslation:\n tx = (targetX - bone.worldX) * MathUtils.signum(bone.skeleton.scaleX);\n ty = (targetY - bone.worldY) * MathUtils.signum(bone.skeleton.scaleY);\n break;\n case TransformMode.NoRotationOrReflection:\n let s = Math.abs(pa * pd - pb * pc) / Math.max(0.0001, pa * pa + pc * pc);\n let sa = pa / bone.skeleton.scaleX;\n let sc = pc / bone.skeleton.scaleY;\n pb = -sc * s * bone.skeleton.scaleX;\n pd = sa * s * bone.skeleton.scaleY;\n rotationIK += Math.atan2(sc, sa) * MathUtils.radDeg;\n // Fall through\n default:\n let x = targetX - p.worldX, y = targetY - p.worldY;\n let d = pa * pd - pb * pc;\n if (Math.abs(d) <= 0.0001) {\n tx = 0;\n ty = 0;\n }\n else {\n tx = (x * pd - y * pb) / d - bone.ax;\n ty = (y * pa - x * pc) / d - bone.ay;\n }\n }\n rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg;\n if (bone.ascaleX < 0)\n rotationIK += 180;\n if (rotationIK > 180)\n rotationIK -= 360;\n else if (rotationIK < -180)\n rotationIK += 360;\n let sx = bone.ascaleX, sy = bone.ascaleY;\n if (compress || stretch) {\n switch (bone.data.transformMode) {\n case TransformMode.NoScale:\n case TransformMode.NoScaleOrReflection:\n tx = targetX - bone.worldX;\n ty = targetY - bone.worldY;\n }\n const b = bone.data.length * sx;\n if (b > 0.0001) {\n const dd = tx * tx + ty * ty;\n if ((compress && dd < b * b) || (stretch && dd > b * b)) {\n const s = (Math.sqrt(dd) / b - 1) * alpha + 1;\n sx *= s;\n if (uniform)\n sy *= s;\n }\n }\n }\n bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY);\n }\n /** Applies 2 bone IK. The target is specified in the world coordinate system.\n * @param child A direct descendant of the parent bone. */\n apply2(parent, child, targetX, targetY, bendDir, stretch, uniform, softness, alpha) {\n let px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX;\n let os1 = 0, os2 = 0, s2 = 0;\n if (psx < 0) {\n psx = -psx;\n os1 = 180;\n s2 = -1;\n }\n else {\n os1 = 0;\n s2 = 1;\n }\n if (psy < 0) {\n psy = -psy;\n s2 = -s2;\n }\n if (csx < 0) {\n csx = -csx;\n os2 = 180;\n }\n else\n os2 = 0;\n let cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d;\n let u = Math.abs(psx - psy) <= 0.0001;\n if (!u || stretch) {\n cy = 0;\n cwx = a * cx + parent.worldX;\n cwy = c * cx + parent.worldY;\n }\n else {\n cy = child.ay;\n cwx = a * cx + b * cy + parent.worldX;\n cwy = c * cx + d * cy + parent.worldY;\n }\n let pp = parent.parent;\n if (!pp)\n throw new Error(\"IK parent must itself have a parent.\");\n a = pp.a;\n b = pp.b;\n c = pp.c;\n d = pp.d;\n let id = a * d - b * c, x = cwx - pp.worldX, y = cwy - pp.worldY;\n id = Math.abs(id) <= 0.0001 ? 0 : 1 / id;\n let dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;\n let l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2;\n if (l1 < 0.0001) {\n this.apply1(parent, targetX, targetY, false, stretch, false, alpha);\n child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);\n return;\n }\n x = targetX - pp.worldX;\n y = targetY - pp.worldY;\n let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;\n let dd = tx * tx + ty * ty;\n if (softness != 0) {\n softness *= psx * (csx + 1) * 0.5;\n let td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness;\n if (sd > 0) {\n let p = Math.min(1, sd / (softness * 2)) - 1;\n p = (sd - softness * (1 - p * p)) / td;\n tx -= p * tx;\n ty -= p * ty;\n dd = tx * tx + ty * ty;\n }\n }\n outer: if (u) {\n l2 *= psx;\n let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);\n if (cos < -1) {\n cos = -1;\n a2 = Math.PI * bendDir;\n }\n else if (cos > 1) {\n cos = 1;\n a2 = 0;\n if (stretch) {\n a = (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;\n sx *= a;\n if (uniform)\n sy *= a;\n }\n }\n else\n a2 = Math.acos(cos) * bendDir;\n a = l1 + l2 * cos;\n b = l2 * Math.sin(a2);\n a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);\n }\n else {\n a = psx * l2;\n b = psy * l2;\n let aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);\n c = bb * l1 * l1 + aa * dd - aa * bb;\n let c1 = -2 * bb * l1, c2 = bb - aa;\n d = c1 * c1 - 4 * c2 * c;\n if (d >= 0) {\n let q = Math.sqrt(d);\n if (c1 < 0)\n q = -q;\n q = -(c1 + q) * 0.5;\n let r0 = q / c2, r1 = c / q;\n let r = Math.abs(r0) < Math.abs(r1) ? r0 : r1;\n if (r * r <= dd) {\n y = Math.sqrt(dd - r * r) * bendDir;\n a1 = ta - Math.atan2(y, r);\n a2 = Math.atan2(y / psy, (r - l1) / psx);\n break outer;\n }\n }\n let minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;\n let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;\n c = -a * l1 / (aa - bb);\n if (c >= -1 && c <= 1) {\n c = Math.acos(c);\n x = a * Math.cos(c) + l1;\n y = b * Math.sin(c);\n d = x * x + y * y;\n if (d < minDist) {\n minAngle = c;\n minDist = d;\n minX = x;\n minY = y;\n }\n if (d > maxDist) {\n maxAngle = c;\n maxDist = d;\n maxX = x;\n maxY = y;\n }\n }\n if (dd <= (minDist + maxDist) * 0.5) {\n a1 = ta - Math.atan2(minY * bendDir, minX);\n a2 = minAngle * bendDir;\n }\n else {\n a1 = ta - Math.atan2(maxY * bendDir, maxX);\n a2 = maxAngle * bendDir;\n }\n }\n let os = Math.atan2(cy, cx) * s2;\n let rotation = parent.arotation;\n a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation;\n if (a1 > 180)\n a1 -= 360;\n else if (a1 < -180) //\n a1 += 360;\n parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, sy, 0, 0);\n rotation = child.arotation;\n a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;\n if (a2 > 180)\n a2 -= 360;\n else if (a2 < -180) //\n a2 += 360;\n child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSWtDb25zdHJhaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0lrQ29uc3RyYWludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUk5QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXZDOzs7cUdBR3FHO0FBQ3JHLE1BQU0sT0FBTyxZQUFZO0lBQ3hCLDJDQUEyQztJQUMzQyxJQUFJLENBQW1CO0lBRXZCLDZEQUE2RDtJQUM3RCxLQUFLLENBQWM7SUFFbkIsc0NBQXNDO0lBQ3RDLE1BQU0sQ0FBTztJQUViLG1FQUFtRTtJQUNuRSxhQUFhLEdBQUcsQ0FBQyxDQUFDO0lBRWxCLHlIQUF5SDtJQUN6SCxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBRWpCO2lGQUM2RTtJQUM3RSxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBRWhCLG9HQUFvRztJQUNwRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBRVIsaUdBQWlHO0lBQ2pHLFFBQVEsR0FBRyxDQUFDLENBQUM7SUFDYixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBRWYsWUFBYSxJQUFzQixFQUFFLFFBQWtCO1FBQ3RELElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUNwQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxD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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { ConstraintData } from \"./ConstraintData.js\";\n/** Stores the setup pose for an {@link IkConstraint}.\n *

\n * See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. */\nexport class IkConstraintData extends ConstraintData {\n /** The bones that are constrained by this IK constraint. */\n bones = new Array();\n /** The bone that is the IK target. */\n _target = null;\n set target(boneData) { this._target = boneData; }\n get target() {\n if (!this._target)\n throw new Error(\"BoneData not set.\");\n else\n return this._target;\n }\n /** Controls the bend direction of the IK bones, either 1 or -1. */\n bendDirection = 1;\n /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */\n compress = false;\n /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained\n * and the parent bone has local nonuniform scale, stretch is not applied. */\n stretch = false;\n /** When true, only a single bone is being constrained, and {@link #getCompress()} or {@link #getStretch()} is used, the bone\n * is scaled on both the X and Y axes. */\n uniform = false;\n /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */\n mix = 1;\n /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */\n softness = 0;\n constructor(name) {\n super(name, 0, false);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSWtDb25zdHJhaW50RGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Ja0NvbnN0cmFpbnREYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHckQ7O3FHQUVxRztBQUNyRyxNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsY0FBYztJQUNuRCw0REFBNEQ7SUFDNUQsS0FBSyxHQUFHLElBQUksS0FBSyxFQUFZLENBQUM7SUFFOUIsc0NBQXNDO0lBQzlCLE9BQU8sR0FBb0IsSUFBSSxDQUFDO0lBQ3hDLElBQVcsTUFBTSxDQUFFLFFBQWtCLElBQUksSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ25FLElBQVcsTUFBTTtRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUE7O1lBQ2xELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUMxQixDQUFDO0lBRUQsbUVBQW1FO0lBQ25FLGFBQWEsR0FBRyxDQUFDLENBQUM7SUFFbEIseUhBQXlIO0lBQ3pILFFBQVEsR0FBRyxLQUFLLENBQUM7SUFFakI7aUZBQzZFO0lBQzdFLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEI7NkNBQ3lDO0lBQ3pDLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEIsb0dBQW9HO0lBQ3BHLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFFUixpR0FBaUc7SUFDakcsUUFBUSxHQUFHLENBQUMsQ0FBQztJQUViLFlBQWEsSUFBWTtRQUN4QixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2QixDQUFDO0NBQ0QifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { ConstraintData } from \"./ConstraintData.js\";\n/** Stores the setup pose for a {@link PathConstraint}.\n *\n * See [path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. */\nexport class PathConstraintData extends ConstraintData {\n /** The bones that will be modified by this path constraint. */\n bones = new Array();\n /** The slot whose path attachment will be used to constrained the bones. */\n _target = null;\n set target(slotData) { this._target = slotData; }\n get target() {\n if (!this._target)\n throw new Error(\"SlotData not set.\");\n else\n return this._target;\n }\n /** The mode for positioning the first bone on the path. */\n positionMode = PositionMode.Fixed;\n /** The mode for positioning the bones after the first bone on the path. */\n spacingMode = SpacingMode.Fixed;\n /** The mode for adjusting the rotation of the bones. */\n rotateMode = RotateMode.Chain;\n /** An offset added to the constrained bone rotation. */\n offsetRotation = 0;\n /** The position along the path. */\n position = 0;\n /** The spacing between bones. */\n spacing = 0;\n mixRotate = 0;\n mixX = 0;\n mixY = 0;\n constructor(name) {\n super(name, 0, false);\n }\n}\n/** Controls how the first bone is positioned along the path.\n *\n * See [position](http://esotericsoftware.com/spine-path-constraints#Position) in the Spine User Guide. */\nexport var PositionMode;\n(function (PositionMode) {\n PositionMode[PositionMode[\"Fixed\"] = 0] = \"Fixed\";\n PositionMode[PositionMode[\"Percent\"] = 1] = \"Percent\";\n})(PositionMode || (PositionMode = {}));\n/** Controls how bones after the first bone are positioned along the path.\n *\n * See [spacing](http://esotericsoftware.com/spine-path-constraints#Spacing) in the Spine User Guide. */\nexport var SpacingMode;\n(function (SpacingMode) {\n SpacingMode[SpacingMode[\"Length\"] = 0] = \"Length\";\n SpacingMode[SpacingMode[\"Fixed\"] = 1] = \"Fixed\";\n SpacingMode[SpacingMode[\"Percent\"] = 2] = \"Percent\";\n SpacingMode[SpacingMode[\"Proportional\"] = 3] = \"Proportional\";\n})(SpacingMode || (SpacingMode = {}));\n/** Controls how bones are rotated, translated, and scaled to match the path.\n *\n * See [rotate mix](http://esotericsoftware.com/spine-path-constraints#Rotate-mix) in the Spine User Guide. */\nexport var RotateMode;\n(function (RotateMode) {\n RotateMode[RotateMode[\"Tangent\"] = 0] = \"Tangent\";\n RotateMode[RotateMode[\"Chain\"] = 1] = \"Chain\";\n RotateMode[RotateMode[\"ChainScale\"] = 2] = \"ChainScale\";\n})(RotateMode || (RotateMode = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGF0aENvbnN0cmFpbnREYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1BhdGhDb25zdHJhaW50RGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBSXJEOzt5R0FFeUc7QUFDekcsTUFBTSxPQUFPLGtCQUFtQixTQUFRLGNBQWM7SUFFckQsK0RBQStEO0lBQy9ELEtBQUssR0FBRyxJQUFJLEtBQUssRUFBWSxDQUFDO0lBRTlCLDRFQUE0RTtJQUNwRSxPQUFPLEdBQW9CLElBQUksQ0FBQztJQUN4QyxJQUFXLE1BQU0sQ0FBRSxRQUFrQixJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNuRSxJQUFXLE1BQU07UUFDaEIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBOztZQUNsRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDMUIsQ0FBQztJQUVELDJEQUEyRDtJQUMzRCxZQUFZLEdBQWlCLFlBQVksQ0FBQyxLQUFLLENBQUM7SUFFaEQsMkVBQTJFO0lBQzNFLFdBQVcsR0FBZ0IsV0FBVyxDQUFDLEtBQUssQ0FBQztJQUU3Qyx3REFBd0Q7SUFDeEQsVUFBVSxHQUFlLFVBQVUsQ0FBQyxLQUFLLENBQUM7SUFFMUMsd0RBQXdEO0lBQ3hELGNBQWMsR0FBVyxDQUFDLENBQUM7SUFFM0IsbUNBQW1DO0lBQ25DLFFBQVEsR0FBVyxDQUFDLENBQUM7SUFFckIsaUNBQWlDO0lBQ2pDLE9BQU8sR0FBVyxDQUFDLENBQUM7SUFFcEIsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLElBQUksR0FBRyxDQUFDLENBQUM7SUFDVCxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBRVQsWUFBYSxJQUFZO1FBQ3hCLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7Q0FDRDtBQUVEOzswR0FFMEc7QUFDMUcsTUFBTSxDQUFOLElBQVksWUFBK0I7QUFBM0MsV0FBWSxZQUFZO0lBQUcsaURBQUssQ0FBQTtJQUFFLHFEQUFPLENBQUE7QUFBQyxDQUFDLEVBQS9CLFlBQVksS0FBWixZQUFZLFFBQW1CO0FBRTNDOzt3R0FFd0c7QUFDeEcsTUFBTSxDQUFOLElBQVksV0FBb0Q7QUFBaEUsV0FBWSxXQUFXO0lBQUcsaURBQU0sQ0FBQTtJQUFFLCtDQUFLLENBQUE7SUFBRSxtREFBTyxDQUFBO0lBQUUsNkRBQVksQ0FBQTtBQUFDLENBQUMsRUFBcEQsV0FBVyxLQUFYLFdBQVcsUUFBeUM7QUFFaEU7OzhHQUU4RztBQUM5RyxNQUFNLENBQU4sSUFBWSxVQUF5QztBQUFyRCxXQUFZLFVBQVU7SUFBRyxpREFBTyxDQUFBO0lBQUUsNkNBQUssQ0FBQTtJQUFFLHVEQUFVLENBQUE7QUFBQyxDQUFDLEVBQXpDLFVBQVUsS0FBVixVQUFVLFFBQStCIn0=","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { PathAttachment } from \"./attachments/PathAttachment.js\";\nimport { RotateMode, SpacingMode, PositionMode } from \"./PathConstraintData.js\";\nimport { Utils, MathUtils } from \"./Utils.js\";\n/** Stores the current pose for a path constraint. A path constraint adjusts the rotation, translation, and scale of the\n * constrained bones so they follow a {@link PathAttachment}.\n *\n * See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. */\nexport class PathConstraint {\n static NONE = -1;\n static BEFORE = -2;\n static AFTER = -3;\n static epsilon = 0.00001;\n /** The path constraint's setup pose data. */\n data;\n /** The bones that will be modified by this path constraint. */\n bones;\n /** The slot whose path attachment will be used to constrained the bones. */\n target;\n /** The position along the path. */\n position = 0;\n /** The spacing between bones. */\n spacing = 0;\n mixRotate = 0;\n mixX = 0;\n mixY = 0;\n spaces = new Array();\n positions = new Array();\n world = new Array();\n curves = new Array();\n lengths = new Array();\n segments = new Array();\n active = false;\n constructor(data, skeleton) {\n if (!data)\n throw new Error(\"data cannot be null.\");\n if (!skeleton)\n throw new Error(\"skeleton cannot be null.\");\n this.data = data;\n this.bones = new Array();\n for (let i = 0, n = data.bones.length; i < n; i++) {\n let bone = skeleton.findBone(data.bones[i].name);\n if (!bone)\n throw new Error(`Couldn't find bone ${data.bones[i].name}.`);\n this.bones.push(bone);\n }\n let target = skeleton.findSlot(data.target.name);\n if (!target)\n throw new Error(`Couldn't find target bone ${data.target.name}`);\n this.target = target;\n this.position = data.position;\n this.spacing = data.spacing;\n this.mixRotate = data.mixRotate;\n this.mixX = data.mixX;\n this.mixY = data.mixY;\n }\n isActive() {\n return this.active;\n }\n setToSetupPose() {\n const data = this.data;\n this.position = data.position;\n this.spacing = data.spacing;\n this.mixRotate = data.mixRotate;\n this.mixX = data.mixX;\n this.mixY = data.mixY;\n }\n update(physics) {\n let attachment = this.target.getAttachment();\n if (!(attachment instanceof PathAttachment))\n return;\n let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY;\n if (mixRotate == 0 && mixX == 0 && mixY == 0)\n return;\n let data = this.data;\n let tangents = data.rotateMode == RotateMode.Tangent, scale = data.rotateMode == RotateMode.ChainScale;\n let bones = this.bones;\n let boneCount = bones.length, spacesCount = tangents ? boneCount : boneCount + 1;\n let spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = scale ? this.lengths = Utils.setArraySize(this.lengths, boneCount) : [];\n let spacing = this.spacing;\n switch (data.spacingMode) {\n case SpacingMode.Percent:\n if (scale) {\n for (let i = 0, n = spacesCount - 1; i < n; i++) {\n let bone = bones[i];\n let setupLength = bone.data.length;\n let x = setupLength * bone.a, y = setupLength * bone.c;\n lengths[i] = Math.sqrt(x * x + y * y);\n }\n }\n Utils.arrayFill(spaces, 1, spacesCount, spacing);\n break;\n case SpacingMode.Proportional:\n let sum = 0;\n for (let i = 0, n = spacesCount - 1; i < n;) {\n let bone = bones[i];\n let setupLength = bone.data.length;\n if (setupLength < PathConstraint.epsilon) {\n if (scale)\n lengths[i] = 0;\n spaces[++i] = spacing;\n }\n else {\n let x = setupLength * bone.a, y = setupLength * bone.c;\n let length = Math.sqrt(x * x + y * y);\n if (scale)\n lengths[i] = length;\n spaces[++i] = length;\n sum += length;\n }\n }\n if (sum > 0) {\n sum = spacesCount / sum * spacing;\n for (let i = 1; i < spacesCount; i++)\n spaces[i] *= sum;\n }\n break;\n default:\n let lengthSpacing = data.spacingMode == SpacingMode.Length;\n for (let i = 0, n = spacesCount - 1; i < n;) {\n let bone = bones[i];\n let setupLength = bone.data.length;\n if (setupLength < PathConstraint.epsilon) {\n if (scale)\n lengths[i] = 0;\n spaces[++i] = spacing;\n }\n else {\n let x = setupLength * bone.a, y = setupLength * bone.c;\n let length = Math.sqrt(x * x + y * y);\n if (scale)\n lengths[i] = length;\n spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;\n }\n }\n }\n let positions = this.computeWorldPositions(attachment, spacesCount, tangents);\n let boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;\n let tip = false;\n if (offsetRotation == 0)\n tip = data.rotateMode == RotateMode.Chain;\n else {\n tip = false;\n let p = this.target.bone;\n offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad;\n }\n for (let i = 0, p = 3; i < boneCount; i++, p += 3) {\n let bone = bones[i];\n bone.worldX += (boneX - bone.worldX) * mixX;\n bone.worldY += (boneY - bone.worldY) * mixY;\n let x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;\n if (scale) {\n let length = lengths[i];\n if (length != 0) {\n let s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * mixRotate + 1;\n bone.a *= s;\n bone.c *= s;\n }\n }\n boneX = x;\n boneY = y;\n if (mixRotate > 0) {\n let a = bone.a, b = bone.b, c = bone.c, d = bone.d, r = 0, cos = 0, sin = 0;\n if (tangents)\n r = positions[p - 1];\n else if (spaces[i + 1] == 0)\n r = positions[p + 2];\n else\n r = Math.atan2(dy, dx);\n r -= Math.atan2(c, a);\n if (tip) {\n cos = Math.cos(r);\n sin = Math.sin(r);\n let length = bone.data.length;\n boneX += (length * (cos * a - sin * c) - dx) * mixRotate;\n boneY += (length * (sin * a + cos * c) - dy) * mixRotate;\n }\n else {\n r += offsetRotation;\n }\n if (r > MathUtils.PI)\n r -= MathUtils.PI2;\n else if (r < -MathUtils.PI) //\n r += MathUtils.PI2;\n r *= mixRotate;\n cos = Math.cos(r);\n sin = Math.sin(r);\n bone.a = cos * a - sin * c;\n bone.b = cos * b - sin * d;\n bone.c = sin * a + cos * c;\n bone.d = sin * b + cos * d;\n }\n bone.updateAppliedTransform();\n }\n }\n computeWorldPositions(path, spacesCount, tangents) {\n let target = this.target;\n let position = this.position;\n let spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = this.world;\n let closed = path.closed;\n let verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE;\n if (!path.constantSpeed) {\n let lengths = path.lengths;\n curveCount -= closed ? 1 : 2;\n let pathLength = lengths[curveCount];\n if (this.data.positionMode == PositionMode.Percent)\n position *= pathLength;\n let multiplier;\n switch (this.data.spacingMode) {\n case SpacingMode.Percent:\n multiplier = pathLength;\n break;\n case SpacingMode.Proportional:\n multiplier = pathLength / spacesCount;\n break;\n default:\n multiplier = 1;\n }\n world = Utils.setArraySize(this.world, 8);\n for (let i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {\n let space = spaces[i] * multiplier;\n position += space;\n let p = position;\n if (closed) {\n p %= pathLength;\n if (p < 0)\n p += pathLength;\n curve = 0;\n }\n else if (p < 0) {\n if (prevCurve != PathConstraint.BEFORE) {\n prevCurve = PathConstraint.BEFORE;\n path.computeWorldVertices(target, 2, 4, world, 0, 2);\n }\n this.addBeforePosition(p, world, 0, out, o);\n continue;\n }\n else if (p > pathLength) {\n if (prevCurve != PathConstraint.AFTER) {\n prevCurve = PathConstraint.AFTER;\n path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2);\n }\n this.addAfterPosition(p - pathLength, world, 0, out, o);\n continue;\n }\n // Determine curve containing position.\n for (;; curve++) {\n let length = lengths[curve];\n if (p > length)\n continue;\n if (curve == 0)\n p /= length;\n else {\n let prev = lengths[curve - 1];\n p = (p - prev) / (length - prev);\n }\n break;\n }\n if (curve != prevCurve) {\n prevCurve = curve;\n if (closed && curve == curveCount) {\n path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2);\n path.computeWorldVertices(target, 0, 4, world, 4, 2);\n }\n else\n path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2);\n }\n this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0));\n }\n return out;\n }\n // World vertices.\n if (closed) {\n verticesLength += 2;\n world = Utils.setArraySize(this.world, verticesLength);\n path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2);\n path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2);\n world[verticesLength - 2] = world[0];\n world[verticesLength - 1] = world[1];\n }\n else {\n curveCount--;\n verticesLength -= 4;\n world = Utils.setArraySize(this.world, verticesLength);\n path.computeWorldVertices(target, 2, verticesLength, world, 0, 2);\n }\n // Curve lengths.\n let curves = Utils.setArraySize(this.curves, curveCount);\n let pathLength = 0;\n let x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;\n let tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0;\n for (let i = 0, w = 2; i < curveCount; i++, w += 6) {\n cx1 = world[w];\n cy1 = world[w + 1];\n cx2 = world[w + 2];\n cy2 = world[w + 3];\n x2 = world[w + 4];\n y2 = world[w + 5];\n tmpx = (x1 - cx1 * 2 + cx2) * 0.1875;\n tmpy = (y1 - cy1 * 2 + cy2) * 0.1875;\n dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375;\n dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375;\n ddfx = tmpx * 2 + dddfx;\n ddfy = tmpy * 2 + dddfy;\n dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667;\n dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667;\n pathLength += Math.sqrt(dfx * dfx + dfy * dfy);\n dfx += ddfx;\n dfy += ddfy;\n ddfx += dddfx;\n ddfy += dddfy;\n pathLength += Math.sqrt(dfx * dfx + dfy * dfy);\n dfx += ddfx;\n dfy += ddfy;\n pathLength += Math.sqrt(dfx * dfx + dfy * dfy);\n dfx += ddfx + dddfx;\n dfy += ddfy + dddfy;\n pathLength += Math.sqrt(dfx * dfx + dfy * dfy);\n curves[i] = pathLength;\n x1 = x2;\n y1 = y2;\n }\n if (this.data.positionMode == PositionMode.Percent)\n position *= pathLength;\n let multiplier;\n switch (this.data.spacingMode) {\n case SpacingMode.Percent:\n multiplier = pathLength;\n break;\n case SpacingMode.Proportional:\n multiplier = pathLength / spacesCount;\n break;\n default:\n multiplier = 1;\n }\n let segments = this.segments;\n let curveLength = 0;\n for (let i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {\n let space = spaces[i] * multiplier;\n position += space;\n let p = position;\n if (closed) {\n p %= pathLength;\n if (p < 0)\n p += pathLength;\n curve = 0;\n }\n else if (p < 0) {\n this.addBeforePosition(p, world, 0, out, o);\n continue;\n }\n else if (p > pathLength) {\n this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o);\n continue;\n }\n // Determine curve containing position.\n for (;; curve++) {\n let length = curves[curve];\n if (p > length)\n continue;\n if (curve == 0)\n p /= length;\n else {\n let prev = curves[curve - 1];\n p = (p - prev) / (length - prev);\n }\n break;\n }\n // Curve segment lengths.\n if (curve != prevCurve) {\n prevCurve = curve;\n let ii = curve * 6;\n x1 = world[ii];\n y1 = world[ii + 1];\n cx1 = world[ii + 2];\n cy1 = world[ii + 3];\n cx2 = world[ii + 4];\n cy2 = world[ii + 5];\n x2 = world[ii + 6];\n y2 = world[ii + 7];\n tmpx = (x1 - cx1 * 2 + cx2) * 0.03;\n tmpy = (y1 - cy1 * 2 + cy2) * 0.03;\n dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006;\n dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006;\n ddfx = tmpx * 2 + dddfx;\n ddfy = tmpy * 2 + dddfy;\n dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667;\n dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667;\n curveLength = Math.sqrt(dfx * dfx + dfy * dfy);\n segments[0] = curveLength;\n for (ii = 1; ii < 8; ii++) {\n dfx += ddfx;\n dfy += ddfy;\n ddfx += dddfx;\n ddfy += dddfy;\n curveLength += Math.sqrt(dfx * dfx + dfy * dfy);\n segments[ii] = curveLength;\n }\n dfx += ddfx;\n dfy += ddfy;\n curveLength += Math.sqrt(dfx * dfx + dfy * dfy);\n segments[8] = curveLength;\n dfx += ddfx + dddfx;\n dfy += ddfy + dddfy;\n curveLength += Math.sqrt(dfx * dfx + dfy * dfy);\n segments[9] = curveLength;\n segment = 0;\n }\n // Weight by segment length.\n p *= curveLength;\n for (;; segment++) {\n let length = segments[segment];\n if (p > length)\n continue;\n if (segment == 0)\n p /= length;\n else {\n let prev = segments[segment - 1];\n p = segment + (p - prev) / (length - prev);\n }\n break;\n }\n this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0));\n }\n return out;\n }\n addBeforePosition(p, temp, i, out, o) {\n let x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx);\n out[o] = x1 + p * Math.cos(r);\n out[o + 1] = y1 + p * Math.sin(r);\n out[o + 2] = r;\n }\n addAfterPosition(p, temp, i, out, o) {\n let x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx);\n out[o] = x1 + p * Math.cos(r);\n out[o + 1] = y1 + p * Math.sin(r);\n out[o + 2] = r;\n }\n addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) {\n if (p == 0 || isNaN(p)) {\n out[o] = x1;\n out[o + 1] = y1;\n out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1);\n return;\n }\n let tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u;\n let ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p;\n let x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;\n out[o] = x;\n out[o + 1] = y;\n if (tangents) {\n if (p < 0.001)\n out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1);\n else\n out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));\n }\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGF0aENvbnN0cmFpbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvUGF0aENvbnN0cmFpbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVqRSxPQUFPLEVBQXNCLFVBQVUsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFJcEcsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFHOUM7Ozt5R0FHeUc7QUFDekcsTUFBTSxPQUFPLGNBQWM7SUFDMUIsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQztJQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFBQyxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBRXpCLDZDQUE2QztJQUM3QyxJQUFJLENBQXFCO0lBRXpCLCtEQUErRDtJQUMvRCxLQUFLLENBQWM7SUFFbkIsNEVBQTRFO0lBQzVFLE1BQU0sQ0FBTztJQUViLG1DQUFtQztJQUNuQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBRWIsaUNBQWlDO0lBQ2pDLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFFWixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBRWQsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUVULElBQUksR0FBRyxDQUFDLENBQUM7SUFFVCxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztJQUFDLFNBQVMsR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO0lBQzlELEtBQUssR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO0lBQUMsTUFBTSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7SUFBQyxPQUFPLEdB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QUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDckYsSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDbkYsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDbkQsR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNmLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ25CLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ25CLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ25CLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLElBQUksR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQztZQUNyQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUM7WUFDckMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUM7WUFDOUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcs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QUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1osR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDaEIsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzVDLE9BQU87U0FDUDtRQUNELElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDbEUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDO1FBQ3pHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDWCxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNmLElBQUksUUFBUSxFQUFFO1lBQ2IsSUFBSSxDQUFDLEdBQUcsS0FBSztnQkFDWixHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUM7O2dCQUU1QyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUMzRztJQUNGLENBQUMifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Physics } from \"./Skeleton.js\";\nimport { MathUtils } from \"./Utils.js\";\n/** Stores the current pose for a physics constraint. A physics constraint applies physics to bones.\n *

\n * See Physics constraints in the Spine User Guide. */\nexport class PhysicsConstraint {\n data;\n _bone = null;\n /** The bone constrained by this physics constraint. */\n set bone(bone) { this._bone = bone; }\n get bone() {\n if (!this._bone)\n throw new Error(\"Bone not set.\");\n else\n return this._bone;\n }\n inertia = 0;\n strength = 0;\n damping = 0;\n massInverse = 0;\n wind = 0;\n gravity = 0;\n mix = 0;\n _reset = true;\n ux = 0;\n uy = 0;\n cx = 0;\n cy = 0;\n tx = 0;\n ty = 0;\n xOffset = 0;\n xVelocity = 0;\n yOffset = 0;\n yVelocity = 0;\n rotateOffset = 0;\n rotateVelocity = 0;\n scaleOffset = 0;\n scaleVelocity = 0;\n active = false;\n skeleton;\n remaining = 0;\n lastTime = 0;\n constructor(data, skeleton) {\n this.data = data;\n this.skeleton = skeleton;\n this.bone = skeleton.bones[data.bone.index];\n this.inertia = data.inertia;\n this.strength = data.strength;\n this.damping = data.damping;\n this.massInverse = data.massInverse;\n this.wind = data.wind;\n this.gravity = data.gravity;\n this.mix = data.mix;\n }\n reset() {\n this.remaining = 0;\n this.lastTime = this.skeleton.time;\n this._reset = true;\n this.xOffset = 0;\n this.xVelocity = 0;\n this.yOffset = 0;\n this.yVelocity = 0;\n this.rotateOffset = 0;\n this.rotateVelocity = 0;\n this.scaleOffset = 0;\n this.scaleVelocity = 0;\n }\n setToSetupPose() {\n const data = this.data;\n this.inertia = data.inertia;\n this.strength = data.strength;\n this.damping = data.damping;\n this.massInverse = data.massInverse;\n this.wind = data.wind;\n this.gravity = data.gravity;\n this.mix = data.mix;\n }\n isActive() {\n return this.active;\n }\n /** Applies the constraint to the constrained bones. */\n update(physics) {\n const mix = this.mix;\n if (mix == 0)\n return;\n const x = this.data.x > 0, y = this.data.y > 0, rotateOrShearX = this.data.rotate > 0 || this.data.shearX > 0, scaleX = this.data.scaleX > 0;\n const bone = this.bone;\n const l = bone.data.length;\n switch (physics) {\n case Physics.none:\n return;\n case Physics.reset:\n this.reset();\n // Fall through.\n case Physics.update:\n this.remaining += Math.max(this.skeleton.time - this.lastTime, 0);\n this.lastTime = this.skeleton.time;\n const bx = bone.worldX, by = bone.worldY;\n if (this._reset) {\n this._reset = false;\n this.ux = bx;\n this.uy = by;\n }\n else {\n let remaining = this.remaining, i = this.inertia, step = this.data.step;\n if (x || y) {\n if (x) {\n this.xOffset += (this.ux - bx) * i;\n this.ux = bx;\n }\n if (y) {\n this.yOffset += (this.uy - by) * i;\n this.uy = by;\n }\n if (remaining >= step) {\n const m = this.massInverse * step, e = this.strength, w = this.wind * 100, g = this.gravity * -100;\n const d = Math.pow(this.damping, 60 * step);\n do {\n if (x) {\n this.xVelocity += (w - this.xOffset * e) * m;\n this.xOffset += this.xVelocity * step;\n this.xVelocity *= d;\n }\n if (y) {\n this.yVelocity += (g - this.yOffset * e) * m;\n this.yOffset += this.yVelocity * step;\n this.yVelocity *= d;\n }\n remaining -= step;\n } while (remaining >= step);\n }\n if (x)\n bone.worldX += this.xOffset * mix * this.data.x;\n if (y)\n bone.worldY += this.yOffset * mix * this.data.y;\n }\n if (rotateOrShearX || scaleX) {\n let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0;\n if (rotateOrShearX) {\n mr = (this.data.rotate + this.data.shearX) * mix;\n let dx = this.cx - bone.worldX, dy = this.cy - bone.worldY, r = Math.atan2(dy + this.ty, dx + this.tx) - ca - this.rotateOffset * mr;\n this.rotateOffset += (r - Math.ceil(r * MathUtils.invPI2 - 0.5) * MathUtils.PI2) * i;\n r = this.rotateOffset * mr + ca;\n c = Math.cos(r);\n s = Math.sin(r);\n if (scaleX) {\n r = l * bone.getWorldScaleX();\n if (r > 0)\n this.scaleOffset += (dx * c + dy * s) * i / r;\n }\n }\n else {\n c = Math.cos(ca);\n s = Math.sin(ca);\n const r = l * bone.getWorldScaleX();\n if (r > 0)\n this.scaleOffset += ((this.cx - bone.worldX) * c + (this.cy - bone.worldY) * s) * i / r;\n }\n remaining = this.remaining;\n if (remaining >= step) {\n const m = this.massInverse * step, e = this.strength, w = this.wind, g = this.gravity;\n const d = Math.pow(this.damping, 60 * step);\n while (true) {\n remaining -= step;\n if (scaleX) {\n this.scaleVelocity += (w * c - g * s - this.scaleOffset * e) * m;\n this.scaleOffset += this.scaleVelocity * step;\n this.scaleVelocity *= d;\n }\n if (rotateOrShearX) {\n this.rotateVelocity += (-0.01 * l * (w * s + g * c) - this.rotateOffset * e) * m;\n this.rotateOffset += this.rotateVelocity * step;\n this.rotateVelocity *= d;\n if (remaining < step)\n break;\n const r = this.rotateOffset * mr + ca;\n c = Math.cos(r);\n s = Math.sin(r);\n }\n else if (remaining < step) //\n break;\n }\n }\n }\n this.remaining = remaining;\n }\n this.cx = bone.worldX;\n this.cy = bone.worldY;\n break;\n case Physics.pose:\n if (x)\n bone.worldX += this.xOffset * mix * this.data.x;\n if (y)\n bone.worldY += this.yOffset * mix * this.data.y;\n }\n if (rotateOrShearX) {\n let o = this.rotateOffset * mix, s = 0, c = 0, a = 0;\n if (this.data.shearX > 0) {\n let r = 0;\n if (this.data.rotate > 0) {\n r = o * this.data.rotate;\n s = Math.sin(r);\n c = Math.cos(r);\n a = bone.b;\n bone.b = c * a - s * bone.d;\n bone.d = s * a + c * bone.d;\n }\n r += o * this.data.shearX;\n s = Math.sin(r);\n c = Math.cos(r);\n a = bone.a;\n bone.a = c * a - s * bone.c;\n bone.c = s * a + c * bone.c;\n }\n else {\n o *= this.data.rotate;\n s = Math.sin(o);\n c = Math.cos(o);\n a = bone.a;\n bone.a = c * a - s * bone.c;\n bone.c = s * a + c * bone.c;\n a = bone.b;\n bone.b = c * a - s * bone.d;\n bone.d = s * a + c * bone.d;\n }\n }\n if (scaleX) {\n const s = 1 + this.scaleOffset * mix * this.data.scaleX;\n bone.a *= s;\n bone.c *= s;\n }\n if (physics != Physics.pose) {\n this.tx = l * bone.a;\n this.ty = l * bone.c;\n }\n bone.updateAppliedTransform();\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGh5c2ljc0NvbnN0cmFpbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvUGh5c2ljc0NvbnN0cmFpbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSS9FLE9BQU8sRUFBRSxPQUFPLEVBQVksTUFBTSxlQUFlLENBQUM7QUFFbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUd2Qzs7MEhBRTBIO0FBQzFILE1BQU0sT0FBTyxpQkFBaUI7SUFDcEIsSUFBSSxDQUF3QjtJQUM3QixLQUFLLEdBQWdCLElBQUksQ0FBQztJQUNsQyx1REFBdUQ7SUFDdkQsSUFBVyxJQUFJLENBQUUsSUFBVSxJQUFJLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNuRCxJQUFXLElBQUk7UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUs7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFBOztZQUM1QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDWixRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUNaLFdBQVcsR0FBRyxDQUFDLENBQUM7SUFDaEIsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUNULE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDWixHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBRVIsTUFBTSxHQUFHLElBQUksQ0FBQztJQUNkLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDUCxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1AsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNQLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDUCxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1AsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNQLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDWixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUNaLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFDZCxZQUFZLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLGNBQWMsR0FBRyxDQUFDLENBQUM7SUFDbkIsV0FBVyxHQUFHLENBQUMsQ0FBQTtJQUNmLGFBQWEsR0FBRyxDQUFDLENBQUM7SUFFbEIsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUVOLFFBQVEsQ0FBVztJQUM1QixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsUUFBUSxHQUFHLENBQUMsQ0FBQztJQUViLFlBQWEsSUFBMkIsRUFBRSxRQUFrQjtRQUMzRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDNUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQzlCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM1QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDcEMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM1QixJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDckIsQ0FBQztJQUVELEtBQUs7UUFDSixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNuQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ25CLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxjQUFjO1FBQ2IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDNUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQzlCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM1QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDcEMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM1QixJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDckIsQ0FBQztJQUVELFFBQVE7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDcEIsQ0FBQztJQUVELHVEQUF1RDtJQUN2RCxNQUFNLENBQUUsT0FBZ0I7UUFDdkIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUNyQixJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQUUsT0FBTztRQUVyQixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQzdJLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDdkIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFM0IsUUFBUSxPQUFPLEVBQUU7WUFDaEIsS0FBSyxPQUFPLENBQUMsSUFBSTtnQkFDaEIsT0FBTztZQUNSLEtBQUssT0FBTyxDQUFDLEtBQUs7Z0JBQ2pCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNkLGdCQUFnQjtZQUNoQixLQUFLLE9BQU8sQ0FBQyxNQUFNO2dCQUNsQixJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDbEUsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztnQkFFbkMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDekMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO29CQUNoQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztvQkFDcEIsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7b0JBQ2IsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7aUJBQ2I7cUJBQU07b0JBQ04sSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7b0JBQ3hFLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTt3QkFDWCxJQUFJLENBQUMsRUFBRTs0QkFDTixJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7NEJBQ25DLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO3lCQUNiO3dCQUNELElBQUksQ0FBQyxFQUFFOzRCQUNOLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQzs0QkFDbkMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7eUJBQ2I7d0JBQ0QsSUFBSSxTQUFTLElBQUksSUFBSSxFQUFFOzRCQUN0QixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUM7NEJBQ25HLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7NEJBQzVDLEdBQUc7Z0NBQ0YsSUFBSSxDQUFDLEVBQUU7b0NBQ04sSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQ0FDN0MsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztvQ0FDdEMsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUM7aUNBQ3BCO2dDQUNELElBQUksQ0FBQyxFQUFFO29DQUNOLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7b0NBQzdDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7b0NBQ3RDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDO2lDQUNwQjtnQ0FDRCxTQUFTLElBQUksSUFBSSxDQUFDOzZCQUNsQixRQUFRLFNBQVMsSUFBSSxJQUFJLEVBQUU7eUJBQzVCO3dCQUNELElBQUksQ0FBQzs0QkFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUN2RCxJQUFJLENBQUM7NEJBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztxQkFDdkQ7b0JBQ0QsSUFBSSxjQUFjLElBQUksTUFBTSxFQUFFO3dCQUM3QixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO3dCQUMxRCxJQUFJLGNBQWMsRUFBRTs0QkFDbkIsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUM7NEJBQ2pELElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDOzRCQUNySSxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzs0QkFDckYsQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQzs0QkFDaEMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ2hCLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNoQixJQUFJLE1BQU0sRUFBRTtnQ0FDWCxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQ0FDOUIsSUFBSSxDQUFDLEdBQUcsQ0FBQztvQ0FBRSxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzs2QkFDekQ7eUJBQ0Q7NkJBQU07NEJBQ04sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7NEJBQ2pCLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDOzRCQUNqQixNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDOzRCQUNwQyxJQUFJLENBQUMsR0FBRyxDQUFDO2dDQUFFLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7eUJBQ25HO3dCQUNELFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO3dCQUMzQixJQUFJLFNBQVMsSUFBSSxJQUFJLEVBQUU7NEJBQ3RCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDOzRCQUN0RixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDOzRCQUM1QyxPQUFPLElBQUksRUFBRTtnQ0FDWixTQUFTLElBQUksSUFBSSxDQUFDO2dDQUNsQixJQUFJLE1BQU0sRUFBRTtvQ0FDWCxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29DQUNqRSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO29DQUM5QyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsQ0FBQztpQ0FDeEI7Z0NBQ0QsSUFBSSxjQUFjLEVBQUU7b0NBQ25CLElBQUksQ0FBQyxjQUFjLElBQUksQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQ0FDakYsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztvQ0FDaEQsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUM7b0NBQ3pCLElBQUksU0FBUyxHQUFHLElBQUk7d0NBQUUsTUFBTTtvQ0FDNUIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO29DQUN0QyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQ0FDaEIsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7aUNBQ2hCO3FDQUFNLElBQUksU0FBUyxHQUFHLElBQUksRUFBRSxFQUFFO29DQUM5QixNQUFNOzZCQUNQO3lCQUNEO3FCQUNEO29CQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO2lCQUMzQjtnQkFDRCxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDdEIsTUFBTTtZQUNQLEtBQUssT0FBTyxDQUFDLElBQUk7Z0JBQ2hCLElBQUksQ0FBQztvQkFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUN2RCxJQUFJLENBQUM7b0JBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUN4RDtRQUVELElBQUksY0FBYyxFQUFFO1lBQ25CLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JELElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUN6QixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ1YsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7b0JBQ3pCLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7b0JBQ3pCLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNoQixDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDaEIsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ1gsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO29CQUM1QixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7aUJBQzVCO2dCQUNELENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7Z0JBQzFCLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNoQixDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEIsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ1gsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUM1QixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDNUI7aUJBQU07Z0JBQ04sQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO2dCQUN0QixDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEIsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hCLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNYLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUM1QixDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDWCxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzVCLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzthQUM1QjtTQUNEO1FBQ0QsSUFBSSxNQUFNLEVBQUU7WUFDWCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDeEQsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDWixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNaO1FBQ0QsSUFBSSxPQUFPLElBQUksT0FBTyxDQUFDLElBQUksRUFBRTtZQUM1QixJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3JCLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDckI7UUFDRCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztJQUMvQixDQUFDO0NBQ0QifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { VertexAttachment } from \"./attachments/Attachment.js\";\nimport { Color } from \"./Utils.js\";\n/** Stores a slot's current pose. Slots organize attachments for {@link Skeleton#drawOrder} purposes and provide a place to store\n * state for an attachment. State cannot be stored in an attachment itself because attachments are stateless and may be shared\n * across multiple skeletons. */\nexport class Slot {\n /** The slot's setup pose data. */\n data;\n /** The bone this slot belongs to. */\n bone;\n /** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two\n * color tinting. */\n color;\n /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark\n * color's alpha is not used. */\n darkColor = null;\n attachment = null;\n attachmentState = 0;\n /** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the\n * {@link Sequence#getSetupIndex()}. */\n sequenceIndex = -1;\n /** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a\n * weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions.\n *\n * See {@link VertexAttachment#computeWorldVertices()} and {@link DeformTimeline}. */\n deform = new Array();\n constructor(data, bone) {\n if (!data)\n throw new Error(\"data cannot be null.\");\n if (!bone)\n throw new Error(\"bone cannot be null.\");\n this.data = data;\n this.bone = bone;\n this.color = new Color();\n this.darkColor = !data.darkColor ? null : new Color();\n this.setToSetupPose();\n }\n /** The skeleton this slot belongs to. */\n getSkeleton() {\n return this.bone.skeleton;\n }\n /** The current attachment for the slot, or null if the slot has no attachment. */\n getAttachment() {\n return this.attachment;\n }\n /** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}.\n * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getTimelineAttachment()} as the\n * specified attachment. */\n setAttachment(attachment) {\n if (this.attachment == attachment)\n return;\n if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment)\n || attachment.timelineAttachment != this.attachment.timelineAttachment) {\n this.deform.length = 0;\n }\n this.attachment = attachment;\n this.sequenceIndex = -1;\n }\n /** Sets this slot to the setup pose. */\n setToSetupPose() {\n this.color.setFromColor(this.data.color);\n if (this.darkColor)\n this.darkColor.setFromColor(this.data.darkColor);\n if (!this.data.attachmentName)\n this.attachment = null;\n else {\n this.attachment = null;\n this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName));\n }\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2xvdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9TbG90LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUUvRSxPQUFPLEVBQWMsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUkzRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRW5DOztnQ0FFZ0M7QUFDaEMsTUFBTSxPQUFPLElBQUk7SUFDaEIsa0NBQWtDO0lBQ2xDLElBQUksQ0FBVztJQUVmLHFDQUFxQztJQUNyQyxJQUFJLENBQU87SUFFWDt3QkFDb0I7SUFDcEIsS0FBSyxDQUFRO0lBRWI7b0NBQ2dDO0lBQ2hDLFNBQVMsR0FBaUIsSUFBSSxDQUFDO0lBRS9CLFVBQVUsR0FBc0IsSUFBSSxDQUFDO0lBRXJDLGVBQWUsR0FBVyxDQUFDLENBQUM7SUFFNUI7MkNBQ3VDO0lBQ3ZDLGFBQWEsR0FBVyxDQUFDLENBQUMsQ0FBQztJQUUzQjs7O3lGQUdxRjtJQUNyRixNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztJQUU3QixZQUFhLElBQWMsRUFBRSxJQUFVO1FBQ3RDLElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3RELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQseUNBQXlDO0lBQ3pDLFdBQVc7UUFDVixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQzNCLENBQUM7SUFFRCxrRkFBa0Y7SUFDbEYsYUFBYTtRQUNaLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN4QixDQUFDO0lBRUQ7OytCQUUyQjtJQUMzQixhQUFhLENBQUUsVUFBNkI7UUFDM0MsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLFVBQVU7WUFBRSxPQUFPO1FBQzFDLElBQUksQ0FBQyxDQUFDLFVBQVUsWUFBWSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxZQUFZLGdCQUFnQixDQUFDO2VBQ3hFLFVBQVcsQ0FBQyxrQkFBa0IsSUFBdUIsSUFBSSxDQUFDLFVBQVcsQ0FBQyxrQkFBa0IsRUFBRTtZQUNoSCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7U0FDdkI7UUFDRCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCx3Q0FBd0M7SUFDeEMsY0FBYztRQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekMsSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBVSxDQUFDLENBQUM7UUFDdEUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYztZQUM1QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQzthQUNuQjtZQUNKLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztTQUNoRztJQUNGLENBQUM7Q0FDRCJ9","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Vector2, MathUtils } from \"./Utils.js\";\n/** Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained\n * bones to match that of the target bone.\n *\n * See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. */\nexport class TransformConstraint {\n /** The transform constraint's setup pose data. */\n data;\n /** The bones that will be modified by this transform constraint. */\n bones;\n /** The target bone whose world transform will be copied to the constrained bones. */\n target;\n mixRotate = 0;\n mixX = 0;\n mixY = 0;\n mixScaleX = 0;\n mixScaleY = 0;\n mixShearY = 0;\n temp = new Vector2();\n active = false;\n constructor(data, skeleton) {\n if (!data)\n throw new Error(\"data cannot be null.\");\n if (!skeleton)\n throw new Error(\"skeleton cannot be null.\");\n this.data = data;\n this.mixRotate = data.mixRotate;\n this.mixX = data.mixX;\n this.mixY = data.mixY;\n this.mixScaleX = data.mixScaleX;\n this.mixScaleY = data.mixScaleY;\n this.mixShearY = data.mixShearY;\n this.bones = new Array();\n for (let i = 0; i < data.bones.length; i++) {\n let bone = skeleton.findBone(data.bones[i].name);\n if (!bone)\n throw new Error(`Couldn't find bone ${data.bones[i].name}.`);\n this.bones.push(bone);\n }\n let target = skeleton.findBone(data.target.name);\n if (!target)\n throw new Error(`Couldn't find target bone ${data.target.name}.`);\n this.target = target;\n }\n isActive() {\n return this.active;\n }\n setToSetupPose() {\n const data = this.data;\n this.mixRotate = data.mixRotate;\n this.mixX = data.mixX;\n this.mixY = data.mixY;\n this.mixScaleX = data.mixScaleX;\n this.mixScaleY = data.mixScaleY;\n this.mixShearY = data.mixShearY;\n }\n update(physics) {\n if (this.mixRotate == 0 && this.mixX == 0 && this.mixY == 0 && this.mixScaleX == 0 && this.mixScaleY == 0 && this.mixShearY == 0)\n return;\n if (this.data.local) {\n if (this.data.relative)\n this.applyRelativeLocal();\n else\n this.applyAbsoluteLocal();\n }\n else {\n if (this.data.relative)\n this.applyRelativeWorld();\n else\n this.applyAbsoluteWorld();\n }\n }\n applyAbsoluteWorld() {\n let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;\n let translate = mixX != 0 || mixY != 0;\n let target = this.target;\n let ta = target.a, tb = target.b, tc = target.c, td = target.d;\n let degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad;\n let offsetRotation = this.data.offsetRotation * degRadReflect;\n let offsetShearY = this.data.offsetShearY * degRadReflect;\n let bones = this.bones;\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n if (mixRotate != 0) {\n let a = bone.a, b = bone.b, c = bone.c, d = bone.d;\n let r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation;\n if (r > MathUtils.PI)\n r -= MathUtils.PI2;\n else if (r < -MathUtils.PI) //\n r += MathUtils.PI2;\n r *= mixRotate;\n let cos = Math.cos(r), sin = Math.sin(r);\n bone.a = cos * a - sin * c;\n bone.b = cos * b - sin * d;\n bone.c = sin * a + cos * c;\n bone.d = sin * b + cos * d;\n }\n if (translate) {\n let temp = this.temp;\n target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));\n bone.worldX += (temp.x - bone.worldX) * mixX;\n bone.worldY += (temp.y - bone.worldY) * mixY;\n }\n if (mixScaleX != 0) {\n let s = Math.sqrt(bone.a * bone.a + bone.c * bone.c);\n if (s != 0)\n s = (s + (Math.sqrt(ta * ta + tc * tc) - s + this.data.offsetScaleX) * mixScaleX) / s;\n bone.a *= s;\n bone.c *= s;\n }\n if (mixScaleY != 0) {\n let s = Math.sqrt(bone.b * bone.b + bone.d * bone.d);\n if (s != 0)\n s = (s + (Math.sqrt(tb * tb + td * td) - s + this.data.offsetScaleY) * mixScaleY) / s;\n bone.b *= s;\n bone.d *= s;\n }\n if (mixShearY > 0) {\n let b = bone.b, d = bone.d;\n let by = Math.atan2(d, b);\n let r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a));\n if (r > MathUtils.PI)\n r -= MathUtils.PI2;\n else if (r < -MathUtils.PI) //\n r += MathUtils.PI2;\n r = by + (r + offsetShearY) * mixShearY;\n let s = Math.sqrt(b * b + d * d);\n bone.b = Math.cos(r) * s;\n bone.d = Math.sin(r) * s;\n }\n bone.updateAppliedTransform();\n }\n }\n applyRelativeWorld() {\n let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;\n let translate = mixX != 0 || mixY != 0;\n let target = this.target;\n let ta = target.a, tb = target.b, tc = target.c, td = target.d;\n let degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad;\n let offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect;\n let bones = this.bones;\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n if (mixRotate != 0) {\n let a = bone.a, b = bone.b, c = bone.c, d = bone.d;\n let r = Math.atan2(tc, ta) + offsetRotation;\n if (r > MathUtils.PI)\n r -= MathUtils.PI2;\n else if (r < -MathUtils.PI) //\n r += MathUtils.PI2;\n r *= mixRotate;\n let cos = Math.cos(r), sin = Math.sin(r);\n bone.a = cos * a - sin * c;\n bone.b = cos * b - sin * d;\n bone.c = sin * a + cos * c;\n bone.d = sin * b + cos * d;\n }\n if (translate) {\n let temp = this.temp;\n target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));\n bone.worldX += temp.x * mixX;\n bone.worldY += temp.y * mixY;\n }\n if (mixScaleX != 0) {\n let s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * mixScaleX + 1;\n bone.a *= s;\n bone.c *= s;\n }\n if (mixScaleY != 0) {\n let s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * mixScaleY + 1;\n bone.b *= s;\n bone.d *= s;\n }\n if (mixShearY > 0) {\n let r = Math.atan2(td, tb) - Math.atan2(tc, ta);\n if (r > MathUtils.PI)\n r -= MathUtils.PI2;\n else if (r < -MathUtils.PI) //\n r += MathUtils.PI2;\n let b = bone.b, d = bone.d;\n r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * mixShearY;\n let s = Math.sqrt(b * b + d * d);\n bone.b = Math.cos(r) * s;\n bone.d = Math.sin(r) * s;\n }\n bone.updateAppliedTransform();\n }\n }\n applyAbsoluteLocal() {\n let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;\n let target = this.target;\n let bones = this.bones;\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n let rotation = bone.arotation;\n if (mixRotate != 0) {\n let r = target.arotation - rotation + this.data.offsetRotation;\n r -= Math.ceil(r / 360 - 0.5) * 360;\n rotation += r * mixRotate;\n }\n let x = bone.ax, y = bone.ay;\n x += (target.ax - x + this.data.offsetX) * mixX;\n y += (target.ay - y + this.data.offsetY) * mixY;\n let scaleX = bone.ascaleX, scaleY = bone.ascaleY;\n if (mixScaleX != 0 && scaleX != 0)\n scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * mixScaleX) / scaleX;\n if (mixScaleY != 0 && scaleY != 0)\n scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * mixScaleY) / scaleY;\n let shearY = bone.ashearY;\n if (mixShearY != 0) {\n let r = target.ashearY - shearY + this.data.offsetShearY;\n r -= Math.ceil(r / 360 - 0.5) * 360;\n shearY += r * mixShearY;\n }\n bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);\n }\n }\n applyRelativeLocal() {\n let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;\n let target = this.target;\n let bones = this.bones;\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n let rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate;\n let x = bone.ax + (target.ax + this.data.offsetX) * mixX;\n let y = bone.ay + (target.ay + this.data.offsetY) * mixY;\n let scaleX = bone.ascaleX * (((target.ascaleX - 1 + this.data.offsetScaleX) * mixScaleX) + 1);\n let scaleY = bone.ascaleY * (((target.ascaleY - 1 + this.data.offsetScaleY) * mixScaleY) + 1);\n let shearY = bone.ashearY + (target.ashearY + this.data.offsetShearY) * mixShearY;\n bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);\n }\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNmb3JtQ29uc3RyYWludC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9UcmFuc2Zvcm1Db25zdHJhaW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQU0vRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUdoRDs7O21IQUdtSDtBQUNuSCxNQUFNLE9BQU8sbUJBQW1CO0lBRS9CLGtEQUFrRDtJQUNsRCxJQUFJLENBQTBCO0lBRTlCLG9FQUFvRTtJQUNwRSxLQUFLLENBQWM7SUFFbkIscUZBQXFGO0lBQ3JGLE1BQU0sQ0FBTztJQUViLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUUvRSxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQUNyQixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBRWYsWUFBYSxJQUE2QixFQUFFLFFBQWtCO1FBQzdELElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNoQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxT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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { MeshAttachment } from \"./attachments/MeshAttachment.js\";\nimport { PathAttachment } from \"./attachments/PathAttachment.js\";\nimport { RegionAttachment } from \"./attachments/RegionAttachment.js\";\nimport { Bone } from \"./Bone.js\";\nimport { IkConstraint } from \"./IkConstraint.js\";\nimport { PathConstraint } from \"./PathConstraint.js\";\nimport { PhysicsConstraint } from \"./PhysicsConstraint.js\";\nimport { Slot } from \"./Slot.js\";\nimport { TransformConstraint } from \"./TransformConstraint.js\";\nimport { Color, Utils, MathUtils, Vector2 } from \"./Utils.js\";\n/** Stores the current pose for a skeleton.\n *\n * See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine Runtimes Guide. */\nexport class Skeleton {\n static yDown = false;\n ;\n /** The skeleton's setup pose data. */\n data;\n /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */\n bones;\n /** The skeleton's slots. */\n slots;\n /** The skeleton's slots in the order they should be drawn. The returned array may be modified to change the draw order. */\n drawOrder;\n /** The skeleton's IK constraints. */\n ikConstraints;\n /** The skeleton's transform constraints. */\n transformConstraints;\n /** The skeleton's path constraints. */\n pathConstraints;\n /** The skeleton's physics constraints. */\n physicsConstraints;\n /** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */\n _updateCache = new Array();\n /** The skeleton's current skin. May be null. */\n skin = null;\n /** The color to tint all the skeleton's attachments. */\n color;\n /** Scales the entire skeleton on the X axis. This affects all bones, even if the bone's transform mode disallows scale\n * inheritance. */\n scaleX = 1;\n /** Scales the entire skeleton on the Y axis. This affects all bones, even if the bone's transform mode disallows scale\n * inheritance. */\n _scaleY = 1;\n get scaleY() {\n return Skeleton.yDown ? -this._scaleY : this._scaleY;\n }\n set scaleY(scaleY) {\n this._scaleY = scaleY;\n }\n /** Sets the skeleton X position, which is added to the root bone worldX position. */\n x = 0;\n /** Sets the skeleton Y position, which is added to the root bone worldY position. */\n y = 0;\n /** Returns the skeleton's time. This is used for time-based manipulations, such as {@link PhysicsConstraint}.\n *

\n * See {@link #update(float)}. */\n time = 0;\n constructor(data) {\n if (!data)\n throw new Error(\"data cannot be null.\");\n this.data = data;\n this.bones = new Array();\n for (let i = 0; i < data.bones.length; i++) {\n let boneData = data.bones[i];\n let bone;\n if (!boneData.parent)\n bone = new Bone(boneData, this, null);\n else {\n let parent = this.bones[boneData.parent.index];\n bone = new Bone(boneData, this, parent);\n parent.children.push(bone);\n }\n this.bones.push(bone);\n }\n this.slots = new Array();\n this.drawOrder = new Array();\n for (let i = 0; i < data.slots.length; i++) {\n let slotData = data.slots[i];\n let bone = this.bones[slotData.boneData.index];\n let slot = new Slot(slotData, bone);\n this.slots.push(slot);\n this.drawOrder.push(slot);\n }\n this.ikConstraints = new Array();\n for (let i = 0; i < data.ikConstraints.length; i++) {\n let ikConstraintData = data.ikConstraints[i];\n this.ikConstraints.push(new IkConstraint(ikConstraintData, this));\n }\n this.transformConstraints = new Array();\n for (let i = 0; i < data.transformConstraints.length; i++) {\n let transformConstraintData = data.transformConstraints[i];\n this.transformConstraints.push(new TransformConstraint(transformConstraintData, this));\n }\n this.pathConstraints = new Array();\n for (let i = 0; i < data.pathConstraints.length; i++) {\n let pathConstraintData = data.pathConstraints[i];\n this.pathConstraints.push(new PathConstraint(pathConstraintData, this));\n }\n this.physicsConstraints = new Array();\n for (let i = 0; i < data.physicsConstraints.length; i++) {\n let physicsConstraintData = data.physicsConstraints[i];\n this.physicsConstraints.push(new PhysicsConstraint(physicsConstraintData, this));\n }\n this.color = new Color(1, 1, 1, 1);\n this.updateCache();\n }\n /** Caches information about bones and constraints. Must be called if the {@link #getSkin()} is modified or if bones,\n * constraints, or weighted path attachments are added or removed. */\n updateCache() {\n let updateCache = this._updateCache;\n updateCache.length = 0;\n let bones = this.bones;\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n bone.sorted = bone.data.skinRequired;\n bone.active = !bone.sorted;\n }\n if (this.skin) {\n let skinBones = this.skin.bones;\n for (let i = 0, n = this.skin.bones.length; i < n; i++) {\n let bone = this.bones[skinBones[i].index];\n do {\n bone.sorted = false;\n bone.active = true;\n bone = bone.parent;\n } while (bone);\n }\n }\n // IK first, lowest hierarchy depth first.\n let ikConstraints = this.ikConstraints;\n let transformConstraints = this.transformConstraints;\n let pathConstraints = this.pathConstraints;\n let physicsConstraints = this.physicsConstraints;\n let ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length, physicsCount = this.physicsConstraints.length;\n let constraintCount = ikCount + transformCount + pathCount + physicsCount;\n outer: for (let i = 0; i < constraintCount; i++) {\n for (let ii = 0; ii < ikCount; ii++) {\n let constraint = ikConstraints[ii];\n if (constraint.data.order == i) {\n this.sortIkConstraint(constraint);\n continue outer;\n }\n }\n for (let ii = 0; ii < transformCount; ii++) {\n let constraint = transformConstraints[ii];\n if (constraint.data.order == i) {\n this.sortTransformConstraint(constraint);\n continue outer;\n }\n }\n for (let ii = 0; ii < pathCount; ii++) {\n let constraint = pathConstraints[ii];\n if (constraint.data.order == i) {\n this.sortPathConstraint(constraint);\n continue outer;\n }\n }\n for (let ii = 0; ii < physicsCount; ii++) {\n const constraint = physicsConstraints[ii];\n if (constraint.data.order == i) {\n this.sortPhysicsConstraint(constraint);\n continue outer;\n }\n }\n }\n for (let i = 0, n = bones.length; i < n; i++)\n this.sortBone(bones[i]);\n }\n sortIkConstraint(constraint) {\n constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));\n if (!constraint.active)\n return;\n let target = constraint.target;\n this.sortBone(target);\n let constrained = constraint.bones;\n let parent = constrained[0];\n this.sortBone(parent);\n if (constrained.length == 1) {\n this._updateCache.push(constraint);\n this.sortReset(parent.children);\n }\n else {\n let child = constrained[constrained.length - 1];\n this.sortBone(child);\n this._updateCache.push(constraint);\n this.sortReset(parent.children);\n child.sorted = true;\n }\n }\n sortPathConstraint(constraint) {\n constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));\n if (!constraint.active)\n return;\n let slot = constraint.target;\n let slotIndex = slot.data.index;\n let slotBone = slot.bone;\n if (this.skin)\n this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone);\n if (this.data.defaultSkin && this.data.defaultSkin != this.skin)\n this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone);\n for (let i = 0, n = this.data.skins.length; i < n; i++)\n this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone);\n let attachment = slot.getAttachment();\n if (attachment instanceof PathAttachment)\n this.sortPathConstraintAttachmentWith(attachment, slotBone);\n let constrained = constraint.bones;\n let boneCount = constrained.length;\n for (let i = 0; i < boneCount; i++)\n this.sortBone(constrained[i]);\n this._updateCache.push(constraint);\n for (let i = 0; i < boneCount; i++)\n this.sortReset(constrained[i].children);\n for (let i = 0; i < boneCount; i++)\n constrained[i].sorted = true;\n }\n sortTransformConstraint(constraint) {\n constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));\n if (!constraint.active)\n return;\n this.sortBone(constraint.target);\n let constrained = constraint.bones;\n let boneCount = constrained.length;\n if (constraint.data.local) {\n for (let i = 0; i < boneCount; i++) {\n let child = constrained[i];\n this.sortBone(child.parent);\n this.sortBone(child);\n }\n }\n else {\n for (let i = 0; i < boneCount; i++) {\n this.sortBone(constrained[i]);\n }\n }\n this._updateCache.push(constraint);\n for (let i = 0; i < boneCount; i++)\n this.sortReset(constrained[i].children);\n for (let i = 0; i < boneCount; i++)\n constrained[i].sorted = true;\n }\n sortPathConstraintAttachment(skin, slotIndex, slotBone) {\n let attachments = skin.attachments[slotIndex];\n if (!attachments)\n return;\n for (let key in attachments) {\n this.sortPathConstraintAttachmentWith(attachments[key], slotBone);\n }\n }\n sortPathConstraintAttachmentWith(attachment, slotBone) {\n if (!(attachment instanceof PathAttachment))\n return;\n let pathBones = attachment.bones;\n if (!pathBones)\n this.sortBone(slotBone);\n else {\n let bones = this.bones;\n for (let i = 0, n = pathBones.length; i < n;) {\n let nn = pathBones[i++];\n nn += i;\n while (i < nn)\n this.sortBone(bones[pathBones[i++]]);\n }\n }\n }\n sortPhysicsConstraint(constraint) {\n const bone = constraint.bone;\n constraint.active = bone.active && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)));\n if (!constraint.active)\n return;\n this.sortBone(bone);\n this._updateCache.push(constraint);\n this.sortReset(bone.children);\n bone.sorted = true;\n }\n sortBone(bone) {\n if (!bone)\n return;\n if (bone.sorted)\n return;\n let parent = bone.parent;\n if (parent)\n this.sortBone(parent);\n bone.sorted = true;\n this._updateCache.push(bone);\n }\n sortReset(bones) {\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n if (!bone.active)\n continue;\n if (bone.sorted)\n this.sortReset(bone.children);\n bone.sorted = false;\n }\n }\n /** Updates the world transform for each bone and applies all constraints.\n *\n * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine\n * Runtimes Guide. */\n updateWorldTransform(physics) {\n if (!physics)\n throw new Error(\"physics is undefined\");\n let bones = this.bones;\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n bone.ax = bone.x;\n bone.ay = bone.y;\n bone.arotation = bone.rotation;\n bone.ascaleX = bone.scaleX;\n bone.ascaleY = bone.scaleY;\n bone.ashearX = bone.shearX;\n bone.ashearY = bone.shearY;\n }\n let updateCache = this._updateCache;\n for (let i = 0, n = updateCache.length; i < n; i++)\n updateCache[i].update(physics);\n }\n updateWorldTransformWith(physics, parent) {\n // Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection.\n let rootBone = this.getRootBone();\n if (!rootBone)\n throw new Error(\"Root bone must not be null.\");\n let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;\n rootBone.worldX = pa * this.x + pb * this.y + parent.worldX;\n rootBone.worldY = pc * this.x + pd * this.y + parent.worldY;\n const rx = (rootBone.rotation + rootBone.shearX) * MathUtils.degRad;\n const ry = (rootBone.rotation + 90 + rootBone.shearY) * MathUtils.degRad;\n const la = Math.cos(rx) * rootBone.scaleX;\n const lb = Math.cos(ry) * rootBone.scaleY;\n const lc = Math.sin(rx) * rootBone.scaleX;\n const ld = Math.sin(ry) * rootBone.scaleY;\n rootBone.a = (pa * la + pb * lc) * this.scaleX;\n rootBone.b = (pa * lb + pb * ld) * this.scaleX;\n rootBone.c = (pc * la + pd * lc) * this.scaleY;\n rootBone.d = (pc * lb + pd * ld) * this.scaleY;\n // Update everything except root bone.\n let updateCache = this._updateCache;\n for (let i = 0, n = updateCache.length; i < n; i++) {\n let updatable = updateCache[i];\n if (updatable != rootBone)\n updatable.update(physics);\n }\n }\n /** Sets the bones, constraints, and slots to their setup pose values. */\n setToSetupPose() {\n this.setBonesToSetupPose();\n this.setSlotsToSetupPose();\n }\n /** Sets the bones and constraints to their setup pose values. */\n setBonesToSetupPose() {\n for (const bone of this.bones)\n bone.setToSetupPose();\n for (const constraint of this.ikConstraints)\n constraint.setToSetupPose();\n for (const constraint of this.transformConstraints)\n constraint.setToSetupPose();\n for (const constraint of this.pathConstraints)\n constraint.setToSetupPose();\n for (const constraint of this.physicsConstraints)\n constraint.setToSetupPose();\n }\n /** Sets the slots and draw order to their setup pose values. */\n setSlotsToSetupPose() {\n let slots = this.slots;\n Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length);\n for (let i = 0, n = slots.length; i < n; i++)\n slots[i].setToSetupPose();\n }\n /** @returns May return null. */\n getRootBone() {\n if (this.bones.length == 0)\n return null;\n return this.bones[0];\n }\n /** @returns May be null. */\n findBone(boneName) {\n if (!boneName)\n throw new Error(\"boneName cannot be null.\");\n let bones = this.bones;\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n if (bone.data.name == boneName)\n return bone;\n }\n return null;\n }\n /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it\n * repeatedly.\n * @returns May be null. */\n findSlot(slotName) {\n if (!slotName)\n throw new Error(\"slotName cannot be null.\");\n let slots = this.slots;\n for (let i = 0, n = slots.length; i < n; i++) {\n let slot = slots[i];\n if (slot.data.name == slotName)\n return slot;\n }\n return null;\n }\n /** Sets a skin by name.\n *\n * See {@link #setSkin()}. */\n setSkinByName(skinName) {\n let skin = this.data.findSkin(skinName);\n if (!skin)\n throw new Error(\"Skin not found: \" + skinName);\n this.setSkin(skin);\n }\n /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#defaultSkin default skin}. If the\n * skin is changed, {@link #updateCache()} is called.\n *\n * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no\n * old skin, each slot's setup mode attachment is attached from the new skin.\n *\n * After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling\n * {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply()} is called before the next time the\n * skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.\n * @param newSkin May be null. */\n setSkin(newSkin) {\n if (newSkin == this.skin)\n return;\n if (newSkin) {\n if (this.skin)\n newSkin.attachAll(this, this.skin);\n else {\n let slots = this.slots;\n for (let i = 0, n = slots.length; i < n; i++) {\n let slot = slots[i];\n let name = slot.data.attachmentName;\n if (name) {\n let attachment = newSkin.getAttachment(i, name);\n if (attachment)\n slot.setAttachment(attachment);\n }\n }\n }\n }\n this.skin = newSkin;\n this.updateCache();\n }\n /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment\n * name.\n *\n * See {@link #getAttachment()}.\n * @returns May be null. */\n getAttachmentByName(slotName, attachmentName) {\n let slot = this.data.findSlot(slotName);\n if (!slot)\n throw new Error(`Can't find slot with name ${slotName}`);\n return this.getAttachment(slot.index, attachmentName);\n }\n /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot index and\n * attachment name. First the skin is checked and if the attachment was not found, the default skin is checked.\n *\n * See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide.\n * @returns May be null. */\n getAttachment(slotIndex, attachmentName) {\n if (!attachmentName)\n throw new Error(\"attachmentName cannot be null.\");\n if (this.skin) {\n let attachment = this.skin.getAttachment(slotIndex, attachmentName);\n if (attachment)\n return attachment;\n }\n if (this.data.defaultSkin)\n return this.data.defaultSkin.getAttachment(slotIndex, attachmentName);\n return null;\n }\n /** A convenience method to set an attachment by finding the slot with {@link #findSlot()}, finding the attachment with\n * {@link #getAttachment()}, then setting the slot's {@link Slot#attachment}.\n * @param attachmentName May be null to clear the slot's attachment. */\n setAttachment(slotName, attachmentName) {\n if (!slotName)\n throw new Error(\"slotName cannot be null.\");\n let slots = this.slots;\n for (let i = 0, n = slots.length; i < n; i++) {\n let slot = slots[i];\n if (slot.data.name == slotName) {\n let attachment = null;\n if (attachmentName) {\n attachment = this.getAttachment(i, attachmentName);\n if (!attachment)\n throw new Error(\"Attachment not found: \" + attachmentName + \", for slot: \" + slotName);\n }\n slot.setAttachment(attachment);\n return;\n }\n }\n throw new Error(\"Slot not found: \" + slotName);\n }\n /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method\n * than to call it repeatedly.\n * @return May be null. */\n findIkConstraint(constraintName) {\n if (!constraintName)\n throw new Error(\"constraintName cannot be null.\");\n return this.ikConstraints.find((constraint) => constraint.data.name == constraintName) ?? null;\n }\n /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of\n * this method than to call it repeatedly.\n * @return May be null. */\n findTransformConstraint(constraintName) {\n if (!constraintName)\n throw new Error(\"constraintName cannot be null.\");\n return this.transformConstraints.find((constraint) => constraint.data.name == constraintName) ?? null;\n }\n /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method\n * than to call it repeatedly.\n * @return May be null. */\n findPathConstraint(constraintName) {\n if (!constraintName)\n throw new Error(\"constraintName cannot be null.\");\n return this.pathConstraints.find((constraint) => constraint.data.name == constraintName) ?? null;\n }\n /** Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this\n * method than to call it repeatedly. */\n findPhysicsConstraint(constraintName) {\n if (constraintName == null)\n throw new Error(\"constraintName cannot be null.\");\n return this.physicsConstraints.find((constraint) => constraint.data.name == constraintName) ?? null;\n }\n /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose as `{ x: number, y: number, width: number, height: number }`.\n * Note that this method will create temporary objects which can add to garbage collection pressure. Use `getBounds()` if garbage collection is a concern. */\n getBoundsRect() {\n let offset = new Vector2();\n let size = new Vector2();\n this.getBounds(offset, size);\n return { x: offset.x, y: offset.y, width: size.x, height: size.y };\n }\n /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.\n * @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB.\n * @param size An output value, the width and height of the AABB.\n * @param temp Working memory to temporarily store attachments' computed world vertices. */\n getBounds(offset, size, temp = new Array(2)) {\n if (!offset)\n throw new Error(\"offset cannot be null.\");\n if (!size)\n throw new Error(\"size cannot be null.\");\n let drawOrder = this.drawOrder;\n let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;\n for (let i = 0, n = drawOrder.length; i < n; i++) {\n let slot = drawOrder[i];\n if (!slot.bone.active)\n continue;\n let verticesLength = 0;\n let vertices = null;\n let attachment = slot.getAttachment();\n if (attachment instanceof RegionAttachment) {\n verticesLength = 8;\n vertices = Utils.setArraySize(temp, verticesLength, 0);\n attachment.computeWorldVertices(slot, vertices, 0, 2);\n }\n else if (attachment instanceof MeshAttachment) {\n let mesh = attachment;\n verticesLength = mesh.worldVerticesLength;\n vertices = Utils.setArraySize(temp, verticesLength, 0);\n mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);\n }\n if (vertices) {\n for (let ii = 0, nn = vertices.length; ii < nn; ii += 2) {\n let x = vertices[ii], y = vertices[ii + 1];\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n }\n }\n offset.set(minX, minY);\n size.set(maxX - minX, maxY - minY);\n }\n /** Increments the skeleton's {@link #time}. */\n update(delta) {\n this.time += delta;\n }\n}\n/** Determines how physics and other non-deterministic updates are applied. */\nexport var Physics;\n(function (Physics) {\n /** Physics are not updated or applied. */\n Physics[Physics[\"none\"] = 0] = \"none\";\n /** Physics are reset to the current pose. */\n Physics[Physics[\"reset\"] = 1] = \"reset\";\n /** Physics are updated and the pose from physics is applied. */\n Physics[Physics[\"update\"] = 2] = \"update\";\n /** Physics are not updated but the pose from physics is applied. */\n Physics[Physics[\"pose\"] = 3] = \"pose\";\n})(Physics || (Physics = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU2tlbGV0b24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDckUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNqQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzNELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDakMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFL0QsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBbUIsTUFBTSxZQUFZLENBQUM7QUFFL0U7O2tJQUVrSTtBQUNsSSxNQUFNLE9BQU8sUUFBUTtJQUNwQixNQUFNLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUFBLENBQUM7SUFFdEIsc0NBQXNDO0lBQ3RDLElBQUksQ0FBZTtJQUVuQix5RkFBeUY7SUFDekYsS0FBSyxDQUFjO0lBRW5CLDRCQUE0QjtJQUM1QixLQUFLLENBQWM7SUFFbkIsMkhBQTJIO0lBQzNILFNBQVMsQ0FBYztJQUV2QixxQ0FBcUM7SUFDckMsYUFBYSxDQUFzQjtJQUVuQyw0Q0FBNEM7SUFDNUMsb0JBQW9CLENBQTZCO0lBRWpELHVDQUF1QztJQUN2QyxlQUFlLENBQXdCO0lBR3ZD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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { ConstraintData } from \"./ConstraintData.js\";\n/** Stores the setup pose for a {@link PhysicsConstraint}.\n *

\n * See Physics constraints in the Spine User Guide. */\nexport class PhysicsConstraintData extends ConstraintData {\n _bone = null;\n /** The bone constrained by this physics constraint. */\n set bone(boneData) { this._bone = boneData; }\n get bone() {\n if (!this._bone)\n throw new Error(\"BoneData not set.\");\n else\n return this._bone;\n }\n x = 0;\n y = 0;\n rotate = 0;\n scaleX = 0;\n shearX = 0;\n step = 0;\n inertia = 0;\n strength = 0;\n damping = 0;\n massInverse = 0;\n wind = 0;\n gravity = 0;\n /** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */\n mix = 0;\n inertiaGlobal = false;\n strengthGlobal = false;\n dampingGlobal = false;\n massGlobal = false;\n windGlobal = false;\n gravityGlobal = false;\n mixGlobal = false;\n constructor(name) {\n super(name, 0, false);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGh5c2ljc0NvbnN0cmFpbnREYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1BoeXNpY3NDb25zdHJhaW50RGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBR3JEOzswSEFFMEg7QUFDMUgsTUFBTSxPQUFPLHFCQUFzQixTQUFRLGNBQWM7SUFDaEQsS0FBSyxHQUFvQixJQUFJLENBQUM7SUFDdEMsdURBQXVEO0lBQ3ZELElBQVcsSUFBSSxDQUFFLFFBQWtCLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQy9ELElBQVcsSUFBSTtRQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTs7WUFDaEQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ04sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNOLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ1gsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNYLElBQUksR0FBRyxDQUFDLENBQUM7SUFDVCxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ1osUUFBUSxHQUFHLENBQUMsQ0FBQztJQUNiLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDWixXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLElBQUksR0FBRyxDQUFDLENBQUM7SUFDVCxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ1osZ0dBQWdHO0lBQ2hHLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDUixhQUFhLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFDdkIsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUN0QixVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQ25CLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDbkIsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUN0QixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBRWxCLFlBQWEsSUFBWTtRQUN4QixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2QixDQUFDO0NBQ0QifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\n/** Stores the setup pose and all of the stateless data for a skeleton.\n *\n * See [Data objects](http://esotericsoftware.com/spine-runtime-architecture#Data-objects) in the Spine Runtimes\n * Guide. */\nexport class SkeletonData {\n /** The skeleton's name, which by default is the name of the skeleton data file, if possible. May be null. */\n name = null;\n /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */\n bones = new Array(); // Ordered parents first.\n /** The skeleton's slots. */\n slots = new Array(); // Setup pose draw order.\n skins = new Array();\n /** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine.\n *\n * See {@link Skeleton#getAttachmentByName()}.\n * May be null. */\n defaultSkin = null;\n /** The skeleton's events. */\n events = new Array();\n /** The skeleton's animations. */\n animations = new Array();\n /** The skeleton's IK constraints. */\n ikConstraints = new Array();\n /** The skeleton's transform constraints. */\n transformConstraints = new Array();\n /** The skeleton's path constraints. */\n pathConstraints = new Array();\n /** The skeleton's physics constraints. */\n physicsConstraints = new Array();\n /** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */\n x = 0;\n /** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */\n y = 0;\n /** The width of the skeleton's axis aligned bounding box in the setup pose. */\n width = 0;\n /** The height of the skeleton's axis aligned bounding box in the setup pose. */\n height = 0;\n /** The Spine version used to export the skeleton data, or null. */\n version = null;\n /** The skeleton data hash. This value will change if any of the skeleton data has changed. May be null. */\n hash = null;\n // Nonessential\n /** The dopesheet FPS in Spine. Available only when nonessential data was exported. */\n fps = 0;\n /** The path to the images directory as defined in Spine. Available only when nonessential data was exported. May be null. */\n imagesPath = null;\n /** The path to the audio directory as defined in Spine. Available only when nonessential data was exported. May be null. */\n audioPath = null;\n /** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it\n * multiple times.\n * @returns May be null. */\n findBone(boneName) {\n if (!boneName)\n throw new Error(\"boneName cannot be null.\");\n let bones = this.bones;\n for (let i = 0, n = bones.length; i < n; i++) {\n let bone = bones[i];\n if (bone.name == boneName)\n return bone;\n }\n return null;\n }\n /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it\n * multiple times.\n * @returns May be null. */\n findSlot(slotName) {\n if (!slotName)\n throw new Error(\"slotName cannot be null.\");\n let slots = this.slots;\n for (let i = 0, n = slots.length; i < n; i++) {\n let slot = slots[i];\n if (slot.name == slotName)\n return slot;\n }\n return null;\n }\n /** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it\n * multiple times.\n * @returns May be null. */\n findSkin(skinName) {\n if (!skinName)\n throw new Error(\"skinName cannot be null.\");\n let skins = this.skins;\n for (let i = 0, n = skins.length; i < n; i++) {\n let skin = skins[i];\n if (skin.name == skinName)\n return skin;\n }\n return null;\n }\n /** Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it\n * multiple times.\n * @returns May be null. */\n findEvent(eventDataName) {\n if (!eventDataName)\n throw new Error(\"eventDataName cannot be null.\");\n let events = this.events;\n for (let i = 0, n = events.length; i < n; i++) {\n let event = events[i];\n if (event.name == eventDataName)\n return event;\n }\n return null;\n }\n /** Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to\n * call it multiple times.\n * @returns May be null. */\n findAnimation(animationName) {\n if (!animationName)\n throw new Error(\"animationName cannot be null.\");\n let animations = this.animations;\n for (let i = 0, n = animations.length; i < n; i++) {\n let animation = animations[i];\n if (animation.name == animationName)\n return animation;\n }\n return null;\n }\n /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method\n * than to call it multiple times.\n * @return May be null. */\n findIkConstraint(constraintName) {\n if (!constraintName)\n throw new Error(\"constraintName cannot be null.\");\n const ikConstraints = this.ikConstraints;\n for (let i = 0, n = ikConstraints.length; i < n; i++) {\n const constraint = ikConstraints[i];\n if (constraint.name == constraintName)\n return constraint;\n }\n return null;\n }\n /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of\n * this method than to call it multiple times.\n * @return May be null. */\n findTransformConstraint(constraintName) {\n if (!constraintName)\n throw new Error(\"constraintName cannot be null.\");\n const transformConstraints = this.transformConstraints;\n for (let i = 0, n = transformConstraints.length; i < n; i++) {\n const constraint = transformConstraints[i];\n if (constraint.name == constraintName)\n return constraint;\n }\n return null;\n }\n /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method\n * than to call it multiple times.\n * @return May be null. */\n findPathConstraint(constraintName) {\n if (!constraintName)\n throw new Error(\"constraintName cannot be null.\");\n const pathConstraints = this.pathConstraints;\n for (let i = 0, n = pathConstraints.length; i < n; i++) {\n const constraint = pathConstraints[i];\n if (constraint.name == constraintName)\n return constraint;\n }\n return null;\n }\n /** Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this method\n * than to call it multiple times.\n * @return May be null. */\n findPhysicsConstraint(constraintName) {\n if (!constraintName)\n throw new Error(\"constraintName cannot be null.\");\n const physicsConstraints = this.physicsConstraints;\n for (let i = 0, n = physicsConstraints.length; i < n; i++) {\n const constraint = physicsConstraints[i];\n if (constraint.name == constraintName)\n return constraint;\n }\n return null;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25EYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NrZWxldG9uRGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFZL0U7OztZQUdZO0FBQ1osTUFBTSxPQUFPLFlBQVk7SUFFeEIsNkdBQTZHO0lBQzdHLElBQUksR0FBa0IsSUFBSSxDQUFDO0lBRTNCLHlGQUF5RjtJQUN6RixLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQVksQ0FBQyxDQUFDLHlCQUF5QjtJQUV4RCw0QkFBNEI7SUFDNUIsS0FBSyxHQUFHLElBQUksS0FBSyxFQUFZLENBQUMsQ0FBQyx5QkFBeUI7SUFDeEQsS0FBSyxHQUFHLElBQUksS0FBSyxFQUFRLENBQUM7SUFFMUI7OztzQkFHa0I7SUFDbEIsV0FBVyxHQUFnQixJQUFJLENBQUM7SUFFaEMsNkJBQTZCO0lBQzdCLE1BQU0sR0FBRyxJQUFJLEtBQUssRUFBYSxDQUFDO0lBRWhDLGlDQUFpQztJQUNqQyxVQUFVLEdBQUcsSUFBSSxLQUFLLEVBQWEsQ0FBQztJQUVwQyxxQ0FBcUM7SUFDckMsYUFBYSxHQUFHLElBQUksS0FBSyxFQUFvQixDQUFDO0lBRTlDLDRDQUE0QztJQUM1QyxvQkFBb0IsR0FBRyxJQUFJLEtBQUssRUFBMkIsQ0FBQztJQUU1RCx1Q0FBdUM7SUFDdkMsZUFBZSxHQUFHLElBQUksS0FBSyxFQUFzQixDQUFDO0lBRWxELDBDQUEwQztJQUMxQyxrQkFBa0IsR0FBRyxJQUFJLEtBQUssRUFBeUIsQ0FBQztJQUV4RCxzRkFBc0Y7SUFDdEYsQ0FBQyxHQUFXLENBQUMsQ0FBQztJQUVkLHNGQUFzRjtJQUN0RixDQUFDLEdBQVcsQ0FBQyxDQUFDO0lBRWQsK0VBQStFO0lBQy9FLEtBQUssR0FBVyxDQUFDLENBQUM7SUFFbEIsZ0ZBQWdGO0lBQ2hGLE1BQU0sR0FBVyxDQUFDLENBQUM7SUFFbkIsbUVBQW1FO0lBQ25F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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { MeshAttachment } from \"./attachments/MeshAttachment.js\";\nimport { Color } from \"./Utils.js\";\n/** Stores an entry in the skin consisting of the slot index, name, and attachment **/\nexport class SkinEntry {\n slotIndex;\n name;\n attachment;\n constructor(slotIndex = 0, name, attachment) {\n this.slotIndex = slotIndex;\n this.name = name;\n this.attachment = attachment;\n }\n}\n/** Stores attachments by slot index and attachment name.\n *\n * See SkeletonData {@link SkeletonData#defaultSkin}, Skeleton {@link Skeleton#skin}, and\n * [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. */\nexport class Skin {\n /** The skin's name, which is unique across all skins in the skeleton. */\n name;\n attachments = new Array();\n bones = Array();\n constraints = new Array();\n /** The color of the skin as it was in Spine, or a default color if nonessential data was not exported. */\n color = new Color(0.99607843, 0.61960787, 0.30980393, 1); // fe9e4fff\n constructor(name) {\n if (!name)\n throw new Error(\"name cannot be null.\");\n this.name = name;\n }\n /** Adds an attachment to the skin for the specified slot index and name. */\n setAttachment(slotIndex, name, attachment) {\n if (!attachment)\n throw new Error(\"attachment cannot be null.\");\n let attachments = this.attachments;\n if (slotIndex >= attachments.length)\n attachments.length = slotIndex + 1;\n if (!attachments[slotIndex])\n attachments[slotIndex] = {};\n attachments[slotIndex][name] = attachment;\n }\n /** Adds all attachments, bones, and constraints from the specified skin to this skin. */\n addSkin(skin) {\n for (let i = 0; i < skin.bones.length; i++) {\n let bone = skin.bones[i];\n let contained = false;\n for (let ii = 0; ii < this.bones.length; ii++) {\n if (this.bones[ii] == bone) {\n contained = true;\n break;\n }\n }\n if (!contained)\n this.bones.push(bone);\n }\n for (let i = 0; i < skin.constraints.length; i++) {\n let constraint = skin.constraints[i];\n let contained = false;\n for (let ii = 0; ii < this.constraints.length; ii++) {\n if (this.constraints[ii] == constraint) {\n contained = true;\n break;\n }\n }\n if (!contained)\n this.constraints.push(constraint);\n }\n let attachments = skin.getAttachments();\n for (let i = 0; i < attachments.length; i++) {\n var attachment = attachments[i];\n this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment);\n }\n }\n /** Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not\n * copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. */\n copySkin(skin) {\n for (let i = 0; i < skin.bones.length; i++) {\n let bone = skin.bones[i];\n let contained = false;\n for (let ii = 0; ii < this.bones.length; ii++) {\n if (this.bones[ii] == bone) {\n contained = true;\n break;\n }\n }\n if (!contained)\n this.bones.push(bone);\n }\n for (let i = 0; i < skin.constraints.length; i++) {\n let constraint = skin.constraints[i];\n let contained = false;\n for (let ii = 0; ii < this.constraints.length; ii++) {\n if (this.constraints[ii] == constraint) {\n contained = true;\n break;\n }\n }\n if (!contained)\n this.constraints.push(constraint);\n }\n let attachments = skin.getAttachments();\n for (let i = 0; i < attachments.length; i++) {\n var attachment = attachments[i];\n if (!attachment.attachment)\n continue;\n if (attachment.attachment instanceof MeshAttachment) {\n attachment.attachment = attachment.attachment.newLinkedMesh();\n this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment);\n }\n else {\n attachment.attachment = attachment.attachment.copy();\n this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment);\n }\n }\n }\n /** Returns the attachment for the specified slot index and name, or null. */\n getAttachment(slotIndex, name) {\n let dictionary = this.attachments[slotIndex];\n return dictionary ? dictionary[name] : null;\n }\n /** Removes the attachment in the skin for the specified slot index and name, if any. */\n removeAttachment(slotIndex, name) {\n let dictionary = this.attachments[slotIndex];\n if (dictionary)\n delete dictionary[name];\n }\n /** Returns all attachments in this skin. */\n getAttachments() {\n let entries = new Array();\n for (var i = 0; i < this.attachments.length; i++) {\n let slotAttachments = this.attachments[i];\n if (slotAttachments) {\n for (let name in slotAttachments) {\n let attachment = slotAttachments[name];\n if (attachment)\n entries.push(new SkinEntry(i, name, attachment));\n }\n }\n }\n return entries;\n }\n /** Returns all attachments in this skin for the specified slot index. */\n getAttachmentsForSlot(slotIndex, attachments) {\n let slotAttachments = this.attachments[slotIndex];\n if (slotAttachments) {\n for (let name in slotAttachments) {\n let attachment = slotAttachments[name];\n if (attachment)\n attachments.push(new SkinEntry(slotIndex, name, attachment));\n }\n }\n }\n /** Clears all attachments, bones, and constraints. */\n clear() {\n this.attachments.length = 0;\n this.bones.length = 0;\n this.constraints.length = 0;\n }\n /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */\n attachAll(skeleton, oldSkin) {\n let slotIndex = 0;\n for (let i = 0; i < skeleton.slots.length; i++) {\n let slot = skeleton.slots[i];\n let slotAttachment = slot.getAttachment();\n if (slotAttachment && slotIndex < oldSkin.attachments.length) {\n let dictionary = oldSkin.attachments[slotIndex];\n for (let key in dictionary) {\n let skinAttachment = dictionary[key];\n if (slotAttachment == skinAttachment) {\n let attachment = this.getAttachment(slotIndex, key);\n if (attachment)\n slot.setAttachment(attachment);\n break;\n }\n }\n }\n slotIndex++;\n }\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Ta2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFJakUsT0FBTyxFQUFFLEtBQUssRUFBYSxNQUFNLFlBQVksQ0FBQztBQUU5QyxzRkFBc0Y7QUFDdEYsTUFBTSxPQUFPLFNBQVM7SUFDRDtJQUE4QjtJQUFxQjtJQUF2RSxZQUFvQixZQUFvQixDQUFDLEVBQVMsSUFBWSxFQUFTLFVBQXNCO1FBQXpFLGNBQVMsR0FBVCxTQUFTLENBQVk7UUFBUyxTQUFJLEdBQUosSUFBSSxDQUFRO1FBQVMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtJQUFJLENBQUM7Q0FDbEc7QUFFRDs7O21HQUdtRztBQUNuRyxNQUFNLE9BQU8sSUFBSTtJQUNoQix5RUFBeUU7SUFDekUsSUFBSSxDQUFTO0lBRWIsV0FBVyxHQUFHLElBQUksS0FBSyxFQUF5QixDQUFDO0lBQ2pELEtBQUssR0FBRyxLQUFLLEVBQVksQ0FBQztJQUMxQixXQUFXLEdBQUcsSUFBSSxLQUFLLEVBQWtCLENBQUM7SUFFMUMsMEdBQTBHO0lBQzFHLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVc7SUFFckUsWUFBYSxJQUFZO1FBQ3hCLElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2xCLENBQUM7SUFFRCw0RUFBNEU7SUFDNUUsYUFBYSxDQUFFLFNBQWlCLEVBQUUsSUFBWSxFQUFFLFVBQXNCO1FBQ3JFLElBQUksQ0FBQyxVQUFVO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FB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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Color } from \"./Utils.js\";\n/** Stores the setup pose for a {@link Slot}. */\nexport class SlotData {\n /** The index of the slot in {@link Skeleton#getSlots()}. */\n index = 0;\n /** The name of the slot, which is unique across all slots in the skeleton. */\n name;\n /** The bone this slot belongs to. */\n boneData;\n /** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two\n * color tinting. */\n color = new Color(1, 1, 1, 1);\n /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark\n * color's alpha is not used. */\n darkColor = null;\n /** The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. */\n attachmentName = null;\n /** The blend mode for drawing the slot's attachment. */\n blendMode = BlendMode.Normal;\n /** False if the slot was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */\n visible = true;\n constructor(index, name, boneData) {\n if (index < 0)\n throw new Error(\"index must be >= 0.\");\n if (!name)\n throw new Error(\"name cannot be null.\");\n if (!boneData)\n throw new Error(\"boneData cannot be null.\");\n this.index = index;\n this.name = name;\n this.boneData = boneData;\n }\n}\n/** Determines how images are blended with existing pixels when drawn. */\nexport var BlendMode;\n(function (BlendMode) {\n BlendMode[BlendMode[\"Normal\"] = 0] = \"Normal\";\n BlendMode[BlendMode[\"Additive\"] = 1] = \"Additive\";\n BlendMode[BlendMode[\"Multiply\"] = 2] = \"Multiply\";\n BlendMode[BlendMode[\"Screen\"] = 3] = \"Screen\";\n})(BlendMode || (BlendMode = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2xvdERhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU2xvdERhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFbkMsZ0RBQWdEO0FBQ2hELE1BQU0sT0FBTyxRQUFRO0lBQ3BCLDREQUE0RDtJQUM1RCxLQUFLLEdBQVcsQ0FBQyxDQUFDO0lBRWxCLDhFQUE4RTtJQUM5RSxJQUFJLENBQVM7SUFFYixxQ0FBcUM7SUFDckMsUUFBUSxDQUFXO0lBRW5CO3dCQUNvQjtJQUNwQixLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFOUI7b0NBQ2dDO0lBQ2hDLFNBQVMsR0FBaUIsSUFBSSxDQUFDO0lBRS9CLHVIQUF1SDtJQUN2SCxjQUFjLEdBQWtCLElBQUksQ0FBQztJQUVyQyx3REFBd0Q7SUFDeEQsU0FBUyxHQUFjLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFFeEMsbUhBQW1IO0lBQ25ILE9BQU8sR0FBRyxJQUFJLENBQUM7SUFFZixZQUFhLEtBQWEsRUFBRSxJQUFZLEVBQUUsUUFBa0I7UUFDM0QsSUFBSSxLQUFLLEdBQUcsQ0FBQztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsUUFBUTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMxQixDQUFDO0NBQ0Q7QUFFRCx5RUFBeUU7QUFDekUsTUFBTSxDQUFOLElBQVksU0FBZ0Q7QUFBNUQsV0FBWSxTQUFTO0lBQUcsNkNBQU0sQ0FBQTtJQUFFLGlEQUFRLENBQUE7SUFBRSxpREFBUSxDQUFBO0lBQUUsNkNBQU0sQ0FBQTtBQUFDLENBQUMsRUFBaEQsU0FBUyxLQUFULFNBQVMsUUFBdUMifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { ConstraintData } from \"./ConstraintData.js\";\n/** Stores the setup pose for a {@link TransformConstraint}.\n *\n * See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. */\nexport class TransformConstraintData extends ConstraintData {\n /** The bones that will be modified by this transform constraint. */\n bones = new Array();\n /** The target bone whose world transform will be copied to the constrained bones. */\n _target = null;\n set target(boneData) { this._target = boneData; }\n get target() {\n if (!this._target)\n throw new Error(\"BoneData not set.\");\n else\n return this._target;\n }\n mixRotate = 0;\n mixX = 0;\n mixY = 0;\n mixScaleX = 0;\n mixScaleY = 0;\n mixShearY = 0;\n /** An offset added to the constrained bone rotation. */\n offsetRotation = 0;\n /** An offset added to the constrained bone X translation. */\n offsetX = 0;\n /** An offset added to the constrained bone Y translation. */\n offsetY = 0;\n /** An offset added to the constrained bone scaleX. */\n offsetScaleX = 0;\n /** An offset added to the constrained bone scaleY. */\n offsetScaleY = 0;\n /** An offset added to the constrained bone shearY. */\n offsetShearY = 0;\n relative = false;\n local = false;\n constructor(name) {\n super(name, 0, false);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNmb3JtQ29uc3RyYWludERhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvVHJhbnNmb3JtQ29uc3RyYWludERhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUdyRDs7bUhBRW1IO0FBQ25ILE1BQU0sT0FBTyx1QkFBd0IsU0FBUSxjQUFjO0lBRTFELG9FQUFvRTtJQUNwRSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQVksQ0FBQztJQUU5QixxRkFBcUY7SUFDN0UsT0FBTyxHQUFvQixJQUFJLENBQUM7SUFDeEMsSUFBVyxNQUFNLENBQUUsUUFBa0IsSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbkUsSUFBVyxNQUFNO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTs7WUFDbEQsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQzFCLENBQUM7SUFFRCxTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUNULElBQUksR0FBRyxDQUFDLENBQUM7SUFDVCxTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFFZCx3REFBd0Q7SUFDeEQsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUVuQiw2REFBNkQ7SUFDN0QsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUVaLDZEQUE2RDtJQUM3RCxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBRVosc0RBQXNEO0lBQ3RELFlBQVksR0FBRyxDQUFDLENBQUM7SUFFakIsc0RBQXNEO0lBQ3RELFlBQVksR0FBRyxDQUFDLENBQUM7SUFFakIsc0RBQXNEO0lBQ3RELFlBQVksR0FBRyxDQUFDLENBQUM7SUFFakIsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUNqQixLQUFLLEdBQUcsS0FBSyxDQUFDO0lBRWQsWUFBYSxJQUFZO1FBQ3hCLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7Q0FDRCJ9","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Animation, AttachmentTimeline, RGBATimeline, RGBTimeline, RGBA2Timeline, RGB2Timeline, AlphaTimeline, RotateTimeline, TranslateTimeline, TranslateXTimeline, TranslateYTimeline, ScaleTimeline, ScaleXTimeline, ScaleYTimeline, ShearTimeline, ShearXTimeline, ShearYTimeline, IkConstraintTimeline, TransformConstraintTimeline, PathConstraintPositionTimeline, PathConstraintSpacingTimeline, PathConstraintMixTimeline, DeformTimeline, DrawOrderTimeline, EventTimeline, SequenceTimeline, PhysicsConstraintResetTimeline, PhysicsConstraintInertiaTimeline, PhysicsConstraintStrengthTimeline, PhysicsConstraintDampingTimeline, PhysicsConstraintMassTimeline, PhysicsConstraintWindTimeline, PhysicsConstraintGravityTimeline, PhysicsConstraintMixTimeline } from \"./Animation.js\";\nimport { Sequence, SequenceModeValues } from \"./attachments/Sequence.js\";\nimport { BoneData } from \"./BoneData.js\";\nimport { Event } from \"./Event.js\";\nimport { EventData } from \"./EventData.js\";\nimport { IkConstraintData } from \"./IkConstraintData.js\";\nimport { PathConstraintData, PositionMode, SpacingMode } from \"./PathConstraintData.js\";\nimport { PhysicsConstraintData } from \"./PhysicsConstraintData.js\";\nimport { SkeletonData } from \"./SkeletonData.js\";\nimport { Skin } from \"./Skin.js\";\nimport { SlotData } from \"./SlotData.js\";\nimport { TransformConstraintData } from \"./TransformConstraintData.js\";\nimport { Color, Utils } from \"./Utils.js\";\n/** Loads skeleton data in the Spine binary format.\n *\n * See [Spine binary format](http://esotericsoftware.com/spine-binary-format) and\n * [JSON and binary data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the Spine\n * Runtimes Guide. */\nexport class SkeletonBinary {\n /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at\n * runtime than were used in Spine.\n *\n * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */\n scale = 1;\n attachmentLoader;\n linkedMeshes = new Array();\n constructor(attachmentLoader) {\n this.attachmentLoader = attachmentLoader;\n }\n readSkeletonData(binary) {\n let scale = this.scale;\n let skeletonData = new SkeletonData();\n skeletonData.name = \"\"; // BOZO\n let input = new BinaryInput(binary);\n let lowHash = input.readInt32();\n let highHash = input.readInt32();\n skeletonData.hash = highHash == 0 && lowHash == 0 ? null : highHash.toString(16) + lowHash.toString(16);\n skeletonData.version = input.readString();\n skeletonData.x = input.readFloat();\n skeletonData.y = input.readFloat();\n skeletonData.width = input.readFloat();\n skeletonData.height = input.readFloat();\n let nonessential = input.readBoolean();\n if (nonessential) {\n skeletonData.fps = input.readFloat();\n skeletonData.imagesPath = input.readString();\n skeletonData.audioPath = input.readString();\n }\n let n = 0;\n // Strings.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) {\n let str = input.readString();\n if (!str)\n throw new Error(\"String in string table must not be null.\");\n input.strings.push(str);\n }\n // Bones.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) {\n let name = input.readString();\n if (!name)\n throw new Error(\"Bone name must not be null.\");\n let parent = i == 0 ? null : skeletonData.bones[input.readInt(true)];\n let data = new BoneData(i, name, parent);\n data.rotation = input.readFloat();\n data.x = input.readFloat() * scale;\n data.y = input.readFloat() * scale;\n data.scaleX = input.readFloat();\n data.scaleY = input.readFloat();\n data.shearX = input.readFloat();\n data.shearY = input.readFloat();\n data.length = input.readFloat() * scale;\n data.transformMode = input.readInt(true);\n data.skinRequired = input.readBoolean();\n if (nonessential) {\n Color.rgba8888ToColor(data.color, input.readInt32());\n data.icon = input.readString() ?? undefined;\n data.visible = input.readBoolean();\n }\n skeletonData.bones.push(data);\n }\n // Slots.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) {\n let slotName = input.readString();\n if (!slotName)\n throw new Error(\"Slot name must not be null.\");\n let boneData = skeletonData.bones[input.readInt(true)];\n let data = new SlotData(i, slotName, boneData);\n Color.rgba8888ToColor(data.color, input.readInt32());\n let darkColor = input.readInt32();\n if (darkColor != -1)\n Color.rgb888ToColor(data.darkColor = new Color(), darkColor);\n data.attachmentName = input.readStringRef();\n data.blendMode = input.readInt(true);\n if (nonessential)\n data.visible = input.readBoolean();\n skeletonData.slots.push(data);\n }\n // IK constraints.\n n = input.readInt(true);\n for (let i = 0, nn; i < n; i++) {\n let name = input.readString();\n if (!name)\n throw new Error(\"IK constraint data name must not be null.\");\n let data = new IkConstraintData(name);\n data.order = input.readInt(true);\n nn = input.readInt(true);\n for (let ii = 0; ii < nn; ii++)\n data.bones.push(skeletonData.bones[input.readInt(true)]);\n data.target = skeletonData.bones[input.readInt(true)];\n data.mix = input.readFloat();\n data.softness = input.readFloat() * scale;\n let flags = input.readByte();\n data.skinRequired = (flags & 1) != 0;\n data.bendDirection = (flags & 2) != 0 ? 1 : -1;\n data.compress = (flags & 4) != 0;\n data.stretch = (flags & 8) != 0;\n data.uniform = (flags & 16) != 0;\n skeletonData.ikConstraints.push(data);\n }\n // Transform constraints.\n n = input.readInt(true);\n for (let i = 0, nn; i < n; i++) {\n let name = input.readString();\n if (!name)\n throw new Error(\"Transform constraint data name must not be null.\");\n let data = new TransformConstraintData(name);\n data.order = input.readInt(true);\n nn = input.readInt(true);\n for (let ii = 0; ii < nn; ii++)\n data.bones.push(skeletonData.bones[input.readInt(true)]);\n data.target = skeletonData.bones[input.readInt(true)];\n const flags = input.readByte();\n data.skinRequired = (flags & 1) != 0;\n data.local = (flags & 2) != 0;\n data.relative = (flags & 4) != 0;\n data.offsetRotation = input.readFloat();\n data.offsetX = input.readFloat() * scale;\n data.offsetY = input.readFloat() * scale;\n data.offsetScaleX = input.readFloat();\n data.offsetScaleY = input.readFloat();\n data.offsetShearY = input.readFloat();\n data.mixRotate = input.readFloat();\n data.mixX = input.readFloat();\n data.mixY = input.readFloat();\n data.mixScaleX = input.readFloat();\n data.mixScaleY = input.readFloat();\n data.mixShearY = input.readFloat();\n skeletonData.transformConstraints.push(data);\n }\n // Path constraints.\n n = input.readInt(true);\n for (let i = 0, nn; i < n; i++) {\n let name = input.readString();\n if (!name)\n throw new Error(\"Path constraint data name must not be null.\");\n let data = new PathConstraintData(name);\n data.order = input.readInt(true);\n data.skinRequired = input.readBoolean();\n nn = input.readInt(true);\n for (let ii = 0; ii < nn; ii++)\n data.bones.push(skeletonData.bones[input.readInt(true)]);\n data.target = skeletonData.slots[input.readInt(true)];\n data.positionMode = input.readInt(true);\n data.spacingMode = input.readInt(true);\n data.rotateMode = input.readInt(true);\n data.offsetRotation = input.readFloat();\n data.position = input.readFloat();\n if (data.positionMode == PositionMode.Fixed)\n data.position *= scale;\n data.spacing = input.readFloat();\n if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed)\n data.spacing *= scale;\n data.mixRotate = input.readFloat();\n data.mixX = input.readFloat();\n data.mixY = input.readFloat();\n skeletonData.pathConstraints.push(data);\n }\n // Physics constraints.\n n = input.readInt(true);\n for (let i = 0, nn; i < n; i++) {\n const name = input.readString();\n if (!name)\n throw new Error(\"Physics constraint data name must not be null.\");\n const data = new PhysicsConstraintData(name);\n data.order = input.readInt(true);\n data.bone = skeletonData.bones[input.readInt(true)];\n let flags = input.readByte();\n data.skinRequired = (flags & 1) != 0;\n if ((flags & 2) != 0)\n data.x = input.readFloat();\n if ((flags & 4) != 0)\n data.y = input.readFloat();\n if ((flags & 8) != 0)\n data.rotate = input.readFloat();\n if ((flags & 16) != 0)\n data.scaleX = input.readFloat();\n if ((flags & 32) != 0)\n data.shearX = input.readFloat();\n data.step = 1 / input.readByte();\n data.inertia = input.readFloat();\n data.strength = input.readFloat();\n data.damping = input.readFloat();\n data.massInverse = input.readFloat();\n data.wind = input.readFloat() * scale;\n data.gravity = input.readFloat() * scale;\n data.mix = input.readFloat();\n flags = input.readByte();\n if ((flags & 1) != 0)\n data.inertiaGlobal = true;\n if ((flags & 2) != 0)\n data.strengthGlobal = true;\n if ((flags & 4) != 0)\n data.dampingGlobal = true;\n if ((flags & 8) != 0)\n data.massGlobal = true;\n if ((flags & 16) != 0)\n data.windGlobal = true;\n if ((flags & 32) != 0)\n data.gravityGlobal = true;\n if ((flags & 64) != 0)\n data.mixGlobal = true;\n skeletonData.physicsConstraints.push(data);\n }\n // Default skin.\n let defaultSkin = this.readSkin(input, skeletonData, true, nonessential);\n if (defaultSkin) {\n skeletonData.defaultSkin = defaultSkin;\n skeletonData.skins.push(defaultSkin);\n }\n // Skins.\n {\n let i = skeletonData.skins.length;\n Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true));\n for (; i < n; i++) {\n let skin = this.readSkin(input, skeletonData, false, nonessential);\n if (!skin)\n throw new Error(\"readSkin() should not have returned null.\");\n skeletonData.skins[i] = skin;\n }\n }\n // Linked meshes.\n n = this.linkedMeshes.length;\n for (let i = 0; i < n; i++) {\n let linkedMesh = this.linkedMeshes[i];\n const skin = skeletonData.skins[linkedMesh.skinIndex];\n if (!linkedMesh.parent)\n throw new Error(\"Linked mesh parent must not be null\");\n let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);\n if (!parent)\n throw new Error(`Parent mesh not found: ${linkedMesh.parent}`);\n linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent : linkedMesh.mesh;\n linkedMesh.mesh.setParentMesh(parent);\n if (linkedMesh.mesh.region != null)\n linkedMesh.mesh.updateRegion();\n }\n this.linkedMeshes.length = 0;\n // Events.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) {\n let eventName = input.readString();\n if (!eventName)\n throw new Error(\"Event data name must not be null\");\n let data = new EventData(eventName);\n data.intValue = input.readInt(false);\n data.floatValue = input.readFloat();\n data.stringValue = input.readString();\n data.audioPath = input.readString();\n if (data.audioPath) {\n data.volume = input.readFloat();\n data.balance = input.readFloat();\n }\n skeletonData.events.push(data);\n }\n // Animations.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) {\n let animationName = input.readString();\n if (!animationName)\n throw new Error(\"Animatio name must not be null.\");\n skeletonData.animations.push(this.readAnimation(input, animationName, skeletonData));\n }\n return skeletonData;\n }\n readSkin(input, skeletonData, defaultSkin, nonessential) {\n let skin = null;\n let slotCount = 0;\n if (defaultSkin) {\n slotCount = input.readInt(true);\n if (slotCount == 0)\n return null;\n skin = new Skin(\"default\");\n }\n else {\n let skinName = input.readString();\n if (!skinName)\n throw new Error(\"Skin name must not be null.\");\n skin = new Skin(skinName);\n if (nonessential)\n Color.rgba8888ToColor(skin.color, input.readInt32());\n skin.bones.length = input.readInt(true);\n for (let i = 0, n = skin.bones.length; i < n; i++)\n skin.bones[i] = skeletonData.bones[input.readInt(true)];\n for (let i = 0, n = input.readInt(true); i < n; i++)\n skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]);\n for (let i = 0, n = input.readInt(true); i < n; i++)\n skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]);\n for (let i = 0, n = input.readInt(true); i < n; i++)\n skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]);\n for (let i = 0, n = input.readInt(true); i < n; i++)\n skin.constraints.push(skeletonData.physicsConstraints[input.readInt(true)]);\n slotCount = input.readInt(true);\n }\n for (let i = 0; i < slotCount; i++) {\n let slotIndex = input.readInt(true);\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n let name = input.readStringRef();\n if (!name)\n throw new Error(\"Attachment name must not be null\");\n let attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name, nonessential);\n if (attachment)\n skin.setAttachment(slotIndex, name, attachment);\n }\n }\n return skin;\n }\n readAttachment(input, skeletonData, skin, slotIndex, attachmentName, nonessential) {\n let scale = this.scale;\n let flags = input.readByte();\n const name = (flags & 8) != 0 ? input.readStringRef() : attachmentName;\n if (!name)\n throw new Error(\"Attachment name must not be null\");\n switch ((flags & 0b111)) { // BUG?\n case AttachmentType.Region: {\n let path = (flags & 16) != 0 ? input.readStringRef() : null;\n const color = (flags & 32) != 0 ? input.readInt32() : 0xffffffff;\n const sequence = (flags & 64) != 0 ? this.readSequence(input) : null;\n let rotation = input.readFloat();\n let x = input.readFloat();\n let y = input.readFloat();\n let scaleX = input.readFloat();\n let scaleY = input.readFloat();\n let width = input.readFloat();\n let height = input.readFloat();\n if (!path)\n path = name;\n let region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence);\n if (!region)\n return null;\n region.path = path;\n region.x = x * scale;\n region.y = y * scale;\n region.scaleX = scaleX;\n region.scaleY = scaleY;\n region.rotation = rotation;\n region.width = width * scale;\n region.height = height * scale;\n Color.rgba8888ToColor(region.color, color);\n region.sequence = sequence;\n if (sequence == null)\n region.updateRegion();\n return region;\n }\n case AttachmentType.BoundingBox: {\n let vertices = this.readVertices(input, (flags & 16) != 0);\n let color = nonessential ? input.readInt32() : 0;\n let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name);\n if (!box)\n return null;\n box.worldVerticesLength = vertices.length;\n box.vertices = vertices.vertices;\n box.bones = vertices.bones;\n if (nonessential)\n Color.rgba8888ToColor(box.color, color);\n return box;\n }\n case AttachmentType.Mesh: {\n let path = (flags & 16) != 0 ? input.readStringRef() : name;\n const color = (flags & 32) != 0 ? input.readInt32() : 0xffffffff;\n const sequence = (flags & 64) != 0 ? this.readSequence(input) : null;\n const hullLength = input.readInt(true);\n const vertices = this.readVertices(input, (flags & 128) != 0);\n const uvs = this.readFloatArray(input, vertices.length, 1);\n const triangles = this.readShortArray(input, (vertices.length - hullLength - 2) * 3);\n let edges = [];\n let width = 0, height = 0;\n if (nonessential) {\n edges = this.readShortArray(input, input.readInt(true));\n width = input.readFloat();\n height = input.readFloat();\n }\n if (!path)\n path = name;\n let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence);\n if (!mesh)\n return null;\n mesh.path = path;\n Color.rgba8888ToColor(mesh.color, color);\n mesh.bones = vertices.bones;\n mesh.vertices = vertices.vertices;\n mesh.worldVerticesLength = vertices.length;\n mesh.triangles = triangles;\n mesh.regionUVs = uvs;\n if (sequence == null)\n mesh.updateRegion();\n mesh.hullLength = hullLength << 1;\n mesh.sequence = sequence;\n if (nonessential) {\n mesh.edges = edges;\n mesh.width = width * scale;\n mesh.height = height * scale;\n }\n return mesh;\n }\n case AttachmentType.LinkedMesh: {\n const path = (flags & 16) != 0 ? input.readStringRef() : name;\n if (path == null)\n throw new Error(\"Path of linked mesh must not be null\");\n const color = (flags & 32) != 0 ? input.readInt32() : 0xffffffff;\n const sequence = (flags & 64) != 0 ? this.readSequence(input) : null;\n const inheritTimelines = (flags & 128) != 0;\n const skinIndex = input.readInt(true);\n const parent = input.readStringRef();\n let width = 0, height = 0;\n if (nonessential) {\n width = input.readFloat();\n height = input.readFloat();\n }\n let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence);\n if (!mesh)\n return null;\n mesh.path = path;\n Color.rgba8888ToColor(mesh.color, color);\n mesh.sequence = sequence;\n if (nonessential) {\n mesh.width = width * scale;\n mesh.height = height * scale;\n }\n this.linkedMeshes.push(new LinkedMesh(mesh, skinIndex, slotIndex, parent, inheritTimelines));\n return mesh;\n }\n case AttachmentType.Path: {\n const closed = (flags & 16) != 0;\n const constantSpeed = (flags & 32) != 0;\n const vertices = this.readVertices(input, (flags & 64) != 0);\n const lengths = Utils.newArray(vertices.length / 6, 0);\n for (let i = 0, n = lengths.length; i < n; i++)\n lengths[i] = input.readFloat() * scale;\n const color = nonessential ? input.readInt32() : 0;\n const path = this.attachmentLoader.newPathAttachment(skin, name);\n if (!path)\n return null;\n path.closed = closed;\n path.constantSpeed = constantSpeed;\n path.worldVerticesLength = vertices.length;\n path.vertices = vertices.vertices;\n path.bones = vertices.bones;\n path.lengths = lengths;\n if (nonessential)\n Color.rgba8888ToColor(path.color, color);\n return path;\n }\n case AttachmentType.Point: {\n const rotation = input.readFloat();\n const x = input.readFloat();\n const y = input.readFloat();\n const color = nonessential ? input.readInt32() : 0;\n const point = this.attachmentLoader.newPointAttachment(skin, name);\n if (!point)\n return null;\n point.x = x * scale;\n point.y = y * scale;\n point.rotation = rotation;\n if (nonessential)\n Color.rgba8888ToColor(point.color, color);\n return point;\n }\n case AttachmentType.Clipping: {\n const endSlotIndex = input.readInt(true);\n const vertices = this.readVertices(input, (flags & 16) != 0);\n let color = nonessential ? input.readInt32() : 0;\n let clip = this.attachmentLoader.newClippingAttachment(skin, name);\n if (!clip)\n return null;\n clip.endSlot = skeletonData.slots[endSlotIndex];\n clip.worldVerticesLength = vertices.length;\n clip.vertices = vertices.vertices;\n clip.bones = vertices.bones;\n if (nonessential)\n Color.rgba8888ToColor(clip.color, color);\n return clip;\n }\n }\n return null;\n }\n readSequence(input) {\n if (!input.readBoolean())\n return null;\n let sequence = new Sequence(input.readInt(true));\n sequence.start = input.readInt(true);\n sequence.digits = input.readInt(true);\n sequence.setupIndex = input.readInt(true);\n return sequence;\n }\n readVertices(input, weighted) {\n const scale = this.scale;\n const vertexCount = input.readInt(true);\n const vertices = new Vertices();\n vertices.length = vertexCount << 1;\n if (!weighted) {\n vertices.vertices = this.readFloatArray(input, vertices.length, scale);\n return vertices;\n }\n let weights = new Array();\n let bonesArray = new Array();\n for (let i = 0; i < vertexCount; i++) {\n let boneCount = input.readInt(true);\n bonesArray.push(boneCount);\n for (let ii = 0; ii < boneCount; ii++) {\n bonesArray.push(input.readInt(true));\n weights.push(input.readFloat() * scale);\n weights.push(input.readFloat() * scale);\n weights.push(input.readFloat());\n }\n }\n vertices.vertices = Utils.toFloatArray(weights);\n vertices.bones = bonesArray;\n return vertices;\n }\n readFloatArray(input, n, scale) {\n let array = new Array(n);\n if (scale == 1) {\n for (let i = 0; i < n; i++)\n array[i] = input.readFloat();\n }\n else {\n for (let i = 0; i < n; i++)\n array[i] = input.readFloat() * scale;\n }\n return array;\n }\n readShortArray(input, n) {\n let array = new Array(n);\n for (let i = 0; i < n; i++)\n array[i] = input.readInt(true);\n return array;\n }\n readAnimation(input, name, skeletonData) {\n input.readInt(true); // Number of timelines.\n let timelines = new Array();\n let scale = this.scale;\n // Slot timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n let slotIndex = input.readInt(true);\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n let timelineType = input.readByte();\n let frameCount = input.readInt(true);\n let frameLast = frameCount - 1;\n switch (timelineType) {\n case SLOT_ATTACHMENT: {\n let timeline = new AttachmentTimeline(frameCount, slotIndex);\n for (let frame = 0; frame < frameCount; frame++)\n timeline.setFrame(frame, input.readFloat(), input.readStringRef());\n timelines.push(timeline);\n break;\n }\n case SLOT_RGBA: {\n let bezierCount = input.readInt(true);\n let timeline = new RGBATimeline(frameCount, bezierCount, slotIndex);\n let time = input.readFloat();\n let r = input.readUnsignedByte() / 255.0;\n let g = input.readUnsignedByte() / 255.0;\n let b = input.readUnsignedByte() / 255.0;\n let a = input.readUnsignedByte() / 255.0;\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, r, g, b, a);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat();\n let r2 = input.readUnsignedByte() / 255.0;\n let g2 = input.readUnsignedByte() / 255.0;\n let b2 = input.readUnsignedByte() / 255.0;\n let a2 = input.readUnsignedByte() / 255.0;\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1);\n setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1);\n setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1);\n setBezier(input, timeline, bezier++, frame, 3, time, time2, a, a2, 1);\n }\n time = time2;\n r = r2;\n g = g2;\n b = b2;\n a = a2;\n }\n timelines.push(timeline);\n break;\n }\n case SLOT_RGB: {\n let bezierCount = input.readInt(true);\n let timeline = new RGBTimeline(frameCount, bezierCount, slotIndex);\n let time = input.readFloat();\n let r = input.readUnsignedByte() / 255.0;\n let g = input.readUnsignedByte() / 255.0;\n let b = input.readUnsignedByte() / 255.0;\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, r, g, b);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat();\n let r2 = input.readUnsignedByte() / 255.0;\n let g2 = input.readUnsignedByte() / 255.0;\n let b2 = input.readUnsignedByte() / 255.0;\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1);\n setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1);\n setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1);\n }\n time = time2;\n r = r2;\n g = g2;\n b = b2;\n }\n timelines.push(timeline);\n break;\n }\n case SLOT_RGBA2: {\n let bezierCount = input.readInt(true);\n let timeline = new RGBA2Timeline(frameCount, bezierCount, slotIndex);\n let time = input.readFloat();\n let r = input.readUnsignedByte() / 255.0;\n let g = input.readUnsignedByte() / 255.0;\n let b = input.readUnsignedByte() / 255.0;\n let a = input.readUnsignedByte() / 255.0;\n let r2 = input.readUnsignedByte() / 255.0;\n let g2 = input.readUnsignedByte() / 255.0;\n let b2 = input.readUnsignedByte() / 255.0;\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, r, g, b, a, r2, g2, b2);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat();\n let nr = input.readUnsignedByte() / 255.0;\n let ng = input.readUnsignedByte() / 255.0;\n let nb = input.readUnsignedByte() / 255.0;\n let na = input.readUnsignedByte() / 255.0;\n let nr2 = input.readUnsignedByte() / 255.0;\n let ng2 = input.readUnsignedByte() / 255.0;\n let nb2 = input.readUnsignedByte() / 255.0;\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1);\n setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1);\n setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1);\n setBezier(input, timeline, bezier++, frame, 3, time, time2, a, na, 1);\n setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2, 1);\n setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2, 1);\n setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2, 1);\n }\n time = time2;\n r = nr;\n g = ng;\n b = nb;\n a = na;\n r2 = nr2;\n g2 = ng2;\n b2 = nb2;\n }\n timelines.push(timeline);\n break;\n }\n case SLOT_RGB2: {\n let bezierCount = input.readInt(true);\n let timeline = new RGB2Timeline(frameCount, bezierCount, slotIndex);\n let time = input.readFloat();\n let r = input.readUnsignedByte() / 255.0;\n let g = input.readUnsignedByte() / 255.0;\n let b = input.readUnsignedByte() / 255.0;\n let r2 = input.readUnsignedByte() / 255.0;\n let g2 = input.readUnsignedByte() / 255.0;\n let b2 = input.readUnsignedByte() / 255.0;\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, r, g, b, r2, g2, b2);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat();\n let nr = input.readUnsignedByte() / 255.0;\n let ng = input.readUnsignedByte() / 255.0;\n let nb = input.readUnsignedByte() / 255.0;\n let nr2 = input.readUnsignedByte() / 255.0;\n let ng2 = input.readUnsignedByte() / 255.0;\n let nb2 = input.readUnsignedByte() / 255.0;\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1);\n setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1);\n setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1);\n setBezier(input, timeline, bezier++, frame, 3, time, time2, r2, nr2, 1);\n setBezier(input, timeline, bezier++, frame, 4, time, time2, g2, ng2, 1);\n setBezier(input, timeline, bezier++, frame, 5, time, time2, b2, nb2, 1);\n }\n time = time2;\n r = nr;\n g = ng;\n b = nb;\n r2 = nr2;\n g2 = ng2;\n b2 = nb2;\n }\n timelines.push(timeline);\n break;\n }\n case SLOT_ALPHA: {\n let timeline = new AlphaTimeline(frameCount, input.readInt(true), slotIndex);\n let time = input.readFloat(), a = input.readUnsignedByte() / 255;\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, a);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat();\n let a2 = input.readUnsignedByte() / 255;\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, a, a2, 1);\n }\n time = time2;\n a = a2;\n }\n timelines.push(timeline);\n }\n }\n }\n }\n // Bone timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n let boneIndex = input.readInt(true);\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n let type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true);\n switch (type) {\n case BONE_ROTATE:\n timelines.push(readTimeline1(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1));\n break;\n case BONE_TRANSLATE:\n timelines.push(readTimeline2(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale));\n break;\n case BONE_TRANSLATEX:\n timelines.push(readTimeline1(input, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale));\n break;\n case BONE_TRANSLATEY:\n timelines.push(readTimeline1(input, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale));\n break;\n case BONE_SCALE:\n timelines.push(readTimeline2(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1));\n break;\n case BONE_SCALEX:\n timelines.push(readTimeline1(input, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1));\n break;\n case BONE_SCALEY:\n timelines.push(readTimeline1(input, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1));\n break;\n case BONE_SHEAR:\n timelines.push(readTimeline2(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1));\n break;\n case BONE_SHEARX:\n timelines.push(readTimeline1(input, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1));\n break;\n case BONE_SHEARY:\n timelines.push(readTimeline1(input, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1));\n }\n }\n }\n // IK constraint timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n let index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1;\n let timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index);\n let time = input.readFloat(), mix = input.readFloat(), softness = input.readFloat() * scale;\n for (let frame = 0, bezier = 0;; frame++) {\n const flags = input.readByte();\n timeline.setFrame(frame, time, mix, softness, input.readByte(), (flags & 1) != 0, (flags & 2) != 0);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat(), mix2 = input.readFloat(), softness2 = input.readFloat() * scale;\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1);\n setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale);\n }\n time = time2;\n mix = mix2;\n softness = softness2;\n }\n timelines.push(timeline);\n }\n // Transform constraint timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n let index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1;\n let timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index);\n let time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(), mixScaleX = input.readFloat(), mixScaleY = input.readFloat(), mixShearY = input.readFloat();\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(), mixScaleX2 = input.readFloat(), mixScaleY2 = input.readFloat(), mixShearY2 = input.readFloat();\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1);\n setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1);\n setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1);\n setBezier(input, timeline, bezier++, frame, 3, time, time2, mixScaleX, mixScaleX2, 1);\n setBezier(input, timeline, bezier++, frame, 4, time, time2, mixScaleY, mixScaleY2, 1);\n setBezier(input, timeline, bezier++, frame, 5, time, time2, mixShearY, mixShearY2, 1);\n }\n time = time2;\n mixRotate = mixRotate2;\n mixX = mixX2;\n mixY = mixY2;\n mixScaleX = mixScaleX2;\n mixScaleY = mixScaleY2;\n mixShearY = mixShearY2;\n }\n timelines.push(timeline);\n }\n // Path constraint timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n let index = input.readInt(true);\n let data = skeletonData.pathConstraints[index];\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n const type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true);\n switch (type) {\n case PATH_POSITION:\n timelines\n .push(readTimeline1(input, new PathConstraintPositionTimeline(frameCount, bezierCount, index), data.positionMode == PositionMode.Fixed ? scale : 1));\n break;\n case PATH_SPACING:\n timelines\n .push(readTimeline1(input, new PathConstraintSpacingTimeline(frameCount, bezierCount, index), data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1));\n break;\n case PATH_MIX:\n let timeline = new PathConstraintMixTimeline(frameCount, bezierCount, index);\n let time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat();\n for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) {\n timeline.setFrame(frame, time, mixRotate, mixX, mixY);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat();\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1);\n setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1);\n setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1);\n }\n time = time2;\n mixRotate = mixRotate2;\n mixX = mixX2;\n mixY = mixY2;\n }\n timelines.push(timeline);\n }\n }\n }\n // Physics timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n const index = input.readInt(true) - 1;\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n const type = input.readByte(), frameCount = input.readInt(true);\n if (type == PHYSICS_RESET) {\n const timeline = new PhysicsConstraintResetTimeline(frameCount, index);\n for (let frame = 0; frame < frameCount; frame++)\n timeline.setFrame(frame, input.readFloat());\n timelines.push(timeline);\n continue;\n }\n const bezierCount = input.readInt(true);\n switch (type) {\n case PHYSICS_INERTIA:\n timelines.push(readTimeline1(input, new PhysicsConstraintInertiaTimeline(frameCount, bezierCount, index), 1));\n break;\n case PHYSICS_STRENGTH:\n timelines.push(readTimeline1(input, new PhysicsConstraintStrengthTimeline(frameCount, bezierCount, index), 1));\n break;\n case PHYSICS_DAMPING:\n timelines.push(readTimeline1(input, new PhysicsConstraintDampingTimeline(frameCount, bezierCount, index), 1));\n break;\n case PHYSICS_MASS:\n timelines.push(readTimeline1(input, new PhysicsConstraintMassTimeline(frameCount, bezierCount, index), 1));\n break;\n case PHYSICS_WIND:\n timelines.push(readTimeline1(input, new PhysicsConstraintWindTimeline(frameCount, bezierCount, index), scale));\n break;\n case PHYSICS_GRAVITY:\n timelines.push(readTimeline1(input, new PhysicsConstraintGravityTimeline(frameCount, bezierCount, index), scale));\n break;\n case PHYSICS_MIX:\n timelines.push(readTimeline1(input, new PhysicsConstraintMixTimeline(frameCount, bezierCount, index), 1));\n }\n }\n }\n // Deform timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n let skin = skeletonData.skins[input.readInt(true)];\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n let slotIndex = input.readInt(true);\n for (let iii = 0, nnn = input.readInt(true); iii < nnn; iii++) {\n let attachmentName = input.readStringRef();\n if (!attachmentName)\n throw new Error(\"attachmentName must not be null.\");\n let attachment = skin.getAttachment(slotIndex, attachmentName);\n let timelineType = input.readByte();\n let frameCount = input.readInt(true);\n let frameLast = frameCount - 1;\n switch (timelineType) {\n case ATTACHMENT_DEFORM: {\n let vertexAttachment = attachment;\n let weighted = vertexAttachment.bones;\n let vertices = vertexAttachment.vertices;\n let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;\n let bezierCount = input.readInt(true);\n let timeline = new DeformTimeline(frameCount, bezierCount, slotIndex, vertexAttachment);\n let time = input.readFloat();\n for (let frame = 0, bezier = 0;; frame++) {\n let deform;\n let end = input.readInt(true);\n if (end == 0)\n deform = weighted ? Utils.newFloatArray(deformLength) : vertices;\n else {\n deform = Utils.newFloatArray(deformLength);\n let start = input.readInt(true);\n end += start;\n if (scale == 1) {\n for (let v = start; v < end; v++)\n deform[v] = input.readFloat();\n }\n else {\n for (let v = start; v < end; v++)\n deform[v] = input.readFloat() * scale;\n }\n if (!weighted) {\n for (let v = 0, vn = deform.length; v < vn; v++)\n deform[v] += vertices[v];\n }\n }\n timeline.setFrame(frame, time, deform);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat();\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1);\n }\n time = time2;\n }\n timelines.push(timeline);\n break;\n }\n case ATTACHMENT_SEQUENCE: {\n let timeline = new SequenceTimeline(frameCount, slotIndex, attachment);\n for (let frame = 0; frame < frameCount; frame++) {\n let time = input.readFloat();\n let modeAndIndex = input.readInt32();\n timeline.setFrame(frame, time, SequenceModeValues[modeAndIndex & 0xf], modeAndIndex >> 4, input.readFloat());\n }\n timelines.push(timeline);\n break;\n }\n }\n }\n }\n }\n // Draw order timeline.\n let drawOrderCount = input.readInt(true);\n if (drawOrderCount > 0) {\n let timeline = new DrawOrderTimeline(drawOrderCount);\n let slotCount = skeletonData.slots.length;\n for (let i = 0; i < drawOrderCount; i++) {\n let time = input.readFloat();\n let offsetCount = input.readInt(true);\n let drawOrder = Utils.newArray(slotCount, 0);\n for (let ii = slotCount - 1; ii >= 0; ii--)\n drawOrder[ii] = -1;\n let unchanged = Utils.newArray(slotCount - offsetCount, 0);\n let originalIndex = 0, unchangedIndex = 0;\n for (let ii = 0; ii < offsetCount; ii++) {\n let slotIndex = input.readInt(true);\n // Collect unchanged items.\n while (originalIndex != slotIndex)\n unchanged[unchangedIndex++] = originalIndex++;\n // Set changed items.\n drawOrder[originalIndex + input.readInt(true)] = originalIndex++;\n }\n // Collect remaining unchanged items.\n while (originalIndex < slotCount)\n unchanged[unchangedIndex++] = originalIndex++;\n // Fill in unchanged items.\n for (let ii = slotCount - 1; ii >= 0; ii--)\n if (drawOrder[ii] == -1)\n drawOrder[ii] = unchanged[--unchangedIndex];\n timeline.setFrame(i, time, drawOrder);\n }\n timelines.push(timeline);\n }\n // Event timeline.\n let eventCount = input.readInt(true);\n if (eventCount > 0) {\n let timeline = new EventTimeline(eventCount);\n for (let i = 0; i < eventCount; i++) {\n let time = input.readFloat();\n let eventData = skeletonData.events[input.readInt(true)];\n let event = new Event(time, eventData);\n event.intValue = input.readInt(false);\n event.floatValue = input.readFloat();\n event.stringValue = input.readString();\n if (event.stringValue == null)\n event.stringValue = eventData.stringValue;\n if (event.data.audioPath) {\n event.volume = input.readFloat();\n event.balance = input.readFloat();\n }\n timeline.setFrame(i, event);\n }\n timelines.push(timeline);\n }\n let duration = 0;\n for (let i = 0, n = timelines.length; i < n; i++)\n duration = Math.max(duration, timelines[i].getDuration());\n return new Animation(name, timelines, duration);\n }\n}\nexport class BinaryInput {\n strings;\n index;\n buffer;\n constructor(data, strings = new Array(), index = 0, buffer = new DataView(data.buffer)) {\n this.strings = strings;\n this.index = index;\n this.buffer = buffer;\n }\n readByte() {\n return this.buffer.getInt8(this.index++);\n }\n readUnsignedByte() {\n return this.buffer.getUint8(this.index++);\n }\n readShort() {\n let value = this.buffer.getInt16(this.index);\n this.index += 2;\n return value;\n }\n readInt32() {\n let value = this.buffer.getInt32(this.index);\n this.index += 4;\n return value;\n }\n readInt(optimizePositive) {\n let b = this.readByte();\n let result = b & 0x7F;\n if ((b & 0x80) != 0) {\n b = this.readByte();\n result |= (b & 0x7F) << 7;\n if ((b & 0x80) != 0) {\n b = this.readByte();\n result |= (b & 0x7F) << 14;\n if ((b & 0x80) != 0) {\n b = this.readByte();\n result |= (b & 0x7F) << 21;\n if ((b & 0x80) != 0) {\n b = this.readByte();\n result |= (b & 0x7F) << 28;\n }\n }\n }\n }\n return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));\n }\n readStringRef() {\n let index = this.readInt(true);\n return index == 0 ? null : this.strings[index - 1];\n }\n readString() {\n let byteCount = this.readInt(true);\n switch (byteCount) {\n case 0:\n return null;\n case 1:\n return \"\";\n }\n byteCount--;\n let chars = \"\";\n let charCount = 0;\n for (let i = 0; i < byteCount;) {\n let b = this.readUnsignedByte();\n switch (b >> 4) {\n case 12:\n case 13:\n chars += String.fromCharCode(((b & 0x1F) << 6 | this.readByte() & 0x3F));\n i += 2;\n break;\n case 14:\n chars += String.fromCharCode(((b & 0x0F) << 12 | (this.readByte() & 0x3F) << 6 | this.readByte() & 0x3F));\n i += 3;\n break;\n default:\n chars += String.fromCharCode(b);\n i++;\n }\n }\n return chars;\n }\n readFloat() {\n let value = this.buffer.getFloat32(this.index);\n this.index += 4;\n return value;\n }\n readBoolean() {\n return this.readByte() != 0;\n }\n}\nclass LinkedMesh {\n parent;\n skinIndex;\n slotIndex;\n mesh;\n inheritTimeline;\n constructor(mesh, skinIndex, slotIndex, parent, inheritDeform) {\n this.mesh = mesh;\n this.skinIndex = skinIndex;\n this.slotIndex = slotIndex;\n this.parent = parent;\n this.inheritTimeline = inheritDeform;\n }\n}\nclass Vertices {\n bones;\n vertices;\n length;\n constructor(bones = null, vertices = null, length = 0) {\n this.bones = bones;\n this.vertices = vertices;\n this.length = length;\n }\n}\nvar AttachmentType;\n(function (AttachmentType) {\n AttachmentType[AttachmentType[\"Region\"] = 0] = \"Region\";\n AttachmentType[AttachmentType[\"BoundingBox\"] = 1] = \"BoundingBox\";\n AttachmentType[AttachmentType[\"Mesh\"] = 2] = \"Mesh\";\n AttachmentType[AttachmentType[\"LinkedMesh\"] = 3] = \"LinkedMesh\";\n AttachmentType[AttachmentType[\"Path\"] = 4] = \"Path\";\n AttachmentType[AttachmentType[\"Point\"] = 5] = \"Point\";\n AttachmentType[AttachmentType[\"Clipping\"] = 6] = \"Clipping\";\n})(AttachmentType || (AttachmentType = {}));\nfunction readTimeline1(input, timeline, scale) {\n let time = input.readFloat(), value = input.readFloat() * scale;\n for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) {\n timeline.setFrame(frame, time, value);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat(), value2 = input.readFloat() * scale;\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, value, value2, scale);\n }\n time = time2;\n value = value2;\n }\n return timeline;\n}\nfunction readTimeline2(input, timeline, scale) {\n let time = input.readFloat(), value1 = input.readFloat() * scale, value2 = input.readFloat() * scale;\n for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) {\n timeline.setFrame(frame, time, value1, value2);\n if (frame == frameLast)\n break;\n let time2 = input.readFloat(), nvalue1 = input.readFloat() * scale, nvalue2 = input.readFloat() * scale;\n switch (input.readByte()) {\n case CURVE_STEPPED:\n timeline.setStepped(frame);\n break;\n case CURVE_BEZIER:\n setBezier(input, timeline, bezier++, frame, 0, time, time2, value1, nvalue1, scale);\n setBezier(input, timeline, bezier++, frame, 1, time, time2, value2, nvalue2, scale);\n }\n time = time2;\n value1 = nvalue1;\n value2 = nvalue2;\n }\n return timeline;\n}\nfunction setBezier(input, timeline, bezier, frame, value, time1, time2, value1, value2, scale) {\n timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(), input.readFloat() * scale, time2, value2);\n}\nconst BONE_ROTATE = 0;\nconst BONE_TRANSLATE = 1;\nconst BONE_TRANSLATEX = 2;\nconst BONE_TRANSLATEY = 3;\nconst BONE_SCALE = 4;\nconst BONE_SCALEX = 5;\nconst BONE_SCALEY = 6;\nconst BONE_SHEAR = 7;\nconst BONE_SHEARX = 8;\nconst BONE_SHEARY = 9;\nconst SLOT_ATTACHMENT = 0;\nconst SLOT_RGBA = 1;\nconst SLOT_RGB = 2;\nconst SLOT_RGBA2 = 3;\nconst SLOT_RGB2 = 4;\nconst SLOT_ALPHA = 5;\nconst ATTACHMENT_DEFORM = 0;\nconst ATTACHMENT_SEQUENCE = 1;\nconst PATH_POSITION = 0;\nconst PATH_SPACING = 1;\nconst PATH_MIX = 2;\nconst PHYSICS_INERTIA = 0;\nconst PHYSICS_STRENGTH = 1;\nconst PHYSICS_DAMPING = 2;\nconst PHYSICS_MASS = 4;\nconst PHYSICS_WIND = 5;\nconst PHYSICS_GRAVITY = 6;\nconst PHYSICS_MIX = 7;\nconst PHYSICS_RESET = 8;\nconst CURVE_LINEAR = 0;\nconst CURVE_STEPPED = 1;\nconst CURVE_BEZIER = 2;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25CaW5hcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU2tlbGV0b25CaW5hcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxTQUFTLEVBQVksa0JBQWtCLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsMkJBQTJCLEVBQUUsOEJBQThCLEVBQUUsNkJBQTZCLEVBQUUseUJBQXlCLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBaUQsZ0JBQWdCLEVBQUUsOEJBQThCLEVBQUUsZ0NBQWdDLEVBQUUsaUNBQWlDLEVBQUUsZ0NBQWdDLEVBQUUsNkJBQTZCLEVBQUUsNkJBQTZCLEVBQUUsZ0NBQWdDLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUs5ekIsT0FBTyxFQUFFLFFBQVEsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNuQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDekQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIs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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Pool } from \"./Utils.js\";\nexport class Triangulator {\n convexPolygons = new Array();\n convexPolygonsIndices = new Array();\n indicesArray = new Array();\n isConcaveArray = new Array();\n triangles = new Array();\n polygonPool = new Pool(() => {\n return new Array();\n });\n polygonIndicesPool = new Pool(() => {\n return new Array();\n });\n triangulate(verticesArray) {\n let vertices = verticesArray;\n let vertexCount = verticesArray.length >> 1;\n let indices = this.indicesArray;\n indices.length = 0;\n for (let i = 0; i < vertexCount; i++)\n indices[i] = i;\n let isConcave = this.isConcaveArray;\n isConcave.length = 0;\n for (let i = 0, n = vertexCount; i < n; ++i)\n isConcave[i] = Triangulator.isConcave(i, vertexCount, vertices, indices);\n let triangles = this.triangles;\n triangles.length = 0;\n while (vertexCount > 3) {\n // Find ear tip.\n let previous = vertexCount - 1, i = 0, next = 1;\n while (true) {\n outer: if (!isConcave[i]) {\n let p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;\n let p1x = vertices[p1], p1y = vertices[p1 + 1];\n let p2x = vertices[p2], p2y = vertices[p2 + 1];\n let p3x = vertices[p3], p3y = vertices[p3 + 1];\n for (let ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {\n if (!isConcave[ii])\n continue;\n let v = indices[ii] << 1;\n let vx = vertices[v], vy = vertices[v + 1];\n if (Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {\n if (Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {\n if (Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy))\n break outer;\n }\n }\n }\n break;\n }\n if (next == 0) {\n do {\n if (!isConcave[i])\n break;\n i--;\n } while (i > 0);\n break;\n }\n previous = i;\n i = next;\n next = (next + 1) % vertexCount;\n }\n // Cut ear tip.\n triangles.push(indices[(vertexCount + i - 1) % vertexCount]);\n triangles.push(indices[i]);\n triangles.push(indices[(i + 1) % vertexCount]);\n indices.splice(i, 1);\n isConcave.splice(i, 1);\n vertexCount--;\n let previousIndex = (vertexCount + i - 1) % vertexCount;\n let nextIndex = i == vertexCount ? 0 : i;\n isConcave[previousIndex] = Triangulator.isConcave(previousIndex, vertexCount, vertices, indices);\n isConcave[nextIndex] = Triangulator.isConcave(nextIndex, vertexCount, vertices, indices);\n }\n if (vertexCount == 3) {\n triangles.push(indices[2]);\n triangles.push(indices[0]);\n triangles.push(indices[1]);\n }\n return triangles;\n }\n decompose(verticesArray, triangles) {\n let vertices = verticesArray;\n let convexPolygons = this.convexPolygons;\n this.polygonPool.freeAll(convexPolygons);\n convexPolygons.length = 0;\n let convexPolygonsIndices = this.convexPolygonsIndices;\n this.polygonIndicesPool.freeAll(convexPolygonsIndices);\n convexPolygonsIndices.length = 0;\n let polygonIndices = this.polygonIndicesPool.obtain();\n polygonIndices.length = 0;\n let polygon = this.polygonPool.obtain();\n polygon.length = 0;\n // Merge subsequent triangles if they form a triangle fan.\n let fanBaseIndex = -1, lastWinding = 0;\n for (let i = 0, n = triangles.length; i < n; i += 3) {\n let t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;\n let x1 = vertices[t1], y1 = vertices[t1 + 1];\n let x2 = vertices[t2], y2 = vertices[t2 + 1];\n let x3 = vertices[t3], y3 = vertices[t3 + 1];\n // If the base of the last triangle is the same as this triangle, check if they form a convex polygon (triangle fan).\n let merged = false;\n if (fanBaseIndex == t1) {\n let o = polygon.length - 4;\n let winding1 = Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);\n let winding2 = Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);\n if (winding1 == lastWinding && winding2 == lastWinding) {\n polygon.push(x3);\n polygon.push(y3);\n polygonIndices.push(t3);\n merged = true;\n }\n }\n // Otherwise make this triangle the new base.\n if (!merged) {\n if (polygon.length > 0) {\n convexPolygons.push(polygon);\n convexPolygonsIndices.push(polygonIndices);\n }\n else {\n this.polygonPool.free(polygon);\n this.polygonIndicesPool.free(polygonIndices);\n }\n polygon = this.polygonPool.obtain();\n polygon.length = 0;\n polygon.push(x1);\n polygon.push(y1);\n polygon.push(x2);\n polygon.push(y2);\n polygon.push(x3);\n polygon.push(y3);\n polygonIndices = this.polygonIndicesPool.obtain();\n polygonIndices.length = 0;\n polygonIndices.push(t1);\n polygonIndices.push(t2);\n polygonIndices.push(t3);\n lastWinding = Triangulator.winding(x1, y1, x2, y2, x3, y3);\n fanBaseIndex = t1;\n }\n }\n if (polygon.length > 0) {\n convexPolygons.push(polygon);\n convexPolygonsIndices.push(polygonIndices);\n }\n // Go through the list of polygons and try to merge the remaining triangles with the found triangle fans.\n for (let i = 0, n = convexPolygons.length; i < n; i++) {\n polygonIndices = convexPolygonsIndices[i];\n if (polygonIndices.length == 0)\n continue;\n let firstIndex = polygonIndices[0];\n let lastIndex = polygonIndices[polygonIndices.length - 1];\n polygon = convexPolygons[i];\n let o = polygon.length - 4;\n let prevPrevX = polygon[o], prevPrevY = polygon[o + 1];\n let prevX = polygon[o + 2], prevY = polygon[o + 3];\n let firstX = polygon[0], firstY = polygon[1];\n let secondX = polygon[2], secondY = polygon[3];\n let winding = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);\n for (let ii = 0; ii < n; ii++) {\n if (ii == i)\n continue;\n let otherIndices = convexPolygonsIndices[ii];\n if (otherIndices.length != 3)\n continue;\n let otherFirstIndex = otherIndices[0];\n let otherSecondIndex = otherIndices[1];\n let otherLastIndex = otherIndices[2];\n let otherPoly = convexPolygons[ii];\n let x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];\n if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)\n continue;\n let winding1 = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);\n let winding2 = Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY);\n if (winding1 == winding && winding2 == winding) {\n otherPoly.length = 0;\n otherIndices.length = 0;\n polygon.push(x3);\n polygon.push(y3);\n polygonIndices.push(otherLastIndex);\n prevPrevX = prevX;\n prevPrevY = prevY;\n prevX = x3;\n prevY = y3;\n ii = 0;\n }\n }\n }\n // Remove empty polygons that resulted from the merge step above.\n for (let i = convexPolygons.length - 1; i >= 0; i--) {\n polygon = convexPolygons[i];\n if (polygon.length == 0) {\n convexPolygons.splice(i, 1);\n this.polygonPool.free(polygon);\n polygonIndices = convexPolygonsIndices[i];\n convexPolygonsIndices.splice(i, 1);\n this.polygonIndicesPool.free(polygonIndices);\n }\n }\n return convexPolygons;\n }\n static isConcave(index, vertexCount, vertices, indices) {\n let previous = indices[(vertexCount + index - 1) % vertexCount] << 1;\n let current = indices[index] << 1;\n let next = indices[(index + 1) % vertexCount] << 1;\n return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);\n }\n static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y) {\n return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;\n }\n static winding(p1x, p1y, p2x, p2y, p3x, p3y) {\n let px = p2x - p1x, py = p2y - p1y;\n return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJpYW5ndWxhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1RyaWFuZ3VsYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUFtQixJQUFJLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFbkQsTUFBTSxPQUFPLFlBQVk7SUFDaEIsY0FBYyxHQUFHLElBQUksS0FBSyxFQUFpQixDQUFDO0lBQzVDLHFCQUFxQixHQUFHLElBQUksS0FBSyxFQUFpQixDQUFDO0lBRW5ELFlBQVksR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO0lBQ25DLGNBQWMsR0FBRyxJQUFJLEtBQUssRUFBVyxDQUFDO0lBQ3RDLFNBQVMsR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO0lBRWhDLFdBQVcsR0FBRyxJQUFJLElBQUksQ0FBZ0IsR0FBRyxFQUFFO1FBQ2xELE9BQU8sSUFBSSxLQUFLLEVBQVUsQ0FBQztJQUM1QixDQUFDLENBQUMsQ0FBQztJQUVLLGtCQUFrQixHQUFHLElBQUksSUFBSSxDQUFnQixHQUFHLEVBQUU7UUFDekQsT0FBTyxJQUFJLEtBQUssRUFBVSxDQUFDO0lBQzVCLENBQUMsQ0FBQyxDQUFDO0lBRUksV0FBVyxDQUFFLGFBQThCO1FBQ2pELElBQUksUUFBUSxHQUFHLGFBQWEsQ0FBQztRQUM3QixJQUFJLFdBQVcsR0FBRyxhQUFhLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUU1QyxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQ2hDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLEVBQUUsQ0FBQyxFQUFFO1lBQ25DLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFaEIsSUFBSSxTQUFTLEdBQUcsSUFB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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Triangulator } from \"./Triangulator.js\";\nimport { Utils } from \"./Utils.js\";\nexport class SkeletonClipping {\n triangulator = new Triangulator();\n clippingPolygon = new Array();\n clipOutput = new Array();\n clippedVertices = new Array();\n clippedTriangles = new Array();\n scratch = new Array();\n clipAttachment = null;\n clippingPolygons = null;\n clipStart(slot, clip) {\n if (this.clipAttachment)\n return 0;\n this.clipAttachment = clip;\n let n = clip.worldVerticesLength;\n let vertices = Utils.setArraySize(this.clippingPolygon, n);\n clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);\n let clippingPolygon = this.clippingPolygon;\n SkeletonClipping.makeClockwise(clippingPolygon);\n let clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon));\n for (let i = 0, n = clippingPolygons.length; i < n; i++) {\n let polygon = clippingPolygons[i];\n SkeletonClipping.makeClockwise(polygon);\n polygon.push(polygon[0]);\n polygon.push(polygon[1]);\n }\n return clippingPolygons.length;\n }\n clipEndWithSlot(slot) {\n if (this.clipAttachment && this.clipAttachment.endSlot == slot.data)\n this.clipEnd();\n }\n clipEnd() {\n if (!this.clipAttachment)\n return;\n this.clipAttachment = null;\n this.clippingPolygons = null;\n this.clippedVertices.length = 0;\n this.clippedTriangles.length = 0;\n this.clippingPolygon.length = 0;\n }\n isClipping() {\n return this.clipAttachment != null;\n }\n clipTriangles(vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {\n let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;\n let clippedTriangles = this.clippedTriangles;\n let polygons = this.clippingPolygons;\n let polygonsCount = polygons.length;\n let vertexSize = twoColor ? 12 : 8;\n let index = 0;\n clippedVertices.length = 0;\n clippedTriangles.length = 0;\n outer: for (let i = 0; i < trianglesLength; i += 3) {\n let vertexOffset = triangles[i] << 1;\n let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];\n let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];\n vertexOffset = triangles[i + 1] << 1;\n let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];\n let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];\n vertexOffset = triangles[i + 2] << 1;\n let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];\n let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];\n for (let p = 0; p < polygonsCount; p++) {\n let s = clippedVertices.length;\n if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {\n let clipOutputLength = clipOutput.length;\n if (clipOutputLength == 0)\n continue;\n let d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;\n let d = 1 / (d0 * d2 + d1 * (y1 - y3));\n let clipOutputCount = clipOutputLength >> 1;\n let clipOutputItems = this.clipOutput;\n let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);\n for (let ii = 0; ii < clipOutputLength; ii += 2) {\n let x = clipOutputItems[ii], y = clipOutputItems[ii + 1];\n clippedVerticesItems[s] = x;\n clippedVerticesItems[s + 1] = y;\n clippedVerticesItems[s + 2] = light.r;\n clippedVerticesItems[s + 3] = light.g;\n clippedVerticesItems[s + 4] = light.b;\n clippedVerticesItems[s + 5] = light.a;\n let c0 = x - x3, c1 = y - y3;\n let a = (d0 * c0 + d1 * c1) * d;\n let b = (d4 * c0 + d2 * c1) * d;\n let c = 1 - a - b;\n clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;\n clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;\n if (twoColor) {\n clippedVerticesItems[s + 8] = dark.r;\n clippedVerticesItems[s + 9] = dark.g;\n clippedVerticesItems[s + 10] = dark.b;\n clippedVerticesItems[s + 11] = dark.a;\n }\n s += vertexSize;\n }\n s = clippedTriangles.length;\n let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));\n clipOutputCount--;\n for (let ii = 1; ii < clipOutputCount; ii++) {\n clippedTrianglesItems[s] = index;\n clippedTrianglesItems[s + 1] = (index + ii);\n clippedTrianglesItems[s + 2] = (index + ii + 1);\n s += 3;\n }\n index += clipOutputCount + 1;\n }\n else {\n let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * vertexSize);\n clippedVerticesItems[s] = x1;\n clippedVerticesItems[s + 1] = y1;\n clippedVerticesItems[s + 2] = light.r;\n clippedVerticesItems[s + 3] = light.g;\n clippedVerticesItems[s + 4] = light.b;\n clippedVerticesItems[s + 5] = light.a;\n if (!twoColor) {\n clippedVerticesItems[s + 6] = u1;\n clippedVerticesItems[s + 7] = v1;\n clippedVerticesItems[s + 8] = x2;\n clippedVerticesItems[s + 9] = y2;\n clippedVerticesItems[s + 10] = light.r;\n clippedVerticesItems[s + 11] = light.g;\n clippedVerticesItems[s + 12] = light.b;\n clippedVerticesItems[s + 13] = light.a;\n clippedVerticesItems[s + 14] = u2;\n clippedVerticesItems[s + 15] = v2;\n clippedVerticesItems[s + 16] = x3;\n clippedVerticesItems[s + 17] = y3;\n clippedVerticesItems[s + 18] = light.r;\n clippedVerticesItems[s + 19] = light.g;\n clippedVerticesItems[s + 20] = light.b;\n clippedVerticesItems[s + 21] = light.a;\n clippedVerticesItems[s + 22] = u3;\n clippedVerticesItems[s + 23] = v3;\n }\n else {\n clippedVerticesItems[s + 6] = u1;\n clippedVerticesItems[s + 7] = v1;\n clippedVerticesItems[s + 8] = dark.r;\n clippedVerticesItems[s + 9] = dark.g;\n clippedVerticesItems[s + 10] = dark.b;\n clippedVerticesItems[s + 11] = dark.a;\n clippedVerticesItems[s + 12] = x2;\n clippedVerticesItems[s + 13] = y2;\n clippedVerticesItems[s + 14] = light.r;\n clippedVerticesItems[s + 15] = light.g;\n clippedVerticesItems[s + 16] = light.b;\n clippedVerticesItems[s + 17] = light.a;\n clippedVerticesItems[s + 18] = u2;\n clippedVerticesItems[s + 19] = v2;\n clippedVerticesItems[s + 20] = dark.r;\n clippedVerticesItems[s + 21] = dark.g;\n clippedVerticesItems[s + 22] = dark.b;\n clippedVerticesItems[s + 23] = dark.a;\n clippedVerticesItems[s + 24] = x3;\n clippedVerticesItems[s + 25] = y3;\n clippedVerticesItems[s + 26] = light.r;\n clippedVerticesItems[s + 27] = light.g;\n clippedVerticesItems[s + 28] = light.b;\n clippedVerticesItems[s + 29] = light.a;\n clippedVerticesItems[s + 30] = u3;\n clippedVerticesItems[s + 31] = v3;\n clippedVerticesItems[s + 32] = dark.r;\n clippedVerticesItems[s + 33] = dark.g;\n clippedVerticesItems[s + 34] = dark.b;\n clippedVerticesItems[s + 35] = dark.a;\n }\n s = clippedTriangles.length;\n let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3);\n clippedTrianglesItems[s] = index;\n clippedTrianglesItems[s + 1] = (index + 1);\n clippedTrianglesItems[s + 2] = (index + 2);\n index += 3;\n continue outer;\n }\n }\n }\n }\n /** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping\n * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */\n clip(x1, y1, x2, y2, x3, y3, clippingArea, output) {\n let originalOutput = output;\n let clipped = false;\n // Avoid copy at the end.\n let input;\n if (clippingArea.length % 4 >= 2) {\n input = output;\n output = this.scratch;\n }\n else\n input = this.scratch;\n input.length = 0;\n input.push(x1);\n input.push(y1);\n input.push(x2);\n input.push(y2);\n input.push(x3);\n input.push(y3);\n input.push(x1);\n input.push(y1);\n output.length = 0;\n let clippingVertices = clippingArea;\n let clippingVerticesLast = clippingArea.length - 4;\n for (let i = 0;; i += 2) {\n let edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];\n let edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];\n let deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;\n let inputVertices = input;\n let inputVerticesLength = input.length - 2, outputStart = output.length;\n for (let ii = 0; ii < inputVerticesLength; ii += 2) {\n let inputX = inputVertices[ii], inputY = inputVertices[ii + 1];\n let inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];\n let side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;\n if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {\n if (side2) { // v1 inside, v2 inside\n output.push(inputX2);\n output.push(inputY2);\n continue;\n }\n // v1 inside, v2 outside\n let c0 = inputY2 - inputY, c2 = inputX2 - inputX;\n let s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY);\n if (Math.abs(s) > 0.000001) {\n let ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s;\n output.push(edgeX + (edgeX2 - edgeX) * ua);\n output.push(edgeY + (edgeY2 - edgeY) * ua);\n }\n else {\n output.push(edgeX);\n output.push(edgeY);\n }\n }\n else if (side2) { // v1 outside, v2 inside\n let c0 = inputY2 - inputY, c2 = inputX2 - inputX;\n let s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY);\n if (Math.abs(s) > 0.000001) {\n let ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s;\n output.push(edgeX + (edgeX2 - edgeX) * ua);\n output.push(edgeY + (edgeY2 - edgeY) * ua);\n }\n else {\n output.push(edgeX);\n output.push(edgeY);\n }\n output.push(inputX2);\n output.push(inputY2);\n }\n clipped = true;\n }\n if (outputStart == output.length) { // All edges outside.\n originalOutput.length = 0;\n return true;\n }\n output.push(output[0]);\n output.push(output[1]);\n if (i == clippingVerticesLast)\n break;\n let temp = output;\n output = input;\n output.length = 0;\n input = temp;\n }\n if (originalOutput != output) {\n originalOutput.length = 0;\n for (let i = 0, n = output.length - 2; i < n; i++)\n originalOutput[i] = output[i];\n }\n else\n originalOutput.length = originalOutput.length - 2;\n return clipped;\n }\n static makeClockwise(polygon) {\n let vertices = polygon;\n let verticeslength = polygon.length;\n let area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;\n for (let i = 0, n = verticeslength - 3; i < n; i += 2) {\n p1x = vertices[i];\n p1y = vertices[i + 1];\n p2x = vertices[i + 2];\n p2y = vertices[i + 3];\n area += p1x * p2y - p2x * p1y;\n }\n if (area < 0)\n return;\n for (let i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {\n let x = vertices[i], y = vertices[i + 1];\n let other = lastX - i;\n vertices[i] = vertices[other];\n vertices[i + 1] = vertices[other + 1];\n vertices[other] = x;\n vertices[other + 1] = y;\n }\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25DbGlwcGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Ta2VsZXRvbkNsaXBwaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUkvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLEtBQUssRUFBMEIsTUFBTSxZQUFZLENBQUM7QUFFM0QsTUFBTSxPQUFPLGdCQUFnQjtJQUNwQixZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUNsQyxlQUFlLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztJQUN0QyxVQUFVLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztJQUN6QyxlQUFlLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztJQUN0QyxnQkFBZ0IsR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO0lBQy9CLE9BQU8sR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO0lBRTlCLGNBQWMsR0FBOEIsSUFBSSxDQUFDO0lBQ2pELGdCQUFnQixHQUFnQyxJQUFJLENBQUM7SUFFN0QsU0FBUyxDQUFFLElBQVUsRUFBRSxJQUF3QjtRQUM5QyxJQUFJLElBQUksQ0FBQyxjQUFjO1lBQUUsT0FBTyxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFFM0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDO1FBQ2pDLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN0RCxJQUFJLGVBQWUsR0FBRyxJQUFJLENBQUMs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QUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFFakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBRWxDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNsQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO3FCQUNsQzt5QkFBTTt3QkFDTixvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNqQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNqQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFDckMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7d0JBQ3JDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUN0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFFdEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUN0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFDdEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7d0JBQ3RDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUV0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNsQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNsQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7d0JBQ3RDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMs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QUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7d0JBQzdELE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO3dCQUMzQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztxQkFDM0M7eUJBQU07d0JBQ04sTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDbkIsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztxQkFDbkI7aUJBQ0Q7cUJBQU0sSUFBSSxLQUFLLEVBQUUsRUFBRSx3QkFBd0I7b0JBQzNDLElBQUksRUFBRSxHQUFHLE9BQU8sR0FBRyxNQUFNLEVBQUUsRUFBRSxHQUFHLE9BQU8sR0FBRyxNQUFNLENBQUM7b0JBQ2pELElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUM7b0JBQ3RELElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLEVBQUU7d0JBQzNCLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzt3QkFDN0QsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7d0JBQzNDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsTUFBTSxHQUFH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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { Animation, AttachmentTimeline, RGBATimeline, RGBTimeline, AlphaTimeline, RGBA2Timeline, RGB2Timeline, RotateTimeline, TranslateTimeline, TranslateXTimeline, TranslateYTimeline, ScaleTimeline, ScaleXTimeline, ScaleYTimeline, ShearTimeline, ShearXTimeline, ShearYTimeline, IkConstraintTimeline, TransformConstraintTimeline, PathConstraintPositionTimeline, PathConstraintSpacingTimeline, PathConstraintMixTimeline, DeformTimeline, DrawOrderTimeline, EventTimeline, PhysicsConstraintResetTimeline, PhysicsConstraintInertiaTimeline, PhysicsConstraintStrengthTimeline, PhysicsConstraintDampingTimeline, PhysicsConstraintMassTimeline, PhysicsConstraintWindTimeline, PhysicsConstraintGravityTimeline, PhysicsConstraintMixTimeline } from \"./Animation.js\";\nimport { BoneData, TransformMode } from \"./BoneData.js\";\nimport { EventData } from \"./EventData.js\";\nimport { Event } from \"./Event.js\";\nimport { IkConstraintData } from \"./IkConstraintData.js\";\nimport { PathConstraintData, PositionMode, SpacingMode, RotateMode } from \"./PathConstraintData.js\";\nimport { SkeletonData } from \"./SkeletonData.js\";\nimport { Skin } from \"./Skin.js\";\nimport { SlotData, BlendMode } from \"./SlotData.js\";\nimport { TransformConstraintData } from \"./TransformConstraintData.js\";\nimport { Utils, Color } from \"./Utils.js\";\nimport { Sequence, SequenceMode } from \"./attachments/Sequence.js\";\nimport { SequenceTimeline } from \"./Animation.js\";\nimport { PhysicsConstraintData } from \"./PhysicsConstraintData.js\";\n/** Loads skeleton data in the Spine JSON format.\n *\n * See [Spine JSON format](http://esotericsoftware.com/spine-json-format) and\n * [JSON and binary data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the Spine\n * Runtimes Guide. */\nexport class SkeletonJson {\n attachmentLoader;\n /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at\n * runtime than were used in Spine.\n *\n * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */\n scale = 1;\n linkedMeshes = new Array();\n constructor(attachmentLoader) {\n this.attachmentLoader = attachmentLoader;\n }\n readSkeletonData(json) {\n let scale = this.scale;\n let skeletonData = new SkeletonData();\n let root = typeof (json) === \"string\" ? JSON.parse(json) : json;\n // Skeleton\n let skeletonMap = root.skeleton;\n if (skeletonMap) {\n skeletonData.hash = skeletonMap.hash;\n skeletonData.version = skeletonMap.spine;\n skeletonData.x = skeletonMap.x;\n skeletonData.y = skeletonMap.y;\n skeletonData.width = skeletonMap.width;\n skeletonData.height = skeletonMap.height;\n skeletonData.fps = skeletonMap.fps;\n skeletonData.imagesPath = skeletonMap.images;\n }\n // Bones\n if (root.bones) {\n for (let i = 0; i < root.bones.length; i++) {\n let boneMap = root.bones[i];\n let parent = null;\n let parentName = getValue(boneMap, \"parent\", null);\n if (parentName)\n parent = skeletonData.findBone(parentName);\n let data = new BoneData(skeletonData.bones.length, boneMap.name, parent);\n data.length = getValue(boneMap, \"length\", 0) * scale;\n data.x = getValue(boneMap, \"x\", 0) * scale;\n data.y = getValue(boneMap, \"y\", 0) * scale;\n data.rotation = getValue(boneMap, \"rotation\", 0);\n data.scaleX = getValue(boneMap, \"scaleX\", 1);\n data.scaleY = getValue(boneMap, \"scaleY\", 1);\n data.shearX = getValue(boneMap, \"shearX\", 0);\n data.shearY = getValue(boneMap, \"shearY\", 0);\n data.transformMode = Utils.enumValue(TransformMode, getValue(boneMap, \"transform\", \"Normal\"));\n data.skinRequired = getValue(boneMap, \"skin\", false);\n let color = getValue(boneMap, \"color\", null);\n if (color)\n data.color.setFromString(color);\n skeletonData.bones.push(data);\n }\n }\n // Slots.\n if (root.slots) {\n for (let i = 0; i < root.slots.length; i++) {\n let slotMap = root.slots[i];\n let boneData = skeletonData.findBone(slotMap.bone);\n if (!boneData)\n throw new Error(`Couldn't find bone ${slotMap.bone} for slot ${slotMap.name}`);\n let data = new SlotData(skeletonData.slots.length, slotMap.name, boneData);\n let color = getValue(slotMap, \"color\", null);\n if (color)\n data.color.setFromString(color);\n let dark = getValue(slotMap, \"dark\", null);\n if (dark)\n data.darkColor = Color.fromString(dark);\n data.attachmentName = getValue(slotMap, \"attachment\", null);\n data.blendMode = Utils.enumValue(BlendMode, getValue(slotMap, \"blend\", \"normal\"));\n skeletonData.slots.push(data);\n }\n }\n // IK constraints\n if (root.ik) {\n for (let i = 0; i < root.ik.length; i++) {\n let constraintMap = root.ik[i];\n let data = new IkConstraintData(constraintMap.name);\n data.order = getValue(constraintMap, \"order\", 0);\n data.skinRequired = getValue(constraintMap, \"skin\", false);\n for (let ii = 0; ii < constraintMap.bones.length; ii++) {\n let bone = skeletonData.findBone(constraintMap.bones[ii]);\n if (!bone)\n throw new Error(`Couldn't find bone ${constraintMap.bones[ii]} for IK constraint ${constraintMap.name}.`);\n data.bones.push(bone);\n }\n let target = skeletonData.findBone(constraintMap.target);\n ;\n if (!target)\n throw new Error(`Couldn't find target bone ${constraintMap.target} for IK constraint ${constraintMap.name}.`);\n data.target = target;\n data.mix = getValue(constraintMap, \"mix\", 1);\n data.softness = getValue(constraintMap, \"softness\", 0) * scale;\n data.bendDirection = getValue(constraintMap, \"bendPositive\", true) ? 1 : -1;\n data.compress = getValue(constraintMap, \"compress\", false);\n data.stretch = getValue(constraintMap, \"stretch\", false);\n data.uniform = getValue(constraintMap, \"uniform\", false);\n skeletonData.ikConstraints.push(data);\n }\n }\n // Transform constraints.\n if (root.transform) {\n for (let i = 0; i < root.transform.length; i++) {\n let constraintMap = root.transform[i];\n let data = new TransformConstraintData(constraintMap.name);\n data.order = getValue(constraintMap, \"order\", 0);\n data.skinRequired = getValue(constraintMap, \"skin\", false);\n for (let ii = 0; ii < constraintMap.bones.length; ii++) {\n let boneName = constraintMap.bones[ii];\n let bone = skeletonData.findBone(boneName);\n if (!bone)\n throw new Error(`Couldn't find bone ${boneName} for transform constraint ${constraintMap.name}.`);\n data.bones.push(bone);\n }\n let targetName = constraintMap.target;\n let target = skeletonData.findBone(targetName);\n if (!target)\n throw new Error(`Couldn't find target bone ${targetName} for transform constraint ${constraintMap.name}.`);\n data.target = target;\n data.local = getValue(constraintMap, \"local\", false);\n data.relative = getValue(constraintMap, \"relative\", false);\n data.offsetRotation = getValue(constraintMap, \"rotation\", 0);\n data.offsetX = getValue(constraintMap, \"x\", 0) * scale;\n data.offsetY = getValue(constraintMap, \"y\", 0) * scale;\n data.offsetScaleX = getValue(constraintMap, \"scaleX\", 0);\n data.offsetScaleY = getValue(constraintMap, \"scaleY\", 0);\n data.offsetShearY = getValue(constraintMap, \"shearY\", 0);\n data.mixRotate = getValue(constraintMap, \"mixRotate\", 1);\n data.mixX = getValue(constraintMap, \"mixX\", 1);\n data.mixY = getValue(constraintMap, \"mixY\", data.mixX);\n data.mixScaleX = getValue(constraintMap, \"mixScaleX\", 1);\n data.mixScaleY = getValue(constraintMap, \"mixScaleY\", data.mixScaleX);\n data.mixShearY = getValue(constraintMap, \"mixShearY\", 1);\n skeletonData.transformConstraints.push(data);\n }\n }\n // Path constraints.\n if (root.path) {\n for (let i = 0; i < root.path.length; i++) {\n let constraintMap = root.path[i];\n let data = new PathConstraintData(constraintMap.name);\n data.order = getValue(constraintMap, \"order\", 0);\n data.skinRequired = getValue(constraintMap, \"skin\", false);\n for (let ii = 0; ii < constraintMap.bones.length; ii++) {\n let boneName = constraintMap.bones[ii];\n let bone = skeletonData.findBone(boneName);\n if (!bone)\n throw new Error(`Couldn't find bone ${boneName} for path constraint ${constraintMap.name}.`);\n data.bones.push(bone);\n }\n let targetName = constraintMap.target;\n let target = skeletonData.findSlot(targetName);\n if (!target)\n throw new Error(`Couldn't find target slot ${targetName} for path constraint ${constraintMap.name}.`);\n data.target = target;\n data.positionMode = Utils.enumValue(PositionMode, getValue(constraintMap, \"positionMode\", \"Percent\"));\n data.spacingMode = Utils.enumValue(SpacingMode, getValue(constraintMap, \"spacingMode\", \"Length\"));\n data.rotateMode = Utils.enumValue(RotateMode, getValue(constraintMap, \"rotateMode\", \"Tangent\"));\n data.offsetRotation = getValue(constraintMap, \"rotation\", 0);\n data.position = getValue(constraintMap, \"position\", 0);\n if (data.positionMode == PositionMode.Fixed)\n data.position *= scale;\n data.spacing = getValue(constraintMap, \"spacing\", 0);\n if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed)\n data.spacing *= scale;\n data.mixRotate = getValue(constraintMap, \"mixRotate\", 1);\n data.mixX = getValue(constraintMap, \"mixX\", 1);\n data.mixY = getValue(constraintMap, \"mixY\", data.mixX);\n skeletonData.pathConstraints.push(data);\n }\n }\n if (root.physics) {\n // Physics constraints.\n for (let i = 0; i < root.physics.length; i++) {\n const constraintMap = root.physics[i];\n const data = new PhysicsConstraintData(constraintMap.name);\n data.order = getValue(constraintMap, \"order\", 0);\n data.skinRequired = getValue(constraintMap, \"skin\", false);\n const boneName = constraintMap.bone;\n const bone = skeletonData.findBone(boneName);\n if (bone == null)\n throw new Error(\"Physics bone not found: \" + boneName);\n data.bone = bone;\n data.x = getValue(constraintMap, \"x\", 0);\n data.y = getValue(constraintMap, \"y\", 0);\n data.rotate = getValue(constraintMap, \"rotate\", 0);\n data.scaleX = getValue(constraintMap, \"scaleX\", 0);\n data.shearX = getValue(constraintMap, \"shearX\", 0);\n data.step = 1 / getValue(constraintMap, \"fps\", 60);\n data.inertia = getValue(constraintMap, \"inertia\", 1);\n data.strength = getValue(constraintMap, \"strength\", 100);\n data.damping = getValue(constraintMap, \"damping\", 1);\n data.massInverse = 1 / getValue(constraintMap, \"mass\", 1);\n data.wind = getValue(constraintMap, \"wind\", 0) * scale;\n data.gravity = getValue(constraintMap, \"gravity\", 0) * scale;\n data.mix = getValue(constraintMap, \"mix\", 1);\n data.inertiaGlobal = getValue(constraintMap, \"inertiaGlobal\", false);\n data.strengthGlobal = getValue(constraintMap, \"strengthGlobal\", false);\n data.dampingGlobal = getValue(constraintMap, \"dampingGlobal\", false);\n data.massGlobal = getValue(constraintMap, \"massGlobal\", false);\n data.windGlobal = getValue(constraintMap, \"windGlobal\", false);\n data.gravityGlobal = getValue(constraintMap, \"gravityGlobal\", false);\n data.mixGlobal = getValue(constraintMap, \"mixGlobal\", false);\n skeletonData.physicsConstraints.push(data);\n }\n }\n // Skins.\n if (root.skins) {\n for (let i = 0; i < root.skins.length; i++) {\n let skinMap = root.skins[i];\n let skin = new Skin(skinMap.name);\n if (skinMap.bones) {\n for (let ii = 0; ii < skinMap.bones.length; ii++) {\n let boneName = skinMap.bones[ii];\n let bone = skeletonData.findBone(boneName);\n if (!bone)\n throw new Error(`Couldn't find bone ${boneName} for skin ${skinMap.name}.`);\n skin.bones.push(bone);\n }\n }\n if (skinMap.ik) {\n for (let ii = 0; ii < skinMap.ik.length; ii++) {\n let constraintName = skinMap.ik[ii];\n let constraint = skeletonData.findIkConstraint(constraintName);\n if (!constraint)\n throw new Error(`Couldn't find IK constraint ${constraintName} for skin ${skinMap.name}.`);\n skin.constraints.push(constraint);\n }\n }\n if (skinMap.transform) {\n for (let ii = 0; ii < skinMap.transform.length; ii++) {\n let constraintName = skinMap.transform[ii];\n let constraint = skeletonData.findTransformConstraint(constraintName);\n if (!constraint)\n throw new Error(`Couldn't find transform constraint ${constraintName} for skin ${skinMap.name}.`);\n skin.constraints.push(constraint);\n }\n }\n if (skinMap.path) {\n for (let ii = 0; ii < skinMap.path.length; ii++) {\n let constraintName = skinMap.path[ii];\n let constraint = skeletonData.findPathConstraint(constraintName);\n if (!constraint)\n throw new Error(`Couldn't find path constraint ${constraintName} for skin ${skinMap.name}.`);\n skin.constraints.push(constraint);\n }\n }\n if (skinMap.physics) {\n for (let ii = 0; ii < skinMap.physics.length; ii++) {\n let constraintName = skinMap.physics[ii];\n let constraint = skeletonData.findPhysicsConstraint(constraintName);\n if (!constraint)\n throw new Error(`Couldn't find physics constraint ${constraintName} for skin ${skinMap.name}.`);\n skin.constraints.push(constraint);\n }\n }\n for (let slotName in skinMap.attachments) {\n let slot = skeletonData.findSlot(slotName);\n if (!slot)\n throw new Error(`Couldn't find slot ${slotName} for skin ${skinMap.name}.`);\n let slotMap = skinMap.attachments[slotName];\n for (let entryName in slotMap) {\n let attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);\n if (attachment)\n skin.setAttachment(slot.index, entryName, attachment);\n }\n }\n skeletonData.skins.push(skin);\n if (skin.name == \"default\")\n skeletonData.defaultSkin = skin;\n }\n }\n // Linked meshes.\n for (let i = 0, n = this.linkedMeshes.length; i < n; i++) {\n let linkedMesh = this.linkedMeshes[i];\n let skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);\n if (!skin)\n throw new Error(`Skin not found: ${linkedMesh.skin}`);\n let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);\n if (!parent)\n throw new Error(`Parent mesh not found: ${linkedMesh.parent}`);\n linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent : linkedMesh.mesh;\n linkedMesh.mesh.setParentMesh(parent);\n if (linkedMesh.mesh.region != null)\n linkedMesh.mesh.updateRegion();\n }\n this.linkedMeshes.length = 0;\n // Events.\n if (root.events) {\n for (let eventName in root.events) {\n let eventMap = root.events[eventName];\n let data = new EventData(eventName);\n data.intValue = getValue(eventMap, \"int\", 0);\n data.floatValue = getValue(eventMap, \"float\", 0);\n data.stringValue = getValue(eventMap, \"string\", \"\");\n data.audioPath = getValue(eventMap, \"audio\", null);\n if (data.audioPath) {\n data.volume = getValue(eventMap, \"volume\", 1);\n data.balance = getValue(eventMap, \"balance\", 0);\n }\n skeletonData.events.push(data);\n }\n }\n // Animations.\n if (root.animations) {\n for (let animationName in root.animations) {\n let animationMap = root.animations[animationName];\n this.readAnimation(animationMap, animationName, skeletonData);\n }\n }\n return skeletonData;\n }\n readAttachment(map, skin, slotIndex, name, skeletonData) {\n let scale = this.scale;\n name = getValue(map, \"name\", name);\n switch (getValue(map, \"type\", \"region\")) {\n case \"region\": {\n let path = getValue(map, \"path\", name);\n let sequence = this.readSequence(getValue(map, \"sequence\", null));\n let region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence);\n if (!region)\n return null;\n region.path = path;\n region.x = getValue(map, \"x\", 0) * scale;\n region.y = getValue(map, \"y\", 0) * scale;\n region.scaleX = getValue(map, \"scaleX\", 1);\n region.scaleY = getValue(map, \"scaleY\", 1);\n region.rotation = getValue(map, \"rotation\", 0);\n region.width = map.width * scale;\n region.height = map.height * scale;\n region.sequence = sequence;\n let color = getValue(map, \"color\", null);\n if (color)\n region.color.setFromString(color);\n if (region.region != null)\n region.updateRegion();\n return region;\n }\n case \"boundingbox\": {\n let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name);\n if (!box)\n return null;\n this.readVertices(map, box, map.vertexCount << 1);\n let color = getValue(map, \"color\", null);\n if (color)\n box.color.setFromString(color);\n return box;\n }\n case \"mesh\":\n case \"linkedmesh\": {\n let path = getValue(map, \"path\", name);\n let sequence = this.readSequence(getValue(map, \"sequence\", null));\n let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence);\n if (!mesh)\n return null;\n mesh.path = path;\n let color = getValue(map, \"color\", null);\n if (color)\n mesh.color.setFromString(color);\n mesh.width = getValue(map, \"width\", 0) * scale;\n mesh.height = getValue(map, \"height\", 0) * scale;\n mesh.sequence = sequence;\n let parent = getValue(map, \"parent\", null);\n if (parent) {\n this.linkedMeshes.push(new LinkedMesh(mesh, getValue(map, \"skin\", null), slotIndex, parent, getValue(map, \"timelines\", true)));\n return mesh;\n }\n let uvs = map.uvs;\n this.readVertices(map, mesh, uvs.length);\n mesh.triangles = map.triangles;\n mesh.regionUVs = uvs;\n if (mesh.region != null)\n mesh.updateRegion();\n mesh.edges = getValue(map, \"edges\", null);\n mesh.hullLength = getValue(map, \"hull\", 0) * 2;\n return mesh;\n }\n case \"path\": {\n let path = this.attachmentLoader.newPathAttachment(skin, name);\n if (!path)\n return null;\n path.closed = getValue(map, \"closed\", false);\n path.constantSpeed = getValue(map, \"constantSpeed\", true);\n let vertexCount = map.vertexCount;\n this.readVertices(map, path, vertexCount << 1);\n let lengths = Utils.newArray(vertexCount / 3, 0);\n for (let i = 0; i < map.lengths.length; i++)\n lengths[i] = map.lengths[i] * scale;\n path.lengths = lengths;\n let color = getValue(map, \"color\", null);\n if (color)\n path.color.setFromString(color);\n return path;\n }\n case \"point\": {\n let point = this.attachmentLoader.newPointAttachment(skin, name);\n if (!point)\n return null;\n point.x = getValue(map, \"x\", 0) * scale;\n point.y = getValue(map, \"y\", 0) * scale;\n point.rotation = getValue(map, \"rotation\", 0);\n let color = getValue(map, \"color\", null);\n if (color)\n point.color.setFromString(color);\n return point;\n }\n case \"clipping\": {\n let clip = this.attachmentLoader.newClippingAttachment(skin, name);\n if (!clip)\n return null;\n let end = getValue(map, \"end\", null);\n if (end)\n clip.endSlot = skeletonData.findSlot(end);\n let vertexCount = map.vertexCount;\n this.readVertices(map, clip, vertexCount << 1);\n let color = getValue(map, \"color\", null);\n if (color)\n clip.color.setFromString(color);\n return clip;\n }\n }\n return null;\n }\n readSequence(map) {\n if (map == null)\n return null;\n let sequence = new Sequence(getValue(map, \"count\", 0));\n sequence.start = getValue(map, \"start\", 1);\n sequence.digits = getValue(map, \"digits\", 0);\n sequence.setupIndex = getValue(map, \"setup\", 0);\n return sequence;\n }\n readVertices(map, attachment, verticesLength) {\n let scale = this.scale;\n attachment.worldVerticesLength = verticesLength;\n let vertices = map.vertices;\n if (verticesLength == vertices.length) {\n let scaledVertices = Utils.toFloatArray(vertices);\n if (scale != 1) {\n for (let i = 0, n = vertices.length; i < n; i++)\n scaledVertices[i] *= scale;\n }\n attachment.vertices = scaledVertices;\n return;\n }\n let weights = new Array();\n let bones = new Array();\n for (let i = 0, n = vertices.length; i < n;) {\n let boneCount = vertices[i++];\n bones.push(boneCount);\n for (let nn = i + boneCount * 4; i < nn; i += 4) {\n bones.push(vertices[i]);\n weights.push(vertices[i + 1] * scale);\n weights.push(vertices[i + 2] * scale);\n weights.push(vertices[i + 3]);\n }\n }\n attachment.bones = bones;\n attachment.vertices = Utils.toFloatArray(weights);\n }\n readAnimation(map, name, skeletonData) {\n let scale = this.scale;\n let timelines = new Array();\n // Slot timelines.\n if (map.slots) {\n for (let slotName in map.slots) {\n let slotMap = map.slots[slotName];\n let slot = skeletonData.findSlot(slotName);\n if (!slot)\n throw new Error(\"Slot not found: \" + slotName);\n let slotIndex = slot.index;\n for (let timelineName in slotMap) {\n let timelineMap = slotMap[timelineName];\n if (!timelineMap)\n continue;\n let frames = timelineMap.length;\n if (timelineName == \"attachment\") {\n let timeline = new AttachmentTimeline(frames, slotIndex);\n for (let frame = 0; frame < frames; frame++) {\n let keyMap = timelineMap[frame];\n timeline.setFrame(frame, getValue(keyMap, \"time\", 0), getValue(keyMap, \"name\", null));\n }\n timelines.push(timeline);\n }\n else if (timelineName == \"rgba\") {\n let timeline = new RGBATimeline(frames, frames << 2, slotIndex);\n let keyMap = timelineMap[0];\n let time = getValue(keyMap, \"time\", 0);\n let color = Color.fromString(keyMap.color);\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, color.r, color.g, color.b, color.a);\n let nextMap = timelineMap[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n break;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let newColor = Color.fromString(nextMap.color);\n let curve = keyMap.curve;\n if (curve) {\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1);\n }\n time = time2;\n color = newColor;\n keyMap = nextMap;\n }\n timelines.push(timeline);\n }\n else if (timelineName == \"rgb\") {\n let timeline = new RGBTimeline(frames, frames * 3, slotIndex);\n let keyMap = timelineMap[0];\n let time = getValue(keyMap, \"time\", 0);\n let color = Color.fromString(keyMap.color);\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, color.r, color.g, color.b);\n let nextMap = timelineMap[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n break;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let newColor = Color.fromString(nextMap.color);\n let curve = keyMap.curve;\n if (curve) {\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);\n }\n time = time2;\n color = newColor;\n keyMap = nextMap;\n }\n timelines.push(timeline);\n }\n else if (timelineName == \"alpha\") {\n timelines.push(readTimeline1(timelineMap, new AlphaTimeline(frames, frames, slotIndex), 0, 1));\n }\n else if (timelineName == \"rgba2\") {\n let timeline = new RGBA2Timeline(frames, frames * 7, slotIndex);\n let keyMap = timelineMap[0];\n let time = getValue(keyMap, \"time\", 0);\n let color = Color.fromString(keyMap.light);\n let color2 = Color.fromString(keyMap.dark);\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b);\n let nextMap = timelineMap[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n break;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let newColor = Color.fromString(nextMap.light);\n let newColor2 = Color.fromString(nextMap.dark);\n let curve = keyMap.curve;\n if (curve) {\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.r, newColor2.r, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.g, newColor2.g, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, color2.b, newColor2.b, 1);\n }\n time = time2;\n color = newColor;\n color2 = newColor2;\n keyMap = nextMap;\n }\n timelines.push(timeline);\n }\n else if (timelineName == \"rgb2\") {\n let timeline = new RGB2Timeline(frames, frames * 6, slotIndex);\n let keyMap = timelineMap[0];\n let time = getValue(keyMap, \"time\", 0);\n let color = Color.fromString(keyMap.light);\n let color2 = Color.fromString(keyMap.dark);\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, color.r, color.g, color.b, color2.r, color2.g, color2.b);\n let nextMap = timelineMap[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n break;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let newColor = Color.fromString(nextMap.light);\n let newColor2 = Color.fromString(nextMap.dark);\n let curve = keyMap.curve;\n if (curve) {\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color2.r, newColor2.r, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.g, newColor2.g, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.b, newColor2.b, 1);\n }\n time = time2;\n color = newColor;\n color2 = newColor2;\n keyMap = nextMap;\n }\n timelines.push(timeline);\n }\n }\n }\n }\n // Bone timelines.\n if (map.bones) {\n for (let boneName in map.bones) {\n let boneMap = map.bones[boneName];\n let bone = skeletonData.findBone(boneName);\n if (!bone)\n throw new Error(\"Bone not found: \" + boneName);\n let boneIndex = bone.index;\n for (let timelineName in boneMap) {\n let timelineMap = boneMap[timelineName];\n let frames = timelineMap.length;\n if (frames == 0)\n continue;\n if (timelineName === \"rotate\") {\n timelines.push(readTimeline1(timelineMap, new RotateTimeline(frames, frames, boneIndex), 0, 1));\n }\n else if (timelineName === \"translate\") {\n let timeline = new TranslateTimeline(frames, frames << 1, boneIndex);\n timelines.push(readTimeline2(timelineMap, timeline, \"x\", \"y\", 0, scale));\n }\n else if (timelineName === \"translatex\") {\n let timeline = new TranslateXTimeline(frames, frames, boneIndex);\n timelines.push(readTimeline1(timelineMap, timeline, 0, scale));\n }\n else if (timelineName === \"translatey\") {\n let timeline = new TranslateYTimeline(frames, frames, boneIndex);\n timelines.push(readTimeline1(timelineMap, timeline, 0, scale));\n }\n else if (timelineName === \"scale\") {\n let timeline = new ScaleTimeline(frames, frames << 1, boneIndex);\n timelines.push(readTimeline2(timelineMap, timeline, \"x\", \"y\", 1, 1));\n }\n else if (timelineName === \"scalex\") {\n let timeline = new ScaleXTimeline(frames, frames, boneIndex);\n timelines.push(readTimeline1(timelineMap, timeline, 1, 1));\n }\n else if (timelineName === \"scaley\") {\n let timeline = new ScaleYTimeline(frames, frames, boneIndex);\n timelines.push(readTimeline1(timelineMap, timeline, 1, 1));\n }\n else if (timelineName === \"shear\") {\n let timeline = new ShearTimeline(frames, frames << 1, boneIndex);\n timelines.push(readTimeline2(timelineMap, timeline, \"x\", \"y\", 0, 1));\n }\n else if (timelineName === \"shearx\") {\n let timeline = new ShearXTimeline(frames, frames, boneIndex);\n timelines.push(readTimeline1(timelineMap, timeline, 0, 1));\n }\n else if (timelineName === \"sheary\") {\n let timeline = new ShearYTimeline(frames, frames, boneIndex);\n timelines.push(readTimeline1(timelineMap, timeline, 0, 1));\n }\n }\n }\n }\n // IK constraint timelines.\n if (map.ik) {\n for (let constraintName in map.ik) {\n let constraintMap = map.ik[constraintName];\n let keyMap = constraintMap[0];\n if (!keyMap)\n continue;\n let constraint = skeletonData.findIkConstraint(constraintName);\n if (!constraint)\n throw new Error(\"IK Constraint not found: \" + constraintName);\n let constraintIndex = skeletonData.ikConstraints.indexOf(constraint);\n let timeline = new IkConstraintTimeline(constraintMap.length, constraintMap.length << 1, constraintIndex);\n let time = getValue(keyMap, \"time\", 0);\n let mix = getValue(keyMap, \"mix\", 1);\n let softness = getValue(keyMap, \"softness\", 0) * scale;\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, mix, softness, getValue(keyMap, \"bendPositive\", true) ? 1 : -1, getValue(keyMap, \"compress\", false), getValue(keyMap, \"stretch\", false));\n let nextMap = constraintMap[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n break;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let mix2 = getValue(nextMap, \"mix\", 1);\n let softness2 = getValue(nextMap, \"softness\", 0) * scale;\n let curve = keyMap.curve;\n if (curve) {\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, scale);\n }\n time = time2;\n mix = mix2;\n softness = softness2;\n keyMap = nextMap;\n }\n timelines.push(timeline);\n }\n }\n // Transform constraint timelines.\n if (map.transform) {\n for (let constraintName in map.transform) {\n let timelineMap = map.transform[constraintName];\n let keyMap = timelineMap[0];\n if (!keyMap)\n continue;\n let constraint = skeletonData.findTransformConstraint(constraintName);\n if (!constraint)\n throw new Error(\"Transform constraint not found: \" + constraintName);\n let constraintIndex = skeletonData.transformConstraints.indexOf(constraint);\n let timeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length * 6, constraintIndex);\n let time = getValue(keyMap, \"time\", 0);\n let mixRotate = getValue(keyMap, \"mixRotate\", 1);\n let mixX = getValue(keyMap, \"mixX\", 1);\n let mixY = getValue(keyMap, \"mixY\", mixX);\n let mixScaleX = getValue(keyMap, \"mixScaleX\", 1);\n let mixScaleY = getValue(keyMap, \"mixScaleY\", mixScaleX);\n let mixShearY = getValue(keyMap, \"mixShearY\", 1);\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY);\n let nextMap = timelineMap[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n break;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let mixRotate2 = getValue(nextMap, \"mixRotate\", 1);\n let mixX2 = getValue(nextMap, \"mixX\", 1);\n let mixY2 = getValue(nextMap, \"mixY\", mixX2);\n let mixScaleX2 = getValue(nextMap, \"mixScaleX\", 1);\n let mixScaleY2 = getValue(nextMap, \"mixScaleY\", mixScaleX2);\n let mixShearY2 = getValue(nextMap, \"mixShearY\", 1);\n let curve = keyMap.curve;\n if (curve) {\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, mixScaleX, mixScaleX2, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, mixScaleY, mixScaleY2, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, mixShearY, mixShearY2, 1);\n }\n time = time2;\n mixRotate = mixRotate2;\n mixX = mixX2;\n mixY = mixY2;\n mixScaleX = mixScaleX2;\n mixScaleY = mixScaleY2;\n mixScaleX = mixScaleX2;\n keyMap = nextMap;\n }\n timelines.push(timeline);\n }\n }\n // Path constraint timelines.\n if (map.path) {\n for (let constraintName in map.path) {\n let constraintMap = map.path[constraintName];\n let constraint = skeletonData.findPathConstraint(constraintName);\n if (!constraint)\n throw new Error(\"Path constraint not found: \" + constraintName);\n let constraintIndex = skeletonData.pathConstraints.indexOf(constraint);\n for (let timelineName in constraintMap) {\n let timelineMap = constraintMap[timelineName];\n let keyMap = timelineMap[0];\n if (!keyMap)\n continue;\n let frames = timelineMap.length;\n if (timelineName === \"position\") {\n let timeline = new PathConstraintPositionTimeline(frames, frames, constraintIndex);\n timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.positionMode == PositionMode.Fixed ? scale : 1));\n }\n else if (timelineName === \"spacing\") {\n let timeline = new PathConstraintSpacingTimeline(frames, frames, constraintIndex);\n timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.spacingMode == SpacingMode.Length || constraint.spacingMode == SpacingMode.Fixed ? scale : 1));\n }\n else if (timelineName === \"mix\") {\n let timeline = new PathConstraintMixTimeline(frames, frames * 3, constraintIndex);\n let time = getValue(keyMap, \"time\", 0);\n let mixRotate = getValue(keyMap, \"mixRotate\", 1);\n let mixX = getValue(keyMap, \"mixX\", 1);\n let mixY = getValue(keyMap, \"mixY\", mixX);\n for (let frame = 0, bezier = 0;; frame++) {\n timeline.setFrame(frame, time, mixRotate, mixX, mixY);\n let nextMap = timelineMap[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n break;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let mixRotate2 = getValue(nextMap, \"mixRotate\", 1);\n let mixX2 = getValue(nextMap, \"mixX\", 1);\n let mixY2 = getValue(nextMap, \"mixY\", mixX2);\n let curve = keyMap.curve;\n if (curve) {\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1);\n bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1);\n }\n time = time2;\n mixRotate = mixRotate2;\n mixX = mixX2;\n mixY = mixY2;\n keyMap = nextMap;\n }\n timelines.push(timeline);\n }\n }\n }\n }\n // Physics constraint timelines.\n if (map.physics) {\n for (let constraintName in map.physics) {\n let constraintMap = map.physics[constraintName];\n let constraintIndex = -1;\n if (constraintName.length > 0) {\n let constraint = skeletonData.findPhysicsConstraint(constraintName);\n if (!constraint)\n throw new Error(\"Physics constraint not found: \" + constraintName);\n constraintIndex = skeletonData.physicsConstraints.indexOf(constraint);\n }\n for (let timelineName in constraintMap) {\n let timelineMap = constraintMap[timelineName];\n let keyMap = timelineMap[0];\n if (!keyMap)\n continue;\n let frames = timelineMap.length;\n if (timelineName == \"reset\") {\n const timeline = new PhysicsConstraintResetTimeline(timelineMap.size, constraintIndex);\n for (let frame = 0; keyMap != null; keyMap = timelineMap[frame + 1], frame++)\n timeline.setFrame(frame, getValue(keyMap, \"time\", 0));\n timelines.push(timeline);\n continue;\n }\n let timeline;\n let timelineScale = 1;\n if (timelineName == \"inertia\")\n timeline = new PhysicsConstraintInertiaTimeline(frames, frames, constraintIndex);\n else if (timelineName == \"strength\")\n timeline = new PhysicsConstraintStrengthTimeline(frames, frames, constraintIndex);\n else if (timelineName == \"damping\")\n timeline = new PhysicsConstraintDampingTimeline(frames, frames, constraintIndex);\n else if (timelineName == \"mass\")\n timeline = new PhysicsConstraintMassTimeline(frames, frames, constraintIndex);\n else if (timelineName == \"wind\") {\n timeline = new PhysicsConstraintWindTimeline(frames, frames, constraintIndex);\n timelineScale = scale;\n }\n else if (timelineName == \"gravity\") {\n timeline = new PhysicsConstraintGravityTimeline(frames, frames, constraintIndex);\n timelineScale = scale;\n }\n else if (timelineName == \"mix\") //\n timeline = new PhysicsConstraintMixTimeline(frames, frames, constraintIndex);\n else\n continue;\n timelines.push(readTimeline1(timelineMap, timeline, 0, timelineScale));\n }\n }\n }\n // Attachment timelines.\n if (map.attachments) {\n for (let attachmentsName in map.attachments) {\n let attachmentsMap = map.attachments[attachmentsName];\n let skin = skeletonData.findSkin(attachmentsName);\n if (!skin)\n throw new Error(\"Skin not found: \" + attachmentsName);\n for (let slotMapName in attachmentsMap) {\n let slotMap = attachmentsMap[slotMapName];\n let slot = skeletonData.findSlot(slotMapName);\n if (!slot)\n throw new Error(\"Slot not found: \" + slotMapName);\n let slotIndex = slot.index;\n for (let attachmentMapName in slotMap) {\n let attachmentMap = slotMap[attachmentMapName];\n let attachment = skin.getAttachment(slotIndex, attachmentMapName);\n for (let timelineMapName in attachmentMap) {\n let timelineMap = attachmentMap[timelineMapName];\n let keyMap = timelineMap[0];\n if (!keyMap)\n continue;\n if (timelineMapName == \"deform\") {\n let weighted = attachment.bones;\n let vertices = attachment.vertices;\n let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;\n let timeline = new DeformTimeline(timelineMap.length, timelineMap.length, slotIndex, attachment);\n let time = getValue(keyMap, \"time\", 0);\n for (let frame = 0, bezier = 0;; frame++) {\n let deform;\n let verticesValue = getValue(keyMap, \"vertices\", null);\n if (!verticesValue)\n deform = weighted ? Utils.newFloatArray(deformLength) : vertices;\n else {\n deform = Utils.newFloatArray(deformLength);\n let start = getValue(keyMap, \"offset\", 0);\n Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length);\n if (scale != 1) {\n for (let i = start, n = i + verticesValue.length; i < n; i++)\n deform[i] *= scale;\n }\n if (!weighted) {\n for (let i = 0; i < deformLength; i++)\n deform[i] += vertices[i];\n }\n }\n timeline.setFrame(frame, time, deform);\n let nextMap = timelineMap[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n break;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let curve = keyMap.curve;\n if (curve)\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);\n time = time2;\n keyMap = nextMap;\n }\n timelines.push(timeline);\n }\n else if (timelineMapName == \"sequence\") {\n let timeline = new SequenceTimeline(timelineMap.length, slotIndex, attachment);\n let lastDelay = 0;\n for (let frame = 0; frame < timelineMap.length; frame++) {\n let delay = getValue(keyMap, \"delay\", lastDelay);\n let time = getValue(keyMap, \"time\", 0);\n let mode = SequenceMode[getValue(keyMap, \"mode\", \"hold\")];\n let index = getValue(keyMap, \"index\", 0);\n timeline.setFrame(frame, time, mode, index, delay);\n lastDelay = delay;\n keyMap = timelineMap[frame + 1];\n }\n timelines.push(timeline);\n }\n }\n }\n }\n }\n }\n // Draw order timelines.\n if (map.drawOrder) {\n let timeline = new DrawOrderTimeline(map.drawOrder.length);\n let slotCount = skeletonData.slots.length;\n let frame = 0;\n for (let i = 0; i < map.drawOrder.length; i++, frame++) {\n let drawOrderMap = map.drawOrder[i];\n let drawOrder = null;\n let offsets = getValue(drawOrderMap, \"offsets\", null);\n if (offsets) {\n drawOrder = Utils.newArray(slotCount, -1);\n let unchanged = Utils.newArray(slotCount - offsets.length, 0);\n let originalIndex = 0, unchangedIndex = 0;\n for (let ii = 0; ii < offsets.length; ii++) {\n let offsetMap = offsets[ii];\n let slot = skeletonData.findSlot(offsetMap.slot);\n if (!slot)\n throw new Error(\"Slot not found: \" + slot);\n let slotIndex = slot.index;\n // Collect unchanged items.\n while (originalIndex != slotIndex)\n unchanged[unchangedIndex++] = originalIndex++;\n // Set changed items.\n drawOrder[originalIndex + offsetMap.offset] = originalIndex++;\n }\n // Collect remaining unchanged items.\n while (originalIndex < slotCount)\n unchanged[unchangedIndex++] = originalIndex++;\n // Fill in unchanged items.\n for (let ii = slotCount - 1; ii >= 0; ii--)\n if (drawOrder[ii] == -1)\n drawOrder[ii] = unchanged[--unchangedIndex];\n }\n timeline.setFrame(frame, getValue(drawOrderMap, \"time\", 0), drawOrder);\n }\n timelines.push(timeline);\n }\n // Event timelines.\n if (map.events) {\n let timeline = new EventTimeline(map.events.length);\n let frame = 0;\n for (let i = 0; i < map.events.length; i++, frame++) {\n let eventMap = map.events[i];\n let eventData = skeletonData.findEvent(eventMap.name);\n if (!eventData)\n throw new Error(\"Event not found: \" + eventMap.name);\n let event = new Event(Utils.toSinglePrecision(getValue(eventMap, \"time\", 0)), eventData);\n event.intValue = getValue(eventMap, \"int\", eventData.intValue);\n event.floatValue = getValue(eventMap, \"float\", eventData.floatValue);\n event.stringValue = getValue(eventMap, \"string\", eventData.stringValue);\n if (event.data.audioPath) {\n event.volume = getValue(eventMap, \"volume\", 1);\n event.balance = getValue(eventMap, \"balance\", 0);\n }\n timeline.setFrame(frame, event);\n }\n timelines.push(timeline);\n }\n let duration = 0;\n for (let i = 0, n = timelines.length; i < n; i++)\n duration = Math.max(duration, timelines[i].getDuration());\n skeletonData.animations.push(new Animation(name, timelines, duration));\n }\n}\nclass LinkedMesh {\n parent;\n skin;\n slotIndex;\n mesh;\n inheritTimeline;\n constructor(mesh, skin, slotIndex, parent, inheritDeform) {\n this.mesh = mesh;\n this.skin = skin;\n this.slotIndex = slotIndex;\n this.parent = parent;\n this.inheritTimeline = inheritDeform;\n }\n}\nfunction readTimeline1(keys, timeline, defaultValue, scale) {\n let keyMap = keys[0];\n let time = getValue(keyMap, \"time\", 0);\n let value = getValue(keyMap, \"value\", defaultValue) * scale;\n let bezier = 0;\n for (let frame = 0;; frame++) {\n timeline.setFrame(frame, time, value);\n let nextMap = keys[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n return timeline;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let value2 = getValue(nextMap, \"value\", defaultValue) * scale;\n if (keyMap.curve)\n bezier = readCurve(keyMap.curve, timeline, bezier, frame, 0, time, time2, value, value2, scale);\n time = time2;\n value = value2;\n keyMap = nextMap;\n }\n}\nfunction readTimeline2(keys, timeline, name1, name2, defaultValue, scale) {\n let keyMap = keys[0];\n let time = getValue(keyMap, \"time\", 0);\n let value1 = getValue(keyMap, name1, defaultValue) * scale;\n let value2 = getValue(keyMap, name2, defaultValue) * scale;\n let bezier = 0;\n for (let frame = 0;; frame++) {\n timeline.setFrame(frame, time, value1, value2);\n let nextMap = keys[frame + 1];\n if (!nextMap) {\n timeline.shrink(bezier);\n return timeline;\n }\n let time2 = getValue(nextMap, \"time\", 0);\n let nvalue1 = getValue(nextMap, name1, defaultValue) * scale;\n let nvalue2 = getValue(nextMap, name2, defaultValue) * scale;\n let curve = keyMap.curve;\n if (curve) {\n bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale);\n bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale);\n }\n time = time2;\n value1 = nvalue1;\n value2 = nvalue2;\n keyMap = nextMap;\n }\n}\nfunction readCurve(curve, timeline, bezier, frame, value, time1, time2, value1, value2, scale) {\n if (curve == \"stepped\") {\n timeline.setStepped(frame);\n return bezier;\n }\n let i = value << 2;\n let cx1 = curve[i];\n let cy1 = curve[i + 1] * scale;\n let cx2 = curve[i + 2];\n let cy2 = curve[i + 3] * scale;\n timeline.setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);\n return bezier + 1;\n}\nfunction getValue(map, property, defaultValue) {\n return map[property] !== undefined ? map[property] : defaultValue;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25Kc29uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NrZWxldG9uSnNvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUFFLFNBQVMsRUFBWSxrQkFBa0IsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxvQkFBb0IsRUFBRSwyQkFBMkIsRUFBRSw4QkFBOEIsRUFBRSw2QkFBNkIsRUFBRSx5QkFBeUIsRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFpRCw4QkFBOEIsRUFBRSxnQ0FBZ0MsRUFBRSxpQ0FBaUMsRUFBRSxnQ0FBZ0MsRUFBRSw2QkFBNkIsRUFBRSw2QkFBNkIsRUFBRSxnQ0FBZ0MsRUFBRSw0QkFBNEIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSTV5QixPQUFPLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNuQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNqQyxP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SUFBSSxLQUFLLEVBQUU7d0JBQ1YsTUFBTSxHQUFHLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDN0YsTUFBTSxHQUFHLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDbkYsTUFBTSxHQUFHLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDbkYsTUFBTSxHQUFHLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDN0YsTUFBTSxHQUFHLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDN0YsTUFBTSxHQUFHLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztxQkFDN0Y7b0JBRUQsSUFBSSxHQUFHLEtBQUssQ0FBQztvQkFDYixTQUFTLEdBQUcsVUFBVSxDQUFDO29CQUN2QixJQUFJLEdBQUcsS0FBSyxDQUFDO29CQUNiLElB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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\n(() => {\n if (typeof Math.fround === \"undefined\") {\n Math.fround = (function (array) {\n return function (x) {\n return array[0] = x, array[0];\n };\n })(new Float32Array(1));\n }\n})();\nexport {};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9seWZpbGxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3BvbHlmaWxscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsQ0FBQyxHQUFHLEVBQUU7SUFDTCxJQUFJLE9BQU8sSUFBSSxDQUFDLE1BQU0sS0FBSyxXQUFXLEVBQUU7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLFVBQVUsS0FBSztZQUM3QixPQUFPLFVBQVUsQ0FBUztnQkFDekIsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvQixDQUFDLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQyxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQ3hCO0FBQ0YsQ0FBQyxDQUFDLEVBQUUsQ0FBQyJ9","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { BlendMode, Texture, TextureFilter, TextureWrap } from \"@esotericsoftware/spine-core\";\nimport * as THREE from \"three\";\nexport class ThreeJsTexture extends Texture {\n texture;\n constructor(image) {\n super(image);\n if (image instanceof ImageBitmap)\n this.texture = new THREE.CanvasTexture(image);\n else\n this.texture = new THREE.Texture(image);\n this.texture.flipY = false;\n this.texture.needsUpdate = true;\n }\n setFilters(minFilter, magFilter) {\n this.texture.minFilter = ThreeJsTexture.toThreeJsTextureFilter(minFilter);\n this.texture.magFilter = ThreeJsTexture.toThreeJsTextureFilter(magFilter);\n }\n setWraps(uWrap, vWrap) {\n this.texture.wrapS = ThreeJsTexture.toThreeJsTextureWrap(uWrap);\n this.texture.wrapT = ThreeJsTexture.toThreeJsTextureWrap(vWrap);\n }\n dispose() {\n this.texture.dispose();\n }\n static toThreeJsTextureFilter(filter) {\n if (filter === TextureFilter.Linear)\n return THREE.LinearFilter;\n else if (filter === TextureFilter.MipMap)\n return THREE.LinearMipMapLinearFilter; // also includes TextureFilter.MipMapLinearLinear\n else if (filter === TextureFilter.MipMapLinearNearest)\n return THREE.LinearMipMapNearestFilter;\n else if (filter === TextureFilter.MipMapNearestLinear)\n return THREE.NearestMipMapLinearFilter;\n else if (filter === TextureFilter.MipMapNearestNearest)\n return THREE.NearestMipMapNearestFilter;\n else if (filter === TextureFilter.Nearest)\n return THREE.NearestFilter;\n else\n throw new Error(\"Unknown texture filter: \" + filter);\n }\n static toThreeJsTextureWrap(wrap) {\n if (wrap === TextureWrap.ClampToEdge)\n return THREE.ClampToEdgeWrapping;\n else if (wrap === TextureWrap.MirroredRepeat)\n return THREE.MirroredRepeatWrapping;\n else if (wrap === TextureWrap.Repeat)\n return THREE.RepeatWrapping;\n else\n throw new Error(\"Unknown texture wrap: \" + wrap);\n }\n static toThreeJsBlending(blend) {\n if (blend === BlendMode.Normal)\n return THREE.NormalBlending;\n else if (blend === BlendMode.Additive)\n return THREE.AdditiveBlending;\n else if (blend === BlendMode.Multiply)\n return THREE.MultiplyBlending;\n else if (blend === BlendMode.Screen)\n return THREE.CustomBlending;\n else\n throw new Error(\"Unknown blendMode: \" + blend);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGhyZWVKc1RleHR1cmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvVGhyZWVKc1RleHR1cmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RixPQUFPLEtBQUssS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUUvQixNQUFNLE9BQU8sY0FBZSxTQUFRLE9BQU87SUFDMUMsT0FBTyxDQUFnQjtJQUV2QixZQUFhLEtBQXFDO1FBQ2pELEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNiLElBQUksS0FBSyxZQUFZLFdBQVc7WUFDL0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7O1lBRTlDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDakMsQ0FBQztJQUVELFVBQVUsQ0FBRSxTQUF3QixFQUFFLFNBQXdCO1FBQzdELElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxHQUFHLGNBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsR0FBRyxjQUFjLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUVELFFBQVEsQ0FBRSxLQUFrQixFQUFFLEtBQWtCO1FBQy9DLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELE9BQU87UUFDTixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxNQUFNLENBQUMsc0JBQXNCLENBQUUsTUFBcUI7UUFDbkQsSUFBSSxNQUFNLEtBQUssYUFBYSxDQUFDLE1BQU07WUFBRSxPQUFPLEtBQUssQ0FBQyxZQUFZLENBQUM7YUFDMUQsSUFBSSxNQUFNLEtBQUssYUFBYSxDQUFDLE1BQU07WUFBRSxPQUFPLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLGlEQUFpRDthQUM3SCxJQUFJLE1BQU0sS0FBSyxhQUFhLENBQUMsbUJBQW1CO1lBQUUsT0FBTyxLQUFLLENBQUMseUJBQXlCLENBQUM7YUFDekYsSUFBSSxNQUFNLEtBQUssYUFBYSxDQUFDLG1CQUFtQjtZQUFFLE9BQU8sS0FBSyxDQUFDLHlCQUF5QixDQUFDO2FBQ3pGLElBQUksTUFBTSxLQUFLLGFBQWEsQ0FBQyxvQkFBb0I7WUFBRSxPQUFPLEtBQUssQ0FBQywwQkFBMEIsQ0FBQzthQUMzRixJQUFJLE1BQU0sS0FBSyxhQUFhLENBQUMsT0FBTztZQUFFLE9BQU8sS0FBSyxDQUFDLGFBQWEsQ0FBQzs7WUFDakUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsR0FBRyxNQUFNLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsTUFBTSxDQUFDLG9CQUFvQixDQUFFLElBQWlCO1FBQzdDLElBQUksSUFBSSxLQUFLLFdBQVcsQ0FBQyxXQUFXO1lBQUUsT0FBTyxLQUFLLENBQUMsbUJBQW1CLENBQUM7YUFDbEUsSUFBSSxJQUFJLEtBQUssV0FBVyxDQUFDLGNBQWM7WUFBRSxPQUFPLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQzthQUM3RSxJQUFJLElBQUksS0FBSyxXQUFXLENBQUMsTUFBTTtZQUFFLE9BQU8sS0FBSyxDQUFDLGNBQWMsQ0FBQzs7WUFDN0QsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsTUFBTSxDQUFDLGlCQUFpQixDQUFFLEtBQWdCO1FBQ3pDLElBQUksS0FBSyxLQUFLLFNBQVMsQ0FBQyxNQUFNO1lBQUUsT0FBTyxLQUFLLENBQUMsY0FBYyxDQUFDO2FBQ3ZELElBQUksS0FBSyxLQUFLLFNBQVMsQ0FBQyxRQUFRO1lBQUUsT0FBTyxLQUFLLENBQUMsZ0JBQWdCLENBQUM7YUFDaEUsSUFBSSxLQUFLLEtBQUssU0FBUyxDQUFDLFFBQVE7WUFBRSxPQUFPLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQzthQUNoRSxJQUFJLEtBQUssS0FBSyxTQUFTLENBQUMsTUFBTTtZQUFFLE9BQU8sS0FBSyxDQUFDLGNBQWMsQ0FBQzs7WUFDNUQsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUNyRCxDQUFDO0NBQ0QifQ==","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { AssetManagerBase, Downloader } from \"@esotericsoftware/spine-core\";\nimport { ThreeJsTexture } from \"./ThreeJsTexture.js\";\nexport class AssetManager extends AssetManagerBase {\n constructor(pathPrefix = \"\", downloader = new Downloader()) {\n super((image) => {\n return new ThreeJsTexture(image);\n }, pathPrefix, downloader);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXNzZXRNYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0Fzc2V0TWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFVBQVUsRUFBRSxNQUFNLDhCQUE4QixDQUFBO0FBQzNFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVyRCxNQUFNLE9BQU8sWUFBYSxTQUFRLGdCQUFnQjtJQUNqRCxZQUFhLGFBQXFCLEVBQUUsRUFBRSxhQUF5QixJQUFJLFVBQVUsRUFBRTtRQUM5RSxLQUFLLENBQUMsQ0FBQyxLQUFxQyxFQUFFLEVBQUU7WUFDL0MsT0FBTyxJQUFJLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxDQUFDLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQzVCLENBQUM7Q0FDRCJ9","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { AnimationState, AnimationStateData, ClippingAttachment, Color, MeshAttachment, Physics, RegionAttachment, Skeleton, SkeletonClipping, Utils, Vector2, } from \"@esotericsoftware/spine-core\";\nimport { MeshBatcher } from \"./MeshBatcher.js\";\nimport * as THREE from \"three\";\nexport class SkeletonMeshMaterial extends THREE.ShaderMaterial {\n constructor(customizer) {\n let vertexShader = `\n\t\t\tattribute vec4 color;\n\t\t\tvarying vec2 vUv;\n\t\t\tvarying vec4 vColor;\n\t\t\tvoid main() {\n\t\t\t\tvUv = uv;\n\t\t\t\tvColor = color;\n\t\t\t\tgl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);\n\t\t\t}\n\t\t`;\n let fragmentShader = `\n\t\t\tuniform sampler2D map;\n\t\t\t#ifdef USE_SPINE_ALPHATEST\n\t\t\tuniform float alphaTest;\n\t\t\t#endif\n\t\t\tvarying vec2 vUv;\n\t\t\tvarying vec4 vColor;\n\t\t\tvoid main(void) {\n\t\t\t\tgl_FragColor = texture2D(map, vUv)*vColor;\n\t\t\t\t#ifdef USE_SPINE_ALPHATEST\n\t\t\t\tif (gl_FragColor.a < alphaTest) discard;\n\t\t\t\t#endif\n\t\t\t}\n\t\t`;\n let parameters = {\n uniforms: {\n map: { value: null },\n },\n vertexShader: vertexShader,\n fragmentShader: fragmentShader,\n side: THREE.DoubleSide,\n transparent: true,\n depthWrite: true,\n alphaTest: 0.0,\n };\n customizer(parameters);\n if (parameters.alphaTest && parameters.alphaTest > 0) {\n parameters.defines = { USE_SPINE_ALPHATEST: 1 };\n if (!parameters.uniforms)\n parameters.uniforms = {};\n parameters.uniforms[\"alphaTest\"] = { value: parameters.alphaTest };\n }\n super(parameters);\n }\n}\nexport class SkeletonMesh extends THREE.Object3D {\n materialCustomerizer;\n tempPos = new Vector2();\n tempUv = new Vector2();\n tempLight = new Color();\n tempDark = new Color();\n skeleton;\n state;\n zOffset = 0.1;\n batches = new Array();\n nextBatchIndex = 0;\n clipper = new SkeletonClipping();\n static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];\n static VERTEX_SIZE = 2 + 2 + 4;\n vertices = Utils.newFloatArray(1024);\n tempColor = new Color();\n constructor(skeletonData, materialCustomerizer = (material) => { }) {\n super();\n this.materialCustomerizer = materialCustomerizer;\n this.skeleton = new Skeleton(skeletonData);\n let animData = new AnimationStateData(skeletonData);\n this.state = new AnimationState(animData);\n }\n update(deltaTime) {\n let state = this.state;\n let skeleton = this.skeleton;\n state.update(deltaTime);\n state.apply(skeleton);\n skeleton.updateWorldTransform(Physics.update);\n this.updateGeometry();\n }\n dispose() {\n for (var i = 0; i < this.batches.length; i++) {\n this.batches[i].dispose();\n }\n }\n clearBatches() {\n for (var i = 0; i < this.batches.length; i++) {\n this.batches[i].clear();\n this.batches[i].visible = false;\n }\n this.nextBatchIndex = 0;\n }\n nextBatch() {\n if (this.batches.length == this.nextBatchIndex) {\n let batch = new MeshBatcher(10920, this.materialCustomerizer);\n this.add(batch);\n this.batches.push(batch);\n }\n let batch = this.batches[this.nextBatchIndex++];\n batch.visible = true;\n return batch;\n }\n updateGeometry() {\n this.clearBatches();\n let tempPos = this.tempPos;\n let tempUv = this.tempUv;\n let tempLight = this.tempLight;\n let tempDark = this.tempDark;\n let clipper = this.clipper;\n let vertices = this.vertices;\n let triangles = null;\n let uvs = null;\n let drawOrder = this.skeleton.drawOrder;\n let batch = this.nextBatch();\n batch.begin();\n let z = 0;\n let zOffset = this.zOffset;\n for (let i = 0, n = drawOrder.length; i < n; i++) {\n let vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE;\n let slot = drawOrder[i];\n if (!slot.bone.active) {\n clipper.clipEndWithSlot(slot);\n continue;\n }\n let attachment = slot.getAttachment();\n let attachmentColor;\n let texture;\n let numFloats = 0;\n if (attachment instanceof RegionAttachment) {\n let region = attachment;\n attachmentColor = region.color;\n vertices = this.vertices;\n numFloats = vertexSize * 4;\n region.computeWorldVertices(slot, vertices, 0, vertexSize);\n triangles = SkeletonMesh.QUAD_TRIANGLES;\n uvs = region.uvs;\n texture = region.region.texture;\n }\n else if (attachment instanceof MeshAttachment) {\n let mesh = attachment;\n attachmentColor = mesh.color;\n vertices = this.vertices;\n numFloats = (mesh.worldVerticesLength >> 1) * vertexSize;\n if (numFloats > vertices.length) {\n vertices = this.vertices = Utils.newFloatArray(numFloats);\n }\n mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, vertexSize);\n triangles = mesh.triangles;\n uvs = mesh.uvs;\n texture = mesh.region.texture;\n }\n else if (attachment instanceof ClippingAttachment) {\n let clip = attachment;\n clipper.clipStart(slot, clip);\n continue;\n }\n else {\n clipper.clipEndWithSlot(slot);\n continue;\n }\n if (texture != null) {\n let skeleton = slot.bone.skeleton;\n let skeletonColor = skeleton.color;\n let slotColor = slot.color;\n let alpha = skeletonColor.a * slotColor.a * attachmentColor.a;\n let color = this.tempColor;\n color.set(skeletonColor.r * slotColor.r * attachmentColor.r, skeletonColor.g * slotColor.g * attachmentColor.g, skeletonColor.b * slotColor.b * attachmentColor.b, alpha);\n let finalVertices;\n let finalVerticesLength;\n let finalIndices;\n let finalIndicesLength;\n if (clipper.isClipping()) {\n clipper.clipTriangles(vertices, numFloats, triangles, triangles.length, uvs, color, tempLight, false);\n let clippedVertices = clipper.clippedVertices;\n let clippedTriangles = clipper.clippedTriangles;\n finalVertices = clippedVertices;\n finalVerticesLength = clippedVertices.length;\n finalIndices = clippedTriangles;\n finalIndicesLength = clippedTriangles.length;\n }\n else {\n let verts = vertices;\n for (let v = 2, u = 0, n = numFloats; v < n; v += vertexSize, u += 2) {\n verts[v] = color.r;\n verts[v + 1] = color.g;\n verts[v + 2] = color.b;\n verts[v + 3] = color.a;\n verts[v + 4] = uvs[u];\n verts[v + 5] = uvs[u + 1];\n }\n finalVertices = vertices;\n finalVerticesLength = numFloats;\n finalIndices = triangles;\n finalIndicesLength = triangles.length;\n }\n if (finalVerticesLength == 0 || finalIndicesLength == 0) {\n clipper.clipEndWithSlot(slot);\n continue;\n }\n // Start new batch if this one can't hold vertices/indices\n if (!batch.canBatch(finalVerticesLength / SkeletonMesh.VERTEX_SIZE, finalIndicesLength)) {\n batch.end();\n batch = this.nextBatch();\n batch.begin();\n }\n const slotBlendMode = slot.data.blendMode;\n const slotTexture = texture.texture;\n const materialGroup = batch.findMaterialGroup(slotTexture, slotBlendMode);\n batch.addMaterialGroup(finalIndicesLength, materialGroup);\n batch.batch(finalVertices, finalVerticesLength, finalIndices, finalIndicesLength, z);\n z += zOffset;\n }\n clipper.clipEndWithSlot(slot);\n }\n clipper.clipEnd();\n batch.end();\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25NZXNoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NrZWxldG9uTWVzaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUNOLGNBQWMsRUFDZCxrQkFBa0IsRUFFbEIsa0JBQWtCLEVBQ2xCLEtBQUssRUFDTCxjQUFjLEVBRWQsT0FBTyxFQUNQLGdCQUFnQixFQUNoQixRQUFRLEVBQ1IsZ0JBQWdCLEVBR2hCLEtBQUssRUFDTCxPQUFPLEdBQ1AsTUFBTSw4QkFBOEIsQ0FBQztBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDL0MsT0FBTyxLQUFLLEtBQUssTUFBTSxPQUFPLENBQUM7QUFPL0IsTUFBTSxPQUFPLG9CQUFxQixTQUFRLEtBQUssQ0FBQyxjQUFjO0lBQzdELFlBQWEsVUFBb0Q7UUFDaEUsSUFBSSxZQUFZLEdBQUc7Ozs7Ozs7OztHQVNsQixDQUFDO1FBQ0YsSUFBSSxjQUFjLEdBQUc7Ozs7Ozs7Ozs7Ozs7R0FhcEIsQ0FBQztRQUVGLElBQUksVUFBVSxHQUFtQztZQUNoRCxRQUFRLEVBQUU7Z0JBQ1QsR0FBRyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTthQUNwQjtZQUNELFlBQVksRUFBRSxZQUFZO1lBQzFCLGNBQWMsRUFBRSxjQUFjO1lBQzlCLElBQUksRUFBRSxLQUFLLENBQUMsVUFBVTtZQUN0QixXQUFXLEVBQUUsSUFBSTtZQUNqQixVQUFVLEVBQUUsSUFBSTtZQUNoQixTQUFTLEVBQUUsR0FBRztTQUNkLENBQUM7UUFDRixVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkIsSUFBSSxVQUFVLENBQUMsU0FBUyxJQUFJLFVBQVUsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxFQUFFO1lBQ3JELFVBQVUsQ0FBQyxPQUFPLEdBQUcsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLEVB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","/******************************************************************************\n * Spine Runtimes License Agreement\n * Last updated July 28, 2023. Replaces all prior versions.\n *\n * Copyright (c) 2013-2023, Esoteric Software LLC\n *\n * Integration of the Spine Runtimes into software or otherwise creating\n * derivative works of the Spine Runtimes is permitted under the terms and\n * conditions of Section 2 of the Spine Editor License Agreement:\n * http://esotericsoftware.com/spine-editor-license\n *\n * Otherwise, it is permitted to integrate the Spine Runtimes into software or\n * otherwise create derivative works of the Spine Runtimes (collectively,\n * \"Products\"), provided that each user of the Products must obtain their own\n * Spine Editor license and redistribution of the Products in any form must\n * include this license and copyright notice.\n *\n * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,\n * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\n * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *****************************************************************************/\nimport { SkeletonMeshMaterial } from \"./SkeletonMesh.js\";\nimport * as THREE from \"three\";\nimport { ThreeJsTexture } from \"./ThreeJsTexture.js\";\nexport class MeshBatcher extends THREE.Mesh {\n materialCustomizer;\n static VERTEX_SIZE = 9;\n vertexBuffer;\n vertices;\n verticesLength = 0;\n indices;\n indicesLength = 0;\n materialGroups = [];\n constructor(maxVertices = 10920, materialCustomizer = (parameters) => { }) {\n super();\n this.materialCustomizer = materialCustomizer;\n if (maxVertices > 10920)\n throw new Error(\"Can't have more than 10920 triangles per batch: \" + maxVertices);\n let vertices = this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);\n let indices = this.indices = new Uint16Array(maxVertices * 3);\n let geo = new THREE.BufferGeometry();\n let vertexBuffer = this.vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);\n vertexBuffer.usage = WebGLRenderingContext.DYNAMIC_DRAW;\n geo.setAttribute(\"position\", new THREE.InterleavedBufferAttribute(vertexBuffer, 3, 0, false));\n geo.setAttribute(\"color\", new THREE.InterleavedBufferAttribute(vertexBuffer, 4, 3, false));\n geo.setAttribute(\"uv\", new THREE.InterleavedBufferAttribute(vertexBuffer, 2, 7, false));\n geo.setIndex(new THREE.BufferAttribute(indices, 1));\n geo.getIndex().usage = WebGLRenderingContext.DYNAMIC_DRAW;\n geo.drawRange.start = 0;\n geo.drawRange.count = 0;\n this.geometry = geo;\n this.material = [new SkeletonMeshMaterial(materialCustomizer)];\n }\n dispose() {\n this.geometry.dispose();\n if (this.material instanceof THREE.Material)\n this.material.dispose();\n else if (this.material) {\n for (let i = 0; i < this.material.length; i++) {\n let material = this.material[i];\n if (material instanceof THREE.Material)\n material.dispose();\n }\n }\n }\n clear() {\n let geo = this.geometry;\n geo.drawRange.start = 0;\n geo.drawRange.count = 0;\n geo.clearGroups();\n this.materialGroups = [];\n if (this.material instanceof THREE.Material) {\n const meshMaterial = this.material;\n meshMaterial.uniforms.map.value = null;\n meshMaterial.blending = THREE.NormalBlending;\n }\n else if (Array.isArray(this.material)) {\n for (let i = 0; i < this.material.length; i++) {\n const meshMaterial = this.material[i];\n meshMaterial.uniforms.map.value = null;\n meshMaterial.blending = THREE.NormalBlending;\n }\n }\n return this;\n }\n begin() {\n this.verticesLength = 0;\n this.indicesLength = 0;\n }\n canBatch(numVertices, numIndices) {\n if (this.indicesLength + numIndices >= this.indices.byteLength / 2)\n return false;\n if (this.verticesLength / MeshBatcher.VERTEX_SIZE + numVertices >= (this.vertices.byteLength / 4) / MeshBatcher.VERTEX_SIZE)\n return false;\n return true;\n }\n batch(vertices, verticesLength, indices, indicesLength, z = 0) {\n let indexStart = this.verticesLength / MeshBatcher.VERTEX_SIZE;\n let vertexBuffer = this.vertices;\n let i = this.verticesLength;\n let j = 0;\n for (; j < verticesLength;) {\n vertexBuffer[i++] = vertices[j++];\n vertexBuffer[i++] = vertices[j++];\n vertexBuffer[i++] = z;\n vertexBuffer[i++] = vertices[j++];\n vertexBuffer[i++] = vertices[j++];\n vertexBuffer[i++] = vertices[j++];\n vertexBuffer[i++] = vertices[j++];\n vertexBuffer[i++] = vertices[j++];\n vertexBuffer[i++] = vertices[j++];\n }\n this.verticesLength = i;\n let indicesArray = this.indices;\n for (i = this.indicesLength, j = 0; j < indicesLength; i++, j++)\n indicesArray[i] = indices[j] + indexStart;\n this.indicesLength += indicesLength;\n }\n end() {\n this.vertexBuffer.needsUpdate = this.verticesLength > 0;\n this.vertexBuffer.updateRange.offset = 0;\n this.vertexBuffer.updateRange.count = this.verticesLength;\n let geo = this.geometry;\n this.closeMaterialGroups();\n let index = geo.getIndex();\n if (!index)\n throw new Error(\"BufferAttribute must not be null.\");\n index.needsUpdate = this.indicesLength > 0;\n index.updateRange.offset = 0;\n index.updateRange.count = this.indicesLength;\n geo.drawRange.start = 0;\n geo.drawRange.count = this.indicesLength;\n }\n addMaterialGroup(indicesLength, materialGroup) {\n const currentGroup = this.materialGroups[this.materialGroups.length - 1];\n if (currentGroup === undefined || currentGroup[2] !== materialGroup) {\n this.materialGroups.push([this.indicesLength, indicesLength, materialGroup]);\n }\n else {\n currentGroup[1] += indicesLength;\n }\n }\n closeMaterialGroups() {\n const geometry = this.geometry;\n for (let i = 0; i < this.materialGroups.length; i++) {\n const [startIndex, count, materialGroup] = this.materialGroups[i];\n geometry.addGroup(startIndex, count, materialGroup);\n }\n }\n findMaterialGroup(slotTexture, slotBlendMode) {\n const blending = ThreeJsTexture.toThreeJsBlending(slotBlendMode);\n let group = -1;\n if (Array.isArray(this.material)) {\n for (let i = 0; i < this.material.length; i++) {\n const meshMaterial = this.material[i];\n if (!meshMaterial.uniforms.map.value) {\n updateMeshMaterial(meshMaterial, slotTexture, blending);\n return i;\n }\n if (meshMaterial.uniforms.map.value === slotTexture && meshMaterial.blending === blending) {\n return i;\n }\n }\n const meshMaterial = new SkeletonMeshMaterial(this.materialCustomizer);\n updateMeshMaterial(meshMaterial, slotTexture, blending);\n this.material.push(meshMaterial);\n group = this.material.length - 1;\n }\n else {\n throw new Error(\"MeshBatcher.material needs to be an array for geometry groups to work\");\n }\n return group;\n }\n}\nfunction updateMeshMaterial(meshMaterial, slotTexture, blending) {\n meshMaterial.uniforms.map.value = slotTexture;\n meshMaterial.blending = blending;\n meshMaterial.blendDst = blending === THREE.CustomBlending ? THREE.OneMinusSrcColorFactor : THREE.OneMinusSrcAlphaFactor;\n meshMaterial.blendSrc = blending === THREE.CustomBlending ? THREE.OneFactor : THREE.SrcAlphaFactor;\n meshMaterial.needsUpdate = true;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWVzaEJhdGNoZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvTWVzaEJhdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxvQkFBb0IsRUFBNEMsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRyxPQUFPLEtBQUssS0FBSyxNQUFNLE9BQU8sQ0FBQTtBQUM5QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHckQsTUFBTSxPQUFPLFdBQVksU0FBUSxLQUFLLENBQUMsSUFBSTtJQVNRO0lBUjFDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZCLFlBQVksQ0FBMEI7SUFDdEMsUUFBUSxDQUFlO0lBQ3ZCLGNBQWMsR0FBRyxDQUFDLENBQUM7SUFDbkIsT0FBTyxDQUFjO0lBQ3JCLGFBQWEsR0FBRyxDQUFDLENBQUM7SUFDbEIsY0FBYyxHQUErQixFQUFFLENBQUM7SUFFeEQsWUFBYSxjQUFzQixLQUFLLEVBQVUscUJBQStELENBQUMsVUFBVSxFQUFFLEVBQUUsR0FBRyxDQUFDO1FBQ25JLEtBQUssRUFBRSxDQUFDO1FBRHlDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBZ0U7UUFFbkksSUFBSSxXQUFXLEdBQUcsS0FBSztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELEdBQUcsV0FBVyxDQUFDLENBQUM7UUFDM0csSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFlBQVksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3ZGLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxXQUFXLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzlELElBQUksR0FBRyxHQUFHLElBQUksS0FBSyxDQUFDLGNBQWMsRUFBRSxD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","export const API_URL = (() => {\n\tif ([\"127.0.0.1\", \"localhost\"].includes(window.location.hostname))\n\t\treturn `${window.location.protocol}//${window.location.hostname}:42069`;\n\telse return `${window.location.protocol}//${window.location.hostname}`;\n})();\n","import { defineComponent, Types } from \"bitecs\";\n\nconst { f32, eid, i8 } = Types;\n\nexport const Vector3Schema = { x: f32, y: f32, z: f32 };\nexport const QuaternionSchema = { x: f32, y: f32, z: f32, w: f32 };\n\nexport type Vector3Component = {\n\tx: Float32Array;\n\ty: Float32Array;\n\tz: Float32Array;\n};\n\nexport type QuaternionComponent = {\n\tx: Float32Array;\n\ty: Float32Array;\n\tz: Float32Array;\n\tw: Float32Array;\n};\n\nexport type TransformComponentType = {\n\tposition: Vector3Component;\n\trotation: QuaternionComponent;\n\tscale: Vector3Component;\n};\n\nexport const TransformComponent = defineComponent({\n\tposition: Vector3Schema,\n\trotation: QuaternionSchema,\n\tscale: Vector3Schema,\n});\n\nexport const SpineComponent = defineComponent({ timeScale: f32 });\n\nexport const GltfComponent = defineComponent({\n\tanimState: i8,\n\tanimAction: i8,\n\ttimeScale: f32,\n});\n\nexport const ObjectOutlineComponent = defineComponent();\n\nexport const ObjectComponent = defineComponent();\n\nexport const PlayerComponent = defineComponent();\n\nexport const LocalPlayerComponent = defineComponent();\n\nexport const MoveTowardsComponent =\n\tdefineComponent(Vector3Schema);\n\nexport const NameplateComponent = defineComponent({ owner: eid });\n\nexport const ChatMessageComponent = defineComponent();\n","import {\n\tAnimationClip,\n\tBone,\n\tBox3,\n\tBufferAttribute,\n\tBufferGeometry,\n\tClampToEdgeWrapping,\n\tColor,\n\tDirectionalLight,\n\tDoubleSide,\n\tFileLoader,\n\tFrontSide,\n\tGroup,\n\tImageBitmapLoader,\n\tInterleavedBuffer,\n\tInterleavedBufferAttribute,\n\tInterpolant,\n\tInterpolateDiscrete,\n\tInterpolateLinear,\n\tLine,\n\tLineBasicMaterial,\n\tLineLoop,\n\tLineSegments,\n\tLinearFilter,\n\tLinearMipmapLinearFilter,\n\tLinearMipmapNearestFilter,\n\tLoader,\n\tLoaderUtils,\n\tMaterial,\n\tMathUtils,\n\tMatrix4,\n\tMesh,\n\tMeshBasicMaterial,\n\tMeshPhysicalMaterial,\n\tMeshStandardMaterial,\n\tMirroredRepeatWrapping,\n\tNearestFilter,\n\tNearestMipmapLinearFilter,\n\tNearestMipmapNearestFilter,\n\tNumberKeyframeTrack,\n\tObject3D,\n\tOrthographicCamera,\n\tPerspectiveCamera,\n\tPointLight,\n\tPoints,\n\tPointsMaterial,\n\tPropertyBinding,\n\tQuaternion,\n\tQuaternionKeyframeTrack,\n\tRepeatWrapping,\n\tSkeleton,\n\tSkinnedMesh,\n\tSphere,\n\tSpotLight,\n\tTangentSpaceNormalMap,\n\tTexture,\n\tTextureLoader,\n\tTriangleFanDrawMode,\n\tTriangleStripDrawMode,\n\tVector2,\n\tVector3,\n\tVectorKeyframeTrack,\n\tsRGBEncoding\n} from 'three';\n\nclass GLTFLoader extends Loader {\n\n\tconstructor( manager ) {\n\n\t\tsuper( manager );\n\n\t\tthis.dracoLoader = null;\n\t\tthis.ktx2Loader = null;\n\t\tthis.meshoptDecoder = null;\n\n\t\tthis.pluginCallbacks = [];\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsClearcoatExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureBasisUExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFTextureWebPExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsSheenExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsTransmissionExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsVolumeExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsIorExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsEmissiveStrengthExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsSpecularExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMaterialsIridescenceExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFLightsExtension( parser );\n\n\t\t} );\n\n\t\tthis.register( function ( parser ) {\n\n\t\t\treturn new GLTFMeshoptCompression( parser );\n\n\t\t} );\n\n\t}\n\n\tload( url, onLoad, onProgress, onError ) {\n\n\t\tconst scope = this;\n\n\t\tlet resourcePath;\n\n\t\tif ( this.resourcePath !== '' ) {\n\n\t\t\tresourcePath = this.resourcePath;\n\n\t\t} else if ( this.path !== '' ) {\n\n\t\t\tresourcePath = this.path;\n\n\t\t} else {\n\n\t\t\tresourcePath = LoaderUtils.extractUrlBase( url );\n\n\t\t}\n\n\t\t// Tells the LoadingManager to track an extra item, which resolves after\n\t\t// the model is fully loaded. This means the count of items loaded will\n\t\t// be incorrect, but ensures manager.onLoad() does not fire early.\n\t\tthis.manager.itemStart( url );\n\n\t\tconst _onError = function ( e ) {\n\n\t\t\tif ( onError ) {\n\n\t\t\t\tonError( e );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( e );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemError( url );\n\t\t\tscope.manager.itemEnd( url );\n\n\t\t};\n\n\t\tconst loader = new FileLoader( this.manager );\n\n\t\tloader.setPath( this.path );\n\t\tloader.setResponseType( 'arraybuffer' );\n\t\tloader.setRequestHeader( this.requestHeader );\n\t\tloader.setWithCredentials( this.withCredentials );\n\n\t\tloader.load( url, function ( data ) {\n\n\t\t\ttry {\n\n\t\t\t\tscope.parse( data, resourcePath, function ( gltf ) {\n\n\t\t\t\t\tonLoad( gltf );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, _onError );\n\n\t\t\t} catch ( e ) {\n\n\t\t\t\t_onError( e );\n\n\t\t\t}\n\n\t\t}, onProgress, _onError );\n\n\t}\n\n\tsetDRACOLoader( dracoLoader ) {\n\n\t\tthis.dracoLoader = dracoLoader;\n\t\treturn this;\n\n\t}\n\n\tsetDDSLoader() {\n\n\t\tthrow new Error(\n\n\t\t\t'THREE.GLTFLoader: \"MSFT_texture_dds\" no longer supported. Please update to \"KHR_texture_basisu\".'\n\n\t\t);\n\n\t}\n\n\tsetKTX2Loader( ktx2Loader ) {\n\n\t\tthis.ktx2Loader = ktx2Loader;\n\t\treturn this;\n\n\t}\n\n\tsetMeshoptDecoder( meshoptDecoder ) {\n\n\t\tthis.meshoptDecoder = meshoptDecoder;\n\t\treturn this;\n\n\t}\n\n\tregister( callback ) {\n\n\t\tif ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {\n\n\t\t\tthis.pluginCallbacks.push( callback );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tunregister( callback ) {\n\n\t\tif ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {\n\n\t\t\tthis.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tparse( data, path, onLoad, onError ) {\n\n\t\tlet content;\n\t\tconst extensions = {};\n\t\tconst plugins = {};\n\n\t\tif ( typeof data === 'string' ) {\n\n\t\t\tcontent = data;\n\n\t\t} else {\n\n\t\t\tconst magic = LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) );\n\n\t\t\tif ( magic === BINARY_EXTENSION_HEADER_MAGIC ) {\n\n\t\t\t\ttry {\n\n\t\t\t\t\textensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError ) onError( error );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tcontent = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content;\n\n\t\t\t} else {\n\n\t\t\t\tcontent = LoaderUtils.decodeText( new Uint8Array( data ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\tconst json = JSON.parse( content );\n\n\t\tif ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) {\n\n\t\t\tif ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.' ) );\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst parser = new GLTFParser( json, {\n\n\t\t\tpath: path || this.resourcePath || '',\n\t\t\tcrossOrigin: this.crossOrigin,\n\t\t\trequestHeader: this.requestHeader,\n\t\t\tmanager: this.manager,\n\t\t\tktx2Loader: this.ktx2Loader,\n\t\t\tmeshoptDecoder: this.meshoptDecoder\n\n\t\t} );\n\n\t\tparser.fileLoader.setRequestHeader( this.requestHeader );\n\n\t\tfor ( let i = 0; i < this.pluginCallbacks.length; i ++ ) {\n\n\t\t\tconst plugin = this.pluginCallbacks[ i ]( parser );\n\t\t\tplugins[ plugin.name ] = plugin;\n\n\t\t\t// Workaround to avoid determining as unknown extension\n\t\t\t// in addUnknownExtensionsToUserData().\n\t\t\t// Remove this workaround if we move all the existing\n\t\t\t// extension handlers to plugin system\n\t\t\textensions[ plugin.name ] = true;\n\n\t\t}\n\n\t\tif ( json.extensionsUsed ) {\n\n\t\t\tfor ( let i = 0; i < json.extensionsUsed.length; ++ i ) {\n\n\t\t\t\tconst extensionName = json.extensionsUsed[ i ];\n\t\t\t\tconst extensionsRequired = json.extensionsRequired || [];\n\n\t\t\t\tswitch ( extensionName ) {\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MATERIALS_UNLIT:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMaterialsUnlitExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_TEXTURE_TRANSFORM:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFTextureTransformExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase EXTENSIONS.KHR_MESH_QUANTIZATION:\n\t\t\t\t\t\textensions[ extensionName ] = new GLTFMeshQuantizationExtension();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Unknown extension \"' + extensionName + '\".' );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tparser.setExtensions( extensions );\n\t\tparser.setPlugins( plugins );\n\t\tparser.parse( onLoad, onError );\n\n\t}\n\n\tparseAsync( data, path ) {\n\n\t\tconst scope = this;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tscope.parse( data, path, resolve, reject );\n\n\t\t} );\n\n\t}\n\n}\n\n/* GLTFREGISTRY */\n\nfunction GLTFRegistry() {\n\n\tlet objects = {};\n\n\treturn\t{\n\n\t\tget: function ( key ) {\n\n\t\t\treturn objects[ key ];\n\n\t\t},\n\n\t\tadd: function ( key, object ) {\n\n\t\t\tobjects[ key ] = object;\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete objects[ key ];\n\n\t\t},\n\n\t\tremoveAll: function () {\n\n\t\t\tobjects = {};\n\n\t\t}\n\n\t};\n\n}\n\n/*********************************/\n/********** EXTENSIONS ***********/\n/*********************************/\n\nconst EXTENSIONS = {\n\tKHR_BINARY_GLTF: 'KHR_binary_glTF',\n\tKHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',\n\tKHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',\n\tKHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',\n\tKHR_MATERIALS_IOR: 'KHR_materials_ior',\n\tKHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',\n\tKHR_MATERIALS_SHEEN: 'KHR_materials_sheen',\n\tKHR_MATERIALS_SPECULAR: 'KHR_materials_specular',\n\tKHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',\n\tKHR_MATERIALS_IRIDESCENCE: 'KHR_materials_iridescence',\n\tKHR_MATERIALS_UNLIT: 'KHR_materials_unlit',\n\tKHR_MATERIALS_VOLUME: 'KHR_materials_volume',\n\tKHR_TEXTURE_BASISU: 'KHR_texture_basisu',\n\tKHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',\n\tKHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',\n\tKHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',\n\tEXT_TEXTURE_WEBP: 'EXT_texture_webp',\n\tEXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression'\n};\n\n/**\n * Punctual Lights Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual\n */\nclass GLTFLightsExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;\n\n\t\t// Object3D instance caches\n\t\tthis.cache = { refs: {}, uses: {} };\n\n\t}\n\n\t_markDefs() {\n\n\t\tconst parser = this.parser;\n\t\tconst nodeDefs = this.parser.json.nodes || [];\n\n\t\tfor ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {\n\n\t\t\tconst nodeDef = nodeDefs[ nodeIndex ];\n\n\t\t\tif ( nodeDef.extensions\n\t\t\t\t\t&& nodeDef.extensions[ this.name ]\n\t\t\t\t\t&& nodeDef.extensions[ this.name ].light !== undefined ) {\n\n\t\t\t\tparser._addNodeRef( this.cache, nodeDef.extensions[ this.name ].light );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t_loadLight( lightIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst cacheKey = 'light:' + lightIndex;\n\t\tlet dependency = parser.cache.get( cacheKey );\n\n\t\tif ( dependency ) return dependency;\n\n\t\tconst json = parser.json;\n\t\tconst extensions = ( json.extensions && json.extensions[ this.name ] ) || {};\n\t\tconst lightDefs = extensions.lights || [];\n\t\tconst lightDef = lightDefs[ lightIndex ];\n\t\tlet lightNode;\n\n\t\tconst color = new Color( 0xffffff );\n\n\t\tif ( lightDef.color !== undefined ) color.fromArray( lightDef.color );\n\n\t\tconst range = lightDef.range !== undefined ? lightDef.range : 0;\n\n\t\tswitch ( lightDef.type ) {\n\n\t\t\tcase 'directional':\n\t\t\t\tlightNode = new DirectionalLight( color );\n\t\t\t\tlightNode.target.position.set( 0, 0, - 1 );\n\t\t\t\tlightNode.add( lightNode.target );\n\t\t\t\tbreak;\n\n\t\t\tcase 'point':\n\t\t\t\tlightNode = new PointLight( color );\n\t\t\t\tlightNode.distance = range;\n\t\t\t\tbreak;\n\n\t\t\tcase 'spot':\n\t\t\t\tlightNode = new SpotLight( color );\n\t\t\t\tlightNode.distance = range;\n\t\t\t\t// Handle spotlight properties.\n\t\t\t\tlightDef.spot = lightDef.spot || {};\n\t\t\t\tlightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;\n\t\t\t\tlightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;\n\t\t\t\tlightNode.angle = lightDef.spot.outerConeAngle;\n\t\t\t\tlightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;\n\t\t\t\tlightNode.target.position.set( 0, 0, - 1 );\n\t\t\t\tlightNode.add( lightNode.target );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: Unexpected light type: ' + lightDef.type );\n\n\t\t}\n\n\t\t// Some lights (e.g. spot) default to a position other than the origin. Reset the position\n\t\t// here, because node-level parsing will only override position if explicitly specified.\n\t\tlightNode.position.set( 0, 0, 0 );\n\n\t\tlightNode.decay = 2;\n\n\t\tif ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;\n\n\t\tlightNode.name = parser.createUniqueName( lightDef.name || ( 'light_' + lightIndex ) );\n\n\t\tdependency = Promise.resolve( lightNode );\n\n\t\tparser.cache.add( cacheKey, dependency );\n\n\t\treturn dependency;\n\n\t}\n\n\tcreateNodeAttachment( nodeIndex ) {\n\n\t\tconst self = this;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\t\tconst lightDef = ( nodeDef.extensions && nodeDef.extensions[ this.name ] ) || {};\n\t\tconst lightIndex = lightDef.light;\n\n\t\tif ( lightIndex === undefined ) return null;\n\n\t\treturn this._loadLight( lightIndex ).then( function ( light ) {\n\n\t\t\treturn parser._getNodeRef( self.cache, lightIndex, light );\n\n\t\t} );\n\n\t}\n\n}\n\n/**\n * Unlit Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit\n */\nclass GLTFMaterialsUnlitExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_UNLIT;\n\n\t}\n\n\tgetMaterialType() {\n\n\t\treturn MeshBasicMaterial;\n\n\t}\n\n\textendParams( materialParams, materialDef, parser ) {\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\tmaterialParams.opacity = 1.0;\n\n\t\tconst metallicRoughness = materialDef.pbrMetallicRoughness;\n\n\t\tif ( metallicRoughness ) {\n\n\t\t\tif ( Array.isArray( metallicRoughness.baseColorFactor ) ) {\n\n\t\t\t\tconst array = metallicRoughness.baseColorFactor;\n\n\t\t\t\tmaterialParams.color.fromArray( array );\n\t\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t\t}\n\n\t\t\tif ( metallicRoughness.baseColorTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, sRGBEncoding ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials Emissive Strength Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md\n */\nclass GLTFMaterialsEmissiveStrengthExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst emissiveStrength = materialDef.extensions[ this.name ].emissiveStrength;\n\n\t\tif ( emissiveStrength !== undefined ) {\n\n\t\t\tmaterialParams.emissiveIntensity = emissiveStrength;\n\n\t\t}\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Clearcoat Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat\n */\nclass GLTFMaterialsClearcoatExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.clearcoatFactor !== undefined ) {\n\n\t\t\tmaterialParams.clearcoat = extension.clearcoatFactor;\n\n\t\t}\n\n\t\tif ( extension.clearcoatTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );\n\n\t\t}\n\n\t\tif ( extension.clearcoatRoughnessFactor !== undefined ) {\n\n\t\t\tmaterialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;\n\n\t\t}\n\n\t\tif ( extension.clearcoatRoughnessTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );\n\n\t\t}\n\n\t\tif ( extension.clearcoatNormalTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );\n\n\t\t\tif ( extension.clearcoatNormalTexture.scale !== undefined ) {\n\n\t\t\t\tconst scale = extension.clearcoatNormalTexture.scale;\n\n\t\t\t\tmaterialParams.clearcoatNormalScale = new Vector2( scale, scale );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Iridescence Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence\n */\nclass GLTFMaterialsIridescenceExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.iridescenceFactor !== undefined ) {\n\n\t\t\tmaterialParams.iridescence = extension.iridescenceFactor;\n\n\t\t}\n\n\t\tif ( extension.iridescenceTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'iridescenceMap', extension.iridescenceTexture ) );\n\n\t\t}\n\n\t\tif ( extension.iridescenceIor !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceIOR = extension.iridescenceIor;\n\n\t\t}\n\n\t\tif ( materialParams.iridescenceThicknessRange === undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange = [ 100, 400 ];\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessMinimum !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange[ 0 ] = extension.iridescenceThicknessMinimum;\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessMaximum !== undefined ) {\n\n\t\t\tmaterialParams.iridescenceThicknessRange[ 1 ] = extension.iridescenceThicknessMaximum;\n\n\t\t}\n\n\t\tif ( extension.iridescenceThicknessTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Sheen Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen\n */\nclass GLTFMaterialsSheenExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_SHEEN;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tmaterialParams.sheenColor = new Color( 0, 0, 0 );\n\t\tmaterialParams.sheenRoughness = 0;\n\t\tmaterialParams.sheen = 1;\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.sheenColorFactor !== undefined ) {\n\n\t\t\tmaterialParams.sheenColor.fromArray( extension.sheenColorFactor );\n\n\t\t}\n\n\t\tif ( extension.sheenRoughnessFactor !== undefined ) {\n\n\t\t\tmaterialParams.sheenRoughness = extension.sheenRoughnessFactor;\n\n\t\t}\n\n\t\tif ( extension.sheenColorTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'sheenColorMap', extension.sheenColorTexture, sRGBEncoding ) );\n\n\t\t}\n\n\t\tif ( extension.sheenRoughnessTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'sheenRoughnessMap', extension.sheenRoughnessTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Transmission Materials Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission\n * Draft: https://github.com/KhronosGroup/glTF/pull/1698\n */\nclass GLTFMaterialsTransmissionExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tif ( extension.transmissionFactor !== undefined ) {\n\n\t\t\tmaterialParams.transmission = extension.transmissionFactor;\n\n\t\t}\n\n\t\tif ( extension.transmissionTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'transmissionMap', extension.transmissionTexture ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials Volume Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume\n */\nclass GLTFMaterialsVolumeExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_VOLUME;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0;\n\n\t\tif ( extension.thicknessTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'thicknessMap', extension.thicknessTexture ) );\n\n\t\t}\n\n\t\tmaterialParams.attenuationDistance = extension.attenuationDistance || 0;\n\n\t\tconst colorArray = extension.attenuationColor || [ 1, 1, 1 ];\n\t\tmaterialParams.attenuationColor = new Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] );\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * Materials ior Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior\n */\nclass GLTFMaterialsIorExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_IOR;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.ior = extension.ior !== undefined ? extension.ior : 1.5;\n\n\t\treturn Promise.resolve();\n\n\t}\n\n}\n\n/**\n * Materials specular Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular\n */\nclass GLTFMaterialsSpecularExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_SPECULAR;\n\n\t}\n\n\tgetMaterialType( materialIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;\n\n\t\treturn MeshPhysicalMaterial;\n\n\t}\n\n\textendMaterialParams( materialIndex, materialParams ) {\n\n\t\tconst parser = this.parser;\n\t\tconst materialDef = parser.json.materials[ materialIndex ];\n\n\t\tif ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {\n\n\t\t\treturn Promise.resolve();\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tconst extension = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0;\n\n\t\tif ( extension.specularTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'specularIntensityMap', extension.specularTexture ) );\n\n\t\t}\n\n\t\tconst colorArray = extension.specularColorFactor || [ 1, 1, 1 ];\n\t\tmaterialParams.specularColor = new Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] );\n\n\t\tif ( extension.specularColorTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, sRGBEncoding ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n}\n\n/**\n * BasisU Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu\n */\nclass GLTFTextureBasisUExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.KHR_TEXTURE_BASISU;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ this.name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ this.name ];\n\t\tconst loader = parser.options.ktx2Loader;\n\n\t\tif ( ! loader ) {\n\n\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {\n\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures' );\n\n\t\t\t} else {\n\n\t\t\t\t// Assumes that the extension is optional and that a fallback texture is present\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t}\n\n}\n\n/**\n * WebP Texture Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp\n */\nclass GLTFTextureWebPExtension {\n\n\tconstructor( parser ) {\n\n\t\tthis.parser = parser;\n\t\tthis.name = EXTENSIONS.EXT_TEXTURE_WEBP;\n\t\tthis.isSupported = null;\n\n\t}\n\n\tloadTexture( textureIndex ) {\n\n\t\tconst name = this.name;\n\t\tconst parser = this.parser;\n\t\tconst json = parser.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\n\t\tif ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t\tconst extension = textureDef.extensions[ name ];\n\t\tconst source = json.images[ extension.source ];\n\n\t\tlet loader = parser.textureLoader;\n\t\tif ( source.uri ) {\n\n\t\t\tconst handler = parser.options.manager.getHandler( source.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn this.detectSupport().then( function ( isSupported ) {\n\n\t\t\tif ( isSupported ) return parser.loadTextureImage( textureIndex, extension.source, loader );\n\n\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( name ) >= 0 ) {\n\n\t\t\t\tthrow new Error( 'THREE.GLTFLoader: WebP required by asset but unsupported.' );\n\n\t\t\t}\n\n\t\t\t// Fall back to PNG or JPEG.\n\t\t\treturn parser.loadTexture( textureIndex );\n\n\t\t} );\n\n\t}\n\n\tdetectSupport() {\n\n\t\tif ( ! this.isSupported ) {\n\n\t\t\tthis.isSupported = new Promise( function ( resolve ) {\n\n\t\t\t\tconst image = new Image();\n\n\t\t\t\t// Lossy test image. Support for lossy images doesn't guarantee support for all\n\t\t\t\t// WebP images, unfortunately.\n\t\t\t\timage.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';\n\n\t\t\t\timage.onload = image.onerror = function () {\n\n\t\t\t\t\tresolve( image.height === 1 );\n\n\t\t\t\t};\n\n\t\t\t} );\n\n\t\t}\n\n\t\treturn this.isSupported;\n\n\t}\n\n}\n\n/**\n * meshopt BufferView Compression Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression\n */\nclass GLTFMeshoptCompression {\n\n\tconstructor( parser ) {\n\n\t\tthis.name = EXTENSIONS.EXT_MESHOPT_COMPRESSION;\n\t\tthis.parser = parser;\n\n\t}\n\n\tloadBufferView( index ) {\n\n\t\tconst json = this.parser.json;\n\t\tconst bufferView = json.bufferViews[ index ];\n\n\t\tif ( bufferView.extensions && bufferView.extensions[ this.name ] ) {\n\n\t\t\tconst extensionDef = bufferView.extensions[ this.name ];\n\n\t\t\tconst buffer = this.parser.getDependency( 'buffer', extensionDef.buffer );\n\t\t\tconst decoder = this.parser.options.meshoptDecoder;\n\n\t\t\tif ( ! decoder || ! decoder.supported ) {\n\n\t\t\t\tif ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {\n\n\t\t\t\t\tthrow new Error( 'THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files' );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Assumes that the extension is optional and that fallback buffer data is present\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn Promise.all( [ buffer, decoder.ready ] ).then( function ( res ) {\n\n\t\t\t\tconst byteOffset = extensionDef.byteOffset || 0;\n\t\t\t\tconst byteLength = extensionDef.byteLength || 0;\n\n\t\t\t\tconst count = extensionDef.count;\n\t\t\t\tconst stride = extensionDef.byteStride;\n\n\t\t\t\tconst result = new ArrayBuffer( count * stride );\n\t\t\t\tconst source = new Uint8Array( res[ 0 ], byteOffset, byteLength );\n\n\t\t\t\tdecoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter );\n\t\t\t\treturn result;\n\n\t\t\t} );\n\n\t\t} else {\n\n\t\t\treturn null;\n\n\t\t}\n\n\t}\n\n}\n\n/* BINARY EXTENSION */\nconst BINARY_EXTENSION_HEADER_MAGIC = 'glTF';\nconst BINARY_EXTENSION_HEADER_LENGTH = 12;\nconst BINARY_EXTENSION_CHUNK_TYPES = { JSON: 0x4E4F534A, BIN: 0x004E4942 };\n\nclass GLTFBinaryExtension {\n\n\tconstructor( data ) {\n\n\t\tthis.name = EXTENSIONS.KHR_BINARY_GLTF;\n\t\tthis.content = null;\n\t\tthis.body = null;\n\n\t\tconst headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH );\n\n\t\tthis.header = {\n\t\t\tmagic: LoaderUtils.decodeText( new Uint8Array( data.slice( 0, 4 ) ) ),\n\t\t\tversion: headerView.getUint32( 4, true ),\n\t\t\tlength: headerView.getUint32( 8, true )\n\t\t};\n\n\t\tif ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' );\n\n\t\t} else if ( this.header.version < 2.0 ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Legacy binary file detected.' );\n\n\t\t}\n\n\t\tconst chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH;\n\t\tconst chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH );\n\t\tlet chunkIndex = 0;\n\n\t\twhile ( chunkIndex < chunkContentsLength ) {\n\n\t\t\tconst chunkLength = chunkView.getUint32( chunkIndex, true );\n\t\t\tchunkIndex += 4;\n\n\t\t\tconst chunkType = chunkView.getUint32( chunkIndex, true );\n\t\t\tchunkIndex += 4;\n\n\t\t\tif ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) {\n\n\t\t\t\tconst contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength );\n\t\t\t\tthis.content = LoaderUtils.decodeText( contentArray );\n\n\t\t\t} else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) {\n\n\t\t\t\tconst byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;\n\t\t\t\tthis.body = data.slice( byteOffset, byteOffset + chunkLength );\n\n\t\t\t}\n\n\t\t\t// Clients must ignore chunks with unknown types.\n\n\t\t\tchunkIndex += chunkLength;\n\n\t\t}\n\n\t\tif ( this.content === null ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: JSON content not found.' );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * DRACO Mesh Compression Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression\n */\nclass GLTFDracoMeshCompressionExtension {\n\n\tconstructor( json, dracoLoader ) {\n\n\t\tif ( ! dracoLoader ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' );\n\n\t\t}\n\n\t\tthis.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;\n\t\tthis.json = json;\n\t\tthis.dracoLoader = dracoLoader;\n\t\tthis.dracoLoader.preload();\n\n\t}\n\n\tdecodePrimitive( primitive, parser ) {\n\n\t\tconst json = this.json;\n\t\tconst dracoLoader = this.dracoLoader;\n\t\tconst bufferViewIndex = primitive.extensions[ this.name ].bufferView;\n\t\tconst gltfAttributeMap = primitive.extensions[ this.name ].attributes;\n\t\tconst threeAttributeMap = {};\n\t\tconst attributeNormalizedMap = {};\n\t\tconst attributeTypeMap = {};\n\n\t\tfor ( const attributeName in gltfAttributeMap ) {\n\n\t\t\tconst threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();\n\n\t\t\tthreeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];\n\n\t\t}\n\n\t\tfor ( const attributeName in primitive.attributes ) {\n\n\t\t\tconst threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();\n\n\t\t\tif ( gltfAttributeMap[ attributeName ] !== undefined ) {\n\n\t\t\t\tconst accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];\n\t\t\t\tconst componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\n\t\t\t\tattributeTypeMap[ threeAttributeName ] = componentType;\n\t\t\t\tattributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) {\n\n\t\t\treturn new Promise( function ( resolve ) {\n\n\t\t\t\tdracoLoader.decodeDracoFile( bufferView, function ( geometry ) {\n\n\t\t\t\t\tfor ( const attributeName in geometry.attributes ) {\n\n\t\t\t\t\t\tconst attribute = geometry.attributes[ attributeName ];\n\t\t\t\t\t\tconst normalized = attributeNormalizedMap[ attributeName ];\n\n\t\t\t\t\t\tif ( normalized !== undefined ) attribute.normalized = normalized;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve( geometry );\n\n\t\t\t\t}, threeAttributeMap, attributeTypeMap );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n}\n\n/**\n * Texture Transform Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform\n */\nclass GLTFTextureTransformExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;\n\n\t}\n\n\textendTexture( texture, transform ) {\n\n\t\tif ( transform.texCoord !== undefined ) {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Custom UV sets in \"' + this.name + '\" extension not yet supported.' );\n\n\t\t}\n\n\t\tif ( transform.offset === undefined && transform.rotation === undefined && transform.scale === undefined ) {\n\n\t\t\t// See https://github.com/mrdoob/three.js/issues/21819.\n\t\t\treturn texture;\n\n\t\t}\n\n\t\ttexture = texture.clone();\n\n\t\tif ( transform.offset !== undefined ) {\n\n\t\t\ttexture.offset.fromArray( transform.offset );\n\n\t\t}\n\n\t\tif ( transform.rotation !== undefined ) {\n\n\t\t\ttexture.rotation = transform.rotation;\n\n\t\t}\n\n\t\tif ( transform.scale !== undefined ) {\n\n\t\t\ttexture.repeat.fromArray( transform.scale );\n\n\t\t}\n\n\t\ttexture.needsUpdate = true;\n\n\t\treturn texture;\n\n\t}\n\n}\n\n/**\n * Specular-Glossiness Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness\n */\n\n/**\n * A sub class of StandardMaterial with some of the functionality\n * changed via the `onBeforeCompile` callback\n * @pailhead\n */\nclass GLTFMeshStandardSGMaterial extends MeshStandardMaterial {\n\n\tconstructor( params ) {\n\n\t\tsuper();\n\n\t\tthis.isGLTFSpecularGlossinessMaterial = true;\n\n\t\t//various chunks that need replacing\n\t\tconst specularMapParsFragmentChunk = [\n\t\t\t'#ifdef USE_SPECULARMAP',\n\t\t\t'\tuniform sampler2D specularMap;',\n\t\t\t'#endif'\n\t\t].join( '\\n' );\n\n\t\tconst glossinessMapParsFragmentChunk = [\n\t\t\t'#ifdef USE_GLOSSINESSMAP',\n\t\t\t'\tuniform sampler2D glossinessMap;',\n\t\t\t'#endif'\n\t\t].join( '\\n' );\n\n\t\tconst specularMapFragmentChunk = [\n\t\t\t'vec3 specularFactor = specular;',\n\t\t\t'#ifdef USE_SPECULARMAP',\n\t\t\t'\tvec4 texelSpecular = texture2D( specularMap, vUv );',\n\t\t\t'\t// reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture',\n\t\t\t'\tspecularFactor *= texelSpecular.rgb;',\n\t\t\t'#endif'\n\t\t].join( '\\n' );\n\n\t\tconst glossinessMapFragmentChunk = [\n\t\t\t'float glossinessFactor = glossiness;',\n\t\t\t'#ifdef USE_GLOSSINESSMAP',\n\t\t\t'\tvec4 texelGlossiness = texture2D( glossinessMap, vUv );',\n\t\t\t'\t// reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture',\n\t\t\t'\tglossinessFactor *= texelGlossiness.a;',\n\t\t\t'#endif'\n\t\t].join( '\\n' );\n\n\t\tconst lightPhysicalFragmentChunk = [\n\t\t\t'PhysicalMaterial material;',\n\t\t\t'material.diffuseColor = diffuseColor.rgb * ( 1. - max( specularFactor.r, max( specularFactor.g, specularFactor.b ) ) );',\n\t\t\t'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );',\n\t\t\t'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );',\n\t\t\t'material.roughness = max( 1.0 - glossinessFactor, 0.0525 ); // 0.0525 corresponds to the base mip of a 256 cubemap.',\n\t\t\t'material.roughness += geometryRoughness;',\n\t\t\t'material.roughness = min( material.roughness, 1.0 );',\n\t\t\t'material.specularColor = specularFactor;',\n\t\t].join( '\\n' );\n\n\t\tconst uniforms = {\n\t\t\tspecular: { value: new Color().setHex( 0xffffff ) },\n\t\t\tglossiness: { value: 1 },\n\t\t\tspecularMap: { value: null },\n\t\t\tglossinessMap: { value: null }\n\t\t};\n\n\t\tthis._extraUniforms = uniforms;\n\n\t\tthis.onBeforeCompile = function ( shader ) {\n\n\t\t\tfor ( const uniformName in uniforms ) {\n\n\t\t\t\tshader.uniforms[ uniformName ] = uniforms[ uniformName ];\n\n\t\t\t}\n\n\t\t\tshader.fragmentShader = shader.fragmentShader\n\t\t\t\t.replace( 'uniform float roughness;', 'uniform vec3 specular;' )\n\t\t\t\t.replace( 'uniform float metalness;', 'uniform float glossiness;' )\n\t\t\t\t.replace( '#include ', specularMapParsFragmentChunk )\n\t\t\t\t.replace( '#include ', glossinessMapParsFragmentChunk )\n\t\t\t\t.replace( '#include ', specularMapFragmentChunk )\n\t\t\t\t.replace( '#include ', glossinessMapFragmentChunk )\n\t\t\t\t.replace( '#include ', lightPhysicalFragmentChunk );\n\n\t\t};\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tspecular: {\n\t\t\t\tget: function () {\n\n\t\t\t\t\treturn uniforms.specular.value;\n\n\t\t\t\t},\n\t\t\t\tset: function ( v ) {\n\n\t\t\t\t\tuniforms.specular.value = v;\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tspecularMap: {\n\t\t\t\tget: function () {\n\n\t\t\t\t\treturn uniforms.specularMap.value;\n\n\t\t\t\t},\n\t\t\t\tset: function ( v ) {\n\n\t\t\t\t\tuniforms.specularMap.value = v;\n\n\t\t\t\t\tif ( v ) {\n\n\t\t\t\t\t\tthis.defines.USE_SPECULARMAP = ''; // USE_UV is set by the renderer for specular maps\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdelete this.defines.USE_SPECULARMAP;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tglossiness: {\n\t\t\t\tget: function () {\n\n\t\t\t\t\treturn uniforms.glossiness.value;\n\n\t\t\t\t},\n\t\t\t\tset: function ( v ) {\n\n\t\t\t\t\tuniforms.glossiness.value = v;\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tglossinessMap: {\n\t\t\t\tget: function () {\n\n\t\t\t\t\treturn uniforms.glossinessMap.value;\n\n\t\t\t\t},\n\t\t\t\tset: function ( v ) {\n\n\t\t\t\t\tuniforms.glossinessMap.value = v;\n\n\t\t\t\t\tif ( v ) {\n\n\t\t\t\t\t\tthis.defines.USE_GLOSSINESSMAP = '';\n\t\t\t\t\t\tthis.defines.USE_UV = '';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdelete this.defines.USE_GLOSSINESSMAP;\n\t\t\t\t\t\tdelete this.defines.USE_UV;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\t\tdelete this.metalness;\n\t\tdelete this.roughness;\n\t\tdelete this.metalnessMap;\n\t\tdelete this.roughnessMap;\n\n\t\tthis.setValues( params );\n\n\t}\n\n\tcopy( source ) {\n\n\t\tsuper.copy( source );\n\n\t\tthis.specularMap = source.specularMap;\n\t\tthis.specular.copy( source.specular );\n\t\tthis.glossinessMap = source.glossinessMap;\n\t\tthis.glossiness = source.glossiness;\n\t\tdelete this.metalness;\n\t\tdelete this.roughness;\n\t\tdelete this.metalnessMap;\n\t\tdelete this.roughnessMap;\n\t\treturn this;\n\n\t}\n\n}\n\n\nclass GLTFMaterialsPbrSpecularGlossinessExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS;\n\n\t\tthis.specularGlossinessParams = [\n\t\t\t'color',\n\t\t\t'map',\n\t\t\t'lightMap',\n\t\t\t'lightMapIntensity',\n\t\t\t'aoMap',\n\t\t\t'aoMapIntensity',\n\t\t\t'emissive',\n\t\t\t'emissiveIntensity',\n\t\t\t'emissiveMap',\n\t\t\t'bumpMap',\n\t\t\t'bumpScale',\n\t\t\t'normalMap',\n\t\t\t'normalMapType',\n\t\t\t'displacementMap',\n\t\t\t'displacementScale',\n\t\t\t'displacementBias',\n\t\t\t'specularMap',\n\t\t\t'specular',\n\t\t\t'glossinessMap',\n\t\t\t'glossiness',\n\t\t\t'alphaMap',\n\t\t\t'envMap',\n\t\t\t'envMapIntensity'\n\t\t];\n\n\t}\n\n\tgetMaterialType() {\n\n\t\treturn GLTFMeshStandardSGMaterial;\n\n\t}\n\n\textendParams( materialParams, materialDef, parser ) {\n\n\t\tconst pbrSpecularGlossiness = materialDef.extensions[ this.name ];\n\n\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\tmaterialParams.opacity = 1.0;\n\n\t\tconst pending = [];\n\n\t\tif ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) {\n\n\t\t\tconst array = pbrSpecularGlossiness.diffuseFactor;\n\n\t\t\tmaterialParams.color.fromArray( array );\n\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t}\n\n\t\tif ( pbrSpecularGlossiness.diffuseTexture !== undefined ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture, sRGBEncoding ) );\n\n\t\t}\n\n\t\tmaterialParams.emissive = new Color( 0.0, 0.0, 0.0 );\n\t\tmaterialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0;\n\t\tmaterialParams.specular = new Color( 1.0, 1.0, 1.0 );\n\n\t\tif ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) {\n\n\t\t\tmaterialParams.specular.fromArray( pbrSpecularGlossiness.specularFactor );\n\n\t\t}\n\n\t\tif ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) {\n\n\t\t\tconst specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture;\n\t\t\tpending.push( parser.assignTexture( materialParams, 'glossinessMap', specGlossMapDef ) );\n\t\t\tpending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef, sRGBEncoding ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n\tcreateMaterial( materialParams ) {\n\n\t\tconst material = new GLTFMeshStandardSGMaterial( materialParams );\n\t\tmaterial.fog = true;\n\n\t\tmaterial.color = materialParams.color;\n\n\t\tmaterial.map = materialParams.map === undefined ? null : materialParams.map;\n\n\t\tmaterial.lightMap = null;\n\t\tmaterial.lightMapIntensity = 1.0;\n\n\t\tmaterial.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap;\n\t\tmaterial.aoMapIntensity = 1.0;\n\n\t\tmaterial.emissive = materialParams.emissive;\n\t\tmaterial.emissiveIntensity = materialParams.emissiveIntensity === undefined ? 1.0 : materialParams.emissiveIntensity;\n\t\tmaterial.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap;\n\n\t\tmaterial.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap;\n\t\tmaterial.bumpScale = 1;\n\n\t\tmaterial.normalMap = materialParams.normalMap === undefined ? null : materialParams.normalMap;\n\t\tmaterial.normalMapType = TangentSpaceNormalMap;\n\n\t\tif ( materialParams.normalScale ) material.normalScale = materialParams.normalScale;\n\n\t\tmaterial.displacementMap = null;\n\t\tmaterial.displacementScale = 1;\n\t\tmaterial.displacementBias = 0;\n\n\t\tmaterial.specularMap = materialParams.specularMap === undefined ? null : materialParams.specularMap;\n\t\tmaterial.specular = materialParams.specular;\n\n\t\tmaterial.glossinessMap = materialParams.glossinessMap === undefined ? null : materialParams.glossinessMap;\n\t\tmaterial.glossiness = materialParams.glossiness;\n\n\t\tmaterial.alphaMap = null;\n\n\t\tmaterial.envMap = materialParams.envMap === undefined ? null : materialParams.envMap;\n\t\tmaterial.envMapIntensity = 1.0;\n\n\t\treturn material;\n\n\t}\n\n}\n\n/**\n * Mesh Quantization Extension\n *\n * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization\n */\nclass GLTFMeshQuantizationExtension {\n\n\tconstructor() {\n\n\t\tthis.name = EXTENSIONS.KHR_MESH_QUANTIZATION;\n\n\t}\n\n}\n\n/*********************************/\n/********** INTERPOLATION ********/\n/*********************************/\n\n// Spline Interpolation\n// Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation\nclass GLTFCubicSplineInterpolant extends Interpolant {\n\n\tconstructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tsuper( parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tcopySampleValue_( index ) {\n\n\t\t// Copies a sample value to the result buffer. See description of glTF\n\t\t// CUBICSPLINE values layout in interpolate_() function below.\n\n\t\tconst result = this.resultBuffer,\n\t\t\tvalues = this.sampleValues,\n\t\t\tvalueSize = this.valueSize,\n\t\t\toffset = index * valueSize * 3 + valueSize;\n\n\t\tfor ( let i = 0; i !== valueSize; i ++ ) {\n\n\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t}\n\n\t\treturn result;\n\n\t}\n\n}\n\nGLTFCubicSplineInterpolant.prototype.interpolate_ = function ( i1, t0, t, t1 ) {\n\n\tconst result = this.resultBuffer;\n\tconst values = this.sampleValues;\n\tconst stride = this.valueSize;\n\n\tconst stride2 = stride * 2;\n\tconst stride3 = stride * 3;\n\n\tconst td = t1 - t0;\n\n\tconst p = ( t - t0 ) / td;\n\tconst pp = p * p;\n\tconst ppp = pp * p;\n\n\tconst offset1 = i1 * stride3;\n\tconst offset0 = offset1 - stride3;\n\n\tconst s2 = - 2 * ppp + 3 * pp;\n\tconst s3 = ppp - pp;\n\tconst s0 = 1 - s2;\n\tconst s1 = s3 - pp + p;\n\n\t// Layout of keyframe output values for CUBICSPLINE animations:\n\t// [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]\n\tfor ( let i = 0; i !== stride; i ++ ) {\n\n\t\tconst p0 = values[ offset0 + i + stride ]; // splineVertex_k\n\t\tconst m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)\n\t\tconst p1 = values[ offset1 + i + stride ]; // splineVertex_k+1\n\t\tconst m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)\n\n\t\tresult[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;\n\n\t}\n\n\treturn result;\n\n};\n\nconst _q = new Quaternion();\n\nclass GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant {\n\n\tinterpolate_( i1, t0, t, t1 ) {\n\n\t\tconst result = super.interpolate_( i1, t0, t, t1 );\n\n\t\t_q.fromArray( result ).normalize().toArray( result );\n\n\t\treturn result;\n\n\t}\n\n}\n\n\n/*********************************/\n/********** INTERNALS ************/\n/*********************************/\n\n/* CONSTANTS */\n\nconst WEBGL_CONSTANTS = {\n\tFLOAT: 5126,\n\t//FLOAT_MAT2: 35674,\n\tFLOAT_MAT3: 35675,\n\tFLOAT_MAT4: 35676,\n\tFLOAT_VEC2: 35664,\n\tFLOAT_VEC3: 35665,\n\tFLOAT_VEC4: 35666,\n\tLINEAR: 9729,\n\tREPEAT: 10497,\n\tSAMPLER_2D: 35678,\n\tPOINTS: 0,\n\tLINES: 1,\n\tLINE_LOOP: 2,\n\tLINE_STRIP: 3,\n\tTRIANGLES: 4,\n\tTRIANGLE_STRIP: 5,\n\tTRIANGLE_FAN: 6,\n\tUNSIGNED_BYTE: 5121,\n\tUNSIGNED_SHORT: 5123\n};\n\nconst WEBGL_COMPONENT_TYPES = {\n\t5120: Int8Array,\n\t5121: Uint8Array,\n\t5122: Int16Array,\n\t5123: Uint16Array,\n\t5125: Uint32Array,\n\t5126: Float32Array\n};\n\nconst WEBGL_FILTERS = {\n\t9728: NearestFilter,\n\t9729: LinearFilter,\n\t9984: NearestMipmapNearestFilter,\n\t9985: LinearMipmapNearestFilter,\n\t9986: NearestMipmapLinearFilter,\n\t9987: LinearMipmapLinearFilter\n};\n\nconst WEBGL_WRAPPINGS = {\n\t33071: ClampToEdgeWrapping,\n\t33648: MirroredRepeatWrapping,\n\t10497: RepeatWrapping\n};\n\nconst WEBGL_TYPE_SIZES = {\n\t'SCALAR': 1,\n\t'VEC2': 2,\n\t'VEC3': 3,\n\t'VEC4': 4,\n\t'MAT2': 4,\n\t'MAT3': 9,\n\t'MAT4': 16\n};\n\nconst ATTRIBUTES = {\n\tPOSITION: 'position',\n\tNORMAL: 'normal',\n\tTANGENT: 'tangent',\n\tTEXCOORD_0: 'uv',\n\tTEXCOORD_1: 'uv2',\n\tCOLOR_0: 'color',\n\tWEIGHTS_0: 'skinWeight',\n\tJOINTS_0: 'skinIndex',\n};\n\nconst PATH_PROPERTIES = {\n\tscale: 'scale',\n\ttranslation: 'position',\n\trotation: 'quaternion',\n\tweights: 'morphTargetInfluences'\n};\n\nconst INTERPOLATION = {\n\tCUBICSPLINE: undefined, // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each\n\t\t // keyframe track will be initialized with a default interpolation type, then modified.\n\tLINEAR: InterpolateLinear,\n\tSTEP: InterpolateDiscrete\n};\n\nconst ALPHA_MODES = {\n\tOPAQUE: 'OPAQUE',\n\tMASK: 'MASK',\n\tBLEND: 'BLEND'\n};\n\n/**\n * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material\n */\nfunction createDefaultMaterial( cache ) {\n\n\tif ( cache[ 'DefaultMaterial' ] === undefined ) {\n\n\t\tcache[ 'DefaultMaterial' ] = new MeshStandardMaterial( {\n\t\t\tcolor: 0xFFFFFF,\n\t\t\temissive: 0x000000,\n\t\t\tmetalness: 1,\n\t\t\troughness: 1,\n\t\t\ttransparent: false,\n\t\t\tdepthTest: true,\n\t\t\tside: FrontSide\n\t\t} );\n\n\t}\n\n\treturn cache[ 'DefaultMaterial' ];\n\n}\n\nfunction addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {\n\n\t// Add unknown glTF extensions to an object's userData.\n\n\tfor ( const name in objectDef.extensions ) {\n\n\t\tif ( knownExtensions[ name ] === undefined ) {\n\n\t\t\tobject.userData.gltfExtensions = object.userData.gltfExtensions || {};\n\t\t\tobject.userData.gltfExtensions[ name ] = objectDef.extensions[ name ];\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * @param {Object3D|Material|BufferGeometry} object\n * @param {GLTF.definition} gltfDef\n */\nfunction assignExtrasToUserData( object, gltfDef ) {\n\n\tif ( gltfDef.extras !== undefined ) {\n\n\t\tif ( typeof gltfDef.extras === 'object' ) {\n\n\t\t\tObject.assign( object.userData, gltfDef.extras );\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras );\n\n\t\t}\n\n\t}\n\n}\n\n/**\n * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets\n *\n * @param {BufferGeometry} geometry\n * @param {Array} targets\n * @param {GLTFParser} parser\n * @return {Promise}\n */\nfunction addMorphTargets( geometry, targets, parser ) {\n\n\tlet hasMorphPosition = false;\n\tlet hasMorphNormal = false;\n\tlet hasMorphColor = false;\n\n\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\tconst target = targets[ i ];\n\n\t\tif ( target.POSITION !== undefined ) hasMorphPosition = true;\n\t\tif ( target.NORMAL !== undefined ) hasMorphNormal = true;\n\t\tif ( target.COLOR_0 !== undefined ) hasMorphColor = true;\n\n\t\tif ( hasMorphPosition && hasMorphNormal && hasMorphColor ) break;\n\n\t}\n\n\tif ( ! hasMorphPosition && ! hasMorphNormal && ! hasMorphColor ) return Promise.resolve( geometry );\n\n\tconst pendingPositionAccessors = [];\n\tconst pendingNormalAccessors = [];\n\tconst pendingColorAccessors = [];\n\n\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\tconst target = targets[ i ];\n\n\t\tif ( hasMorphPosition ) {\n\n\t\t\tconst pendingAccessor = target.POSITION !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.POSITION )\n\t\t\t\t: geometry.attributes.position;\n\n\t\t\tpendingPositionAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t\tif ( hasMorphNormal ) {\n\n\t\t\tconst pendingAccessor = target.NORMAL !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.NORMAL )\n\t\t\t\t: geometry.attributes.normal;\n\n\t\t\tpendingNormalAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t\tif ( hasMorphColor ) {\n\n\t\t\tconst pendingAccessor = target.COLOR_0 !== undefined\n\t\t\t\t? parser.getDependency( 'accessor', target.COLOR_0 )\n\t\t\t\t: geometry.attributes.color;\n\n\t\t\tpendingColorAccessors.push( pendingAccessor );\n\n\t\t}\n\n\t}\n\n\treturn Promise.all( [\n\t\tPromise.all( pendingPositionAccessors ),\n\t\tPromise.all( pendingNormalAccessors ),\n\t\tPromise.all( pendingColorAccessors )\n\t] ).then( function ( accessors ) {\n\n\t\tconst morphPositions = accessors[ 0 ];\n\t\tconst morphNormals = accessors[ 1 ];\n\t\tconst morphColors = accessors[ 2 ];\n\n\t\tif ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions;\n\t\tif ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals;\n\t\tif ( hasMorphColor ) geometry.morphAttributes.color = morphColors;\n\t\tgeometry.morphTargetsRelative = true;\n\n\t\treturn geometry;\n\n\t} );\n\n}\n\n/**\n * @param {Mesh} mesh\n * @param {GLTF.Mesh} meshDef\n */\nfunction updateMorphTargets( mesh, meshDef ) {\n\n\tmesh.updateMorphTargets();\n\n\tif ( meshDef.weights !== undefined ) {\n\n\t\tfor ( let i = 0, il = meshDef.weights.length; i < il; i ++ ) {\n\n\t\t\tmesh.morphTargetInfluences[ i ] = meshDef.weights[ i ];\n\n\t\t}\n\n\t}\n\n\t// .extras has user-defined data, so check that .extras.targetNames is an array.\n\tif ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) {\n\n\t\tconst targetNames = meshDef.extras.targetNames;\n\n\t\tif ( mesh.morphTargetInfluences.length === targetNames.length ) {\n\n\t\t\tmesh.morphTargetDictionary = {};\n\n\t\t\tfor ( let i = 0, il = targetNames.length; i < il; i ++ ) {\n\n\t\t\t\tmesh.morphTargetDictionary[ targetNames[ i ] ] = i;\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.' );\n\n\t\t}\n\n\t}\n\n}\n\nfunction createPrimitiveKey( primitiveDef ) {\n\n\tconst dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];\n\tlet geometryKey;\n\n\tif ( dracoExtension ) {\n\n\t\tgeometryKey = 'draco:' + dracoExtension.bufferView\n\t\t\t\t+ ':' + dracoExtension.indices\n\t\t\t\t+ ':' + createAttributesKey( dracoExtension.attributes );\n\n\t} else {\n\n\t\tgeometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;\n\n\t}\n\n\treturn geometryKey;\n\n}\n\nfunction createAttributesKey( attributes ) {\n\n\tlet attributesKey = '';\n\n\tconst keys = Object.keys( attributes ).sort();\n\n\tfor ( let i = 0, il = keys.length; i < il; i ++ ) {\n\n\t\tattributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';\n\n\t}\n\n\treturn attributesKey;\n\n}\n\nfunction getNormalizedComponentScale( constructor ) {\n\n\t// Reference:\n\t// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data\n\n\tswitch ( constructor ) {\n\n\t\tcase Int8Array:\n\t\t\treturn 1 / 127;\n\n\t\tcase Uint8Array:\n\t\t\treturn 1 / 255;\n\n\t\tcase Int16Array:\n\t\t\treturn 1 / 32767;\n\n\t\tcase Uint16Array:\n\t\t\treturn 1 / 65535;\n\n\t\tdefault:\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Unsupported normalized accessor component type.' );\n\n\t}\n\n}\n\nfunction getImageURIMimeType( uri ) {\n\n\tif ( uri.search( /\\.jpe?g($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/jpeg/ ) === 0 ) return 'image/jpeg';\n\tif ( uri.search( /\\.webp($|\\?)/i ) > 0 || uri.search( /^data\\:image\\/webp/ ) === 0 ) return 'image/webp';\n\n\treturn 'image/png';\n\n}\n\n/* GLTF PARSER */\n\nclass GLTFParser {\n\n\tconstructor( json = {}, options = {} ) {\n\n\t\tthis.json = json;\n\t\tthis.extensions = {};\n\t\tthis.plugins = {};\n\t\tthis.options = options;\n\n\t\t// loader object cache\n\t\tthis.cache = new GLTFRegistry();\n\n\t\t// associations between Three.js objects and glTF elements\n\t\tthis.associations = new Map();\n\n\t\t// BufferGeometry caching\n\t\tthis.primitiveCache = {};\n\n\t\t// Object3D instance caches\n\t\tthis.meshCache = { refs: {}, uses: {} };\n\t\tthis.cameraCache = { refs: {}, uses: {} };\n\t\tthis.lightCache = { refs: {}, uses: {} };\n\n\t\tthis.sourceCache = {};\n\t\tthis.textureCache = {};\n\n\t\t// Track node names, to ensure no duplicates\n\t\tthis.nodeNamesUsed = {};\n\n\t\t// Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the\n\t\t// expensive work of uploading a texture to the GPU off the main thread.\n\n\t\tconst isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true;\n\t\tconst isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1;\n\t\tconst firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\\/([0-9]+)\\./ )[ 1 ] : - 1;\n\n\t\tif ( typeof createImageBitmap === 'undefined' || isSafari || ( isFirefox && firefoxVersion < 98 ) ) {\n\n\t\t\tthis.textureLoader = new TextureLoader( this.options.manager );\n\n\t\t} else {\n\n\t\t\tthis.textureLoader = new ImageBitmapLoader( this.options.manager );\n\n\t\t}\n\n\t\tthis.textureLoader.setCrossOrigin( this.options.crossOrigin );\n\t\tthis.textureLoader.setRequestHeader( this.options.requestHeader );\n\n\t\tthis.fileLoader = new FileLoader( this.options.manager );\n\t\tthis.fileLoader.setResponseType( 'arraybuffer' );\n\n\t\tif ( this.options.crossOrigin === 'use-credentials' ) {\n\n\t\t\tthis.fileLoader.setWithCredentials( true );\n\n\t\t}\n\n\t}\n\n\tsetExtensions( extensions ) {\n\n\t\tthis.extensions = extensions;\n\n\t}\n\n\tsetPlugins( plugins ) {\n\n\t\tthis.plugins = plugins;\n\n\t}\n\n\tparse( onLoad, onError ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\n\t\t// Clear the loader cache\n\t\tthis.cache.removeAll();\n\n\t\t// Mark the special nodes/meshes in json for efficient parse\n\t\tthis._invokeAll( function ( ext ) {\n\n\t\t\treturn ext._markDefs && ext._markDefs();\n\n\t\t} );\n\n\t\tPromise.all( this._invokeAll( function ( ext ) {\n\n\t\t\treturn ext.beforeRoot && ext.beforeRoot();\n\n\t\t} ) ).then( function () {\n\n\t\t\treturn Promise.all( [\n\n\t\t\t\tparser.getDependencies( 'scene' ),\n\t\t\t\tparser.getDependencies( 'animation' ),\n\t\t\t\tparser.getDependencies( 'camera' ),\n\n\t\t\t] );\n\n\t\t} ).then( function ( dependencies ) {\n\n\t\t\tconst result = {\n\t\t\t\tscene: dependencies[ 0 ][ json.scene || 0 ],\n\t\t\t\tscenes: dependencies[ 0 ],\n\t\t\t\tanimations: dependencies[ 1 ],\n\t\t\t\tcameras: dependencies[ 2 ],\n\t\t\t\tasset: json.asset,\n\t\t\t\tparser: parser,\n\t\t\t\tuserData: {}\n\t\t\t};\n\n\t\t\taddUnknownExtensionsToUserData( extensions, result, json );\n\n\t\t\tassignExtrasToUserData( result, json );\n\n\t\t\tPromise.all( parser._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.afterRoot && ext.afterRoot( result );\n\n\t\t\t} ) ).then( function () {\n\n\t\t\t\tonLoad( result );\n\n\t\t\t} );\n\n\t\t} ).catch( onError );\n\n\t}\n\n\t/**\n\t * Marks the special nodes/meshes in json for efficient parse.\n\t */\n\t_markDefs() {\n\n\t\tconst nodeDefs = this.json.nodes || [];\n\t\tconst skinDefs = this.json.skins || [];\n\t\tconst meshDefs = this.json.meshes || [];\n\n\t\t// Nothing in the node definition indicates whether it is a Bone or an\n\t\t// Object3D. Use the skins' joint references to mark bones.\n\t\tfor ( let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) {\n\n\t\t\tconst joints = skinDefs[ skinIndex ].joints;\n\n\t\t\tfor ( let i = 0, il = joints.length; i < il; i ++ ) {\n\n\t\t\t\tnodeDefs[ joints[ i ] ].isBone = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Iterate over all nodes, marking references to shared resources,\n\t\t// as well as skeleton joints.\n\t\tfor ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {\n\n\t\t\tconst nodeDef = nodeDefs[ nodeIndex ];\n\n\t\t\tif ( nodeDef.mesh !== undefined ) {\n\n\t\t\t\tthis._addNodeRef( this.meshCache, nodeDef.mesh );\n\n\t\t\t\t// Nothing in the mesh definition indicates whether it is\n\t\t\t\t// a SkinnedMesh or Mesh. Use the node's mesh reference\n\t\t\t\t// to mark SkinnedMesh if node has skin.\n\t\t\t\tif ( nodeDef.skin !== undefined ) {\n\n\t\t\t\t\tmeshDefs[ nodeDef.mesh ].isSkinnedMesh = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.camera !== undefined ) {\n\n\t\t\t\tthis._addNodeRef( this.cameraCache, nodeDef.camera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Counts references to shared node / Object3D resources. These resources\n\t * can be reused, or \"instantiated\", at multiple nodes in the scene\n\t * hierarchy. Mesh, Camera, and Light instances are instantiated and must\n\t * be marked. Non-scenegraph resources (like Materials, Geometries, and\n\t * Textures) can be reused directly and are not marked here.\n\t *\n\t * Example: CesiumMilkTruck sample model reuses \"Wheel\" meshes.\n\t */\n\t_addNodeRef( cache, index ) {\n\n\t\tif ( index === undefined ) return;\n\n\t\tif ( cache.refs[ index ] === undefined ) {\n\n\t\t\tcache.refs[ index ] = cache.uses[ index ] = 0;\n\n\t\t}\n\n\t\tcache.refs[ index ] ++;\n\n\t}\n\n\t/** Returns a reference to a shared resource, cloning it if necessary. */\n\t_getNodeRef( cache, index, object ) {\n\n\t\tif ( cache.refs[ index ] <= 1 ) return object;\n\n\t\tconst ref = object.clone();\n\n\t\t// Propagates mappings to the cloned object, prevents mappings on the\n\t\t// original object from being lost.\n\t\tconst updateMappings = ( original, clone ) => {\n\n\t\t\tconst mappings = this.associations.get( original );\n\t\t\tif ( mappings != null ) {\n\n\t\t\t\tthis.associations.set( clone, mappings );\n\n\t\t\t}\n\n\t\t\tfor ( const [ i, child ] of original.children.entries() ) {\n\n\t\t\t\tupdateMappings( child, clone.children[ i ] );\n\n\t\t\t}\n\n\t\t};\n\n\t\tupdateMappings( object, ref );\n\n\t\tref.name += '_instance_' + ( cache.uses[ index ] ++ );\n\n\t\treturn ref;\n\n\t}\n\n\t_invokeOne( func ) {\n\n\t\tconst extensions = Object.values( this.plugins );\n\t\textensions.push( this );\n\n\t\tfor ( let i = 0; i < extensions.length; i ++ ) {\n\n\t\t\tconst result = func( extensions[ i ] );\n\n\t\t\tif ( result ) return result;\n\n\t\t}\n\n\t\treturn null;\n\n\t}\n\n\t_invokeAll( func ) {\n\n\t\tconst extensions = Object.values( this.plugins );\n\t\textensions.unshift( this );\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0; i < extensions.length; i ++ ) {\n\n\t\t\tconst result = func( extensions[ i ] );\n\n\t\t\tif ( result ) pending.push( result );\n\n\t\t}\n\n\t\treturn pending;\n\n\t}\n\n\t/**\n\t * Requests the specified dependency asynchronously, with caching.\n\t * @param {string} type\n\t * @param {number} index\n\t * @return {Promise}\n\t */\n\tgetDependency( type, index ) {\n\n\t\tconst cacheKey = type + ':' + index;\n\t\tlet dependency = this.cache.get( cacheKey );\n\n\t\tif ( ! dependency ) {\n\n\t\t\tswitch ( type ) {\n\n\t\t\t\tcase 'scene':\n\t\t\t\t\tdependency = this.loadScene( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'node':\n\t\t\t\t\tdependency = this.loadNode( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'mesh':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadMesh && ext.loadMesh( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'accessor':\n\t\t\t\t\tdependency = this.loadAccessor( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'bufferView':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadBufferView && ext.loadBufferView( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'buffer':\n\t\t\t\t\tdependency = this.loadBuffer( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'material':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadMaterial && ext.loadMaterial( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'texture':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadTexture && ext.loadTexture( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'skin':\n\t\t\t\t\tdependency = this.loadSkin( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'animation':\n\t\t\t\t\tdependency = this._invokeOne( function ( ext ) {\n\n\t\t\t\t\t\treturn ext.loadAnimation && ext.loadAnimation( index );\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'camera':\n\t\t\t\t\tdependency = this.loadCamera( index );\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error( 'Unknown type: ' + type );\n\n\t\t\t}\n\n\t\t\tthis.cache.add( cacheKey, dependency );\n\n\t\t}\n\n\t\treturn dependency;\n\n\t}\n\n\t/**\n\t * Requests all dependencies of the specified type asynchronously, with caching.\n\t * @param {string} type\n\t * @return {Promise>}\n\t */\n\tgetDependencies( type ) {\n\n\t\tlet dependencies = this.cache.get( type );\n\n\t\tif ( ! dependencies ) {\n\n\t\t\tconst parser = this;\n\t\t\tconst defs = this.json[ type + ( type === 'mesh' ? 'es' : 's' ) ] || [];\n\n\t\t\tdependencies = Promise.all( defs.map( function ( def, index ) {\n\n\t\t\t\treturn parser.getDependency( type, index );\n\n\t\t\t} ) );\n\n\t\t\tthis.cache.add( type, dependencies );\n\n\t\t}\n\n\t\treturn dependencies;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views\n\t * @param {number} bufferIndex\n\t * @return {Promise}\n\t */\n\tloadBuffer( bufferIndex ) {\n\n\t\tconst bufferDef = this.json.buffers[ bufferIndex ];\n\t\tconst loader = this.fileLoader;\n\n\t\tif ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' );\n\n\t\t}\n\n\t\t// If present, GLB container is required to be the first buffer.\n\t\tif ( bufferDef.uri === undefined && bufferIndex === 0 ) {\n\n\t\t\treturn Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body );\n\n\t\t}\n\n\t\tconst options = this.options;\n\n\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\tloader.load( LoaderUtils.resolveURL( bufferDef.uri, options.path ), resolve, undefined, function () {\n\n\t\t\t\treject( new Error( 'THREE.GLTFLoader: Failed to load buffer \"' + bufferDef.uri + '\".' ) );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views\n\t * @param {number} bufferViewIndex\n\t * @return {Promise}\n\t */\n\tloadBufferView( bufferViewIndex ) {\n\n\t\tconst bufferViewDef = this.json.bufferViews[ bufferViewIndex ];\n\n\t\treturn this.getDependency( 'buffer', bufferViewDef.buffer ).then( function ( buffer ) {\n\n\t\t\tconst byteLength = bufferViewDef.byteLength || 0;\n\t\t\tconst byteOffset = bufferViewDef.byteOffset || 0;\n\t\t\treturn buffer.slice( byteOffset, byteOffset + byteLength );\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors\n\t * @param {number} accessorIndex\n\t * @return {Promise}\n\t */\n\tloadAccessor( accessorIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\n\t\tconst accessorDef = this.json.accessors[ accessorIndex ];\n\n\t\tif ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {\n\n\t\t\t// Ignore empty accessors, which may be used to declare runtime\n\t\t\t// information about attributes coming from another source (e.g. Draco\n\t\t\t// compression extension).\n\t\t\treturn Promise.resolve( null );\n\n\t\t}\n\n\t\tconst pendingBufferViews = [];\n\n\t\tif ( accessorDef.bufferView !== undefined ) {\n\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) );\n\n\t\t} else {\n\n\t\t\tpendingBufferViews.push( null );\n\n\t\t}\n\n\t\tif ( accessorDef.sparse !== undefined ) {\n\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.indices.bufferView ) );\n\t\t\tpendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.values.bufferView ) );\n\n\t\t}\n\n\t\treturn Promise.all( pendingBufferViews ).then( function ( bufferViews ) {\n\n\t\t\tconst bufferView = bufferViews[ 0 ];\n\n\t\t\tconst itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];\n\t\t\tconst TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];\n\n\t\t\t// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.\n\t\t\tconst elementBytes = TypedArray.BYTES_PER_ELEMENT;\n\t\t\tconst itemBytes = elementBytes * itemSize;\n\t\t\tconst byteOffset = accessorDef.byteOffset || 0;\n\t\t\tconst byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[ accessorDef.bufferView ].byteStride : undefined;\n\t\t\tconst normalized = accessorDef.normalized === true;\n\t\t\tlet array, bufferAttribute;\n\n\t\t\t// The buffer is not interleaved if the stride is the item size in bytes.\n\t\t\tif ( byteStride && byteStride !== itemBytes ) {\n\n\t\t\t\t// Each \"slice\" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own InterleavedBuffer\n\t\t\t\t// This makes sure that IBA.count reflects accessor.count properly\n\t\t\t\tconst ibSlice = Math.floor( byteOffset / byteStride );\n\t\t\t\tconst ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;\n\t\t\t\tlet ib = parser.cache.get( ibCacheKey );\n\n\t\t\t\tif ( ! ib ) {\n\n\t\t\t\t\tarray = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );\n\n\t\t\t\t\t// Integer parameters to IB/IBA are in array elements, not bytes.\n\t\t\t\t\tib = new InterleavedBuffer( array, byteStride / elementBytes );\n\n\t\t\t\t\tparser.cache.add( ibCacheKey, ib );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute = new InterleavedBufferAttribute( ib, itemSize, ( byteOffset % byteStride ) / elementBytes, normalized );\n\n\t\t\t} else {\n\n\t\t\t\tif ( bufferView === null ) {\n\n\t\t\t\t\tarray = new TypedArray( accessorDef.count * itemSize );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tarray = new TypedArray( bufferView, byteOffset, accessorDef.count * itemSize );\n\n\t\t\t\t}\n\n\t\t\t\tbufferAttribute = new BufferAttribute( array, itemSize, normalized );\n\n\t\t\t}\n\n\t\t\t// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors\n\t\t\tif ( accessorDef.sparse !== undefined ) {\n\n\t\t\t\tconst itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;\n\t\t\t\tconst TypedArrayIndices = WEBGL_COMPONENT_TYPES[ accessorDef.sparse.indices.componentType ];\n\n\t\t\t\tconst byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0;\n\t\t\t\tconst byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;\n\n\t\t\t\tconst sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices );\n\t\t\t\tconst sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize );\n\n\t\t\t\tif ( bufferView !== null ) {\n\n\t\t\t\t\t// Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.\n\t\t\t\t\tbufferAttribute = new BufferAttribute( bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let i = 0, il = sparseIndices.length; i < il; i ++ ) {\n\n\t\t\t\t\tconst index = sparseIndices[ i ];\n\n\t\t\t\t\tbufferAttribute.setX( index, sparseValues[ i * itemSize ] );\n\t\t\t\t\tif ( itemSize >= 2 ) bufferAttribute.setY( index, sparseValues[ i * itemSize + 1 ] );\n\t\t\t\t\tif ( itemSize >= 3 ) bufferAttribute.setZ( index, sparseValues[ i * itemSize + 2 ] );\n\t\t\t\t\tif ( itemSize >= 4 ) bufferAttribute.setW( index, sparseValues[ i * itemSize + 3 ] );\n\t\t\t\t\tif ( itemSize >= 5 ) throw new Error( 'THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn bufferAttribute;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures\n\t * @param {number} textureIndex\n\t * @return {Promise}\n\t */\n\tloadTexture( textureIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst options = this.options;\n\t\tconst textureDef = json.textures[ textureIndex ];\n\t\tconst sourceIndex = textureDef.source;\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tlet loader = this.textureLoader;\n\n\t\tif ( sourceDef.uri ) {\n\n\t\t\tconst handler = options.manager.getHandler( sourceDef.uri );\n\t\t\tif ( handler !== null ) loader = handler;\n\n\t\t}\n\n\t\treturn this.loadTextureImage( textureIndex, sourceIndex, loader );\n\n\t}\n\n\tloadTextureImage( textureIndex, sourceIndex, loader ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\n\t\tconst textureDef = json.textures[ textureIndex ];\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tconst cacheKey = ( sourceDef.uri || sourceDef.bufferView ) + ':' + textureDef.sampler;\n\n\t\tif ( this.textureCache[ cacheKey ] ) {\n\n\t\t\t// See https://github.com/mrdoob/three.js/issues/21559.\n\t\t\treturn this.textureCache[ cacheKey ];\n\n\t\t}\n\n\t\tconst promise = this.loadImageSource( sourceIndex, loader ).then( function ( texture ) {\n\n\t\t\ttexture.flipY = false;\n\n\t\t\tif ( textureDef.name ) texture.name = textureDef.name;\n\n\t\t\tconst samplers = json.samplers || {};\n\t\t\tconst sampler = samplers[ textureDef.sampler ] || {};\n\n\t\t\ttexture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || LinearFilter;\n\t\t\ttexture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || LinearMipmapLinearFilter;\n\t\t\ttexture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || RepeatWrapping;\n\t\t\ttexture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || RepeatWrapping;\n\n\t\t\tparser.associations.set( texture, { textures: textureIndex } );\n\n\t\t\treturn texture;\n\n\t\t} ).catch( function () {\n\n\t\t\treturn null;\n\n\t\t} );\n\n\t\tthis.textureCache[ cacheKey ] = promise;\n\n\t\treturn promise;\n\n\t}\n\n\tloadImageSource( sourceIndex, loader ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst options = this.options;\n\n\t\tif ( this.sourceCache[ sourceIndex ] !== undefined ) {\n\n\t\t\treturn this.sourceCache[ sourceIndex ].then( ( texture ) => texture.clone() );\n\n\t\t}\n\n\t\tconst sourceDef = json.images[ sourceIndex ];\n\n\t\tconst URL = self.URL || self.webkitURL;\n\n\t\tlet sourceURI = sourceDef.uri || '';\n\t\tlet isObjectURL = false;\n\n\t\tif ( sourceDef.bufferView !== undefined ) {\n\n\t\t\t// Load binary image data from bufferView, if provided.\n\n\t\t\tsourceURI = parser.getDependency( 'bufferView', sourceDef.bufferView ).then( function ( bufferView ) {\n\n\t\t\t\tisObjectURL = true;\n\t\t\t\tconst blob = new Blob( [ bufferView ], { type: sourceDef.mimeType } );\n\t\t\t\tsourceURI = URL.createObjectURL( blob );\n\t\t\t\treturn sourceURI;\n\n\t\t\t} );\n\n\t\t} else if ( sourceDef.uri === undefined ) {\n\n\t\t\tthrow new Error( 'THREE.GLTFLoader: Image ' + sourceIndex + ' is missing URI and bufferView' );\n\n\t\t}\n\n\t\tconst promise = Promise.resolve( sourceURI ).then( function ( sourceURI ) {\n\n\t\t\treturn new Promise( function ( resolve, reject ) {\n\n\t\t\t\tlet onLoad = resolve;\n\n\t\t\t\tif ( loader.isImageBitmapLoader === true ) {\n\n\t\t\t\t\tonLoad = function ( imageBitmap ) {\n\n\t\t\t\t\t\tconst texture = new Texture( imageBitmap );\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tresolve( texture );\n\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tloader.load( LoaderUtils.resolveURL( sourceURI, options.path ), onLoad, undefined, reject );\n\n\t\t\t} );\n\n\t\t} ).then( function ( texture ) {\n\n\t\t\t// Clean up resources and configure Texture.\n\n\t\t\tif ( isObjectURL === true ) {\n\n\t\t\t\tURL.revokeObjectURL( sourceURI );\n\n\t\t\t}\n\n\t\t\ttexture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType( sourceDef.uri );\n\n\t\t\treturn texture;\n\n\t\t} ).catch( function ( error ) {\n\n\t\t\tconsole.error( 'THREE.GLTFLoader: Couldn\\'t load texture', sourceURI );\n\t\t\tthrow error;\n\n\t\t} );\n\n\t\tthis.sourceCache[ sourceIndex ] = promise;\n\t\treturn promise;\n\n\t}\n\n\t/**\n\t * Asynchronously assigns a texture to the given material parameters.\n\t * @param {Object} materialParams\n\t * @param {string} mapName\n\t * @param {Object} mapDef\n\t * @return {Promise}\n\t */\n\tassignTexture( materialParams, mapName, mapDef, encoding ) {\n\n\t\tconst parser = this;\n\n\t\treturn this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {\n\n\t\t\t// Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured\n\t\t\t// However, we will copy UV set 0 to UV set 1 on demand for aoMap\n\t\t\tif ( mapDef.texCoord !== undefined && mapDef.texCoord != 0 && ! ( mapName === 'aoMap' && mapDef.texCoord == 1 ) ) {\n\n\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Custom UV set ' + mapDef.texCoord + ' for texture ' + mapName + ' not yet supported.' );\n\n\t\t\t}\n\n\t\t\tif ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {\n\n\t\t\t\tconst transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;\n\n\t\t\t\tif ( transform ) {\n\n\t\t\t\t\tconst gltfReference = parser.associations.get( texture );\n\t\t\t\t\ttexture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, transform );\n\t\t\t\t\tparser.associations.set( texture, gltfReference );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( encoding !== undefined ) {\n\n\t\t\t\ttexture.encoding = encoding;\n\n\t\t\t}\n\n\t\t\tmaterialParams[ mapName ] = texture;\n\n\t\t\treturn texture;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Assigns final material to a Mesh, Line, or Points instance. The instance\n\t * already has a material (generated from the glTF material options alone)\n\t * but reuse of the same glTF material may require multiple threejs materials\n\t * to accommodate different primitive types, defines, etc. New materials will\n\t * be created if necessary, and reused from a cache.\n\t * @param {Object3D} mesh Mesh, Line, or Points instance.\n\t */\n\tassignFinalMaterial( mesh ) {\n\n\t\tconst geometry = mesh.geometry;\n\t\tlet material = mesh.material;\n\n\t\tconst useDerivativeTangents = geometry.attributes.tangent === undefined;\n\t\tconst useVertexColors = geometry.attributes.color !== undefined;\n\t\tconst useFlatShading = geometry.attributes.normal === undefined;\n\n\t\tif ( mesh.isPoints ) {\n\n\t\t\tconst cacheKey = 'PointsMaterial:' + material.uuid;\n\n\t\t\tlet pointsMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! pointsMaterial ) {\n\n\t\t\t\tpointsMaterial = new PointsMaterial();\n\t\t\t\tMaterial.prototype.copy.call( pointsMaterial, material );\n\t\t\t\tpointsMaterial.color.copy( material.color );\n\t\t\t\tpointsMaterial.map = material.map;\n\t\t\t\tpointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px\n\n\t\t\t\tthis.cache.add( cacheKey, pointsMaterial );\n\n\t\t\t}\n\n\t\t\tmaterial = pointsMaterial;\n\n\t\t} else if ( mesh.isLine ) {\n\n\t\t\tconst cacheKey = 'LineBasicMaterial:' + material.uuid;\n\n\t\t\tlet lineMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! lineMaterial ) {\n\n\t\t\t\tlineMaterial = new LineBasicMaterial();\n\t\t\t\tMaterial.prototype.copy.call( lineMaterial, material );\n\t\t\t\tlineMaterial.color.copy( material.color );\n\n\t\t\t\tthis.cache.add( cacheKey, lineMaterial );\n\n\t\t\t}\n\n\t\t\tmaterial = lineMaterial;\n\n\t\t}\n\n\t\t// Clone the material if it will be modified\n\t\tif ( useDerivativeTangents || useVertexColors || useFlatShading ) {\n\n\t\t\tlet cacheKey = 'ClonedMaterial:' + material.uuid + ':';\n\n\t\t\tif ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';\n\t\t\tif ( useDerivativeTangents ) cacheKey += 'derivative-tangents:';\n\t\t\tif ( useVertexColors ) cacheKey += 'vertex-colors:';\n\t\t\tif ( useFlatShading ) cacheKey += 'flat-shading:';\n\n\t\t\tlet cachedMaterial = this.cache.get( cacheKey );\n\n\t\t\tif ( ! cachedMaterial ) {\n\n\t\t\t\tcachedMaterial = material.clone();\n\n\t\t\t\tif ( useVertexColors ) cachedMaterial.vertexColors = true;\n\t\t\t\tif ( useFlatShading ) cachedMaterial.flatShading = true;\n\n\t\t\t\tif ( useDerivativeTangents ) {\n\n\t\t\t\t\t// https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995\n\t\t\t\t\tif ( cachedMaterial.normalScale ) cachedMaterial.normalScale.y *= - 1;\n\t\t\t\t\tif ( cachedMaterial.clearcoatNormalScale ) cachedMaterial.clearcoatNormalScale.y *= - 1;\n\n\t\t\t\t}\n\n\t\t\t\tthis.cache.add( cacheKey, cachedMaterial );\n\n\t\t\t\tthis.associations.set( cachedMaterial, this.associations.get( material ) );\n\n\t\t\t}\n\n\t\t\tmaterial = cachedMaterial;\n\n\t\t}\n\n\t\t// workarounds for mesh and geometry\n\n\t\tif ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {\n\n\t\t\tgeometry.setAttribute( 'uv2', geometry.attributes.uv );\n\n\t\t}\n\n\t\tmesh.material = material;\n\n\t}\n\n\tgetMaterialType( /* materialIndex */ ) {\n\n\t\treturn MeshStandardMaterial;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials\n\t * @param {number} materialIndex\n\t * @return {Promise}\n\t */\n\tloadMaterial( materialIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst materialDef = json.materials[ materialIndex ];\n\n\t\tlet materialType;\n\t\tconst materialParams = {};\n\t\tconst materialExtensions = materialDef.extensions || {};\n\n\t\tconst pending = [];\n\n\t\tif ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) {\n\n\t\t\tconst sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ];\n\t\t\tmaterialType = sgExtension.getMaterialType();\n\t\t\tpending.push( sgExtension.extendParams( materialParams, materialDef, parser ) );\n\n\t\t} else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {\n\n\t\t\tconst kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];\n\t\t\tmaterialType = kmuExtension.getMaterialType();\n\t\t\tpending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) );\n\n\t\t} else {\n\n\t\t\t// Specification:\n\t\t\t// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material\n\n\t\t\tconst metallicRoughness = materialDef.pbrMetallicRoughness || {};\n\n\t\t\tmaterialParams.color = new Color( 1.0, 1.0, 1.0 );\n\t\t\tmaterialParams.opacity = 1.0;\n\n\t\t\tif ( Array.isArray( metallicRoughness.baseColorFactor ) ) {\n\n\t\t\t\tconst array = metallicRoughness.baseColorFactor;\n\n\t\t\t\tmaterialParams.color.fromArray( array );\n\t\t\t\tmaterialParams.opacity = array[ 3 ];\n\n\t\t\t}\n\n\t\t\tif ( metallicRoughness.baseColorTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, sRGBEncoding ) );\n\n\t\t\t}\n\n\t\t\tmaterialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;\n\t\t\tmaterialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;\n\n\t\t\tif ( metallicRoughness.metallicRoughnessTexture !== undefined ) {\n\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) );\n\t\t\t\tpending.push( parser.assignTexture( materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture ) );\n\n\t\t\t}\n\n\t\t\tmaterialType = this._invokeOne( function ( ext ) {\n\n\t\t\t\treturn ext.getMaterialType && ext.getMaterialType( materialIndex );\n\n\t\t\t} );\n\n\t\t\tpending.push( Promise.all( this._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );\n\n\t\t\t} ) ) );\n\n\t\t}\n\n\t\tif ( materialDef.doubleSided === true ) {\n\n\t\t\tmaterialParams.side = DoubleSide;\n\n\t\t}\n\n\t\tconst alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;\n\n\t\tif ( alphaMode === ALPHA_MODES.BLEND ) {\n\n\t\t\tmaterialParams.transparent = true;\n\n\t\t\t// See: https://github.com/mrdoob/three.js/issues/17706\n\t\t\tmaterialParams.depthWrite = false;\n\n\t\t} else {\n\n\t\t\tmaterialParams.transparent = false;\n\n\t\t\tif ( alphaMode === ALPHA_MODES.MASK ) {\n\n\t\t\t\tmaterialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.normalTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) );\n\n\t\t\tmaterialParams.normalScale = new Vector2( 1, 1 );\n\n\t\t\tif ( materialDef.normalTexture.scale !== undefined ) {\n\n\t\t\t\tconst scale = materialDef.normalTexture.scale;\n\n\t\t\t\tmaterialParams.normalScale.set( scale, scale );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.occlusionTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) );\n\n\t\t\tif ( materialDef.occlusionTexture.strength !== undefined ) {\n\n\t\t\t\tmaterialParams.aoMapIntensity = materialDef.occlusionTexture.strength;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( materialDef.emissiveFactor !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tmaterialParams.emissive = new Color().fromArray( materialDef.emissiveFactor );\n\n\t\t}\n\n\t\tif ( materialDef.emissiveTexture !== undefined && materialType !== MeshBasicMaterial ) {\n\n\t\t\tpending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture, sRGBEncoding ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function () {\n\n\t\t\tlet material;\n\n\t\t\tif ( materialType === GLTFMeshStandardSGMaterial ) {\n\n\t\t\t\tmaterial = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams );\n\n\t\t\t} else {\n\n\t\t\t\tmaterial = new materialType( materialParams );\n\n\t\t\t}\n\n\t\t\tif ( materialDef.name ) material.name = materialDef.name;\n\n\t\t\tassignExtrasToUserData( material, materialDef );\n\n\t\t\tparser.associations.set( material, { materials: materialIndex } );\n\n\t\t\tif ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );\n\n\t\t\treturn material;\n\n\t\t} );\n\n\t}\n\n\t/** When Object3D instances are targeted by animation, they need unique names. */\n\tcreateUniqueName( originalName ) {\n\n\t\tconst sanitizedName = PropertyBinding.sanitizeNodeName( originalName || '' );\n\n\t\tlet name = sanitizedName;\n\n\t\tfor ( let i = 1; this.nodeNamesUsed[ name ]; ++ i ) {\n\n\t\t\tname = sanitizedName + '_' + i;\n\n\t\t}\n\n\t\tthis.nodeNamesUsed[ name ] = true;\n\n\t\treturn name;\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry\n\t *\n\t * Creates BufferGeometries from primitives.\n\t *\n\t * @param {Array} primitives\n\t * @return {Promise>}\n\t */\n\tloadGeometries( primitives ) {\n\n\t\tconst parser = this;\n\t\tconst extensions = this.extensions;\n\t\tconst cache = this.primitiveCache;\n\n\t\tfunction createDracoPrimitive( primitive ) {\n\n\t\t\treturn extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]\n\t\t\t\t.decodePrimitive( primitive, parser )\n\t\t\t\t.then( function ( geometry ) {\n\n\t\t\t\t\treturn addPrimitiveAttributes( geometry, primitive, parser );\n\n\t\t\t\t} );\n\n\t\t}\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = primitives.length; i < il; i ++ ) {\n\n\t\t\tconst primitive = primitives[ i ];\n\t\t\tconst cacheKey = createPrimitiveKey( primitive );\n\n\t\t\t// See if we've already created this geometry\n\t\t\tconst cached = cache[ cacheKey ];\n\n\t\t\tif ( cached ) {\n\n\t\t\t\t// Use the cached geometry if it exists\n\t\t\t\tpending.push( cached.promise );\n\n\t\t\t} else {\n\n\t\t\t\tlet geometryPromise;\n\n\t\t\t\tif ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) {\n\n\t\t\t\t\t// Use DRACO geometry if available\n\t\t\t\t\tgeometryPromise = createDracoPrimitive( primitive );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Otherwise create a new geometry\n\t\t\t\t\tgeometryPromise = addPrimitiveAttributes( new BufferGeometry(), primitive, parser );\n\n\t\t\t\t}\n\n\t\t\t\t// Cache this geometry\n\t\t\t\tcache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };\n\n\t\t\t\tpending.push( geometryPromise );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes\n\t * @param {number} meshIndex\n\t * @return {Promise}\n\t */\n\tloadMesh( meshIndex ) {\n\n\t\tconst parser = this;\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\n\t\tconst meshDef = json.meshes[ meshIndex ];\n\t\tconst primitives = meshDef.primitives;\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = primitives.length; i < il; i ++ ) {\n\n\t\t\tconst material = primitives[ i ].material === undefined\n\t\t\t\t? createDefaultMaterial( this.cache )\n\t\t\t\t: this.getDependency( 'material', primitives[ i ].material );\n\n\t\t\tpending.push( material );\n\n\t\t}\n\n\t\tpending.push( parser.loadGeometries( primitives ) );\n\n\t\treturn Promise.all( pending ).then( function ( results ) {\n\n\t\t\tconst materials = results.slice( 0, results.length - 1 );\n\t\t\tconst geometries = results[ results.length - 1 ];\n\n\t\t\tconst meshes = [];\n\n\t\t\tfor ( let i = 0, il = geometries.length; i < il; i ++ ) {\n\n\t\t\t\tconst geometry = geometries[ i ];\n\t\t\t\tconst primitive = primitives[ i ];\n\n\t\t\t\t// 1. create Mesh\n\n\t\t\t\tlet mesh;\n\n\t\t\t\tconst material = materials[ i ];\n\n\t\t\t\tif ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||\n\t\t\t\t\t\tprimitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||\n\t\t\t\t\t\tprimitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||\n\t\t\t\t\t\tprimitive.mode === undefined ) {\n\n\t\t\t\t\t// .isSkinnedMesh isn't in glTF spec. See ._markDefs()\n\t\t\t\t\tmesh = meshDef.isSkinnedMesh === true\n\t\t\t\t\t\t? new SkinnedMesh( geometry, material )\n\t\t\t\t\t\t: new Mesh( geometry, material );\n\n\t\t\t\t\tif ( mesh.isSkinnedMesh === true && ! mesh.geometry.attributes.skinWeight.normalized ) {\n\n\t\t\t\t\t\t// we normalize floating point skin weight array to fix malformed assets (see #15319)\n\t\t\t\t\t\t// it's important to skip this for non-float32 data since normalizeSkinWeights assumes non-normalized inputs\n\t\t\t\t\t\tmesh.normalizeSkinWeights();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {\n\n\t\t\t\t\t\tmesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleStripDrawMode );\n\n\t\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {\n\n\t\t\t\t\t\tmesh.geometry = toTrianglesDrawMode( mesh.geometry, TriangleFanDrawMode );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {\n\n\t\t\t\t\tmesh = new LineSegments( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) {\n\n\t\t\t\t\tmesh = new Line( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) {\n\n\t\t\t\t\tmesh = new LineLoop( geometry, material );\n\n\t\t\t\t} else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) {\n\n\t\t\t\t\tmesh = new Points( geometry, material );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode );\n\n\t\t\t\t}\n\n\t\t\t\tif ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) {\n\n\t\t\t\t\tupdateMorphTargets( mesh, meshDef );\n\n\t\t\t\t}\n\n\t\t\t\tmesh.name = parser.createUniqueName( meshDef.name || ( 'mesh_' + meshIndex ) );\n\n\t\t\t\tassignExtrasToUserData( mesh, meshDef );\n\n\t\t\t\tif ( primitive.extensions ) addUnknownExtensionsToUserData( extensions, mesh, primitive );\n\n\t\t\t\tparser.assignFinalMaterial( mesh );\n\n\t\t\t\tmeshes.push( mesh );\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0, il = meshes.length; i < il; i ++ ) {\n\n\t\t\t\tparser.associations.set( meshes[ i ], {\n\t\t\t\t\tmeshes: meshIndex,\n\t\t\t\t\tprimitives: i\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( meshes.length === 1 ) {\n\n\t\t\t\treturn meshes[ 0 ];\n\n\t\t\t}\n\n\t\t\tconst group = new Group();\n\n\t\t\tparser.associations.set( group, { meshes: meshIndex } );\n\n\t\t\tfor ( let i = 0, il = meshes.length; i < il; i ++ ) {\n\n\t\t\t\tgroup.add( meshes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras\n\t * @param {number} cameraIndex\n\t * @return {Promise}\n\t */\n\tloadCamera( cameraIndex ) {\n\n\t\tlet camera;\n\t\tconst cameraDef = this.json.cameras[ cameraIndex ];\n\t\tconst params = cameraDef[ cameraDef.type ];\n\n\t\tif ( ! params ) {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing camera parameters.' );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( cameraDef.type === 'perspective' ) {\n\n\t\t\tcamera = new PerspectiveCamera( MathUtils.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 );\n\n\t\t} else if ( cameraDef.type === 'orthographic' ) {\n\n\t\t\tcamera = new OrthographicCamera( - params.xmag, params.xmag, params.ymag, - params.ymag, params.znear, params.zfar );\n\n\t\t}\n\n\t\tif ( cameraDef.name ) camera.name = this.createUniqueName( cameraDef.name );\n\n\t\tassignExtrasToUserData( camera, cameraDef );\n\n\t\treturn Promise.resolve( camera );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins\n\t * @param {number} skinIndex\n\t * @return {Promise}\n\t */\n\tloadSkin( skinIndex ) {\n\n\t\tconst skinDef = this.json.skins[ skinIndex ];\n\n\t\tconst skinEntry = { joints: skinDef.joints };\n\n\t\tif ( skinDef.inverseBindMatrices === undefined ) {\n\n\t\t\treturn Promise.resolve( skinEntry );\n\n\t\t}\n\n\t\treturn this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) {\n\n\t\t\tskinEntry.inverseBindMatrices = accessor;\n\n\t\t\treturn skinEntry;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations\n\t * @param {number} animationIndex\n\t * @return {Promise}\n\t */\n\tloadAnimation( animationIndex ) {\n\n\t\tconst json = this.json;\n\n\t\tconst animationDef = json.animations[ animationIndex ];\n\n\t\tconst pendingNodes = [];\n\t\tconst pendingInputAccessors = [];\n\t\tconst pendingOutputAccessors = [];\n\t\tconst pendingSamplers = [];\n\t\tconst pendingTargets = [];\n\n\t\tfor ( let i = 0, il = animationDef.channels.length; i < il; i ++ ) {\n\n\t\t\tconst channel = animationDef.channels[ i ];\n\t\t\tconst sampler = animationDef.samplers[ channel.sampler ];\n\t\t\tconst target = channel.target;\n\t\t\tconst name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated.\n\t\t\tconst input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input;\n\t\t\tconst output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output;\n\n\t\t\tpendingNodes.push( this.getDependency( 'node', name ) );\n\t\t\tpendingInputAccessors.push( this.getDependency( 'accessor', input ) );\n\t\t\tpendingOutputAccessors.push( this.getDependency( 'accessor', output ) );\n\t\t\tpendingSamplers.push( sampler );\n\t\t\tpendingTargets.push( target );\n\n\t\t}\n\n\t\treturn Promise.all( [\n\n\t\t\tPromise.all( pendingNodes ),\n\t\t\tPromise.all( pendingInputAccessors ),\n\t\t\tPromise.all( pendingOutputAccessors ),\n\t\t\tPromise.all( pendingSamplers ),\n\t\t\tPromise.all( pendingTargets )\n\n\t\t] ).then( function ( dependencies ) {\n\n\t\t\tconst nodes = dependencies[ 0 ];\n\t\t\tconst inputAccessors = dependencies[ 1 ];\n\t\t\tconst outputAccessors = dependencies[ 2 ];\n\t\t\tconst samplers = dependencies[ 3 ];\n\t\t\tconst targets = dependencies[ 4 ];\n\n\t\t\tconst tracks = [];\n\n\t\t\tfor ( let i = 0, il = nodes.length; i < il; i ++ ) {\n\n\t\t\t\tconst node = nodes[ i ];\n\t\t\t\tconst inputAccessor = inputAccessors[ i ];\n\t\t\t\tconst outputAccessor = outputAccessors[ i ];\n\t\t\t\tconst sampler = samplers[ i ];\n\t\t\t\tconst target = targets[ i ];\n\n\t\t\t\tif ( node === undefined ) continue;\n\n\t\t\t\tnode.updateMatrix();\n\t\t\t\tnode.matrixAutoUpdate = true;\n\n\t\t\t\tlet TypedKeyframeTrack;\n\n\t\t\t\tswitch ( PATH_PROPERTIES[ target.path ] ) {\n\n\t\t\t\t\tcase PATH_PROPERTIES.weights:\n\n\t\t\t\t\t\tTypedKeyframeTrack = NumberKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PATH_PROPERTIES.rotation:\n\n\t\t\t\t\t\tTypedKeyframeTrack = QuaternionKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PATH_PROPERTIES.position:\n\t\t\t\t\tcase PATH_PROPERTIES.scale:\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tTypedKeyframeTrack = VectorKeyframeTrack;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tconst targetName = node.name ? node.name : node.uuid;\n\n\t\t\t\tconst interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : InterpolateLinear;\n\n\t\t\t\tconst targetNames = [];\n\n\t\t\t\tif ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {\n\n\t\t\t\t\tnode.traverse( function ( object ) {\n\n\t\t\t\t\t\tif ( object.morphTargetInfluences ) {\n\n\t\t\t\t\t\t\ttargetNames.push( object.name ? object.name : object.uuid );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\ttargetNames.push( targetName );\n\n\t\t\t\t}\n\n\t\t\t\tlet outputArray = outputAccessor.array;\n\n\t\t\t\tif ( outputAccessor.normalized ) {\n\n\t\t\t\t\tconst scale = getNormalizedComponentScale( outputArray.constructor );\n\t\t\t\t\tconst scaled = new Float32Array( outputArray.length );\n\n\t\t\t\t\tfor ( let j = 0, jl = outputArray.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tscaled[ j ] = outputArray[ j ] * scale;\n\n\t\t\t\t\t}\n\n\t\t\t\t\toutputArray = scaled;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let j = 0, jl = targetNames.length; j < jl; j ++ ) {\n\n\t\t\t\t\tconst track = new TypedKeyframeTrack(\n\t\t\t\t\t\ttargetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],\n\t\t\t\t\t\tinputAccessor.array,\n\t\t\t\t\t\toutputArray,\n\t\t\t\t\t\tinterpolation\n\t\t\t\t\t);\n\n\t\t\t\t\t// Override interpolation with custom factory method.\n\t\t\t\t\tif ( sampler.interpolation === 'CUBICSPLINE' ) {\n\n\t\t\t\t\t\ttrack.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {\n\n\t\t\t\t\t\t\t// A CUBICSPLINE keyframe in glTF has three output values for each input value,\n\t\t\t\t\t\t\t// representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()\n\t\t\t\t\t\t\t// must be divided by three to get the interpolant's sampleSize argument.\n\n\t\t\t\t\t\t\tconst interpolantType = ( this instanceof QuaternionKeyframeTrack ) ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant;\n\n\t\t\t\t\t\t\treturn new interpolantType( this.times, this.values, this.getValueSize() / 3, result );\n\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.\n\t\t\t\t\t\ttrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttracks.push( track );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tconst name = animationDef.name ? animationDef.name : 'animation_' + animationIndex;\n\n\t\t\treturn new AnimationClip( name, undefined, tracks );\n\n\t\t} );\n\n\t}\n\n\tcreateNodeMesh( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst parser = this;\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\tif ( nodeDef.mesh === undefined ) return null;\n\n\t\treturn parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {\n\n\t\t\tconst node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh );\n\n\t\t\t// if weights are provided on the node, override weights on the mesh.\n\t\t\tif ( nodeDef.weights !== undefined ) {\n\n\t\t\t\tnode.traverse( function ( o ) {\n\n\t\t\t\t\tif ( ! o.isMesh ) return;\n\n\t\t\t\t\tfor ( let i = 0, il = nodeDef.weights.length; i < il; i ++ ) {\n\n\t\t\t\t\t\to.morphTargetInfluences[ i ] = nodeDef.weights[ i ];\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy\n\t * @param {number} nodeIndex\n\t * @return {Promise}\n\t */\n\tloadNode( nodeIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst parser = this;\n\n\t\tconst nodeDef = json.nodes[ nodeIndex ];\n\n\t\t// reserve node's name before its dependencies, so the root has the intended name.\n\t\tconst nodeName = nodeDef.name ? parser.createUniqueName( nodeDef.name ) : '';\n\n\t\treturn ( function () {\n\n\t\t\tconst pending = [];\n\n\t\t\tconst meshPromise = parser._invokeOne( function ( ext ) {\n\n\t\t\t\treturn ext.createNodeMesh && ext.createNodeMesh( nodeIndex );\n\n\t\t\t} );\n\n\t\t\tif ( meshPromise ) {\n\n\t\t\t\tpending.push( meshPromise );\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.camera !== undefined ) {\n\n\t\t\t\tpending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {\n\n\t\t\t\t\treturn parser._getNodeRef( parser.cameraCache, nodeDef.camera, camera );\n\n\t\t\t\t} ) );\n\n\t\t\t}\n\n\t\t\tparser._invokeAll( function ( ext ) {\n\n\t\t\t\treturn ext.createNodeAttachment && ext.createNodeAttachment( nodeIndex );\n\n\t\t\t} ).forEach( function ( promise ) {\n\n\t\t\t\tpending.push( promise );\n\n\t\t\t} );\n\n\t\t\treturn Promise.all( pending );\n\n\t\t}() ).then( function ( objects ) {\n\n\t\t\tlet node;\n\n\t\t\t// .isBone isn't in glTF spec. See ._markDefs\n\t\t\tif ( nodeDef.isBone === true ) {\n\n\t\t\t\tnode = new Bone();\n\n\t\t\t} else if ( objects.length > 1 ) {\n\n\t\t\t\tnode = new Group();\n\n\t\t\t} else if ( objects.length === 1 ) {\n\n\t\t\t\tnode = objects[ 0 ];\n\n\t\t\t} else {\n\n\t\t\t\tnode = new Object3D();\n\n\t\t\t}\n\n\t\t\tif ( node !== objects[ 0 ] ) {\n\n\t\t\t\tfor ( let i = 0, il = objects.length; i < il; i ++ ) {\n\n\t\t\t\t\tnode.add( objects[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( nodeDef.name ) {\n\n\t\t\t\tnode.userData.name = nodeDef.name;\n\t\t\t\tnode.name = nodeName;\n\n\t\t\t}\n\n\t\t\tassignExtrasToUserData( node, nodeDef );\n\n\t\t\tif ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );\n\n\t\t\tif ( nodeDef.matrix !== undefined ) {\n\n\t\t\t\tconst matrix = new Matrix4();\n\t\t\t\tmatrix.fromArray( nodeDef.matrix );\n\t\t\t\tnode.applyMatrix4( matrix );\n\n\t\t\t} else {\n\n\t\t\t\tif ( nodeDef.translation !== undefined ) {\n\n\t\t\t\t\tnode.position.fromArray( nodeDef.translation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( nodeDef.rotation !== undefined ) {\n\n\t\t\t\t\tnode.quaternion.fromArray( nodeDef.rotation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( nodeDef.scale !== undefined ) {\n\n\t\t\t\t\tnode.scale.fromArray( nodeDef.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( ! parser.associations.has( node ) ) {\n\n\t\t\t\tparser.associations.set( node, {} );\n\n\t\t\t}\n\n\t\t\tparser.associations.get( node ).nodes = nodeIndex;\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t}\n\n\t/**\n\t * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes\n\t * @param {number} sceneIndex\n\t * @return {Promise}\n\t */\n\tloadScene( sceneIndex ) {\n\n\t\tconst json = this.json;\n\t\tconst extensions = this.extensions;\n\t\tconst sceneDef = this.json.scenes[ sceneIndex ];\n\t\tconst parser = this;\n\n\t\t// Loader returns Group, not Scene.\n\t\t// See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172\n\t\tconst scene = new Group();\n\t\tif ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name );\n\n\t\tassignExtrasToUserData( scene, sceneDef );\n\n\t\tif ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );\n\n\t\tconst nodeIds = sceneDef.nodes || [];\n\n\t\tconst pending = [];\n\n\t\tfor ( let i = 0, il = nodeIds.length; i < il; i ++ ) {\n\n\t\t\tpending.push( buildNodeHierarchy( nodeIds[ i ], scene, json, parser ) );\n\n\t\t}\n\n\t\treturn Promise.all( pending ).then( function () {\n\n\t\t\t// Removes dangling associations, associations that reference a node that\n\t\t\t// didn't make it into the scene.\n\t\t\tconst reduceAssociations = ( node ) => {\n\n\t\t\t\tconst reducedAssociations = new Map();\n\n\t\t\t\tfor ( const [ key, value ] of parser.associations ) {\n\n\t\t\t\t\tif ( key instanceof Material || key instanceof Texture ) {\n\n\t\t\t\t\t\treducedAssociations.set( key, value );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tnode.traverse( ( node ) => {\n\n\t\t\t\t\tconst mappings = parser.associations.get( node );\n\n\t\t\t\t\tif ( mappings != null ) {\n\n\t\t\t\t\t\treducedAssociations.set( node, mappings );\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn reducedAssociations;\n\n\t\t\t};\n\n\t\t\tparser.associations = reduceAssociations( scene );\n\n\t\t\treturn scene;\n\n\t\t} );\n\n\t}\n\n}\n\nfunction buildNodeHierarchy( nodeId, parentObject, json, parser ) {\n\n\tconst nodeDef = json.nodes[ nodeId ];\n\n\treturn parser.getDependency( 'node', nodeId ).then( function ( node ) {\n\n\t\tif ( nodeDef.skin === undefined ) return node;\n\n\t\t// build skeleton here as well\n\n\t\tlet skinEntry;\n\n\t\treturn parser.getDependency( 'skin', nodeDef.skin ).then( function ( skin ) {\n\n\t\t\tskinEntry = skin;\n\n\t\t\tconst pendingJoints = [];\n\n\t\t\tfor ( let i = 0, il = skinEntry.joints.length; i < il; i ++ ) {\n\n\t\t\t\tpendingJoints.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn Promise.all( pendingJoints );\n\n\t\t} ).then( function ( jointNodes ) {\n\n\t\t\tnode.traverse( function ( mesh ) {\n\n\t\t\t\tif ( ! mesh.isMesh ) return;\n\n\t\t\t\tconst bones = [];\n\t\t\t\tconst boneInverses = [];\n\n\t\t\t\tfor ( let j = 0, jl = jointNodes.length; j < jl; j ++ ) {\n\n\t\t\t\t\tconst jointNode = jointNodes[ j ];\n\n\t\t\t\t\tif ( jointNode ) {\n\n\t\t\t\t\t\tbones.push( jointNode );\n\n\t\t\t\t\t\tconst mat = new Matrix4();\n\n\t\t\t\t\t\tif ( skinEntry.inverseBindMatrices !== undefined ) {\n\n\t\t\t\t\t\t\tmat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tboneInverses.push( mat );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Joint \"%s\" could not be found.', skinEntry.joints[ j ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tmesh.bind( new Skeleton( bones, boneInverses ), mesh.matrixWorld );\n\n\t\t\t} );\n\n\t\t\treturn node;\n\n\t\t} );\n\n\t} ).then( function ( node ) {\n\n\t\t// build node hierachy\n\n\t\tparentObject.add( node );\n\n\t\tconst pending = [];\n\n\t\tif ( nodeDef.children ) {\n\n\t\t\tconst children = nodeDef.children;\n\n\t\t\tfor ( let i = 0, il = children.length; i < il; i ++ ) {\n\n\t\t\t\tconst child = children[ i ];\n\t\t\t\tpending.push( buildNodeHierarchy( child, node, json, parser ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn Promise.all( pending );\n\n\t} );\n\n}\n\n/**\n * @param {BufferGeometry} geometry\n * @param {GLTF.Primitive} primitiveDef\n * @param {GLTFParser} parser\n */\nfunction computeBounds( geometry, primitiveDef, parser ) {\n\n\tconst attributes = primitiveDef.attributes;\n\n\tconst box = new Box3();\n\n\tif ( attributes.POSITION !== undefined ) {\n\n\t\tconst accessor = parser.json.accessors[ attributes.POSITION ];\n\n\t\tconst min = accessor.min;\n\t\tconst max = accessor.max;\n\n\t\t// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.\n\n\t\tif ( min !== undefined && max !== undefined ) {\n\n\t\t\tbox.set(\n\t\t\t\tnew Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ),\n\t\t\t\tnew Vector3( max[ 0 ], max[ 1 ], max[ 2 ] )\n\t\t\t);\n\n\t\t\tif ( accessor.normalized ) {\n\n\t\t\t\tconst boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );\n\t\t\t\tbox.min.multiplyScalar( boxScale );\n\t\t\t\tbox.max.multiplyScalar( boxScale );\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );\n\n\t\t\treturn;\n\n\t\t}\n\n\t} else {\n\n\t\treturn;\n\n\t}\n\n\tconst targets = primitiveDef.targets;\n\n\tif ( targets !== undefined ) {\n\n\t\tconst maxDisplacement = new Vector3();\n\t\tconst vector = new Vector3();\n\n\t\tfor ( let i = 0, il = targets.length; i < il; i ++ ) {\n\n\t\t\tconst target = targets[ i ];\n\n\t\t\tif ( target.POSITION !== undefined ) {\n\n\t\t\t\tconst accessor = parser.json.accessors[ target.POSITION ];\n\t\t\t\tconst min = accessor.min;\n\t\t\t\tconst max = accessor.max;\n\n\t\t\t\t// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.\n\n\t\t\t\tif ( min !== undefined && max !== undefined ) {\n\n\t\t\t\t\t// we need to get max of absolute components because target weight is [-1,1]\n\t\t\t\t\tvector.setX( Math.max( Math.abs( min[ 0 ] ), Math.abs( max[ 0 ] ) ) );\n\t\t\t\t\tvector.setY( Math.max( Math.abs( min[ 1 ] ), Math.abs( max[ 1 ] ) ) );\n\t\t\t\t\tvector.setZ( Math.max( Math.abs( min[ 2 ] ), Math.abs( max[ 2 ] ) ) );\n\n\n\t\t\t\t\tif ( accessor.normalized ) {\n\n\t\t\t\t\t\tconst boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );\n\t\t\t\t\t\tvector.multiplyScalar( boxScale );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative\n\t\t\t\t\t// to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets\n\t\t\t\t\t// are used to implement key-frame animations and as such only two are active at a time - this results in very large\n\t\t\t\t\t// boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.\n\t\t\t\t\tmaxDisplacement.max( vector );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.\n\t\tbox.expandByVector( maxDisplacement );\n\n\t}\n\n\tgeometry.boundingBox = box;\n\n\tconst sphere = new Sphere();\n\n\tbox.getCenter( sphere.center );\n\tsphere.radius = box.min.distanceTo( box.max ) / 2;\n\n\tgeometry.boundingSphere = sphere;\n\n}\n\n/**\n * @param {BufferGeometry} geometry\n * @param {GLTF.Primitive} primitiveDef\n * @param {GLTFParser} parser\n * @return {Promise}\n */\nfunction addPrimitiveAttributes( geometry, primitiveDef, parser ) {\n\n\tconst attributes = primitiveDef.attributes;\n\n\tconst pending = [];\n\n\tfunction assignAttributeAccessor( accessorIndex, attributeName ) {\n\n\t\treturn parser.getDependency( 'accessor', accessorIndex )\n\t\t\t.then( function ( accessor ) {\n\n\t\t\t\tgeometry.setAttribute( attributeName, accessor );\n\n\t\t\t} );\n\n\t}\n\n\tfor ( const gltfAttributeName in attributes ) {\n\n\t\tconst threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();\n\n\t\t// Skip attributes already provided by e.g. Draco extension.\n\t\tif ( threeAttributeName in geometry.attributes ) continue;\n\n\t\tpending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) );\n\n\t}\n\n\tif ( primitiveDef.indices !== undefined && ! geometry.index ) {\n\n\t\tconst accessor = parser.getDependency( 'accessor', primitiveDef.indices ).then( function ( accessor ) {\n\n\t\t\tgeometry.setIndex( accessor );\n\n\t\t} );\n\n\t\tpending.push( accessor );\n\n\t}\n\n\tassignExtrasToUserData( geometry, primitiveDef );\n\n\tcomputeBounds( geometry, primitiveDef, parser );\n\n\treturn Promise.all( pending ).then( function () {\n\n\t\treturn primitiveDef.targets !== undefined\n\t\t\t? addMorphTargets( geometry, primitiveDef.targets, parser )\n\t\t\t: geometry;\n\n\t} );\n\n}\n\n/**\n * @param {BufferGeometry} geometry\n * @param {Number} drawMode\n * @return {BufferGeometry}\n */\nfunction toTrianglesDrawMode( geometry, drawMode ) {\n\n\tlet index = geometry.getIndex();\n\n\t// generate index if not present\n\n\tif ( index === null ) {\n\n\t\tconst indices = [];\n\n\t\tconst position = geometry.getAttribute( 'position' );\n\n\t\tif ( position !== undefined ) {\n\n\t\t\tfor ( let i = 0; i < position.count; i ++ ) {\n\n\t\t\t\tindices.push( i );\n\n\t\t\t}\n\n\t\t\tgeometry.setIndex( indices );\n\t\t\tindex = geometry.getIndex();\n\n\t\t} else {\n\n\t\t\tconsole.error( 'THREE.GLTFLoader.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.' );\n\t\t\treturn geometry;\n\n\t\t}\n\n\t}\n\n\t//\n\n\tconst numberOfTriangles = index.count - 2;\n\tconst newIndices = [];\n\n\tif ( drawMode === TriangleFanDrawMode ) {\n\n\t\t// gl.TRIANGLE_FAN\n\n\t\tfor ( let i = 1; i <= numberOfTriangles; i ++ ) {\n\n\t\t\tnewIndices.push( index.getX( 0 ) );\n\t\t\tnewIndices.push( index.getX( i ) );\n\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\n\t\t}\n\n\t} else {\n\n\t\t// gl.TRIANGLE_STRIP\n\n\t\tfor ( let i = 0; i < numberOfTriangles; i ++ ) {\n\n\t\t\tif ( i % 2 === 0 ) {\n\n\t\t\t\tnewIndices.push( index.getX( i ) );\n\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\t\t\t\tnewIndices.push( index.getX( i + 2 ) );\n\n\n\t\t\t} else {\n\n\t\t\t\tnewIndices.push( index.getX( i + 2 ) );\n\t\t\t\tnewIndices.push( index.getX( i + 1 ) );\n\t\t\t\tnewIndices.push( index.getX( i ) );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tif ( ( newIndices.length / 3 ) !== numberOfTriangles ) {\n\n\t\tconsole.error( 'THREE.GLTFLoader.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' );\n\n\t}\n\n\t// build final geometry\n\n\tconst newGeometry = geometry.clone();\n\tnewGeometry.setIndex( newIndices );\n\n\treturn newGeometry;\n\n}\n\nexport { GLTFLoader };\n","import { addComponent, addEntity } from \"bitecs\";\nimport {\n\tGltfComponent,\n\tObjectComponent,\n\tTransformComponent,\n} from \"../components\";\nimport { World } from \"./world\";\n\nimport * as THREE from \"three\";\nimport { GLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\nimport { API_URL } from \"../constants\";\n\nexport type Object = THREE.Group & { eid: number };\n\nexport const createObject = (\n\tworld: World,\n\tname: string = \"Unnamed\",\n\tfileUrl: string | undefined = undefined,\n\tinitialScale: number = 1,\n\tgroup: THREE.Group = new THREE.Group(),\n): Object => {\n\tconst eid = addEntity(world);\n\n\taddComponent(world, ObjectComponent, eid);\n\taddComponent(world, TransformComponent, eid);\n\n\tTransformComponent.scale.x[eid] = 1;\n\tTransformComponent.scale.y[eid] = 1;\n\tTransformComponent.scale.z[eid] = 1;\n\n\tlet entity = Object.assign(group, { eid });\n\tentity.name = `${name} (Object)`;\n\n\t// position\n\tObject.defineProperty(entity.position, \"eid\", { get: () => eid });\n\tObject.defineProperty(entity.position, \"store\", {\n\t\tget: () => TransformComponent.position,\n\t});\n\n\tObject.defineProperty(entity.position, \"x\", {\n\t\tget() {\n\t\t\treturn this.store.x[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.x[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.position, \"y\", {\n\t\tget() {\n\t\t\treturn this.store.y[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.y[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.position, \"z\", {\n\t\tget() {\n\t\t\treturn this.store.z[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.z[this.eid] = n;\n\t\t},\n\t});\n\n\t// rotation\n\tObject.defineProperty(entity.rotation, \"eid\", { get: () => eid });\n\tObject.defineProperty(entity.rotation, \"store\", {\n\t\tget: () => TransformComponent.rotation,\n\t});\n\n\tObject.defineProperty(entity.rotation, \"_x\", {\n\t\tget() {\n\t\t\treturn this.store.x[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.x[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.rotation, \"_y\", {\n\t\tget() {\n\t\t\treturn this.store.y[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.y[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.rotation, \"_z\", {\n\t\tget() {\n\t\t\treturn this.store.z[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.z[this.eid] = n;\n\t\t},\n\t});\n\n\t// scale\n\tObject.defineProperty(entity.scale, \"eid\", { get: () => eid });\n\tObject.defineProperty(entity.scale, \"store\", {\n\t\tget: () => TransformComponent.scale,\n\t});\n\n\tObject.defineProperty(entity.scale, \"x\", {\n\t\tget() {\n\t\t\treturn this.store.x[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.x[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.scale, \"y\", {\n\t\tget() {\n\t\t\treturn this.store.y[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.y[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.scale, \"z\", {\n\t\tget() {\n\t\t\treturn this.store.z[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.z[this.eid] = n;\n\t\t},\n\t});\n\n\tif (fileUrl === undefined) {\n\t\treturn entity;\n\t}\n\n\tconst loader = new GLTFLoader();\n\tloader.load(\n\t\t`${API_URL}${fileUrl}`,\n\t\tfunction (gltf) {\n\t\t\tlet model: THREE.Group | THREE.Object3D = gltf.scene;\n\t\t\tmodel.scale.set(\n\t\t\t\tinitialScale * model.scale.x,\n\t\t\t\tinitialScale * model.scale.y,\n\t\t\t\tinitialScale * model.scale.z,\n\t\t\t);\n\n\t\t\tentity.add(\n\t\t\t\tObject.assign(model, {\n\t\t\t\t\tmixer: new THREE.AnimationMixer(model),\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tmodel = entity.children[0];\n\n\t\t\taddComponent(world, GltfComponent, eid);\n\t\t\tGltfComponent.timeScale[eid] = 1000;\n\t\t\tGltfComponent.animState[eid] = -1;\n\t\t\tGltfComponent.animAction[eid] = -1;\n\n\t\t\tconsole.log(\"Created GLTF mesh\", model);\n\t\t},\n\t\tundefined,\n\t\tfunction (e) {\n\t\t\tconsole.warn(\"Error loading gltf:\", `${API_URL}${fileUrl}`);\n\t\t\tconsole.error(e);\n\t\t},\n\t);\n\n\treturn entity;\n};\n","import * as THREE from \"three\";\nimport * as bitECS from \"bitecs\";\nimport * as spine from \"@esotericsoftware/spine-threejs\";\n\nimport { Player } from \"./player\";\nimport { Nameplate } from \"./nameplate\";\n\nimport { EffectComposer } from \"three/examples/jsm/postprocessing/EffectComposer.js\";\nimport { Network } from \"../systems/network\";\nimport { API_URL } from \"../constants\";\nimport { Object, createObject } from \"./object\";\nimport { Editor } from \"../systems/editor\";\n\nexport type World = {\n\tplayers: Map;\n\tobjects: Map;\n\tcamera: THREE.Camera;\n\tscene: THREE.Scene;\n\trenderer: THREE.WebGLRenderer;\n\tcomposer: EffectComposer;\n\ttime: {\n\t\tlast: number;\n\t\tdelta: number;\n\t\telapsed: number;\n\t};\n\tnetwork: Network;\n\tspineAssetManager: spine.AssetManager;\n\teditor: Editor;\n};\n\nexport const createWorld = (): World => {\n\tconst world: World = bitECS.createWorld();\n\tconst canvas = document.querySelector(\"#app\")!;\n\tconst aspect = window.innerWidth / window.innerHeight;\n\n\tworld.players = new Map();\n\tworld.objects = new Map();\n\n\t// initialize scene\n\tworld.scene = new THREE.Scene();\n\n\t// add a camera\n\tworld.camera = new THREE.PerspectiveCamera(100, aspect, 0.1, 4000);\n\tworld.camera.position.set(0, 10, 20);\n\n\t// add lights\n\tconst hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d, 2);\n\themiLight.position.set(0, 2, 0);\n\tworld.scene.add(hemiLight);\n\n\tconst dirlight = new THREE.DirectionalLight(0xffffff, 3);\n\tdirlight.position.set(0, 2, 1);\n\tworld.scene.add(dirlight);\n\n\t// add a floor\n\tconst gridHelper = new THREE.GridHelper(20, 10, 0xffffff, 0xffffff);\n\t//@ts-ignore\n\tgridHelper.ignoreIntersect = true;\n\tgridHelper.position.y = 0.01;\n\n\tvar textureLoader = new THREE.TextureLoader();\n\n\tvar textureEquirec = textureLoader.load(\n\t\t`${API_URL}/static/assets/backdrops/clear_sky.png`,\n\t);\n\ttextureEquirec.mapping = THREE.EquirectangularReflectionMapping;\n\ttextureEquirec.colorSpace = THREE.SRGBColorSpace;\n\n\tworld.scene.background = textureEquirec;\n\n\tconst planeMesh = new THREE.Mesh(\n\t\tnew THREE.PlaneGeometry(20, 20),\n\t\tnew THREE.MeshBasicMaterial({\n\t\t\tcolor: 0x0,\n\t\t\tside: THREE.DoubleSide,\n\t\t}),\n\t);\n\tplaneMesh.position.z = 0;\n\tplaneMesh.rotation.x = (Math.PI / 180) * -90;\n\tconst plane = createObject(\n\t\tworld,\n\t\t\"Floor\",\n\t\tundefined,\n\t\t1,\n\t\tnew THREE.Group().add(planeMesh).add(gridHelper),\n\t);\n\tworld.objects.set(plane.eid, plane);\n\tworld.scene.add(plane);\n\n\t// add \"stars\" to the background\n\tvar stars = new Array(0);\n\tfor (var i = 0; i < 0; i++) {\n\t\tlet x = THREE.MathUtils.randFloatSpread(50);\n\t\tlet y = THREE.MathUtils.randFloatSpread(50);\n\t\tlet z = THREE.MathUtils.randFloatSpread(50);\n\t\tstars.push(x, y, z);\n\t}\n\tvar starsGeometry = new THREE.BufferGeometry();\n\tstarsGeometry.setAttribute(\n\t\t\"position\",\n\t\tnew THREE.Float32BufferAttribute(stars, 3),\n\t);\n\tconst loader = new THREE.TextureLoader();\n\tvar starsMaterial = new THREE.PointsMaterial({\n\t\tsize: 0.5,\n\t\tmap: loader.load(\n\t\t\t\"https://raw.githubusercontent.com/Kuntal-Das/textures/main/sp2.png\",\n\t\t),\n\t\ttransparent: true,\n\t\tcolor: 0xffffff,\n\t});\n\tvar starField = new THREE.Points(starsGeometry, starsMaterial);\n\tworld.scene.add(starField);\n\n\t// create a default renderer, this can be modified later by render system\n\tworld.renderer = new THREE.WebGLRenderer({ antialias: true, canvas });\n\n\tworld.time = { last: 0, delta: 0, elapsed: 0 };\n\n\tworld.spineAssetManager = new spine.AssetManager(\n\t\t`${API_URL}/static/assets/avatars/`,\n\t);\n\n\treturn world;\n};\n","/*!\n * SystemJS 6.14.3\n */\n!function(){function e(e,t){return(t||\"\")+\" (SystemJS Error#\"+e+\" https://github.com/systemjs/systemjs/blob/main/docs/errors.md#\"+e+\")\"}function t(e,t){if(-1!==e.indexOf(\"\\\\\")&&(e=e.replace(j,\"/\")),\"/\"===e[0]&&\"/\"===e[1])return t.slice(0,t.indexOf(\":\")+1)+e;if(\".\"===e[0]&&(\"/\"===e[1]||\".\"===e[1]&&(\"/\"===e[2]||2===e.length&&(e+=\"/\"))||1===e.length&&(e+=\"/\"))||\"/\"===e[0]){var n,r=t.slice(0,t.indexOf(\":\")+1);if(n=\"/\"===t[r.length+1]?\"file:\"!==r?(n=t.slice(r.length+2)).slice(n.indexOf(\"/\")+1):t.slice(8):t.slice(r.length+(\"/\"===t[r.length])),\"/\"===e[0])return t.slice(0,t.length-n.length-1)+e;for(var i=n.slice(0,n.lastIndexOf(\"/\")+1)+e,o=[],s=-1,u=0;un.length&&\"/\"!==r[r.length-1]))return r+e.slice(n.length);u(\"W2\",n,r,\"should have a trailing '/'\")}}function u(t,n,r,i){console.warn(e(t,\"Package target \"+i+\", resolving target '\"+r+\"' for \"+n))}function c(e,t,n){for(var r=e.scopes,i=n&&o(n,r);i;){var u=s(t,r[i]);if(u)return u;i=o(i.slice(0,i.lastIndexOf(\"/\")),r)}return s(t,e.imports)||-1!==t.indexOf(\":\")&&t}function a(){this[M]={}}function f(e){return e.id}function l(e,t,n,r){if(e.onload(n,t.id,t.d&&t.d.map(f),!!r),n)throw n}function d(t,n,r,i){var o=t[M][n];if(o)return o;var s=[],u=Object.create(null);P&&Object.defineProperty(u,P,{value:\"Module\"});var c=Promise.resolve().then((function(){return t.instantiate(n,r,i)})).then((function(r){if(!r)throw Error(e(2,\"Module \"+n+\" did not instantiate\"));var i=r[1]((function(e,t){o.h=!0;var n=!1;if(\"string\"==typeof e)e in u&&u[e]===t||(u[e]=t,n=!0);else{for(var r in e)t=e[r],r in u&&u[r]===t||(u[r]=t,n=!0);e&&e.__esModule&&(u.__esModule=e.__esModule)}if(n)for(var i=0;i-1){var n=document.createEvent(\"Event\");n.initEvent(\"error\",!1,!1),t.dispatchEvent(n)}return Promise.reject(e)}))}else if(\"systemjs-importmap\"===t.type){t.sp=!0;var r=t.src?(System.fetch||fetch)(t.src,{integrity:t.integrity,passThrough:!0}).then((function(e){if(!e.ok)throw Error(\"Invalid status code: \"+e.status);return e.text()})).catch((function(n){return n.message=e(\"W4\",\"Error fetching systemjs-import map \"+t.src)+\"\\n\"+n.message,console.warn(n),\"function\"==typeof t.onerror&&t.onerror(),\"{}\"})):t.innerHTML;W=W.then((function(){return r})).then((function(n){!function(t,n,r){var o={};try{o=JSON.parse(n)}catch(s){console.warn(Error(e(\"W5\",\"systemjs-importmap contains invalid JSON\")+\"\\n\\n\"+n+\"\\n\"))}i(o,r,t)}(T,n,t.src||g)}))}}))}var g,y=\"undefined\"!=typeof Symbol,b=\"undefined\"!=typeof self,w=\"undefined\"!=typeof document,S=b?self:global;if(w){var E=document.querySelector(\"base[href]\");E&&(g=E.href)}if(!g&&\"undefined\"!=typeof location){var O=(g=location.href.split(\"#\")[0].split(\"?\")[0]).lastIndexOf(\"/\");-1!==O&&(g=g.slice(0,O+1))}var x,j=/\\\\/g,P=y&&Symbol.toStringTag,M=y?Symbol():\"@\",L=a.prototype;L.import=function(e,t,n){var r=this;return t&&\"object\"==typeof t&&(n=t,t=void 0),Promise.resolve(r.prepareImport()).then((function(){return r.resolve(e,t,n)})).then((function(e){var t=d(r,e,void 0,n);return t.C||p(r,t)}))},L.createContext=function(e){var t=this;return{url:e,resolve:function(n,r){return Promise.resolve(t.resolve(n,r||e))}}},L.onload=function(){},L.register=function(e,t,n){x=[e,t,n]},L.getRegister=function(){var e=x;return x=void 0,e};var C=Object.freeze(Object.create(null));S.System=new a;var I,R,W=Promise.resolve(),T={imports:{},scopes:{},depcache:{},integrity:{}},A=w;if(L.prepareImport=function(e){return(A||e)&&(m(),A=!1),W},w&&(m(),window.addEventListener(\"DOMContentLoaded\",m)),L.addImportMap=function(e,t){i(e,t||g,T)},w){window.addEventListener(\"error\",(function(e){_=e.filename,J=e.error}));var N=location.origin}L.createScript=function(e){var t=document.createElement(\"script\");t.async=!0,e.indexOf(N+\"/\")&&(t.crossOrigin=\"anonymous\");var n=T.integrity[e];return n&&(t.integrity=n),t.src=e,t};var _,J,k={},U=L.register;L.register=function(e,t){if(w&&\"loading\"===document.readyState&&\"string\"!=typeof e){var n=document.querySelectorAll(\"script[src]\"),r=n[n.length-1];if(r){I=e;var i=this;R=setTimeout((function(){k[r.src]=[e,t],i.import(r.src)}))}}else I=void 0;return U.call(this,e,t)},L.instantiate=function(t,n){var r=k[t];if(r)return delete k[t],r;var i=this;return Promise.resolve(L.createScript(t)).then((function(r){return new Promise((function(o,s){r.addEventListener(\"error\",(function(){s(Error(e(3,\"Error loading \"+t+(n?\" from \"+n:\"\"))))})),r.addEventListener(\"load\",(function(){if(document.head.removeChild(r),_===t)s(J);else{var e=i.getRegister(t);e&&e[0]===I&&clearTimeout(R),o(e)}})),document.head.appendChild(r)}))}))},L.shouldFetch=function(){return!1},\"undefined\"!=typeof fetch&&(L.fetch=fetch);var $=L.instantiate,B=/^(text|application)\\/(x-)?javascript(;|$)/;L.instantiate=function(t,n,r){var i=this;return this.shouldFetch(t,n,r)?this.fetch(t,{credentials:\"same-origin\",integrity:T.integrity[t],meta:r}).then((function(r){if(!r.ok)throw Error(e(7,r.status+\" \"+r.statusText+\", loading \"+t+(n?\" from \"+n:\"\")));var o=r.headers.get(\"content-type\");if(!o||!B.test(o))throw Error(e(4,'Unknown Content-Type \"'+o+'\", loading '+t+(n?\" from \"+n:\"\")));return r.text().then((function(e){return e.indexOf(\"//# sourceURL=\")<0&&(e+=\"\\n//# sourceURL=\"+t),(0,eval)(e),i.getRegister(t)}))})):$.apply(this,arguments)},L.resolve=function(n,r){return c(T,t(n,r=r||g)||n,r)||function(t,n){throw Error(e(8,\"Unable to resolve bare specifier '\"+t+(n?\"' from \"+n:\"'\")))}(n,r)};var F=L.instantiate;L.instantiate=function(e,t,n){var r=T.depcache[e];if(r)for(var i=0;i {\n var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;\n if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;\n return (\nfunction(Module = {}) {\n\nvar Module=typeof Module!=\"undefined\"?Module:{};var readyPromiseResolve,readyPromiseReject;Module[\"ready\"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram=\"./this.program\";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window==\"object\";var ENVIRONMENT_IS_WORKER=typeof importScripts==\"function\";var ENVIRONMENT_IS_NODE=typeof process==\"object\"&&typeof process.versions==\"object\"&&typeof process.versions.node==\"string\";var scriptDirectory=\"\";function locateFile(path){if(Module[\"locateFile\"]){return Module[\"locateFile\"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;function logExceptionOnExit(e){if(e instanceof ExitStatus)return;let toLog=e;err(\"exiting due to exception: \"+toLog)}if(ENVIRONMENT_IS_NODE){var fs=require(\"fs\");var nodePath=require(\"path\");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+\"/\"}else{scriptDirectory=__dirname+\"/\"}read_=(filename,binary)=>{var ret=tryParseAsDataURI(filename);if(ret){return binary?ret:ret.toString()}filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:\"utf8\")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=(filename,onload,onerror)=>{var ret=tryParseAsDataURI(filename);if(ret){onload(ret)}filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,function(err,data){if(err)onerror(err);else onload(data.buffer)})};if(process[\"argv\"].length>1){thisProgram=process[\"argv\"][1].replace(/\\\\/g,\"/\")}arguments_=process[\"argv\"].slice(2);process[\"on\"](\"uncaughtException\",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});var nodeMajor=process.version.match(/^v(\\d+)\\./)[1];if(nodeMajor<15){process[\"on\"](\"unhandledRejection\",function(reason){throw reason})}quit_=(status,toThrow)=>{if(keepRuntimeAlive()){process[\"exitCode\"]=status;throw toThrow}logExceptionOnExit(toThrow);process[\"exit\"](status)};Module[\"inspect\"]=function(){return\"[Emscripten Module object]\"}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=\"undefined\"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf(\"blob:\")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,\"\").lastIndexOf(\"/\")+1)}else{scriptDirectory=\"\"}{read_=url=>{try{var xhr=new XMLHttpRequest;xhr.open(\"GET\",url,false);xhr.send(null);return xhr.responseText}catch(err){var data=tryParseAsDataURI(url);if(data){return intArrayToString(data)}throw err}};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{try{var xhr=new XMLHttpRequest;xhr.open(\"GET\",url,false);xhr.responseType=\"arraybuffer\";xhr.send(null);return new Uint8Array(xhr.response)}catch(err){var data=tryParseAsDataURI(url);if(data){return data}throw err}}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open(\"GET\",url,true);xhr.responseType=\"arraybuffer\";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}var data=tryParseAsDataURI(url);if(data){onload(data.buffer);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module[\"print\"]||console.log.bind(console);var err=Module[\"printErr\"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module[\"arguments\"])arguments_=Module[\"arguments\"];if(Module[\"thisProgram\"])thisProgram=Module[\"thisProgram\"];if(Module[\"quit\"])quit_=Module[\"quit\"];var wasmBinary;if(Module[\"wasmBinary\"])wasmBinary=Module[\"wasmBinary\"];var noExitRuntime=Module[\"noExitRuntime\"]||true;if(typeof WebAssembly!=\"object\"){abort(\"no native wasm support detected\")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}var UTF8Decoder=typeof TextDecoder!=\"undefined\"?new TextDecoder(\"utf8\"):undefined;function UTF8ArrayToString(heapOrArray,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str=\"\";while(idx>10,56320|ch&1023)}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):\"\"}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len}var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module[\"HEAP8\"]=HEAP8=new Int8Array(b);Module[\"HEAP16\"]=HEAP16=new Int16Array(b);Module[\"HEAP32\"]=HEAP32=new Int32Array(b);Module[\"HEAPU8\"]=HEAPU8=new Uint8Array(b);Module[\"HEAPU16\"]=HEAPU16=new Uint16Array(b);Module[\"HEAPU32\"]=HEAPU32=new Uint32Array(b);Module[\"HEAPF32\"]=HEAPF32=new Float32Array(b);Module[\"HEAPF64\"]=HEAPF64=new Float64Array(b)}var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function keepRuntimeAlive(){return noExitRuntime}function preRun(){if(Module[\"preRun\"]){if(typeof Module[\"preRun\"]==\"function\")Module[\"preRun\"]=[Module[\"preRun\"]];while(Module[\"preRun\"].length){addOnPreRun(Module[\"preRun\"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module[\"postRun\"]){if(typeof Module[\"postRun\"]==\"function\")Module[\"postRun\"]=[Module[\"postRun\"]];while(Module[\"postRun\"].length){addOnPostRun(Module[\"postRun\"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module[\"monitorRunDependencies\"]){Module[\"monitorRunDependencies\"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module[\"monitorRunDependencies\"]){Module[\"monitorRunDependencies\"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module[\"onAbort\"]){Module[\"onAbort\"](what)}what=\"Aborted(\"+what+\")\";err(what);ABORT=true;EXITSTATUS=1;what+=\". Build with -sASSERTIONS for more info.\";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix=\"data:application/octet-stream;base64,\";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith(\"file://\")}var wasmBinaryFile;wasmBinaryFile=\"data:application/octet-stream;base64,AGFzbQEAAAABwQmOAWACf38AYAJ/fwF/YAF/AGABfwF/YAN/f38AYAN/f38Bf2AAAGAEf39/fwBgBH9/f38Bf2AAAX9gB39/f39/f38Bf2AGf39/f39/AX9gBX9/f39/AGAFf39/f38Bf2ACf38BfWAIf39/f39/f38Bf2AGf39/f39/AGACf30AYAABfWABfQBgB39/f39/f38AYAF9AX1gBX9/f399AGAFf35+fn4AYAZ/f39/f30AYAV/f31/fwBgAX8BfWADf399AGAFf39/fX8AYAN/fn8BfmAEf399fwBgCX9/f39/f39/fwF/YAp/f39/f39/f39/AGAIf39/f39/f38AYAJ/fQF/YAZ9fX1/f38AYAZ/f39/fX8AYAJ9fQBgBn9/fX19fwBgBn9/fX9/fQBgBH9/f30AYAF/AXxgA39/fQF/YAd/f39/f399AGAHf39/f31/fQBgBH9+fn8AYAF8AXxgBX9/f319AGAIf399fX1/f38AYAN/fX0AYAZ/f399f38AYAN/fX0Bf2AFf39/f30Bf2AGf399f39/AGALf39/f39/f39/f38AYAh/f39/f399fwBgB39/f39/fX8AYAl/f39/f39/fX8AYAl/f39/f39/f38AYAJ9fQF9YAF8AX1gBH9/fX0AYAJ8fwF8YAZ9fX1/fX0BfWACf3wBfGACf30BfWAGf31/f39/AX9gCn9/f39/f39/f38Bf2AGf3x/f39/AX9gAX4Bf2AAAXxgA31/fwBgA39/fwF9YAR/fX99AX9gCH9/fX9/f31/AGADf31/AGAGf398fH9/AX9gA39/fwF8YA1/f39/f39/f39/f39/AGADf398AGAHf319fX19fQBgCX9/f399f39/fwF/YAd/f399fX19AGACf34AYAJ/fABgCH9/f31/f39/AX9gCX9/fX9/f399fwBgAnx8AXxgAX0Bf2AEfn5+fgF/YAJ/fgF+YAR9fX19AX9gAn5/AX9gAXwBf2AGfHx8f319AX1gBX5+fn99AX1gBn5+fn99fQF9YAV/f39/fQF9YAZ/f39/fX0BfWAGfXx8f319AXxgBX1+fn99AX5gBn1+fn99fQF+YAZ9f39/fX0Bf2AIf39/f31/fX8AYAh/f319f39/fwBgBX99f399AX9gAn5+AXxgCH9/f319f39/AGAEf319fQF9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AhAwOAIEIAMQACACQRBqJAAgAQsyAQF/QZC/BCgCACIBBEAgASABKALsBkEBajYC7AYLIABBmL8EKAIAQdi8BCgCABEBAAvyAgICfwF+AkAgAkUNACAAIAE6AAAgACACaiIDQQFrIAE6AAAgAkEDSQ0AIAAgAToAAiAAIAE6AAEgA0EDayABOgAAIANBAmsgAToAACACQQdJDQAgACABOgADIANBBGsgAToAACACQQlJDQAgAEEAIABrQQNxIgRqIgMgAUH/AXFBgYKECGwiATYCACADIAIgBGtBfHEiBGoiAkEEayABNgIAIARBCUkNACADIAE2AgggAyABNgIEIAJBCGsgATYCACACQQxrIAE2AgAgBEEZSQ0AIAMgATYCGCADIAE2AhQgAyABNgIQIAMgATYCDCACQRBrIAE2AgAgAkEUayABNgIAIAJBGGsgATYCACACQRxrIAE2AgAgBCADQQRxQRhyIgRrIgJBIEkNACABrUKBgICAEH4hBSADIARqIQEDQCABIAU3AxggASAFNwMQIAEgBTcDCCABIAU3AwAgAUEgaiEBIAJBIGsiAkEfSw0ACwsgAAtdAgF/AXwjAEEQayIBJAAgACgCAEGYuQQgAUEMahAHIQIgASgCDBAGIAFBEGokAAJ9Q///f38gAkQAAADg///vR2YNABpD//9//yACRAAAAOD//+/HZQ0AGiACtgsLQwEBfyMAQRBrIgEkACABIAAoAhAQXyAALAAPQQBIBEAgACgCBBArCyAAIAEpAwA3AgQgACABKAIINgIMIAFBEGokAAtZAQJ/IwBBEGsiAiQAIAJBkL8EKAIAIgNBqCpqIABBBHRqIgApAtABNwMIIAIgACkCyAE3AwAgAiACKgIMIAMqAqgqIAGUlDgCDCACEDYhACACQRBqJAAgAAuFAQEDfyABKAIAIgJB8P///wdJBEACQAJAIAJBC08EQCACQQ9yQQFqIgMQKSEEIAAgA0GAgICAeHI2AgggACAENgIAIAAgAjYCBCACIARqIQMgBCEADAELIAAgAjoACyAAIAJqIQMgAkUNAQsgACABQQRqIAIQKhoLIANBADoAAA8LEMoCAAsiAQF/IwBBEGsiAiQAIAIgATYCDCAAIAEQnwIgAkEQaiQAC1ABAX8jAEEQayIEJAAgBCADNgIMIAAgASACIAMQ7gIhAyAABEAgACADIAFBAWsiAiABIANKGyACIANBf0cbIgNqQQA6AAALIARBEGokACADC6ICAgF9AX8Cf0MAAAAAIAAqAgQiAUMAAIA/liABQwAAAABdG0MAAH9DlEMAAAA/kiIBi0MAAABPXQRAIAGoDAELQYCAgIB4C0EIdCECAn9DAAAAACAAKgIAIgFDAACAP5YgAUMAAAAAXRtDAAB/Q5RDAAAAP5IiAYtDAAAAT10EQCABqAwBC0GAgICAeAsgAnIhAiACAn9DAAAAACAAKgIIIgFDAACAP5YgAUMAAAAAXRtDAAB/Q5RDAAAAP5IiAYtDAAAAT10EQCABqAwBC0GAgICAeAtBEHRyIQIgAgJ/QwAAAAAgACoCDCIBQwAAgD+WIAFDAAAAAF0bQwAAf0OUQwAAAD+SIgGLQwAAAE9dBEAgAagMAQtBgICAgHgLQRh0cguLAgIDfwJ+AkAgACkDcCIEUEUgBCAAKQN4IAAoAgQiASAAKAIsIgJrrHwiBVdxRQRAIwBBEGsiAiQAQX8hAQJAIAAQ8AMNACAAIAJBD2pBASAAKAIgEQUAQQFHDQAgAi0ADyEBCyACQRBqJAAgASIDQQBODQEgACgCBCEBIAAoAiwhAgsgAEJ/NwNwIAAgATYCaCAAIAUgAiABa6x8NwN4QX8PCyAFQgF8IQUgACgCBCEBIAAoAgghAgJAIAApA3AiBFANACAEIAV9IgQgAiABa6xZDQAgASAEp2ohAgsgACACNgJoIAAgBSAAKAIsIgAgAWusfDcDeCAAIAFPBEAgAUEBayADOgAACyADC2QCAn8CfQJAIABBAEgNAEGQvwQoAgAiAyAAQQJ0akH0CGoqAgAiBEMAAAAAWyICIAFFcg0AQQAhAiAEIAMqAowBIgVeRQ0AIAQgAyoCGJMgBCAFIAMqApABEPoBQQBKIQILIAILZgEBf0GQvwQoAgAiAigC4DcgAUEAIAAoAswBIAAoAsQBQQJ0akEEaygCABBKIgBGBEAgAiAANgLkNwsgACACKAKcOEYEQCACQQE6AKA4CyAAIAIoAsg3RgRAIABBCyABELQBCyAAC9kIAwV/Bn0CfkGQvwQoAgAiBCABNgLIOCAEQdQ4aiAAKQIANwIAIARB3DhqIAApAgg3AgAgAiAAIAIbIgIpAgAhDyACKQIIIRAgBEHMOGogBCgCsDggA3IiAzYCACAEQdA4akEANgIAIARB7DhqIBA3AgAgBEHkOGogDzcCAAJAIAFFDQAgBCgCqDciAkGqAmogAi8BqgJBASACKAKkAiIGdHI7AQAgASAEKALYOiIHRwRAIAQtAJQ7RQ0BCyAEKALUOiIFKALsBSACKALsBUcNACACIAVGIghFBEAgBSgCCCACKAIIckGAgIAEcUUNAQsgBEHwOGoqAgAhCiAEQew4aioCACENIARB6DhqKgIAIQsgBCoC5DghDgJAIAQtAJU7RQRAQQAhBQwBC0EBIQUgBCgCjDsgBkcNACADQRRxIgYEQCAEKAKYOw0BCyAEIAE2Apg7IAIqAuABIQkgBEGoO2ogCiACKgLkASIMkzgCACAEQaQ7aiANIAmTOAIAIARBoDtqIAsgDJM4AgAgBCAOIAmTOAKcOyAGDQBBACEFIARBADoAlTsgBCAELQCtOzoAlDsLAkAgBC0ArTtFDQAgBCgCsDsiBkGACHEEQCAGQYAEcUUgA0GFAnFBgAJHcQ0BIARB9DtqIQMCQAJAAkAgBCgC7DtBAWoOAwECAAQLIARB/DxqKAIARQRAIARB+DxqENUBCyAEIAQoAvA7QQFrIgU2AvA7IAVFBEBBkL8EKAIAQQA6AK07IAMQ1QFBASEDQZC/BCgCACIFLQCtO0UEQCAFLQCVOyEDCyAFIAM6AJQ7DAQLIAQoAtg6IAFHDQMgBEEBNgLwOwwDCyABIAdGBEAgBEH4O2ooAgBFDQMgBCAFOgCUOyAEQQA6AK07DAMLIAMQ1QEMAgsgBEH8PGooAgANASAEQQA6AK07IARB+DxqENUBQQEhA0GQvwQoAgAiBS0ArTtFBEAgBS0AlTshAwsgBSADOgCUOwwBCyAGQRBxQQR2IAEgB0dyRSADQQxxcg0AIARB9DtBzDwgCBtqIgMQsAUEQCADENUBCyAELQCwO0EgcUUNACALIAIqAvwDIgldRQ0AIAogAioC9AMiDF5FDQAgDiACKgL4A11FDQAgDSACKgLwA15FIAwgCSAKIAkgCl0bIAogDF0bIAwgCSALIAkgC10bIAsgDF0bkyAKIAuTQzMzMz+UYEVyDQAgBEGgPGoiAxCwBUUNACADENUBCyAEKALYOiABRw0AIAQgAjYC1DogBCACKAKkAiIDNgKMOyACKAKsAiEFIARBAToAkDsgBCAFNgLcOiACKgLgASEJIAIgA0EEdGoiAyAKIAIqAuQBIgqTOAKIBiADIA0gCZM4AoQGIAMgCyAKkzgCgAYgAyAOIAmTOAL8BQsgBEEANgK0OAJAIAAgARDDAiIBDQAgACAAQQhqQQEQxgJFDQAgBCAEKALQOEEBcjYC0DgLIAFBAXML0AECAn8BfUGQvwQoAgAhBQJAAkACQCADRQ0AIAEgAkF/IAIbIgNPBEAgBSoCxDIhBwwCCyABIQIDQAJAIAItAAAiBkEjRwRAIAYNAQwDCyACLQABQSNGDQILIAJBAWoiAiADRw0ACyADIQILIAUqAsQyIQcgASACRw0BCyAAIAc4AgQgAEEANgIADwsgACAFKALAMiAHQ///f38gBCABIAJBABCkAiAAAn8gACoCAENY/38/kiIEi0MAAABPXQRAIASoDAELQYCAgIB4C7I4AgALxQoCBX8PfiMAQeAAayIFJAAgBEL///////8/gyEMIAIgBIVCgICAgICAgICAf4MhCiACQv///////z+DIg1CIIghDiAEQjCIp0H//wFxIQcCQAJAIAJCMIinQf//AXEiCUH//wFrQYKAfk8EQCAHQf//AWtBgYB+Sw0BCyABUCACQv///////////wCDIgtCgICAgICAwP//AFQgC0KAgICAgIDA//8AURtFBEAgAkKAgICAgIAghCEKDAILIANQIARC////////////AIMiAkKAgICAgIDA//8AVCACQoCAgICAgMD//wBRG0UEQCAEQoCAgICAgCCEIQogAyEBDAILIAEgC0KAgICAgIDA//8AhYRQBEAgAiADhFAEQEKAgICAgIDg//8AIQpCACEBDAMLIApCgICAgICAwP//AIQhCkIAIQEMAgsgAyACQoCAgICAgMD//wCFhFAEQCABIAuEIQJCACEBIAJQBEBCgICAgICA4P//ACEKDAMLIApCgICAgICAwP//AIQhCgwCCyABIAuEUARAQgAhAQwCCyACIAOEUARAQgAhAQwCCyALQv///////z9YBEAgBUHQAGogASANIAEgDSANUCIGG3kgBkEGdK18pyIGQQ9rEFtBECAGayEGIAUpA1giDUIgiCEOIAUpA1AhAQsgAkL///////8/Vg0AIAVBQGsgAyAMIAMgDCAMUCIIG3kgCEEGdK18pyIIQQ9rEFsgBiAIa0EQaiEG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fyADKAIEIgQgAygCaEcEQCADIARBAWo2AgQgBC0AAAwBCyADEDcLQfGwBGotAABLDQALQcztBUHEADYCAEEAIQhCfyEUCyADKQNwQgBZBEAgAyADKAIEQQFrNgIECyAIQQFyRSAUQn9RcQRAQcztBUHEADYCAEJ+IRQMAQsgFCAIrCIVhSAVfSEUCyAOQRBqJAAgAykDeEIAIAMoAgQgAygCLGusfVENByAJRSAMQfAAR3JFBEAgCSAUPgIADAMLIAkgCyAUENkFDAILIAlFDQEgBykDECEUIAcpAwghFQJAAkACQCALDgMAAQIECyMAQSBrIgIkAAJAIBRC////////////AIMiFkKAgICAgIDAwD99IBZCgICAgICAwL/AAH1UBEAgFEIZiKchBSAVUCAUQv///w+DIhZCgICACFQgFkKAgIAIURtFBEAgBUGBgICABGohBAwCCyAFQYCAgIAEaiEEIBUgFkKAgIAIhYRCAFINASAEIAVBAXFqIQQMAQsgFVAgFkKAgICAgIDA//8AVCAWQoCAgICAgMD//wBRG0UEQCAUQhmIp0H///8BcUGAgID+B3IhBAwBC0GAgID8ByEEIBZC////////v7/AAFYNAEEAIQQgFkIwiKciBUGR/gBJDQAgAkEQaiAVIBRC////////P4NCgICAgICAwACEIhYgBUGB/gBrEFsgAiAVIBZBgf8AIAVrENoBIAIpAwgiFUIZiKchBCACKQMAIAIpAxAgAikDGIRCAFKthCIWUCAVQv///w+DIhVCgICACFQgFUKAgIAIURtFBEAgBEEBaiEEDAELIBYgFUKAgIAIhYRCAFINACAEQQFxIARqIQQLIAJBIGokACAJIAQgFEIgiKdBgICAgHhxcjYCAAwDCyAJIBUgFBDqAzkDAAwCCyAJIBU3AwAgCSAUNwMIDAELQR8gBEEBaiAMQeMARyIRGyEFAkAgC0EBRgRAIAkhAiANBEAgBUECdBBnIgJFDQcLIAdCADcDqAJBACEEA0AgAiEAAkADQAJ/IAMoAgQiAiADKAJoRwRAIAMgAkEBajYCBCACLQAADAELIAMQNwsiAiAHai0AIUUNASAHIAI6ABsCfyAHQRxqIQYgB0GoAmoiAkGQ9wUgAhsiCygCACECAkACfwJAIAdBG2oiCkUEQCACDQFBAAwECwJAIAIEQEEB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NwIAAkAgBiAHQTBsai0ALQ0AIAEoAsw3RQ0AIAFB0DhqIgAgACgCAEGAAXI2AgALAkAgBUUNACABLQDxN0UNACABQdA4aiIAIAAoAgBBBHI2AgALIAFB0DhqIgAgACgCACIAQSByNgIAIARFDQAgAiABKAKcOEYNACABIABB4AByNgLQOAsgASABKAKgOkEBazYCoDogA0EgaiQAC8YJAgR/BX4jAEHwAGsiBiQAIARC////////////AIMhCQJAAkAgAVAiBSACQv///////////wCDIgpCgICAgICAwP//AH1CgICAgICAwICAf1QgClAbRQRAIANCAFIgCUKAgICAgIDA//8AfSILQoCAgICAgMCAgH9WIAtCgICAgICAwICAf1EbDQELIAUgCkKAgICAgIDA//8AVCAKQoCAgICAgMD//wBRG0UEQCACQoCAgICAgCCEIQQgASEDDAILIANQIAlCgICAgICAwP//AFQgCUKAgICAgIDA//8AURtFBEAgBEKAgICAgIAghCEEDAILIAEgCkKAgICAgIDA//8AhYRQBEBCgICAgICA4P//ACACIAEgA4UgAiAEhUKAgICAgICAgIB/hYRQIgUbIQRCACABIAUbIQMMAgsgAyAJQoCAgICAgMD//wCFhFANASABIAqEUARAIAMgCYRCAFINAiABIAODIQMgAiAEgyEEDAILIAMgCYRQRQ0AIAEhAyACIQQMAQsgAyABIAEgA1QgCSAKViAJIApRGyIIGyEKIAQgAiAIGyILQv///////z+DIQkgAiAEIAgbIgJCMIinQf//AXEhByALQjCIp0H//wFxIgVFBEAgBkHgAGogCiAJIAogCSAJUCIFG3kgBUEGdK18pyIFQQ9rEFsgBikDaCEJIAYpA2AhCkEQIAVrIQULIAEgAyAIGyEDIAJC////////P4MhBCAHRQRAIAZB0ABqIAMgBCADIAQgBFAiBxt5IAdBBnStfKciB0EPaxBbQRAgB2shByAGKQNYIQQgBikDUCEDCyAEQgOGIANCPYiEQoCAgICAgIAEhCEBIAlCA4YgCkI9iIQhBCACIAuFIQ0CfiADQgOGIgIgBSAHRg0AGiAFIAdrIgdB/wBLBEBCACEBQgEMAQsgBkFAayACIAFBgAEgB2sQWyAGQTBqIAIgASAHENoBIAYpAzghASAGKQMw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RQ0AIAlB/CpqKgIAIQ0gCCAIKgKsASAJKgLoKpI4AhwgCCANIAgqArABkjgCGCAIIAgpAxg3AwAgCCAAQQBBARBTCyAIQcABaiQAIAwLSgECfyMAQRBrIgEkAEGQvwQoAgAhAiABIAApAgg3AwggASAAKQIANwMAIAEgAioCqCogASoCDJQ4AgwgARA2IQAgAUEQaiQAIAALpQEBBH8gACABaiIDLQAEQQh0IAMtAAVyIgQEQCABQQxqIQUgAiwAACEGQQAhAQNAAkAgACAFIAFBBHRqaiIDLQAAIAZHDQAgAy0AASACLAABRw0AIAMtAAIgAiwAAkcNACADLQADIAIsAANHDQAgAygACCIAQRh0IABBgP4DcUEIdHIgAEEIdkGA/gNxIABBGHZycg8LIAFBAWoiASAERw0ACwtBAAt3AQV/IAAoAggiBCECIAAoAgAiBQRAIAUhAANAIAIgAEEBdiIGQQN0aiIDQQhqIAIgAygCACABSSIDGyECIAAgBkF/c2ogBiADGyIADQALC0EAIQACQCACIAQgBUEDdGpGDQAgAigCACABRw0AIAIoAgQhAAsgAAv5AQIDfgJ/IwBBEGsiBSQAAn4gAb0iA0L///////////8AgyICQoCAgICAgIAIfUL/////////7/8AWARAIAJCPIYhBCACQgSIQoCAgICAgICAPHwMAQsgAkKAgICAgICA+P8AWgRAIANCPIYhBCADQgSIQoCAgICAgMD//wCEDAELIAJQBEBCAAwBCyAFIAJCACADp2dBIGogAkIgiKdnIAJCgICAgBBUGyIGQTFqEFsgBSkDACEEIAUpAwhCgICAgICAwACFQYz4ACAGa61CMIaECyECIAAgBDcDACAAIAIgA0KAgICAgICAgIB/g4Q3AwggBUEQaiQAC0oBAn8CQCAALQAAIgJFIAIgAS0AACIDR3INAANAIAEtAAEhAyAALQABIgJFDQEgAUEBaiEBIABBAWohACACIANGDQALCyACIANrC4EBAQJ/AkACQCACQQRPBEAgACABckEDcQ0BA0AgACgCACABKAIARw0CIAFBBGohASAAQQRqIQAgAkEEayICQQNLDQALCyACRQ0BCwNAIAAtAAAiAyABLQAAIgRGBEAgAUEBaiEBIABBAWohACACQQFrIgINAQwCCwsgAyAEaw8LQQALZgECfyMAQRBrIgIkAEH87AUtAABBAXFFBEBBAkHIlgMQEiEDQfzsBUEBOgAAQfjsBSADNgIAC0H47AUoAgAhAyABKAIAEAUgAiABKAIANgIIIAMgAEHsGyACQQhqEBEgAkEQaiQAC+kCAgh/AX5B5JCLDCAAdkEBcUUgAEEMbEHgowFqKAIAQQhHckUEQEGQvwQoAgAiAiAAQQxsQeijAWooAgBqQagqaiIGKQIAIgqnIQcgCkIgiKchCAJAIAIoAvA5IgMgAkH0OWooAgBHDQAgA0EBaiEEIAMgAwR/IANBAm0gA2oFQQgLIgUgBCAEIAVIGyIFTg0AIAIgAigC7AZBAWo2AuwGIAVBDGxBmL8EKAIAQdi8BCgCABEBACEDIAJB+DlqKAIAIgQEQCADIAQgAigC8DlBDGwQKhoCQCACKAL4OSIJRQ0AQZC/BCgCACIERQ0AIAQgBCgC7AZBAWs2AuwGCyAJQZi/BCgCAEHcvAQoAgARAAALIAIgBTYC9DkgAiADNgL4OSACKALwOSEDCyACQfg5aigCACADQQxsaiIDIAg2AgggAyAHNgIEIAMgADYCACACIAIoAvA5QQFqNgLwOSAGIAEpAgA3AgALC78lBAV9BH4JfwR8IwBBsAFrIhIkAEGQvwQoAgAiFSgCqDciEUEBOgCMAQJAIBEtAI8BDQAgESAAEDkhGBBhIQkgEkGoAWogAEEAQQFDAACAvxA7IBEqAtABIQogESkC0AEhDSASIBVB6CpqKgIAIgggCJIgEioCrAGSIBEqAtQBkiILOAKkASASIA03A5gBIBIgCSAKkiIKOAKgAUMAAAAAIQkgEioCqAEiDEMAAAAAXgRAIAwgFUH8KmoqAgCSIQkLIBIgC0MAAAAAkjgClAEgEiANNwOIASASIAkgCpI4ApABIBJBiAFqIhMgCBB7IBMgGCASQZgBaiAHQYABcSIUQQF0QYACcxA6RQ0AAkAgBkUEQCABQQR0Qdj4AmooAgAhBgwBCyABQQRHDQAgBkH66AAQngFFDQAgBhCeAyEGCyASQZgBaiAYELEBIRcCQAJAIBRFBEAgGEGQvwQoAgAiFigC4DdGBEAgFigCwF0gGEYNAgsgFUHROGotAABBAXEhFgtBACETIBcEQCAVLQDgB0EARyEZIBUvAeoHQQJGIRMLAkACQCAWIBlyIBNyDQAgFSgC4DogGEYNACAVKALsOiAYRw0BCyAYIBEQTCAYIBEQuwEgERBIIBVBAzYC9DcgFA0CIBYNAQJAIBkEQCAVLQD8AUEARyATckUNAQwDCyATDQILIBUoAuw6IBhGDQELIBQNASAVLQCzAUUNASAXQQFzIBUoAuA3IBhHcg0BIBUtAP4HRQ0BIBUqAjBDAAAAP5QQ1wENASAVQQE2AvA6IBUgGDYC4DogFSAYNgLsOgsCQCAHQRBxBEAgBEUgBUVyDQEgASAEIAUQ0gRBAEgNAQtBACEEQQAhBQsgEkGYAWogGCAAIAEgAiAGIAQgBRDRBCEWDAELQQlBCEEHIBcbIBUoAuA3IBhGG0MAAIA/EDIhESASQZgBaiAYQQEQWCASIBIpA5gBIg03A4ABIBIgEikDoAEiDjcDeCAVQewqaioCACEIIBIgDTcDGCASIA43AxAgEkEYaiASQRBqIBFBASAIEHUgBCERQwAAAAAhCEEAIQRDAAAAACELIwBBEGsiFiQAAkBBkL8EKAIAIhMoAuA3IBhHDQACQAJAAkAgEygClDhBAWsOBAADAwEDCyATLQDsAUUNAQwCCyATKALoOiAYRw0BIBMtAOw3DQELEGsLAkAgEygC4DcgGEcNACATQcw4aigCAEGAAXEgB0GAgIABcXINAAJAAkACQAJAAkACQAJAAkACQAJAIAEOCgABAgMEBQYHCAkKCyAWIAIsAAA2AgwgFkEMaiADIBEEfyARLAAABUGAfwsgBQR/IAUsAAAFQf8ACyAGIAcQpwMiBEUNCSACIBYoAgw6AAAMCQsgFiACLQAANgIMIBZBDGogAyARBH8gES0AAAVBAAsgBQR/IAUtAAAFQf8BCyAGIAcQpgMiBEUNCCACIBYoAgw6AAAMCAsgFiACLgEANgIMIBZBDGogAyARBH8gES4BAAVBgIB+CyAFBH8gBS4BAAVB//8BCyAGIAcQpwMiBEUNByACIBYoAgw7AQAMBwsgFiACLwEANgIMIBZBDGogAyARBH8gES8BAAVBAAsgBQR/IAUvAQAFQf//AwsgBiAHEKYDIgRFDQYgAiAWKAIMOwEADAYLIAIgAyARBH8gESgCAAVBgICAgHgLIAUEfyAFKAIABUH/////BwsgBiAHEKcDIQQMBQsgAiADIBEEfyARKAIABUEACyAFBH8gBSgCAAVBfwsgBiAHEKYDIQQMBAsgEQR+IBEpAwAFQoCAgICAgICAgH8LIQ8gBQR+IAUpAwAFQv///////////wALIQ4jAEEQayITJABBkL8EKAIAIQQgDiAPVyADQwAAAABcckUEQCAEKgKgXiAOIA99tJQhAwsgB0EgcSERIAdBgIDAAHEiFEEUdiEFAkAgBCgClDgiF0EBRgR/AkBBABDlAUUNACAEKgIwQwAAAD+UENcBRQ0AIAQgBUECdGoqAvAGIghDCtcjPJQgCCAELQD+ARsiCEMAACBBlCAIIAQtAP0BGyEIDAILIAQoApQ4BSAXC0EERw0AIBNBCGoiF0EGQQVDzczMPUMAACBBEGMgBUECdCAXcioCACEIIANB4PoCKgIAIgkgAyAJYBshAwsgCCADlCIDjCADIBQbIQMCQCARRQ0AIA4gD30iDUIAVw0AIAMgDbSVIQMLIAQtAOw3IRRBACEFAn8CQAJAIA4gD1ciF0UEQCAOIAIpAwAiDVcgA0MAAAAAXnENASANIA9XIANDAAAAAF1xIQULIBQNACAFRQ0BCyAEQQA6AJleIARBADYCnF5BAAwBCwJAIANDAAAAAFwEQCAEQQE6AJleIAQgAyAEKgKcXpI4ApxeDAELIAQtAJleDQBBAAwBCyACKQMAIQ0CQCARBEAgDSAPIA5BAUPNzMw9QwAAgD8QRyIIQwAAAAAQmAIiCbshGiAJIAQqApxekiAPIA5BASAIQwAAAAAQpAMhDQwBCwJ+IAQqApxeIgiLQwAAAF9dBEAgCK4MAQtCgICAgICAgICAfwsgDXwhDUMAAAAAIQgLIAdBwABxRQRAIAYgDRDuASENCyAEQQA6AJleAkAgEQRAIA0gDyAOQQEgCEMAAAAAEJgCIQggBCAEKgKcXiAIuyAaobaTOAKcXiACKQMAIRAMAQsgBCAEKgKcXiANIAIpAwAiEH20kzgCnF4LAkAgFyANIBBRcg0AIANDAAAAAF5FIBAgDSAPIANDAAAAAF1FIA0gEFdyIA0gD1lxGyINV3IgDSAOV3ENACAOIQ0LQQAgDSAQUQ0AGiACIA03AwBBAQshBCATQRBqJAAMAwsgEQR+IBEpAwAFQgALIQ8gBQR+IAUpAwAFQn8LIQ4jAEEQayIRJABBkL8EKAIAIQQgDiAPWCADQwAAAABcckUEQCAEKgKgXiAOIA99tZQhAwsgB0GAgMAAcSITQRR2IQUCQCAEKAKUOCIUQQFGBH8CQEEAEOUBRQ0AIAQqAjBDAAAAP5QQ1wFFDQAgBCAFQQJ0aioC8AYiCEMK1yM8lCAIIAQtAP4BGyIIQwAAIEGUIAggBC0A/QEbIQgMAgsgBCgClDgFIBQLQQRHDQAgEUEIaiIUQQZBBUPNzMw9QwAAIEEQYyAFQQJ0IBRyKgIAIQggA0Hg+gIqAgAiCSADIAlgGyEDCyAIIAOUIgOMIAMgExsiAyADIA4gD321lSAHQSBxIhNFIA4gD1FyGyEDIAQtAOw3IRRBACEFAn8CQAJAIA4gD1giF0UEQCAOIAIpAwAiDVggA0MAAAAAXnENASANIA9YIANDAAAAAF1xIQULIBQNACAFRQ0BCyAEQQA6AJleIARBADYCnF5BAAwBCwJAIANDAAAAAFwEQCAEQQE6AJleIAQgAyAEKgKcXpI4ApxeDAELIAQtAJleDQBBAAwBCyACKQMAIQ0CQCATBEAgDSAPIA5BAUPNzMw9QwAAgD8QRyIIEJcCIgm7IRogCSAEKgKcXpIgDyAOQQEgCBCjAyENDAELAn4gBCoCnF4iCItDAAAAX10EQCAIrgwBC0KAgICAgICAgIB/CyANfCENQwAAAAAhCAsgB0HAAHFFBEAgBiANEO4BIQ0LIARBADoAmV4CQCATBEAgDSAPIA5BASAIEJcCIQggBCAEKgKcXiAIuyAaobaTOAKcXiACKQMAIRAMAQsgBCAEKgKcXiANIAIpAwAiEH20kzgCnF4LAkAgFyANIBBRcg0AIANDAAAAAF5FIBAgDSAPIANDAAAAAF1FIA0gEFhyIA0gD1pxGyINWHIgDSAOWHENACAOIQ0LQQAgDSAQUQ0AGiACIA03AwBBAQshBCARQRBqJAAMAgsgEQR9IBEqAgAFQ///f/8LIQogBQR9IAUqAgAFQ///f38LIQkjAEEQayITJAAgB0GAgMAAcSEUQZC/BCgCACEEAkAgCSAKXkUgA0MAAAAAXHINACAJIAqTIghD//9/f11FDQAgCCAEKgKgXpQhAwsgB0EgcSERIBRBFHYhFwJAIAQoApQ4IgVBAUYEQAJAQQAQ5QFFDQAgBCoCMEMAAAA/lBDXAUUNACAEIBdBAnRqKgLwBiIIQwrXIzyUIAggBC0A/gEbIghDAAAgQZQgCCAELQD9ARshCAwCCyAEKAKUOCEFC0MAAAAAIQggBUEERw0AIAYQtwEhBSATQQhqIhlBBkEFQ83MzD1DAAAgQRBjIBdBAnQgGXIqAgAhCCADAn1DAACAACAFQQBIDQAaIAVBCU0EQCAFQQJ0QeD6AmoqAgAMAQtDAAAgQUEAIAVrshBHCyIMIAMgDGAbIQMLIAggA5QiA4wgAyAUGyEDAkAgEUUNACAJIAqTIghD//9/f11FIAhDvTeGNV5Fcg0AIAMgCJUhAwsgBC0A7DchFEEAIQUCfwJAAkAgCSAKXiIXBEAgCSACKgIAIghfIANDAAAAAF5xDQEgA0MAAAAAXSAIIApfcSEFCyAUDQAgBUUNAQsgBEEAOgCZXiAEQQA2ApxeQQAMAQsCQAJAIANDAAAAAFwEQCAEQQE6AJleIAQgAyAEKgKcXpI4ApxeDAELIAQtAJleRQ0BCyACKgIAIQgCfSARBEAgCCAKIAlBAUPNzMw9IAYQtwGyEEciA0MAAAAAEJYCIgsgBCoCnF6SIAogCUEBIANDAAAAABCiAwwBC0MAAAAAIQMgCCAEKgKcXpILIQggB0HAAHFFBEAgBiAIEKEDIQgLIARBADoAmV4CfSARBEAgCCAKIAlBASADQwAAAAAQlgIgC5MMAQsgCCACKgIAkwshAyAEIAQqApxeIAOTOAKcXgJAIBdFQwAAAAAgCCAIQwAAAABbGyIIIAIqAgAiA1tyDQAgCiAIIAggCl0bIgggCV5FDQAgCSEICyADIAhbDQAgAiAIOAIAQQEMAQtBAAshBCATQRBqJAAMAQsgEQR8IBErAwAFRP///////+//CyEbIAUEfCAFKwMABUT////////vfwshHCMAQRBrIhMkACAHQYCAwABxIRRBkL8EKAIAIQQCQCAbIBxjRSADQwAAAABccg0AIBwgG6EiGkQAAADg///vR2NFDQAgGiAEKgKgXruitiEDCyAHQSBxIREgFEEUdiEXAkAgBCgClDgiBUEBRgR/AkBBABDlAUUNACAEKgIwQwAAAD+UENcBRQ0AIAQgF0ECdGoqAvAGIghDCtcjPJQgCCAELQD+ARsiCEMAACBBlCAIIAQtAP0BGyEIDAILIAQoApQ4BSAFC0EERw0AIAYQtwEhBSATQQhqIhlBBkEFQ83MzD1DAAAgQRBjIBdBAnQgGXIqAgAhCCADAn1DAACAACAFQQBIDQAaIAVBCU0EQCAFQQJ0QeD6AmoqAgAMAQtDAAAgQUEAIAVrshBHCyIJIAMgCWAbIQMLIAggA5QiA4wgAyAUGyEDAkAgEUUNACAcIBuhIhpEAAAA4P//70djRSAaRAAAAKD3xrA+ZEVyDQAgAyAatpUhAwsgBC0A7DchFEEAIQUCfwJAAkAgGyAcYyIXBEAgA0MAAAAAXiAcIAIrAwAiGmVxDQEgA0MAAAAAXSAaIBtlcSEFCyAUDQAgBUUNAQsgBEEAOgCZXiAEQQA2ApxeQQAMAQsCQAJAIANDAAAAAFwEQCAEQQE6AJleIAQgAyAEKgKcXpI4ApxeDAELIAQtAJleRQ0BCyACKwMAIRoCfCARBEAgGiAbIBxBAUPNzMw9IAYQtwGyEEciCEMAAAAAEJUCIgO7IR0gAyAEKgKcXpIgGyAcQQEgCEMAAAAAEKADDAELQwAAAAAhCCAaIAQqApxeu6ALIRogB0HAAHFFBEAgBiAaEJ8DIRoLIARBADoAmV4CQCARBEAgGiAbIBxBASAIQwAAAAAQlQIhAyAEIAQqApxeIAO7IB2htpM4ApxeIAIrAwAhHQwBCyAEIAQqApxeIBogAisDACIdobaTOAKcXgsCQCAXRSAdRAAAAAAAAAAAIBogGkQAAAAAAAAAAGEbIhphcg0AIBsgGiAaIBtjGyIaIBxkRQ0AIBwhGgsgGiAdYQ0AIAIgGjkDAEEBDAELQQALIQQgE0EQaiQACyAWQRBqJAAgBCIWBEAgGBB+CyASQTBqIgRBwAAgASACIAYQmwIgBGohASAVLQCkXwRAQaUIQaAIENABCyASQoCAgPiDgICAPzcDKCASQZgBaiASQaABaiASQTBqIAFBACASQShqQQAQjgEgEioCqAFDAAAAAF5FDQAgFUH8KmoqAgAhAyASIBIqApwBIBUqAugqkjgCJCASIAMgEioCoAGSOAIgIBIgEikDIDcDCCASQQhqIABBAEEBEFMLIBJBsAFqJAAgFgt3AQN/IABBAEoEQEGQvwQoAgAiAigC5DkhAQNAIAIgAigC7DkgAUEUbGpBFGsiASgCAEEEdGoiA0H4K2ogASkCDDcCACADQfAraiABKQIENwIAIAIgAigC5DlBAWsiATYC5DkgAEEBSyEDIABBAWshACADDQALCwuHBgMIfwZ9AX4jAEHwAGsiAiQAQZC/BCgCACIDKAKoNyIEQQE6AIwBAkAgBC0AjwENACAEIAAQOSEFIAJB6ABqIABBAEEBQwAAgL8QOxCJASEKIAQoAtQBIga+IQ0gBCgC0AEiB74hDiACKgJoIgxDAAAAAF4EQCAMIANB/CpqKgIAkiELCyACIANB6CpqKgIAIgwgDJIgAioCbJIgDZI4AmQgAiAKIAuSIA6SOAJgIAIgBjYCXCACIAc2AlggAkHYAGoiCSAMEHsgCSAFQQBBABA6RQ0AIAJB2ABqIAUgAkHXAGogAkHWAGpBABBVIggEQCABIAEtAABBAXM6AAAgBRB+CyACQdgAaiAFQQEQWCACIAY2AkwgAiAHNgJIIAIgCiANkiILOAJEIAIgCiAOkiIMOAJAQQlBCCACLQBWG0EHIAItAFcbQwAAgD8QMiEFIANB7CpqKgIAIQ8gAiACKQNINwMYIAIgAikDQDcDECACQRhqIAJBEGogBUEBIA8QdUESQwAAgD8QMiEGAkAgA0HMOGooAgBBwABxIgcEQCAEKALEBCEEIAICfyAKQ2ZmZkCVIgqLQwAAAE9dBEAgCqgMAQtBgICAgHgLskMAAIA/lyIKIA2SOAI8IAIgCiAOkjgCOCACIAsgCpM4AjQgAiAMIAqTOAIwIAQgAkE4aiACQTBqIAYgAyoC7CpBABBBDAELIAEtAABFDQAgBCgCxAQhBCACAn8gCkMAAMBAlSILi0MAAABPXQRAIAuoDAELQYCAgIB4C7JDAACAP5ciCyANkjgCLCACIAsgDpI4AiggAiACKQMoNwMIIAQgAkEIaiAGIAogCyALkpMQ8wQLIANB/CpqKgIAIQogAiADKgLoKiANkjgCPCACIAwgCpI4AjggAy0ApF8EQEGb7QAhAyACQThqIAcEfyADBUGf7QBBw+0AIAEtAAAbC0EAEI8BCyACKgJoQwAAAABeRQ0AIAIgAikDOCIQNwMgIAIgEDcDACACIABBAEEBEFMLIAJB8ABqJAAgCAtTACAGQYCAgAhPBEAgASAAKAJwRwRAIAAgARC6ASAAQQZBBBBuIAAgAiADIAQgBSAGEN4CIAAQ9QEPCyAAQQZBBBBuIAAgAiADIAQgBSAGEN4CCwuyDQMLfw59AX4jAEEgayIJJAACQCAEQYCAgAhJDQAgBkUEQCAFED4gBWohBgsgBSAGRg0AIAFFBEAgACgCLCgCCCEBCyACQwAAAABbBEAgACgCLCoCDCECCyAJIAApAmg3AxggCSAAKQJgNwMQIAgEQCAJIAkqAhAiFCAIKgIAIhYgFCAWYBs4AhAgCSAJKgIUIhQgCCoCBCIWIBQgFmAbOAIUIAkgCSoCGCIUIAgqAggiFiAUIBZdGzgCGCAJIAkqAhwiFCAIKgIMIhYgFCAWXRs4AhwLIAkgAykCACIiNwMAIAkgIjcDCCABIQ0gACEKIAchICAIQQBHIRBBACEDIwBBEGsiDiQAIAZFBEAgBRA+IAVqIQYLIAkCfyAJKgIAIgeLQwAAAE9dBEAgB6gMAQtBgICAgHgLsiIWOAIAIAkCfyAJKgIEIgeLQwAAAE9dBEAgB6gMAQtBgICAgHgLsiIUOAIEAkAgCSoCHCIHIBRdDQAgDSoCECIVIAIgFZUiGpQhHAJAICBDAAAAAF4iAA0AIBwgFJIiAiAJKgIUIhVdRSAFIAZPcg0AA0AgBUEKIAYgBWsQkQEiAUEBaiAGIAEbIQUgHCACIhSSIgIgFV1FDQEgBSAGSQ0ACwsCQCAAIAYgBWtBkc4ASHJFBEAgByAUXkUEQCAFIQAMAgsgBiAFIgBNDQEgFCECA0AgAEEKIAYgAGsQkQEiAEEBaiAGIAAbIQAgHCACkiICIAddRQ0CIAAgBkkNAAsMAQsgBiEACyAAIAVGDQAgCigCDCERIAogACAFayIBQQZsIhIgAUECdBBuIARB////B3IhEyAKKAIoIQwgCigCOCELIAooAjQhCANAIAkqAgAhFQNAAkAgFiEHIBQhAiADIQEgACAFIgZNDQACfwNAAkACQCAgQwAAAABeBEAgAUUEQCANIBogBiAAICAgByAVk5MQywMiASABIAZGaiEBCyABIAZNDQEgByEWIAIhFCAGIQUgASEDCyAOIAUsAAAiBjYCDCAGQQBIDQEgBUEBagwDCwJAIAAgBk0NAAJAA0AgBkEBaiEBIAYtAAAiD0EgRyAPQQlHcQ0BIAEiBiAARw0ACyAAIQYMAQsgASAGIA9BCkYbIQYLIBwgApIhAkEAIQEgFSEHIAAgBksNAQwDCwsgDkEMaiAFIAAQswEhASAOKAIMIgZFDQEgASAFagshBQJAIAZBH00EQCAGQQpGDQEgBkENRg0ECwJ/IAZB//8DcSIBIA0oAhRPBEAgDSgCLAwBCyANKAIsIA0oAiggDSgCHCABQQF0ai8BACIBQShsaiABQf//A0YbCyIBRQ0DIBogASoCBJQhIQJAIAEoAgAiBkECcUUNACABKgIIIBqUIBaSIhcgCSoCGCIHX0UNACABKgIQIBqUIBaSIgIgCSoCECIVYEUNACABKgIUIBqUIBSSIRsgASoCDCAalCAUkiEfIAEqAiQhHSABKgIgIR4gASoCHCEYIAEqAhghGQJAIBBFBEAgFyEVIAIhByAfIRcgGyECDAELAkAgFSAXXkUEQCAXIRUMAQtDAACAPyACIBWTIAIgF5OVkyAeIBmTlCAZkiEZCwJAIB8gCSoCFCIXXUUEQCAfIRcMAQtDAACAPyAbIBeTIBsgH5OVkyAdIBiTlCAYkiEYCwJAIAIgB15FBEAgAiEHDAELIAcgFZMgAiAVk5UgHiAZk5QgGZIhHgsCQCAbIAkqAhwiAl5FBEAgGyECDAELIAIgF5MgGyAXk5UgHSAYk5QgGJIhHQsgAiAXXw0BCyALIAw7AQYgCyAMOwEAIAsgDEEDajsBCiALIAxBAmoiATsBCCALIAE7AQQgCyAMQQFqOwECIAggEyAEIAZBAXEbIgE2AhAgCCAXOAIEIAggFTgCACAIIAE2AiQgCCAXOAIYIAggBzgCFCAIIBg4AgwgCCAZOAIIIAggATYCOCAIIAI4AiwgCCAHOAIoIAggGDgCICAIIB44AhwgCCABNgJMIAhBQGsgAjgCACAIIBU4AjwgCCAdOAI0IAggHjgCMCAIIB04AkggCCAZOAJEIAtBDGohCyAMQQRqIQwgCEHQAGohCAsgFiAhkiEWDAMLIBUhFiAcIBSSIhQgCSoCHF5FDQELCwsgCiAIIAooAiBrQRRtNgIYIAogCyAKKAIUa0EBdSIANgIMIAooAgggCigCAEEobGpBDGsiASABKAIAIAAgESASamtqNgIAIAogCzYCOCAKIAg2AjQgCiAMNgIoCyAOQRBqJAALIAlBIGokAAvPAgEFfSACKgIEIQggAioCACEHIAEqAgQhBSABKgIAIQYCQCADBEAgACoCaCIEIAcgBCAHXRshByAAKgJkIgQgBSAEIAVeGyEFIAAqAmAiBCAGIAQgBl4bIQYgCCAAKgJsIgReDQELIAghBAsCQCAAKAI8IgIgAEFAaygCAEcNACACQQFqIQEgAiACBH8gAkECbSACagVBCAsiAyABIAEgA0gbIgFODQAgAUEEdBAuIQIgACgCRCIDBEAgAiADIAAoAjxBBHQQKhogACgCRBAsCyAAIAE2AkAgACACNgJEIAAoAjwhAgsgACgCRCACQQR0aiIBIAUgBCAEIAVfGyIEOAIMIAEgBiAHIAYgB2AbIgg4AgggASAFOAIEIAEgBjgCACAAIAQ4AmwgACAIOAJoIAAgBTgCZCAAIAY4AmAgACAAKAI8QQFqNgI8IAAQiwULiQICB38BfiMAQRBrIgMkACADIAApAmg3AwggAyAAKQJgNwMAIAAoAnQhBSAAKAJwIQYgACgCDCEHAkAgACgCACIBIAAoAgRHDQBBCCECIAEgAUECbSABaiACIAEbIgIgAUEBaiIEIAIgBEobIgJODQAgAkEobBAuIQEgACgCCCIEBEAgASAEIAAoAgBBKGwQKhogACgCCBAsCyAAIAI2AgQgACABNgIIIAAoAgAhAQsgACgCCCABQShsaiIBIAMpAwA3AgAgAykDCCEIIAFCADcCHCABIAc2AhggASAFNgIUIAEgBjYCECABIAg3AgggAUEANgIkIAAgACgCAEEBajYCACADQRBqJAALqwICAX0BfyABQwAAAABbBEAgBSACOAIAIAQgAjgCACADIAI4AgAPCwJ/IABDAACAPxD8BUOrqio+lSIAi0MAAABPXQRAIACoDAELQYCAgIB4CyEHQwAAgD8gASAAIAeykyIAlJMgApQhBkMAAIA/IAFDAACAPyAAk5STIAKUIQBDAACAPyABkyAClCEBAkACQAJAAkACQAJAIAcOBQABAgMEBQsgAyACOAIAIAQgADgCACAFIAE4AgAPCyADIAY4AgAgBCACOAIAIAUgATgCAA8LIAMgATgCACAEIAI4AgAgBSAAOAIADwsgAyABOAIAIAQgBjgCACAFIAI4AgAPCyADIAA4AgAgBCABOAIAIAUgAjgCAA8LIAMgAjgCACAEIAE4AgAgBSAGOAIAC5wDAQV/QZC/BCgCACgCqDchASMAQRBrIgMkACADIAA2AgwgASgCzAEgASgCxAFBAnRqQQRrKAIAQX9zIQIgA0EMaiEEQQQhBQNAIAQtAAAgAkH/AXFzQQJ0QdCXAWooAgAgAkEIdnMhAiAEQQFqIQQgBUEBayIFDQALIAJBf3MiAkGQvwQoAgAoAsg3RgRAIAJBBCAAELQBCyADQRBqJAAgAiEEAkAgASgCxAEiACABKALIAUcNACAAIABBAm0gAGpBCCAAGyICIABBAWoiAyACIANKGyICTg0AQZC/BCgCACIABEAgACAAKALsBkEBajYC7AYLIAJBAnRBmL8EKAIAQdi8BCgCABEBACEAIAEoAswBIgMEQCAAIAMgASgCxAFBAnQQKhoCQCABKALMASIFRQ0AQZC/BCgCACIDRQ0AIAMgAygC7AZBAWs2AuwGCyAFQZi/BCgCAEHcvAQoAgARAAALIAEgAjYCyAEgASAANgLMASABKALEASEACyABKALMASAAQQJ0aiAENgIAIAEgASgCxAFBAWo2AsQBC/cKAwZ8A34GfyMAQRBrIg4kACAAEIICIQsgAb0hCSAAvSEIAkACQCABEIICIgxB/w9xIg9BvghrIhBB/35LIAtB/w9rQYJwT3ENACAJEO0FBEBEAAAAAAAA8D8hAiAIQoCAgICAgID4P1ENAiAJQgGGIgpQDQIgCkKBgICAgICAcFQgCEIBhiIIQoCAgICAgIBwWHFFBEAgACABoCECDAMLIAhCgICAgICAgPD/AFENAkQAAAAAAAAAACABIAGiIAhC/////////+//AFYgCUIAWXMbIQIMAgsgCBDtBQRAIAAgAKIhAiAIQgBTBEAgApogAiAJEOwFQQFGGyECCyAJQgBZDQJEAAAAAAAA8D8gAqMQ8gIhAgwCCyAIQgBTBEAgCRDsBSINRQRAIAAQ8gUhAgwDCyALQf8PcSELIA1BAUZBEnQhDSAIQv///////////wCDIQgLIBBB/35NBEBEAAAAAAAA8D8hAiAIQoCAgICAgID4P1ENAiAPQb0HTQRAIAEgAZogCEKAgICAgICA+D9WG0QAAAAAAADwP6AhAgwDCyAMQYAQSSAIQoGAgICAgID4P1RHBEBBABDvBSECDAMLQQAQ7gUhAgwCCyALDQAgAEQAAAAAAAAwQ6K9Qv///////////wCDQoCAgICAgICgA30hCAsCfCAJQoCAgECDvyIFIQcgDiAIQoCAgIDQqqXzP30iCUI0h6e3IgNB2IYEKwMAoiAJQi2Ip0H/AHFBBXQiC0GwhwRqKwMAoCAIIAlCgICAgICAgHiDfSIIQoCAgIAIfEKAgICAcIO/IgAgC0GYhwRqKwMAIgSiRAAAAAAAAPC/oCICIAi/IAChIASiIgSgIgAgA0HQhgQrAwCiIAtBqIcEaisDAKAiAyAAIAOgIgOhoKAgBCAAQeCGBCsDACIEoiIGIAIgBKIiBKCioCACIASiIgIgAyADIAKgIgKhoKAgACAAIAaiIgOiIAMgAyAAQZCHBCsDAKJBiIcEKwMAoKIgAEGAhwQrAwCiQfiGBCsDAKCgoiAAQfCGBCsDAKJB6IYEKwMAoKCioCIAIAIgAiAAoCICoaA5AwggByACvUKAgIBAg78iA6IhACABIAWhIAOiIA4rAwggAiADoaAgAaKgIQECQCAAEIICQf8PcSILRAAAAAAAAJA8EIICIgxrIg9EAAAAAAAAgEAQggIgDGtJDQAgD0EASARAIABEAAAAAAAA8D+gIgCaIAAgDRsMAgtEAAAAAAAAkEAQggIgC0shDEEAIQsgDA0AIAC9QgBTBEAgDRDuBQwCCyANEO8FDAELQeD1AysDACAAokHo9QMrAwAiAqAiAyACoSICQfj1AysDAKIgAkHw9QMrAwCiIACgoCABoCIAIACiIgEgAaIgAEGY9gMrAwCiQZD2AysDAKCiIAEgAEGI9gMrAwCiQYD2AysDAKCiIAO9IgmnQQR0QfAPcSIMQdD2A2orAwAgAKCgoCEAIAxB2PYDaikDACAJIA2tfEIthnwhCCALRQRAAnwgCUKAgICACINQBEAgCEKAgICAgICAiD99vyIBIACiIAGgRAAAAAAAAAB/ogwBCyAIQoCAgICAgIDwP3wiCL8iASAAoiIDIAGgIgCZRAAAAAAAAPA/YwR8RAAAAAAAABAAEPICRAAAAAAAABAAoiECIwBBEGsgAjkDCCAIQoCAgICAgICAgH+DvyAARAAAAAAAAPC/RAAAAAAAAPA/IABEAAAAAAAAAABjGyICoCIFIAMgASAAoaAgACACIAWhoKCgIAKhIgAgAEQAAAAAAAAAAGEbBSAAC0QAAAAAAAAQAKILDAELIAi/IgEgAKIgAaALIQILIA5BEGokACACC1kCAX8BfCMAQRBrIgEkACAAKAIAQbi4BCABQQxqEAchAiABKAIMEAYCfyACRAAAAAAAAPBBYyACRAAAAAAAAAAAZnEEQCACqwwBC0EACyEAIAFBEGokACAAC1ECAX8BfCMAQRBrIgEkACAAKAIAQay4BCABQQxqEAchAiABKAIMEAYCfyACmUQAAAAAAADgQWMEQCACqgwBC0GAgICAeAshACABQRBqJAAgAAtZAgF/AXwjAEEQayIBJAAgACgCAEGUuAQgAUEMahAHIQIgASgCDBAGAn8gAkQAAAAAAADwQWMgAkQAAAAAAAAAAGZxBEAgAqsMAQtBAAshACABQRBqJAAgAAtRAgF/AXwjAEEQayIBJAAgACgCAEGguAQgAUEMahAHIQIgASgCDBAGAn8gAplEAAAAAAAA4EFjBEAgAqoMAQtBgICAgHgLIQAgAUEQaiQAIAALSgECfyAAKAIIIgIEQCAAQgA3AgBBkL8EKAIAIgEEQCABIAEoAuwGQQFrNgLsBgsgAkGYvwQoAgBB3LwEKAIAEQAAIABBADYCCAsLhAMBBn8CQEGQvwQoAgAiAigCzDciA0UgASADRnJFBEAgAi0A1DdFDQELAkAgAigCqDciBiACKAKsN0cNACACKALgNyIFRSABIAVGckUEQCACLQDtN0UNAQsgACAAQQhqIgdBARDGAkUNACACLQCTOw0AAkAgAigC1DoiA0UNACADKALgBSIDRQ0AIAMtAIsBRQ0AIAMgBigC4AVGDQAgAy0AC0EMcUUNACACQQE6ANc3DAELAkAgAQRAIAJBADsB1DcgAiABNgLMNyABIAIoAtA3IgRHBEAgAkIANwPYNwsgAkHMOEGwOCACKALIOCABRhtqLQAAQQRxDQEgAi0A2F9FIAEgBEdyRQRAIAJB0DpqKAIAKAIAQQFBkdwAEGogACAHQf//g3hDAAAAAEEAQwAAgD8QPQtBASEEIAIoAtxfIAFHDQIAC0EBIQQgAkGwOEHMOCACKALIOBtqLQAAQQRxRQ0BCyABIAVGBEBBAEEAEEwLIAJBAToA1zcMAQsgBA8LQQALPwEBfyMAQRBrIgMkACABKAIAIQEgAyACKAIANgIIIAAgAUHEuAQgA0EIahADIgAQCTYCACAAEAAgA0EQaiQAC78CAQZ/IAIgAUGAgPyHeCABLQAAIgdBA3YiBXZBAXEgBUHQnwFqLAAAIghqIgVqIAIbIgMgAUEBaksEQCABLQABIQQLQQAhAiADIAFBAmpLBEAgAS0AAiECCyADIAFBA2pLBEAgAS0AAyEGCyAAIAZBP3EgAkEGdEHAH3EgBEEMdEGA4A9xIAdBACABIANJGyIHIAhBAnQiAUHwnwFqKAIAcUESdHJyciABQbCgAWooAgB2IgM2AgAgAkEEdkEMcSAEQQJ2QTBxciAGQcABcUEGdnIgAyABQZCgAWooAgBJQQZ0ciADQf//A0tBCHRyIANBgHBxQYCwA0ZBB3RyQSpzIAFB0KABaigCAHYEfyAAQf3/AzYCACAFIARBAEcgB0EAR2ogAkH/AXFBAEdqIAZBAEdqIgAgACAFShsFIAULC4cFAQd/IwBBQGoiBSQAQZC/BCgCACIDKAKoNyEGAkAgA0H03wBqKAIAIgRBf0YEQCADQQA2AvRfIAYoAsQBIgRBAWohCAJAIANBgOAAaigCACIBIARKDQAgASABQQJtIAFqQQggARsiAiAIIAIgCEobIgJODQAgAyADKALsBkEBajYC7AYgAkEGdEGYvwQoAgBB2LwEKAIAEQEAIQEgA0GE4ABqKAIAIgcEQCABIAcgAygC/F9BBnQQKhoCQCADKAKEYCIJRQ0AQZC/BCgCACIHRQ0AIAcgBygC7AZBAWs2AuwGCyAJQZi/BCgCAEHcvAQoAgARAAALIAMgAjYCgGAgAyABNgKEYAsgBCADKAL8XyICTgRAA0AgAygChGAgAkEGdGpBAEHAABAvGiACIARHIQEgAkEBaiECIAENAAsLIAMgCDYC/F9BACECIAYoAsQBIgFBAEgNASADQYTgAGooAgAhAwNAIAMgAkEGdGogASACSgR/IAYoAswBIAJBAnRqKAIABSAACzYCACABIAJGIQQgAkEBaiECIARFDQALDAELIAQgBigCxAFHDQAgA0GE4ABqKAIAIQMCQAJAAkACQAJAIAFBBGsOCgAEBAQEBAQBAgMECyAFIAI2AgAgAyAEQQZ0akEGakE6QfroACAFEDUaDAMLIAIQPiEAIAUgAjYCFCAFIAA2AhAgAyAEQQZ0akEGakE6QZmUASAFQRBqEDUaDAILIAUgAjYCICADIARBBnRqQQZqQTpB2DYgBUEgahA1GgwBCyADIARBBnRqIgEtAAYNACAFIAA2AjAgAUEGakE6QbHtACAFQTBqEDUaCyADIARBBnRqQQE6AAULIAVBQGskAAsPACABIAAoAgBqIAI4AgALDQAgASAAKAIAaioCAAuLAgEEfyMAQRBrIgMkAAJAIAAtAAAiAQRAA0ACQCABQSVHDQAgAC0AAUElRg0AA0AgACIEQQFqIQAgBC0AASICQTBrQf8BcUEKSQ0AC0H/////ByEBIANB/////wc2AgwgAkEuRgRAIARBAmogA0EMahDMBC0AACECQQMgAygCDCIAIABB4wBLGyEBC0F/IQACQAJAAkACQCACQeUAaw4DBwECAAsgAkHFAEYNAgsgAkHHAEYgAUH/////B0ZxDQFBAyABIAFB/////wdGGyEADAULIAEiAEH/////B0cNBAtBfyEADAMLIAAgAUElRmpBAWoiAC0AACIBDQALC0EDIQALIANBEGokACAAC38BAX8CQCAAKAIABEAgACACIAMQtgMgAUEERw0BIAAgBCAFELYDIAAgBiAHELYDDAELIAAoAiggACgCLEEObGoiCCAHOwEKIAggBjsBCCAIIAU7AQYgCCAEOwEEIAggAzsBAiAIIAI7AQAgCCABOgAMCyAAIAAoAixBAWo2AiwLlwEAIANBgICACEkgAkMAAAAAX3JFBEACQCAEQQBMBEAgACABIAJBAEEwEN0CIAAgACgCVEEBayIENgJUDAELIAAgASACQwAAAABBA0GABCAEIARBgAROGyAEQQNJGyIBsiICQwAAgL+SQ9sPyUCUIAKVIAFBAWsQhwEgACgCVCEECyAAIAAoAlwgBCADEIgBIABBADYCVAsLpQEBA38CQCAAKAJIIgIgACgCTEcNACACQQFqIQMgAiACBH8gAkECbSACagVBCAsiBCADIAMgBEgbIgRODQAgBEECdBAuIQIgACgCUCIDBEAgAiADIAAoAkhBAnQQKhogACgCUBAsCyAAIAQ2AkwgACACNgJQIAAoAkghAgsgACgCUCACQQJ0aiABNgIAIAAgATYCcCAAIAAoAkhBAWo2AkggABCKBQvuAQICfwV9IAEoAqQCIQMgAUGQvwQoAgAiAigC1DpHBEAgAkEAOgCVOwsgAiADNgKMOyACIAA2Atg6IAIgATYC1DogAiABKAKsAjYC3DogASADQQJ0aiAANgL0BSAAIAIoAsg4RgRAIAJB5DhqKgIAIQUgAkHoOGoqAgAhBiACQew4aioCACEHIAEqAuABIQQgASADQQR0aiIAIAJB8DhqKgIAIAEqAuQBIgiTOAKIBiAAIAcgBJM4AoQGIAAgBiAIkzgCgAYgACAFIASTOAL8BQsgAigClDhBBEYEQCACQQE6AJM7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BTYCBCABKAIAIAJqLQAAIQMgBSECCyAJIANB/wFxciEDIAZBAWoiBiAIRw0ACyADQQFrBUF/CyEDIAEgBCAEIAIgA2oiAiACIARKGyACQQBIGyICNgIECyAAQQA2AgggAEIANwIAIAIgB2siBSAHckEASCAEIAdIciACIARKckUEQCABKAIAIQEgACAFNgIIIAAgASAHajYCAAsLpgEAIANBgICACEkgAkMAAAAAX3JFBEACQCAEQQBMBEAgACABIAJDAAAAv5JBAEEwEN0CIAAgACgCVEEBayIENgJUDAELIAAgASACQwAAAL+SQwAAAABBA0GABCAEIARBgAROGyAEQQNJGyIBsiICQwAAgL+SQ9sPyUCUIAKVIAFBAWsQhwEgACgCVCEECyAAIAAoAlwgBCADQQEgBRBlIABBADYCVAsLRwECfyAAIAAoAjwiAUEBayICNgI8IAAgACgCRCABQQR0akEgayAAKAIsQRhqIAIbIgEpAgA3AmAgACABKQIINwJoIAAQiwULzgEBBX8gACgCCEEASgRAA0AgACgCECEBIAAoAgAgAkYEQCABIAJBGGxqIgFCADcCACABQgA3AhAgAUIANwIIIAAoAhAhAQsgASACQRhsIgRqIgMoAggiBQR/IANCADcCACAFECwgA0EANgIIIAAoAhAFIAELIARqIgFBFGooAgAiAwRAIAFCADcCDCADECwgAUEANgIUCyACQQFqIgIgACgCCEgNAAsLIABCgICAgBA3AgAgACgCECICBEAgAEIANwIIIAIQLCAAQQA2AhALCxsBAX9BkL8EKAIAIgIgATYCwF8gAiAANgK8XwuzAQEEfyMAQUBqIgIkAAJAAkBBkL8EKAIAIgMoAqw6IAMoArg6IgVKBEAgA0G0OmooAgAgBUEkbGooAgAgAEYNAQsgA0EANgKEOQwBCwJAIAFBgICAgAFxBEAgAiADKALEOjYCECACQSBqQRRB1uQAIAJBEGoQNRoMAQsgAiAANgIAIAJBIGpBFEHIDCACEDUaCyACQSBqQQAgAUGAgIAgchCUASIEDQAQZgsgAkFAayQAIAQL0wYCCH8CfiMAQRBrIgckAEGQvwQoAgAiAigCuDohBCACKAKoNyEFAkAgAUEgcQRAIAIoAqw6IARKDQELIAUoAswBIAUoAsQBQQJ0akEEaygCACEIIAIo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AiMAQSBrIgkkAAJAAkAgASADayIDIAAoAggiBiAAKAIEIgRrQQN1TQRAIAAgAwR/IARBACADQQN0IgEQLyABagUgBAs2AgQMAQsgBCAAKAIAIgdrQQN1IgogA2oiBEGAgICAAk8NAQJ/IAlBCGoiAUEANgIMIAEgAEEIajYCEAJAQf////8BIAYgB2siBkECdiIHIAQgBCAHSRsgBkH4////B08bIgQEQCAEQYCAgIACTw0BIARBA3QQKSECCyABIAI2AgAgASACIApBA3RqIgY2AgggASACIARBA3RqNgIMIAEgBjYCBCABDAELEJMDAAsiASABKAIIQQAgA0EDdCICEC8gAmo2AgggASgCBCAAKAIEIAAoAgAiAmsiA2sgAiADEEIhAyAAKAIAIQIgACADNgIAIAEgAjYCBCAAKAIEIQMgACABKAIINgIEIAEgAzYCCCAAKAIIIQQgACABKAIMNgIIIAEgAjYCACABIAQ2AgwgAiADRwRAIAEgAyACIANrQQdqQXhxajYCCAsgAkUNACACECsLIAlBIGokAAwCCxDFAgALIAEgA0kEQCAAIAIgAUEDdGo2AgQLCyAIEAAgACgCBCEBIAUgACgCACICNgIMIAUgASACa0EDdTYCCEHErAMgBUEIahADIgEgACgCDBCgASABEAAgBUEQaiQAIAALsgEBBH8jAEEQayIDJAAgACgCDCEBIAAoAgQhBCADIAAoAgAiAjYCDCADIAQgAmtBAnU2AgggASgCACEEIwBBEGsiASQAQbTtBS0AAEEBcUUEQEECQZysAxASIQJBtO0FQQE6AABBsO0FIAI2AgALQbDtBSgCACECIAEgAykCCDcDCCACIARB7BsgAUEIahARIAFBEGokACAAKAIAIgEEQCAAIAE2AgQgARArCyADQRBqJAALwAECAn8BfCMAQRBrIgIkACAAIAE2AgwgAEEANgIIIABCADcCACABKAIAQcTDABAIIgMQCSEBIAMQACABQei4BCACQQRqEAchBCACKAIEEAYgAAJ/IAREAAAAAAAA8EFjIAREAAAAAAAAAABmcQRAIASrDAELQQALEPUDIAEQACAAKAIEIQEgAiAAKAIAIgM2AgwgAiABIANrQQJ1NgIIQeCrAyACQQhqEAMiASAAKAIMEKABIAEQACACQRBqJAAgAAuyAQEEfyMAQRBr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ACgCACIDNgIMIAIgASADazYCCEHAlgMgAkEIahADIgEgACgCDBCgASABEAAgAkEQaiQAIAALrwEBBH8jAEEQayIDJAAgACgCDCEBIAAoAgQhBCADIAAoAgAiAjYCDCADIAQgAms2AgggASgCACEEIwBBEGsiASQAQYTtBS0AAEEBcUUEQEECQeynAxASIQJBhO0FQQE6AABBgO0FIAI2AgALQYDtBSgCACECIAEgAykCCDcDCCACIARB7BsgAUEIahARIAFBEGokACAAKAIAIgEEQCAAIAE2AgQgARArCyADQRBqJAALvQECAn8BfCMAQRBrIgIkACAAIAE2AgwgAEEANgIIIABCADcCACABKAIAQcTDABAIIgMQCSEBIAMQACABQei4BCACQQRqEAchBCACKAIEEAYgAAJ/IAREAAAAAAAA8EFjIAREAAAAAAAAAABmcQRAIASrDAELQQALEI4DIAEQACAAKAIEIQEgAiAAKAIAIgM2AgwgAiABIANrNgIIQbCnAyACQQhqEAMiASAAKAIMEKABIAEQACACQRBqJAAgAAuRAQICfwF8IwBBEGsiASQAIAFBADYCCANAIAEgACgCFCABQQhqEJcBIAEoAgBBxLgEIAFBDGoQByEDIAEoAgwQBiAAIAEoAghBAnRqAn8gA5lEAAAAAAAA4EFjBEAgA6oMAQtBgICAgHgLNgIEIAEoAgAQACABIAEoAghBAWoiAjYCCCACQQRJDQALIAFBEGokAAuRAQICfwF8IwBBEGsiASQAIAFBADYCCANAIAEgACgCECABQQhqEJcBIAEoAgBBxLgEIAFBDGoQByEDIAEoAgwQBiAAIAEoAghBAnRqAn8gA5lEAAAAAAAA4EFjBEAgA6oMAQtBgICAgHgLNgIEIAEoAgAQACABIAEoAghBAWoiAjYCCCACQQNJDQALIAFBEGokAAuRAQICfwF8IwBBEGsiASQAIAFBADYCCANAIAEgACgCDCABQQhqEJcBIAEoAgBBxLgEIAFBDGoQByEDIAEoAgwQBiAAIAEoAghBAnRqAn8gA5lEAAAAAAAA4EFjBEAgA6oMAQtBgICAgHgLNgIEIAEoAgAQACABIAEoAghBAWoiAjYCCCACQQJJDQALIAFBEGokAAtnAgJ/AX0jAEEQayIBJAAgAUEANgIMA0AgAUEIaiICIAAoAgwgAUEMahCXASACEDAhAyAAIAEoAgxBAnRqIAM4AgQgASgCCBAAIAEgASgCDEEBaiICNgIMIAJBAkkNAAsgAUEQaiQAC2YBAn8jAEEQayIBJAAgAUEANgIEA0AgACgCCCECIAEgACgCBDYCCCABQdC4BCABQQhqEAM2AgAgAiABQQRqIAEQlgEgASgCABAAIAEgASgCBEEBaiICNgIEIAJFDQALIAFBEGokAAvGAQECf0GQvwQoAgAhAiAAKAIIIgNBgIAQcQRAIAJCADcD2DoPCwJAAkAgA0GAgIAgcSAAKALgBSAARnINACAAKAL0BSIARQ0AIAFFDQELIAJCADcD2DogAigC1DoiACACKAKMOyIBQQJ0akEANgL0BSAAIAFBBHRqIgBCADcChAYgAEIANwL8BSACQgA3Apw7IAJBADYCmDsgAkEAOgCWOyACQYECOwGUOyACQaQ7akIANwIADwsgAkEANgLcOiACIAA2Atg6CwwAQZC/BCgCAEEIagtYAQJ/IwBBEGsiASQAQZC/BCgCAEEANgLgXgJAIABFDQAgAUEANgIMIAFBDGoQ5AMhAiAAQeYQEPEDIgBFDQAgAiABKAIMIAAQ9AUgABDiAQsgAUEQaiQACwsAIAEgAiAAEQAAC4kBAQZ9IAMqAgAgASoCACIHkyACKgIAIAeTIgSUIAMqAgQgASoCBCIIkyACKgIEIAiTIgWUkiIGQwAAAABdBEAgACABKQIANwIADwsgBCAElCAFIAWUkiIJIAZdBEAgACACKQIANwIADwsgACAIIAUgBpQgCZWSOAIEIAAgByAEIAaUIAmVkjgCAAvsAQEGfyABIAAoAgQgACgCACIDayICSwRAAkAgASACayIBIAAoAggiBCAAKAIEIgJrTQRAIAAgAQR/IAJBACABEC8gAWoFIAILNgIEDAELIAIgACgCACICayIGIAFqIgVBAE4EQEEAIQNB/////wcgBCACayIEQQF0IgcgBSAFIAdJGyAEQf////8DTxsiBQRAIAUQKSEDCyADIAZqQQAgARAvIQQgACADIAIgBhBCIgMgBWo2AgggACABIARqNgIEIAAgAzYCACACBEAgAhArCwwBCxDFAgALDwsgASACSQRAIAAgASADajYCBAsLDgAgASACIAAoAgARAAALRwEBfyMAQRBrIgUkACAAKAIAIQAgBSAD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IABB5D1qQX82AgAgAEEANgKgPiAAQYk+akEAOwAAIABCgICAgHA3Aqw+IABC////+wc3AqQ+IABBwD5qKAIAIgEEQCAAQgA3Arg+IAAgACgC7AZBAWs2AuwGIAFBmL8EKAIAQdy8BCgCABEAACAAQQA2AsA+CyAAQgA3AsQ+IABBzD5qQgA3AgALhQQBBX9BkL8EKAIAIgFBADYC4F4gAUHk3gBqIQUCfwJAIAFB6N4AaigCACICQQBIBEAgASABKALsBkEBajYC7AZBAEGYvwQoAgBB2LwEKAIAEQEAIQIgAUHs3gBqKAIAIgMEQCACIAMgASgC5F4QKhoCQCABKALsXiIERQ0AQZC/BCgCACIDRQ0AIAMgAygC7AZBAWs2AuwGCyAEQZi/BCgCAEHcvAQoAgARAAALIAEgAjYC7F4gAUIANwLkXgwBCyAFQQA2AgAgAkUNACABQezeAGooAgAhAkEADAELQZC/BCgCACICBEAgAiACKALsBkEBajYC7AYLQQhBmL8EKAIAQdi8BCgCABEBACECIAFB7N4AaigCACIDBEAgAiADIAEoAuReECoaAkAgASgC7F4iBEUNAEGQvwQoAgAiA0UNACADIAMoAuwGQQFrNgLsBgsgBEGYvwQoAgBB3LwEKAIAEQAACyABQQg2AuheIAEgAjYC7F4gASgC5F4LIQRBACEDIAIgBGpBADoAACABIAEoAuReQQFqNgLkXiABKALwXkEASgRAA0AgASABKAL4XiADQSRsaiICIAUgAigCHBEEACADQQFqIgMgASgC8F5IDQALCyAABEAgACAFKAIAIgBBAWsiAkEAIAAgAk8bNgIACyABQezeAGooAgAiAEGUvwQgABsLuQIBB38jAEEQayIDJAAgAyABNgIMIAFB7////wdNBEACQCAAEOsCIAFPDQAgAyAAEOwCNgIIIANBDGogA0EIahDPBSgCABDOBSIBIAAQ6wJGDQAjAEEQayICJAAgABDrAiEEIAAQ7AIhBQJAAn8gAUELSSIIBEBBASEEIAFBAWohBiAAIQEgACgCAAwBCwJ/IAEgBEsEQCACQQhqIAAgAUEBahDnAyACKAIIIQEgAigCDAwBCyACQQhqIAAgAUEBahDnAyACKAIIIgFFDQIgAigCDAshBiAAELsCIQQgABDpAwshByABIAcgABDsAkEBahDNBSAEBEAgBxArCwJAIAhFBEAgACAGEMsFIAAgBRDmAyAAIAEQzAUMAQsgACAFEMoFCwsgAkEQaiQACyADQRBqJAAPCxDKAgALCQAgACABNgIECxYAIAIQKSEBIAAgAjYCBCAAIAE2AgALxwQDB30BfwF+IAAgASkCWCIKNwIAAkAgASoCaCIDQ///f39dRQRAIAqnviEDDAELIAEqAnAhAiABKgKAASEFAkAgASoCeCIGQwAAAABeRQRAIAEqAhwhBAwBCyABKgIcIQQgAyAGQwAAAACSXwRAIAMgApRDAAAAAJIhAwwBCyABKgJgIASSIAWTIgcgBpMgA19FDQAgByADkyAClCADkiEDCyAAIAMgAiAEIAWTlJMiAzgCAAsgAAJ/IAEqAmxD//9/f10EfUMAAAAAIQIgAS0ACEEBcQR9IAIFQZC/BCgCACIJKgLIMiABKgK8BJQhAiAJQegqaioCACIEIASSIAEoAtgFIgkEfSACIAkqArwElAUgAguSCyABEN0BkiABKgKEAZIhBiABKgJ0IQQgASoCbCECAkAgASoCfCIHQwAAAABeRQRAIAEqAiAhBQwBCyABKgIgIQUgAiAHQwAAAACSXwRAIAIgBJRDAAAAAJIhAgwBCyABKgJkIAWSIAaTIgggB5MgAl9FDQAgCCACkyAElCACkiECCyACIAQgBSAGk5STBSAKQiCIp74LIgJDAAAAACACQwAAAABgGyICi0MAAABPXQRAIAKoDAELQYCAgIB4C7IiAjgCBCAAAn8gA0MAAAAAIANDAAAAAGAbIgOLQwAAAE9dBEAgA6gMAQtBgICAgHgLsiIDOAIAAkAgAS0AjQENACABLQCPAQ0AIAAgAyABKgJgIgQgAyAEXRs4AgAgACACIAEqAmQiAyACIANdGzgCBAsLEgAgABC7AgRAIAAoAgAPCyAAC9IDAgJ+An8jAEEgayIEJAACQCABQv///////////wCDIgNCgICAgICAwIA8fSADQoCAgICAgMD/wwB9VARAIAFCBIYgAEI8iIQhAyAAQv//////////D4MiAEKBgICAgICAgAhaBEAgA0KBgICAgICAgMAAfCECDAILIANCgICAgICAgIBAfSECIABCgICAgICAgIAIUg0BIAIgA0IBg3whAgwBCyAAUCADQoCAgICAgMD//wBUIANCgICAgICAwP//AFEbRQRAIAFCBIYgAEI8iIRC/////////wODQoCAgICAgID8/wCEIQIMAQtCgICAgICAgPj/ACECIANC////////v//DAFYNAEIAIQIgA0IwiKciBUGR9wBJDQAgBEEQaiAAIAFC////////P4NCgICAgICAwACEIgIgBUGB9wBrEFsgBCAAIAJBgfgAIAVrENoBIAQpAwhCBIYgBCkDACIAQjyIhCECIAQpAxAgBCkDGIRCAFKtIABC//////////8Pg4QiAEKBgICAgICAgAhaBEAgAkIBfCECDAELIABCgICAgICAgIAIUg0AIAJCAYMgAnwhAgsgBEEgaiQAIAIgAUKAgICAgICAgIB/g4S/C0QBAX8jAEEQayIFJAAgBSABIAIgAyAEQoCAgICAgICAgH+FEHAgBSkDACEBIAAgBSkDCDcDCCAAIAE3AwAgBUEQaiQAC8AEAgN/BH0jAEEwayICJABBkL8EKAIAIQQgAkEgahCtBQJAIAEoAggiA0GAgICAAXEEQCACAn0gBEGMN2ooAgAgBCgChDdB1ABsakGoAWsoAgAiAy0AsgIEQCADKgL0AyEFQ///f38hB0P//3//IQggAyoC/AMMAQsgBEH8KmoqAgAiBiADKgIMIgWSIQggBSADKgIUkiAGkyADKgKAAZMhB0P//3//IQVD//9/fws4AhwgAiAHOAIYIAIgBTgCFCACIAg4AhAgACABQQxqIAFBFGogAUGoAWogAkEgaiACQRBqQQAQ5gIMAQsgA0GAgIAgcQRAIAEqAgwhBiACIAEqAhAiBUMAAIA/kjgCHCACIAZDAACAP5I4AhggAiAGQwAAgL+SOAIQIAIgBUMAAIC/kjgCFCAAIAFBDGogAUEUaiABQagBaiACQSBqIAJBEGpBABDmAgwBCyADQYCAgBBxBEAgBEHgK2oqAgAhBiACQQhqEPcDIAJCADcDGCACQgA3AxACfQJAIAQtAJI7DQAgBC0AkztFDQAgBC0ACEEEcQ0AIAIqAgwiBkMAAABBkiEFIAIqAggiB0MAAIBBkgwBCyAGQwAAwEGUIgcgAioCDCIGkiEFIAcgAioCCCIHkgshCCACIAU4AhwgAiAIOAIYIAIgBkMAAADBkjgCFCACIAdDAACAwZI4AhAgACACQQhqIAFBFGogAUGoAWogAkEgaiACQRBqQQIQ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AgsgAEUNAEH/ACEEQf8AIABrIAFIDQELIAAgAWohBAsgAiAEOgAADwsgAUEtRw0JIAMsAAAhAQJAAkAgBCwAACIAQQBKBEBBgAEhBCAAQYABayABTA0BDAILIABFDQBB/wAhBCAAQf8AaiABSA0BCyABIABrIQQLIAIgBDoAAA8LIAFBK0YEQCACQf8BIAQtAAAgAy0AAGoiACAAQf8BTxs6AAAPCyABQS1HDQggAiADLQAAIgAgBC0AAGsiAUEAIAAgAU8bOgAADwsgAUErRgRAIAMuAQAhAQJAAkAgBC4BACIAQQBIBEBBgIACIQRBgIB+IABrIAFMDQEMAgsgAEUNAEH//wEhBEH//wEgAGsgAUgNAQsgACABaiEECyACIAQ7AQAPCyABQS1HDQcgAy4BACEBAkACQCAELgEAIgBBAEoEQEGAgAIhBCAAQYCAAmsgAUwNAQwCCyAARQ0AQf//ASEEIABB//8BaiABSA0BCyABIABrIQQLIAIgBDsBAA8LIAFBK0YEQCACQf//AyAELwEAIAMvAQBqIgAgAEH//wNPGzsBAA8LIAFBLUcNBiACIAMvAQAiACAELwEAayIBQQAgACABTxs7AQAPCyABQStGBEAgAygCACEBIAICfyAEKAIAIgBBAEgEQEGAgICAeEGAgICAeCAAayABSg0BGgtB/////wcgACABaiIDIABB/////wdzIAFIGyADIABBAEobCzYCAA8LIAFBLUcNBSADKAIAIQEgAgJ/IAQoAgAiAEEASgRAQYCAgIB4IABBgICAgHhyIAFKDQEaC0H/////ByABIABrIgMgAEH/////B2ogAUgbIAMgAEEASBsLNgIADwsgAUErRgRAIAJBfyAEKAIAIgAgAygCAGoiASAAIAFLGzYCAA8LIAFBLUcNBCACIAMoAgAiACAEKAIAayIBQQAgACABTxs2AgAPCyABQStGBEAgAykDACEGIAICfiAEKQMAIgVCAFMEQEKAgICAgICAgIB/QoCAgICAgICAgH8gBX0gBlUNARoLQv///////////wAgBSAGfCIHIAVC////////////AIUgBlMbIAcgBUIAVRsLNwMADwsgAUEtRw0DIAMpAwAhBiACAn4gBCkDACIFQgBVBEBCgICAgICAgICAfyAFQoCAgICAgICAgH+EIAZVDQEaC0L/////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IABBEGogAiAEQQFqECoaIAALIAACQCAAKAIEIAFHDQAgACgCHEEBRg0AIAAgAjYCHAsLmgEAIABBAToANQJAIAAoAgQgAkcNACAAQQE6ADQCQCAAKAIQIgJFBEAgAEEBNgIkIAAgAzYCGCAAIAE2AhAgA0EBRw0CIAAoAjBBAUYNAQwCCyABIAJGBEAgACgCGCICQQJGBEAgACADNgIYIAMhAgsgACgCMEEBRw0CIAJBAUYNAQwCCyAAIAAoAiRBAWo2AiQLIABBAToANgsLTQEBfwJAIAFFDQAgAUHwtgQQggEiAUUNACABKAIIIAAoAghBf3NxDQAgACgCDCABKAIMQQAQWUUNACAAKAIQIAEoAhBBABBZIQILIAILkwECBX0BfyABKgIQIQQgAS0ACEEBcUUEQEGQvwQoAgAiByoCyDIgASoCvASUIQIgB0HoKmoqAgAiAyADkiABKALYBSIHBH0gAiAHKgK8BJQFIAILkiECCyABKgIcIQUgASoCDCEDIAEQ3QEhBiAAIAMgBZI4AgggACAEIAKSIgI4AgQgACADOAIAIAAgAiAGkjgCDAsiAQF/A0AgASAAIgJJBEAgAkECayIALwEAQQpHDQELCyACC10BAX8gACgCECIDRQRAIABBATYCJCAAIAI2AhggACABNgIQDwsCQCABIANGBEAgACgCGEECRw0BIAAgAjYCGA8LIABBAToANiAAQQI2AhggACAAKAIkQQFqNgIkCwsOACAAQdAAahBnQdAAagsWACAAIAEoAgA2AgAgACACKAIANgIECwsAIAAgASACEMcFCwoAIAAgASAAa2oLIQAgACAALQALQYABcSABcjoACyAAIAAtAAtB/wBxOgALCy4AIAAgACgCCEGAgICAeHEgAUH/////B3FyNgIIIAAgACgCCEGAgICAeHI2AggLCQAgACABNgIAC+kBAQV/IwBBEGsiBSQAIwBBIGsiAyQAIwBBEGsiBCQAIAQgATYCDCAEIAEgAmo2AgggA0EYaiAEQQxqIARBCGoQxwUgBEEQaiQAIAMoAhghBCADKAIcIQcjAEEQayICJAAgByAEayEGIAQgB0cEQCAAIAQgBhBCGgsgAiAEIAZqNgIMIAIgACAGajYCCCADQRBqIAJBDGogAkEIahDIBSACQRBqJAAgAyABIAMoAhAQyQU2AgwgAyAAIAMoAhQQyQU2AgggBUEIaiADQQxqIANBCGoQyAUgA0EgaiQAIAUoAgwaIAVBEGokAAskACAAQQtPBH8gAEEQakFwcSIAIABBAWsiACAAQQtGGwVBCgsLKAECfyMAQRBrIgIkACAAKAIAIAEoAgBJIQMgAkEQaiQAIAEgACADGwsMACAAIAEtAAA6AAALDQAgAEHwugQ2AgAgAAuMAgIEfQF/IAEqAgwiByABKgIUkiIFQwAAgL+SIAUgBEMAAAAAWyIJGyEFIAEqAhAiCCABKgIYkiIGQwAAgL+SIAYgCRshBgJAAkACQAJAAkACQCACDgQAAQIDBAsgACAGIAOTOAIMIAAgByAEkjgCCCAAIAggA5I4AgQgACAHIASTOAIADwsgACAGIAOTOAIMIAAgBSAEkjgCCCAAIAggA5I4AgQgACAFIASTOAIADwsgACAIIASSOAIMIAAgBSADkzgCCCAAIAggBJM4AgQMAgsgACAGIASSOAIMIAAgBSADkzgCCCAAIAYgBJM4AgQMAQsgAEIANwIAIABCADcCCA8LIAAgByADkjgCAAuqDwIFfw9+IwBB0AJrIgUkACAEQv///////z+DIQsgAkL///////8/gyEKIAIgBIVCgICAgICAgICAf4MhDSAEQjCIp0H//wFxIQgCQAJAIAJCMIinQf//AXEiCUH//wFrQYKAfk8EQCAIQf//AWtBgYB+Sw0BCyABUCACQv///////////wCDIgxCgICAgICAwP//AFQgDEKAgICAgIDA//8AURtFBEAgAkKAgICAgIAghCENDAILIANQIARC////////////AIMiAkKAgICAgIDA//8AVCACQoCAgICAgMD//wBRG0UEQCAEQoCAgICAgCCEIQ0gAyEBDAILIAEgDEKAgICAgIDA//8AhYRQBEAgAyACQoCAgICAgMD//wCFhFAEQEIAIQFCgICAgICA4P//ACENDAMLIA1CgICAgICAwP//AIQhDUIAIQEMAgsgAyACQoCAgICAgMD//wCFhFAEQEIAIQEMAgsgASAMhFAEQEKAgICAgIDg//8AIA0gAiADhFAbIQ1CACEBDAILIAIgA4RQBEAgDUKAgICAgIDA//8AhCENQgAhAQwCCyAMQv///////z9YBEAgBUHAAmogASAKIAEgCiAKUCIGG3kgBkEGdK18pyIGQQ9rEFtBECAGayEGIAUpA8gCIQogBSkDwAIhAQsgAkL///////8/Vg0AIAVBsAJqIAMgCyADIAsgC1AiBxt5IAdBBnStfKciB0EPaxBbIAYgB2pBEGshBiAFKQO4AiELIAUpA7ACIQMLIAVBoAJqIAtCgICAgICAwACEIhJCD4YgA0IxiIQiAkIAQoCAgICw5ryC9QAgAn0iBEIAEFogBUGQAmpCACAFKQOoAn1CACAEQgAQWiAFQYACaiAFKQOYAkIBhiAFKQOQAkI/iIQiBEIAIAJCABBaIAVB8AFqIARCAEIAIAUpA4gCfUIAEFogBUHgAWogBSkD+AFCAYYgBSkD8AFCP4iEIgRCACACQgAQWiAFQdABaiAEQgBCACAFKQPoAX1CABBaIAVBwAFqIAUpA9gBQgGGIAUpA9ABQj+IhCIEQgAgAkIAEFogBUGwAWogBEIAQgAgBSkDyAF9QgAQWiAFQaABaiACQgAgBSkDuAFCAYYgBSkDsAFCP4iEQgF9IgJCABBaIAVBkAFqIANCD4ZCACACQgAQWiAFQfAAaiACQgBCACAFKQOoASAFKQOgASIMIAUpA5gBfCIEIAxUrXwgBEIBVq18fUIAEFogBUGAAWpCASAEfUIAIAJCABBaIAYgCSAIa2ohBgJ/IAUpA3AiE0IBhiIOIAUpA4gBIg9CAYYgBSkDgAFCP4iEfCIQQufsAH0iFEIgiCICIApCgICAgICAwACEIhVCAYYiFkIgiCIEfiIRIAFCAYYiDEIgiCILIBAgFFatIA4gEFatIAUpA3hCAYYgE0I/iIQgD0I/iHx8fEIBfSITQiCIIhB+fCIOIBFUrSAOIA4gE0L/////D4MiEyABQj+IIhcgCkIBhoRC/////w+DIgp+fCIOVq18IAQgEH58IAQgE34iESAKIBB+fCIPIBFUrUIghiAPQiCIhHwgDiAOIA9CIIZ8Ig5WrXwgDiAOIBRC/////w+DIhQgCn4iESACIAt+fCIPIBFUrSAPIA8gEyAMQv7///8PgyIRfnwiD1atfHwiDlatfCAOIAQgFH4iGCAQIBF+fCIEIAIgCn58IgogCyATfnwiEEIgiCAKIBBWrSAEIBhUrSAEIApWrXx8QiCGhHwiBCAOVK18IAQgDyACIBF+IgIgCyAUfnwiC0IgiCACIAtWrUIghoR8IgIgD1StIAIgEEIghnwgAlStfHwiAiAEVK18IgRC/////////wBYBEAgFiAXhCEVIAVB0ABqIAIgBCADIBIQWiABQjGGIAUpA1h9IAUpA1AiAUIAUq19IQpCACABfSELIAZB/v8AagwBCyAFQeAAaiAEQj+GIAJCAYiEIgIgBEIBiCIEIAMgEhBaIAFCMIYgBSkDaH0gBSkDYCIMQgBSrX0hCkIAIAx9IQsgASEMIAZB//8AagsiBkH//wFOBEAgDUKAgICAgIDA//8AhCENQgAhAQwBCwJ+IAZBAEoEQCAKQgGGIAtCP4iEIQogBEL///////8/gyAGrUIwhoQhDCALQgGGDAELIAZBj39MBEBCACEBDAILIAVBQGsgAiAEQQEgBmsQ2gEgBUEwaiAMIBUgBkHwAGoQWyAFQSBqIAMgEiAFKQNAIgIgBSkDSCIMEFogBSkDOCAFKQMoQgGGIAUpAyAiAUI/iIR9IAUpAzAiBCABQgGGIgFUrX0hCiAEIAF9CyEEIAVBEGogAyASQgNCABBaIAUgAyASQgVCABBaIAwgAiACIAMgAkIBgyIBIAR8IgNUIAogASADVq18IgEgElYgASASURutfCICVq18IgQgAiACIARCgICAgICAwP//AFQgAyAFKQMQViABIAUpAxgiBFYgASAEURtxrXwiAlatfCIEIAIgBEKAgICAgIDA//8AVCADIAUpAwBWIAEgBSkDCCIDViABIANRG3GtfCIBIAJUrXwgDYQhDQsgACABNwMAIAAgDTcDCCAFQdACaiQAC8ABAgF/An5BfyEDAkAgAEIAUiABQv///////////wCDIgRCgICAgICAwP//AFYgBEKAgICAgIDA//8AURsNACACQv///////////wCDIgVCgICAgICAwP//AFYgBUKAgICAgIDA//8AUnENACAAIAQgBYSEUARAQQAPCyABIAKDQgBZBEAgASACUiABIAJTcQ0BIAAgASAChYRCAFIPCyAAQgBSIAEgAlUgASACURsNACAAIAEgAoWEQgBSIQMLIAML7gECAX8IfSMAQRBrIgUkACAAKgIYIQkgACoCECEIIAIqAgQhCyABKgIEIQYgBSABKgIAIgcgACoCDCIKIAAqAhSSIgyTIAIqAgAiDZQgDJIgCiAHkyANlCAHkiIHkyIKOAIIIAUgCyAGIAggCZIiCZOUIAmS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IAYNARpBAkEDIAMgCoRQGwwCCyADIAqEUAsLIQYgAkIwiKciCEH//wFxIgdB//8BRg0AIAYNAQsgBUEQaiABIAIgAyAEEDwgBSAFKQMQIgIgBSkDGCIBIAIgARDTBSAFKQMIIQIgBSkDACEEDAELIAEgAkL///////////8AgyIKIAMgBEL///////////8AgyIJENsBQQBMBEAgASAKIAMgCRDbAQRAIAEhBAwCCyAFQfAAaiABIAJCAEIAEDwgBSkDeCECIAUpA3AhBAwBCyAEQjCIp0H//wFxIQYgBwR+IAEFIAVB4ABqIAEgCkIAQoCAgICAgMC7wAAQPCAFKQNoIgpCMIinQfgAayEHIAUpA2ALIQQgBkUEQCAFQdAAaiADIAlCAEKAgICAgIDAu8AAEDwgBSkDWCIJQjCIp0H4AGshBiAFKQNQIQMLIAlC////////P4NCgICAgICAwACEIQsgCkL///////8/g0KAgICAgIDAAIQhCiAGIAdIBEADQAJ+IAogC30gAyAEVq19IglCAFkEQCAJIAQgA30iBIRQBEAgBUEgaiABIAJCAEIAEDwgBSkDKCECIAUpAyAhBAwFCyAJQgGGIARCP4iEDAELIApCAYYgBEI/iIQLIQogBEIBhiEEIAdBAWsiByAGSg0ACyAGIQcLAkAgCiALfSADIARWrX0iCUIAUwRAIAohCQwBCyAJIAQgA30iBIRCAFINACAFQTBqIAEgAkIAQgAQPCAFKQM4IQIgBSkDMCEEDAELIAlC////////P1gEQANAIARCP4ghASAHQQFrIQcgBEIBhiEEIAEgCUIBhoQiCUKAgICAgIDAAFQNAAsLIAhBgIACcSEGIAdBAEwEQCAFQUBrIAQgCUL///////8/gyAHQfgAaiAGcq1CMIaEQgBCgICAgICAwMM/EDwgBSkDSCECIAUpA0AhBAwBCyAJQv///////z+DIAYgB3KtQjCGhCECCyAAIAQ3AwAgACACNwMIIAVBgAFqJAALvwIBAX8jAEHQAGsiBCQAAkAgA0GAgAFOBEAgBEEgaiABIAJCAEKAgICAgICA//8AEDwgBCkDKCECIAQpAyAhASADQf//AUkEQCADQf//AGshAwwCCyAEQRBqIAEgAkIAQoCAgICAgID//wAQPEH9/wIgAyADQf3/Ak4bQf7/AWshAyAE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EGoQhQEhACACIAEoAgAgASABLAALQQBIGzYCACAAQcMuIAIQrwMgAkEgaiQAC0sBAX8jAEEgayIDJAAgAyABNgIYIANBCGoiASACEDMgA0EYaiABIAARAAAgAywAE0EASARAIAMoAggQKwsgAygCGBAAIANBIGokAAswAQF/IwBBEGsiASQAIAEgACgCACAAIAAsAAtBAEgbNgIAQcMuIAEQNCABQRBqJAALFQAgACgCACAAIAAsAAtBAEgbEKACC64BAgR/AXwjAEEQayIBJAAgACgCABATIgJBnjIQCCIDEA4hBCADEAAgAhAAAkAgBARAIAAoAgBBxLgEIAEQByEFIAEoAgAQBkGQvwQoAgAoAqg3An8gBZlEAAAAAAAA4EFjBEAgBaoMAQtBgICAgHgLEKAEIQAMAQsgASAAEF8gASgCACABIAEsAAtBAEgbENkDIQAgASwAC0EATg0AIAEoAgAQKwsgAUEQaiQAIAALnAECBH8BfCMAQRBrIgEkACAAKAIAEBMiAkGeMhAIIgMQDiEEIAMQACACEAACQCAEBEAgACgCAEHEuAQgARAHIQUgASgCABAGAn8gBZlEAAAAAAAA4EFjBEAgBaoMAQtBgICAgHgLEKoBDAELIAEgABBfIAEoAgAgASABLAALQQBIGxBxIAEsAAtBAE4NACABKAIAECsLIAFBEGokAAsnAQF/IwBBEGsiASQAIAFCADcDCCAAIAFBCGoQLRDjAiABQRBqJAALPQECfyMAQRBrIgIkACACQQhqIgMQ2AMgAiABKAIAIgE2AgAgARAFIAAgAyACEE4gAigCABAAIAJBEGokAAtvAgN/An0jAEEQayICJABBkL8EKAIAKAKoNyIDKgLgASEFIAMqAgwhBiACQQhqIgQgAyoC5AEgAyoCEJM4AgQgBCAFIAaTOAIAIAIgASgCACIBNgIAIAEQBSAAIAQgAhBOIAIoAgAQACACQRBqJAALnQECA30CfyMAQRBrIgQkACAEQgA3AwggACAEQQhqEC0hBUGQvwQoAgAoAqg3IgBBAToAjAEgBSoCBCEBIAAgACoCDCAAKgJYkyAFKgIAkiICOALQASAAIAEgACoCECAAKgJck5IiATgC1AEgACAAKgLoASIDIAIgAiADXxs4AugBIAAgACoC7AEiAiABIAEgAl8bOALsASAEQRBqJAAL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ByAEQf//g3xB/4GAfCADIAAsAKQDRiIHG0MAAAAAQQBDAABAQEMAAIA/IAcbED0gA0EBaiIDIAAoAlRIDQALDAELIAJBoAdqIgcgACADQX8Q4QIgBiAHIARB/4GAfEMAAAAAQQBDAACAPxA9CyABQQFqIgEgBSgChD9IDQALCxBiIAJBgAlqJAAgC0GYmwM2AgAgCygCCCgCAEECRwRAIAsQaQsgC0EQaiQACywBAX8jAEEQayICJAAgAiABNgIIIAJBCGogABECACACKAIIEAAgAkEQaiQAC0cBAn8jAEEQayIBJAAgAUGQvwQoAgBB0DpqKAIAKAIAIgJBNGpBACACLQA0GzYCCCAAQbCRAyABQQhqEAM2AgAgAUEQaiQACwcAIAARBgALLAEBfyMAQRBrIgEkACABEKECNgIIIABB+JkDIAFBCGoQAzYCACABQRBqJAALLAEBfyMAQRBrIgEkACABEIoDNgIIIABB/JcDIAFBCGoQAzYCACABQRBqJAALHQEBf0Hc6wUgADYCACAABH8gACgCAAUgAQsQiwILCQBB3OsFKAIAC3gBAn8CQCAAQYTfAGooAgAiAkUNACACQQRqIQMDQCADIgEtAA0EQEGQvwQoAgBBkDdqIAEoAgAQnAEiAwRAIAMgARCBBiAAKAKEXyECCyABQQA6AA0LIAEgAUEEaygCAGoiAyACIAAoAvxeakEEakYNASABDQALCwusGgIHfwF9QbgBECkiBCEHIAAhAUGQvwQoAgAiAARAIAAgACgC7AZBAWo2AuwGC0GI/ABBmL8EKAIAQdi8BCgCABEBACIAQQhqQQBBoCoQLyICQpqz5vSDgIDgwAA3AyAgAkGJDzYCHCACQfDCADYCGCACQomRouSDgIDQwAA3AxAgAkKAgID8i4CAwL9/NwMIIAJBLGpB/wFB2AAQLxogAkIANwK0ASACQYCAwJMENgKwASACQQE6AKwBIAJBgAI7AKkBIAJCgICA/IOAgMA/NwOgASACQQA6AJgBIAJCgICAgICAgMA/NwOQASACQs2Zs/TTmbOmPTcChAEgAkIANwK8ASACQQA2AsQBIAJC////+////79/NwL8BiACQv////v///+/fzcC3AEgAkEBNgLUASACQQI2AswBIAJBAzYCyAEgAkGAgICGBDYCKANAIAIgBUECdGoiBkGICGpBgICA/Hs2AgAgBkGcCGpBgICA/Hs2AgAgBUEBaiIFQQVHDQALA0AgAiADQQJ0aiIFQewIakGAgID8ezYCACAFQewYakGAgID8ezYCACADQQFqIgNBgARHDQALQQAhAwNAIAIgA0ECdGpB7ChqQYCAgPx7NgIAIANBAWoiA0EURw0ACyAAQagqahCRBhpBACECIABBzDJqQQBB9AMQLyEDA0AgAyACQQN0aiIFIAKyIgggCJJD2w9JQJRDAABAQpUiCBC9ATgCMCAFIAgQvgE4AiwgAkEBaiICQTBHDQALIANBADYCrAMgAEIANwOgNyAAQgA3Arw3IABCADcDiDggAEIANwKcOyAAQdA6akEANgIAIABCADcDyDogAEGkO2pCADcCACAAQgA3AvQ7IABB/DtqQgA3AgAgAEGEPGpCADcCACAAQYw8akIANwIAIABB4DZqQQBBPBAvGiAAQbQ4akEAQZACEC8aIABB4DtqQgA3AwAgAEHYO2pCADcDACAAQdA7akIANwMAIABCADcDyDsgAEGcPGpB////+wc2AgAgAEIANwOgPCAAQZQ8akL////79///v/8ANwIAIABBqDxqQgA3AwAgAEGwPGpCADcDACAAQbg8akIANwMAIABByDxqQf////sHNgIAIABCADcCzDwgAEHAPGpC////+/f//7//ADcDACAAQdQ8akIANwIAIABB3DxqQgA3AgAgAEHkPGpCADcCACAAQfA8akL////79///v/8ANwMAIABB7DxqQf////sHNgIAIABBkD1qQgA3AwAgAEGIPWpCADcDACAAQYA9akIANwMAIABCADcD+DwgAEGcPWpC////+/f//7//ADcCACAAQZg9akH////7BzYCACAAQeg9akEAQSEQLxogAEHcPWpCADcCACAAQgA3AtQ9IABB5D1qQX82AgAgAEIANwKMPiAAQYk+akEAOwAAIABBlD5qQgA3AgAgAEHAPmpBADYCACAAQgA3A7g+IABB4D5qQQA2AgAgAEIANwPYPiAAQew+akEAQcQAEC8aIABBtD9qQQBBtB0QLxogAEHo3ABqEPUEIABBADYC4F8gAEG43wBqQQA2AgAgAEIANwOwXyAAQdTdAGpBAEHAABAvGiAAQbTeAGpBAEEoEC8aIABB5N4AakEAQTwQLxogAEIANwPwXyAAQejfAGpC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ACABKAIAEAUgACgCQBAAIAAgASgCADYCQAsXACAAQdzrBSgCACgCQCIANgIAIAAQBQsjAEHc6wUoAgAhACABKAIAEAUgACgCMBAAIAAgASgCADYCMAsXACAAQdzrBSgCACgCMCIANgIAIAAQBQsjAEHc6wUoAgAhACABKAIAEAUgACgCLBAAIAAgASgCADYCLAsXACAAQdzrBSgCACgCLCIANgIAIAAQBQsjAEHc6wUoAgAhACABKAIAEAUgACgCKBAAIAAgASgCADYCKAsXACAAQdzrBSgCACgCKCIANgIAIAAQBQsjAEHc6wUoAgAhACABKAIAEAUgACgCJBAAIAAgASgCADYCJAsXACAAQdzrBSgCACgCJCIANgIAIAAQBQsjAEHc6wUoAgAhACABKAIAEAUgACgCIBAAIAAgASgCADYCIAsXACAAQdzrBSgCACgCICIANgIAIAAQBQtnAgF/AXwjAEEQayICJAAgAAJ/AkAgASgCACIBQQJGDQAgAUH4igMgAkEMahAHIQMgAigCDBAGIANEAAAAAAAA8EFjIANEAAAAAAAAAABmcUUNACADqwwBC0EACzYCnAEgAkEQaiQACzkBAX8jAEEQayICJAAgACABKAKcASIBBH8gAiABNgIIQfiKAyACQQhqEAMFQQILNgIAIAJBEGokAAs5AQF/IwBBEGsiAiQAIAAgASgCkAEiAQR/IAIgATYCCEG8lQMgAkEIahADBUECCzYCACACQRBqJAALIwBB3OsFKAIAIQAgASgCABAFIAAoAhwQACAAIAEoAgA2AhwLFwAgAEHc6wUoAgAoAhwiADYCACAAEAULHAAgAUEVTQRAIAAgAUECdGogAjYCLAsgAUEWSQseAQF/QX8hAiABQRVNBH8gACABQQJ0aigCLAUgAgsLcwEDfyMAQRBrIgIkAEHc6wUoAgAhAyACIAEQXyADQRBqIQQgAywAG0EASARAIAQoAgAQKwsgBCACKQMANwIAIAQgAigCCDYCCCAAIAEoAgBBAkcEfyADKAIQIAQgAywAG0EASBsFQQALNgIcIAJBEGokAAsYACAAIAEoAhwiAQR/IAEQCAVBAgs2AgALcwEDfyMAQRBrIgIkAEHc6wUoAgAhAyACIAEQXyADQQRqIQQgAywAD0EASARAIAQoAgAQKwsgBCACKQMANwIAIAQgAigC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CikCADcCACAAIAAoAlRBAWoiATYCVCAAIAAoAlwgASAFQQEgBhBlIABBADYCVAsgB0EgaiQAC00BAX8jAEEQayIIJAAgACgCACEAIAggAzYCACAIIAI2AgggASAIQQhqIAggBCAFIAYgByAAERQAIAgoAgAQACAIKAIIEAAgCEEQaiQAC0IBAX8jAEEQayIHJAAgB0IANwMIIAEgB0EIahAtIQEgB0IANwMAIAAgASACIAcQLSADIAQgBSAGEKYCIAdBEGokAAtLAQF/IwBBEGsiByQAIAAoAgAhACAHIAM2AgAgByACNgIIIAEgB0EIaiAHIAQgBSAGIAARJAAgBygCABAAIAcoAggQACAHQRBqJAALPwEBfyMAQRBrIgYkACAGQgA3AwggASAGQQhqEC0hASAGQgA3AwAgACABIAIgBhAtIAMgBCAFEEEgBkEQaiQAC00BAX8jAEEQayIIJAAgACgCACEAIAggAzYCACAIIAI2AgggASAIQQhqIAggBCAFIAYgByAAESwAIAgoAgAQACAIKAIIEAAgCEEQaiQAC0EBAX8jAEEQayIHJAAgB0IANwMIIAEgB0EIahAtIQEgB0IANwMAIAAgASACIAcQLSADIAQgBSAGED0gB0EQaiQAC0kBAX8jAEEQayIGJAAgACgCACEAIAYgAzYCACAGIAI2AgggASAGQQhqIAYgBCAFIAARFgAgBigCABAAIAYoAggQACAGQRBqJAALPQEBfyMAQRBrIgUkACAFQgA3AwggASAFQQhqEC0hASAFQgA3AwAgACABIAIgBRAtIAMgBBBNIAVBEGokAAtPAQF/IwBBEGsiAyQAIAMgASgCRCABKAI8QQR0akEIaykCADcDCCADIAIoAgAiATYCACABEAUgACADQQhqIAMQTiADKAIAEAAgA0EQaiQAC08BAX8jAEEQayIDJAAgAyABKAJEIAEoAjxBBHRqQRBrKQIANwMIIAMgAigCACIBNgIAIAEQBSAAIANBCGogAxBOIAMoAgAQACADQRBqJAALUgIBfwF8IwBBEGsiAiQAIAEoAgBBxLgEIAJBDGoQByEDIAIoAgwQBiAAAn8gA5lEAAAAAAAA4EFjBEAgA6oMAQtBgICAgHgLELoBIAJBEGokAAtaAQF/IwBBIGsiBCQAIARCADcDGCABIARBGGoQLSEBIARCADcD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IASSCyEEIABBAWogBCABkhCwAwtxAgJ/AX0jAEEQayICJAACfUGQvwQoAgAoAqg3KALwAiIBRQRAIAJBCGoQtQIgAioCCAwBCyABKAJkIABBAEgEfyABKAIMBSAAC0EcbGoiACoCHCAAKgIAkyABKgIYIAEqAhSTlAshAyACQRBqJAAgAwtOAgF/AX1BkL8EKAIAKAKoNygC8AIiAUUEQEMAAAAADwsgASoCGCABKgIUIgKTIAEoAmQgAEEASAR/IAEoAgwFIAALQRxsaioCAJQgApILIQEBf0GQvwQoAgAoAqg3KALwAiIARQRAQQEPCyAAKAIQCyABAn9BkL8EKAIAKAKoNygC8AIiAQR/IAEoAgwFIAALC4EBAQR/IABBhD9qKAIAIgIEQCAAQYw/aigCACEDQQAhAQNAAkAgAyABQQN0aigCBCIEQX9GDQAgACgCgD8iBUUNACAFIARByANsakF/NgJMCyABQQFqIgEgAkcNAAsLIABBkN8AaigCACIBBEAgAEIANwKIXyABECwgAEEANgKQXwsLxgIBBH8jAEEQayIBJABBACEAIAFBADYCDCABQQA2AgggASABQQxqNgIAIAEgAUEIajYCBAJAIAJB3OUAIAEQRkECSA0AIAEoAgwhBAJAQZC/BCgCACICQZDfAGooAgAiAEUNACAAQQRqIgMhAANAIAQgACgCAEcEQCAAIABBBGsoAgBqIgAgAyACKAKIX2pHDQEMAgsLIAEoAggiBiAALAANIgNMBEAgAEIANwIAIABCADcCCCADQQBKBEAgAEEQaiECA0AgAkH/AToACiACQgA3AgAgAkH//wM7AQggAiACLQALQfABcUEEcjoACyACQQxqIQIgBUEBaiIFIANHDQALCyAAQQE6AA4gACADOgANIAAgBjoADCAAIAQ2AgAMAgsgAEEANgIAIAEoAgwhBAsgBCABKAIIEOYEIQALIAFBEGokACAAC5AGAQN/IwBBkAFrIgAkACAAQQA2AowBIABBADYCiAEgAEEANgKEASAAQQA2AoABIAAgAEGMAWo2AnACQCADQbvOACAAQfAAahBGQQFGBEAgAiAAKgKMATgCCAwBCyAAIABBhAFqNgJkIAAgAEGIAWo2AmAgA0G3PiAAQeAAahBGQQFHDQAgACgCiAEiAUEASA0AIAEgAiwADE4NACADIAAo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KgIAk5I4AvBjIAAgEzgCACADIAJBAWpB+ABvNgLoYyADQfcAIAMoAuxjIgAgAEH3AE4bQQFqIgA2AuxjIAMgAyoC8GMiEUMAAAAAXgR9QwAAgD8gESAAspWVBUP//39/CzgC2AZBACECQZC/BCgCACIBQdA6aigCACgCACIAQgU3AgAgAEEANgIIIAAgASkDEDcCDCABKALIOkEASgRAA0AgASgC0DogAkECdGooAgAiACAAKQKIATcCeCAAQgA3AogBIAApApABIRkgAEIANwKQASAAIBk3AoABIAAgACoCBCAAKgJ4IhGSOAIUIAAgACoCCCAAKgJ8IhKSOAIYIABDAAAAACAAKgIMIBGTIAAqAoABkiIRIBFDAAAAAF8bOAIcIABDAAAAACAAKgIQIBKTIAAqAoQBkiIRIBFDAAAAAF8bOAIgIAJBAWoiAiABKALIOkgNAAtBkL8EKAIAIQELIAMoApgBQQE6ABAgASgCpAEiAAR/IAAFIAEoApgBKAI8KAIACxD7AwJAIAMoAsg6IgFBAEwEQEP//3//IRND//9/fyERQ///f38hF0P//3//IRYMAQsgA0HQOmooAgAhAEP//39/IRdD//9//yEWQQAhAkP//3//IRND//9/fyERA0AgACACQQJ0aigCACIEKgIEIhUgBCoCDJIiEiATIBIgE14bIRMgBCoCCCIUIAQqAhCSIhIgFiASIBZeGyEWIBUgESARIBVeGyERIBQgFyAUIBddGyEXIAJBAWoiAiABRw0ACwsgA0HwMmogFjgCACADQewyaiATOAIAIANB6DJqIBc4AgAgA0HkMmogETgCACADQdwyaiADQegraioCADgCAEEAIQAgA0HsK2oqAgAiEiADQcwyaiIBKgIUXARAIAEgEjgCFANAIAAgAWogAAR/QQRBgAQCf0PbD0lAQwAAgD8gEiAAsiIRIBEgEl4bIBGVkxCDApWNIhGLQwAAAE9dBEAgEagMAQtBgICAgHgLQQFqQQJtQQF0IgIgAkGABE4bIgIgAkEETBsFQQALOgCwAyAAQQFqIgBBwABHDQALIAEgEkMAUQw7lTgCrAMLIANB9DJqIANB5CtqLQAAIgA2AgACQCADQeUrai0AAEUNACADKALAMigCMC0AAEEEcQ0AIAMgAEECciIANgL0MgsgA0HmK2otAAAEQCADIABBBHIiADYC9DILIAMtAAxBCHEEQCADIABBCHI2AvQyCyADKALIOkEASgRAQQAhAANAIAMoAtA6IABBAnRqKAIAQTRqQQBBLBAvGiAAQQFqIgAgAygCyDpIDQALCwJAIAMtAMQ9RQ0AIANB3D1qKAIAIgIgAygC4DdHDQAgAkGQvwQoAgAiACgC4DdGBEAgACACNgLkNwsgACgCnDggAkcNACAAQQE6AKA4CwJAAkACQCADKALQNwRAIAMoAsw3IgJFDQEgAygC4DcgAkcNAiADQQA2Atw3DAILIANCADcD2DcgAygCzDciAg0BCyADKALgNyEAQQAhAgwBCyADIAMqAhgiESADKgLYN5I4Atg3IAIgAygC4DciAEYEQCACIQAMAQsgAyARIAMqAtw3kjgC3DcLIAMgAjYC0DcgA0EAOgDXNyADQQA2Asw3IAMgAy0A1Tc6ANY3IANBADsB1DcCQCAARSADKALkNyAARnINACADKAKcOCAARw0AQQBBABBMIAMoAuA3IQALIAMqAhghESAABEAgAyARIAMqAug3kjgC6DcLIAMgADYCnDggA0EAOgCgOCADQQA6APE3IANBADYC5DcgA0EAOgDsNyADIAMoApA4NgKkOCADIAMtAPA3OgChOCADIBEgAyoCrDiSOAKsOCADKALAXSICRSAAIAJGckUEQCADQQA2AsBdCyAARQRAIANCADcDgDggA0IANwL0NwtBACEAIANBADYCtD4gA0EAOwDFPSADIAMoAqg+NgKsPiADQv////sHNwKkPiADQZgqai0AAARAQQAhAiADQQhqIgRB+AFqQQBBgAQQLxoDQCAEIAJBAnRqIgFB7AhqQYCAgPx7NgIAIAFB7BhqQYCAgPx7NgIAIAJBAWoiAkGABEcNAAsgBEIANwL0BkEAIQIgBEEANgL0AQNAIAQgAkECdGoiAUHsKGpBgICA/Hs2AgAgAUG8KWpBgICA/Hs2AgAgAkEBaiICQRRHDQALIANBADoAmCoLIANBkL8EKAIAIgUtAPwBIgJBAnIgAiAFLQD9ARsiAkEEciACIAUtAP4BGyICQQhyIAIgBS0A/wEbNgL8BiADQfQYaiADQfQIakGAEBAqGgNAIAMgAEECdGpB9AhqAn1DAACAvyAAIANqLQCAAkUNABpDAAAAACADIABBAnRqQfQIaioCACIRQwAA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AEgEQCAJKAIcECsLIAlBMGokAAurAQECfyMAQUBqIgokACAKQTBqIgsgARAzIAogAzYCICAKIAI2AiggCiAGNgIYIAogBzYCECAKIAg2AgggCiAJNgIAIAsgCkEoaiAKQSBqIAQgBSAKQRhqIApBEGogCkEIaiAKIAAROgAgCigCABAAIAooAggQACAKKAIQEAAgCigCGBAAIAooAiAQACAKKAIoEAAgCiwAO0EASARAIAooAjAQKwsgCkFAayQAC6sBAQJ/IwBBEGsiBiQAQdzrBSgCACEHIAIoAgAQBSAHKAKUARAAIAcgAigCADYClAEgAygCABAFIAcoApgBEAAgAygCACECIAcgBDYCnAEgByACNgKYASAAKAIAIQIgACwACyEDIAYgATYCCCAGQZygAyIBNgIAIAYQlQEgAiAAIANBAEgbIAZBBHJB6gYgBCAFEL8EIQAgBiABNgIAIAYQgwEgBkEQaiQAIAALkQEBAn8jAEEQayIFJABB3OsFKAIAIQYgAigCABAFIAYoAoABEAAgAigCACECIAYgAzYChAEgBiACNgKAASAAKAIAIQIgACwACyEGIAUgATYCCCAFQZygAyIBNgIAIAUQlQEgAiAAIAZBAEgbIAVBBHJB6QYgAyAEEL8EIQAgBSABNgIAIAUQgwEgBUEQaiQAIAALYwECfyMAQSBrIgYkACAGQRBqIgcgARAzIAYgAzYCACAGIAI2AgggByAGQQhqIAYgBCAFIAARDQAhACAGKAIAEAAgBigCCBAAIAYsABtBAEgEQCAGKAIQECsLIAZBIGokACAAC0MBA38jAEEQayICJAAgACgCACEDIAAsAAshBCACQgA3AwggAyAAIARBAEgbIAEgAkEIahAtEMAEIQAgAkEQaiQAIAALuwEBBH8jAEEgayIEJAAgACgCACEHIAAsAAshBSAEQZibAzYCECAHIAAgBUEASBshBSAEIAE2AhgCQCABKAIAQQJGDQAgBEEQahCMASAEKAIYKAIAQQJGDQAgBEEQakEEciEGCyAEQgA3AwggAyAEQQhqEC0hACAFIAYtAAAgAiAAEFAiAARAIAYgBi0AAEEBczoAAAsgBEGYmwM2AhAgBCgCGCgCAEECRwRAIARBEGoQaQsgBEEgaiQAIAALRgEDfyMAQRBrIgQkACAAKAIAIQUgACwACyEGIARCADcDCCAFIAAgBkEASBsgASACIAMgBEEIahAtEFAhACAEQRBqJAAgAAtTAQJ/IwBBIGsiBSQAIAVBEGoiBiABEDMgBSAENgIIIAYgAiADIAVBCGogABEIACEAIAUoAggQACAFLAAbQQBIBEAgBSgCEBArCyAFQSBqJAAgAAuJAwIFfwV9IwBBEGsiAyQAIAAoAgAhBiAALAALIQQgA0GYmwM2AgAgBiAAIARBAEgbIQAgAyABNgIIAkAgASgCAEECRg0AIAMQjAEgAygCCCgCAEECRg0AIANBBHIhBwtBACEGIwBB0ABrIgUkAEGQvwQoAgAoAqg3IgRBAToAjAECQCAELQCPAQ0AAkAgB0UEQEEaIQEMAQtBnoDAACEBIActAABFDQELIAQgABA5IgQgASACciAAQQAQ6gEhBiAHRQ0AIAVBEGpBkL8EKAIAIgBByDhqIgFBPBAqGiAAQdQ4aioCACEJIABB3DhqKgIAIQsgAEHkKmoqAgAhCiAAQdg4aioCACEMIAAqAsQyIQggBBClBSEAIAUgDDgCDCAFIAkgCyAKIAqSkyAIkyIIIAggCV8bOAIIIAAgBUEIahCsAwRAIAdBADoAAAsgASAFQRBqQTwQKhoLIAVB0ABqJAAgBiEAIANBmJsDNgIAIAMoAggoAgBBAkcEQCADEGkLIANBEGokACAAC0cBAX8gACgCACAAIAAsAAtBAEgbIQBBkL8EKAIAKAKoNyICQQE6AIwBIAItAI8BBH9BAAUgAiAAEDkgAUEaciAAQQAQ6gELCzMBAX9BkL8EKAIAKAKoNyIBQQE6AIwBQwAAAAAQrgIgASABKALYAkEBajYC2AIgABCwAgtEAQF/IAAoAgAgACAALAALQQBIGyEBQZC/BCgCACgCqDciAEEBOgCMAUMAAAAAEK4CIAAgACgC2AJBAWo2AtgCIAEQcQtQAQF/IwBBEGsiAyQAIAMgAigCACACIAIsAAtBAEgbNgIAIwBBEGsiAiQAIAIgAzYCDCAAIAFBwy4gAxDCBCEAIAJBEGokACADQRBqJAAgAAs7AQF/IwBBEGsiBCQAIAQgAxAzIAEgAiAEIAARBQAhACAELAALQQBIBEAgBCgCABArCyAEQRBqJAAgAAtPAQN/IwBBEGsiAyQAIAAoAgAhBCAALAALIQUgAyACKAIAIAIgAiwAC0EASBs2AgAgBCAAIAVBAEgbIAFBwy4gAxCXAyEAIANBEGokACAAC1gBAn8jAEEgayIEJAAgBEEQaiIFIAEQMyAEIAMQMyAFIAIgBCAAEQUAIQAgBCwAC0EASARAIAQoAgAQKwsgBCwAG0EASARAIAQoAhAQKwsgBEEgaiQAIAALRAEBfyAAKAIAIAAgACwAC0EASBshAEGQvwQoAgAoAqg3IgJBAToAjAEgAi0AjwEEf0EABSACIAAQOSABIABBABDqAQsLNwEBfyMAQRBrIgIkACACIAEoAgAgASABLAALQQBIGzYCACAAQcMuIAIQxQEhACACQRBqJAAgAAs5AQF/IwBBEGsiAyQAIAMgAhAzIAEgAyAAEQEAIQAgAywAC0EASARAIAMoAgAQKwsgA0EQaiQAIAALTAEDfyMAQRBrIgIkACAAKAIAIQMgACwACyEEIAIgASgCACABIAEsAAtBAEgbNgIAIAMgACAEQQBIG0HDLiACEGAhACACQRBqJAAgAAtWAQJ/IwBBIGsiAyQAIANBEGoiBCABEDMgAyACEDMgBCADIAARAQAhACADLAALQQBIBEAgAygCABArCyADLAAbQQBIBEAgAygCEBArCyADQSBqJAAgAAsVACAAKAIAIAAgACwAC0EASBsQkQILawEDfyMAQSBrIgQkACAAKAIAIQUgACwACyEGIARCADcDGCAEQgA3AxAgASAEQRBqEIUBIQEgBEIANwMIIAQgAyAEQQhqEC0pAgA3AwAgBSAAIAZBAEgbIAEgAiAEEOsBIQAgBEEgaiQAIAALxQEBBH8jAEEwayIEJAAgACgCACEFIAAsAAshBiAEIAE2AiwgBEGgpAM2AhggBEEYaiIHEMABIARBvLADNgIAQQAhASAFIAAgBkEASBshACAEIAM2AhQgB0EEciEFAkAgAygCAEECRg0AIAQQwAEgBCgCFCgCAEECRg0AIARBBHIhAQsgACAFIAIgARDNAiEAIARBvLADNgIAIAQoAhQoAgBBAkcEQCAEEIsBCyAEQaCkAzYCGCAEQRhqEIsBIARBMGokACAAC2EBAn8jAEEgayIFJAAgBUEQaiIGIAEQMyAFIAQ2AgAgBSACNgIIIAYgBUEIaiADIAUgABEIACEAIAUoAgAQACAFKAIIEAAgBSwAG0EASARAIAUoAhAQKwsgBUEgaiQAIAALyQECBX8BfSMAQSBrIgMkACAAKAIAIQYgACwACyEHIAMgATYCGCADQeijAzYCCCADQQhqIgUQiQIjAEEQayIBJAAgASAFQQRyIgQqAgA4AgAgASAEKgIEOAIEIAQqAgghCCABQYCAgPwDNgIMIAEgCDgCCCAGIAAgB0EASBsgASACQQJyQQAQzQIiAARAIAQgASoCADgCACAEIAEqAgQ4AgQgBCABKgIIOAIICyABQRBqJAAgA0HoowM2AgggBRDBASADQSBqJAAgAAtiAQR/IwBBIGsiAyQAIAAoAgAhBSAALAALIQYgAyABNgIcIANBoKQDIgE2AgggA0EIaiIEEMABIAUgACAGQQBIGyAEQQRyIAIQkgIhACADIAE2AgggBBCLASADQSBqJAAgAAtlAQN/IwBBIGsiAyQAIAAoAgAhBCAALAALIQUgAyABNgIYIANB6KMDNgIIIANBCGoiARCJAiAEIAAgBUEASBsgAUEEciACQQJyEJICIQAgA0HoowM2AgggARDBASADQSBqJAAgAAvoFgIFfwF8IwBB4ABrIgckAAJAAkACQAJAAkACQAJAAkACQCABDgoAAQIDBAUICAYHCAsgACgCACEIIAAsAAshCSAHQSBqIAIQgwMhASAHQcCnAzYCCCAHIAM2AhACfwJAIAMoAgBBAkYNACAHIAMQrwE6AAwgAygCAEECRg0AIAdBCGpBBHIMAQtBAAshAiAJQQBIIQMgB0HApwM2AlAgByAENgJYAn8CQCAEKAIAQQJGDQAgByAEEK8BOgBUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDIAdBADYCRCAHQgA3AjwgB0GIogM2AjggByAFNgJIQQAhACAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0EAIAEoAgAiAyABKAIEIANrIAIgBCAAIAYQdiEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQggMMBwsgACgCACEIIAAsAAshCSAHQSBqIAIQgQMhASAHQfynAzYCCCAHIAM2AhACfwJAIAMoAgBBAkYNACAHIAMQrgE6AAwgAygCAEECRg0AIAdBCGpBBHIMAQtBAAshAiAJQQBIIQMgB0H8pwM2AlAgByAENgJYAn8CQCAEKAIAQQJGDQAgByAEEK4BOgBUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDQQAhACAHQQA2AkQgB0IANwI8IAdBiKIDNgI4IAcgBTYCSCAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0EBIAEoAgAiAyABKAIEIANrIAIgBCAAIAYQdiEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQgAMMBgsgACgCACEIIAAsAAshCSAHQSBqIAIQ/wIhASAHQeCoAzYCCCAHIAM2AhACfwJAIAMoAgBBAkYNACAHIAMQrQE7AQwgAygCAEECRg0AIAdBCGpBBHIMAQtBAAshAiAJQQBIIQMgB0HgqAM2AlAgByAENgJYAn8CQCAEKAIAQQJGDQAgByAEEK0BOwFUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDQQAhACAHQQA2AkQgB0IANwI8IAdBiKIDNgI4IAcgBTYCSCAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0ECIAEoAgAiAyABKAIEIANrQQF1IAIgBCAAIAYQdiEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQ/gIMBQsgACgCACEIIAAsAAshCSAHQSBqIAIQ/QIhASAHQcSpAzYCCCAHIAM2AhACfwJAIAMoAgBBAkYNACAHIAMQrAE7AQwgAygCAEECRg0AIAdBCGpBBHIMAQtBAAshAiAJQQBIIQMgB0HEqQM2AlAgByAENgJYAn8CQCAEKAIAQQJGDQAgByAEEKwBOwFUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDQQAhACAHQQA2AkQgB0IANwI8IAdBiKIDNgI4IAcgBTYCSCAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0EDIAEoAgAiAyABKAIEIANrQQF1IAIgBCAAIAYQdiEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQ/AIMBAsgACgCACEIIAAsAAshCSAHQSBqIAIQ+wIhASAHQaiqAzYCCCAHIAM2AhACfwJAIAMoAgAiAkECRg0AIAJBxLgEIAdBOGoQByEMIAcoAjgQBiAHAn8gDJlEAAAAAAAA4EFjBEAgDKoMAQtBgICAgHgLNgIMIAMoAgBBAkYNACAHQQhqQQRyDAELQQALIQIgCUEASCEDIAdBqKoDNgJQIAcgBDYCWAJ/AkAgBCgCACIJQQJGDQAgCUHEuAQgB0E4ahAHIQwgBygCOBAGIAcCfyAMmUQAAAAAAADgQWMEQCAMqgwBC0GAgICAeAs2AlQgBCgCAEECRg0AIAdB0ABqQQRyDAELQQALIQQgCCAAIAMbIQNBACEAIAdBADYCRCAHQgA3AjwgB0GIogM2AjggByAFNgJIIAUoAgBBAkcEQCAHQThqIgAQMSAHKAI8IABBBHIgBywAR0EASBtBACAHKAJIKAIAQQJHGyEACyAHQfCgAzYCOCADQQQgASgCACIDIAEoAgQgA2tBAnUgAiAEIAAgBhB2IQggB0GIogM2AjggBywAR0EASARAIAcoAjwQKwsgARD6AgwDCyAAKAIAIQggACwACyEJIAdBIGogAhD5AiEBIAdBjKsDNgIIIAcgAzYCEAJ/AkAgAygCACICQQJGDQAgAkHQuAQgB0E4ahAHIQwgBygCOBAGIAcCfyAMRAAAAAAAAPBBYyAMRAAAAAAAAAAAZnEEQCAMqwwBC0EACzYCDCADKAIAQQJGDQAgB0EIakEEcgwBC0EACyECIAlBAEghAyAHQYyrAzYCUCAHIAQ2AlgCfwJAIAQoAgAiCUECRg0AIAlB0LgEIAdBOGoQByEMIAcoAjgQBiAHAn8gDEQAAAAAAADwQWMgDEQAAAAAAAAAAGZxBEAgDKsMAQtBAAs2AlQgBCgCAEECRg0AIAdB0ABqQQRyDAELQQALIQQgCCAAIAMbIQNBACEAIAdBADYCRCAHQgA3AjwgB0GIogM2AjggByAFNgJIIAUoAgBBAkcEQCAHQThqIgAQMSAHKAI8IABBBHIgBywAR0EASBtBACAHKAJIKAIAQQJHGyEACyAHQfCgAzYCOCADQQUgASgCACIDIAEoAgQgA2tBAnUgAiAEIAAgBhB2IQggB0GIogM2AjggBywAR0EASARAIAcoAjwQKwsgARD4AgwCCyAAKAIAIQggACwACyEJIAdBIGogAhD3AiEBIAdB8KsDNgIIIAcgAzYCEAJ/AkAgAygCAEECRg0AIAcgAxAwOAIMIAMoAgBBAkYNACAHQQhqQQRyDAELQQALIQIgCUEASCEDIAdB8KsDNgJQIAcgBDYCWAJ/AkAgBCgCAEECRg0AIAcgBBAwOAJUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDQQAhACAHQQA2AkQgB0IANwI8IAdBiKIDNgI4IAcgBTYCSCAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0EIIAEoAgAiAyABKAIEIANrQQJ1IAIgBCAAIAYQdiEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQ9gIMAQsgACgCACEIIAAsAAshCSAHQdAAaiACEPUCIQEgB0E4aiADEL8BIgIoAhAoAgAhAyAHQSBqIAQQvwEiCigCECgCACELQQAhBCAHQQA2AhQgB0IANwIMIAdBiKIDNgIIIAcgBTYCGCAFKAIAQQJHBEAgB0EIaiIEEDEgBygCDCAEQQRyIAcsABdBAEgbQQAgBygCGCgCAEECRxshBAsgB0HwoAM2AgggCCAAIAlBAEgbQQkgASgCACIAIAEoAgQgAGtBA3UgAkEIakEAIANBAkcbIApBCGpBACALQQJHGyAEIAYQdiEIIAdBiKIDNgIIIAcsABdBAEgEQCAHKAIMECsLIAEQ9AILIAdB4ABqJAAgCAunAgEDfyMAQTBrIgYkACAAKAIAIQcgACwACyEIIAYgATYCKCAGQfCvAzYCGCAGQRhqEIUGQQAhASAGQQA2AgwgBkIANwIEIAZBiKIDNgIAIAYgBDYCECAEKAIAQQJHBEAgBhAxIAYoAgQgBkEEciAGLAAPQQBIG0EAIAYoAhAoAgBBAkcbIQELIAZB8KADNgIAIwBBEGsiBCQAIAQgAzkDACAEIAI5AwggByAAIAhBAEgbQQkgBkEgaiAEQQhqQQAgAkQAAAAAAAAAAGQbIARBACADRAAAAAAAAAAAZBsgASAFQYCACHIQ0gIhACAEQRBqJAAgBkGIogM2AgAgBiwAD0EASARAIAYoAgQQKwsgBkHwrwM2AhggBkEYahDzAiAGQTBqJAAgAAtlAQJ/IwBBIGsiByQAIAdBEGoiCCABEDMgByAFNgIAIAcgAjYCCCAIIAdBCGogAyAEIAcgBiAAEUwAIQAgBygCABAAIAcoAggQACAHLAAbQQBIBEAgBygCEBArCyAHQSBqJAAgAAttAQN/IwBBIGsiAyQAIAAoAgAhBCAALAALIQUgAyABNgIcIANBqKYDNgIIIANBCGoiARCEAyAEIAAgBUEASBtBBCABQQRyQQRBAEEAQfroACACEHYhACADQaimAzYCCCABEIUCIANBIGokACAAC20BA38jAEEgayIDJAAgACgCACEEIAAsAAshBSADIAE2AhggA0HwpQM2AgggA0EIaiIBEIUDIAQgACAFQQBIG0EEIAFBBHJBA0EAQQBB+ugAIAIQdiEAIANB8KUDNgIIIAEQhgIgA0EgaiQAIAALaAEDfyMAQRBrIgMkACAAKAIAIQQgACwACyEFIAMgATYCDCADQbilAzYCACADEIYDIAQgACAFQQBIG0EEIANBBHJBAkEAQQBB+ugAIAIQdiEAIANBuKUDNgIAIAMQhwIgA0EQaiQAIAALpQEBA38jAEEQayIFJAAgACgCACEGIAAsAAshByAFIAE2AgggBUGcoAM2AgAgBRCVASMAQRBrIgEkACABIAM2AgggASACNgIMIAYgACAHQQBIG0EEIAVBBHIgAUEMakEAIAJBAEobIAFBCGpBACADQQBKG0HW8gBB+ugAIARBAnEbIAQQ0gIhACABQRBqJAAgBUGcoAM2AgAgBRCDASAFQRBqJAAgAAtVAQJ/IwBBIGsiBiQAIAZBEGoiByABEDMgBiACNgIIIAcgBkEIaiADIAQgBSAAEQ0AIQAgBigCCBAAIAYsABtBAEgEQCAGKAIQECsLIAZBIGokACAAC+cBAQN/IwBBMGsiBCQAIAAoAgAhBSAALAALIQYgBCABNgIsIARBoKQDNgIYIARBGGoQwAFBACEBIARBADYCDCAEQgA3AgQgBEGIogM2AgAgBCACNgIQIAIoAgBBAkcEQCAEEDEgBCgCBCAEQQRyIAQsAA9BAEgbQQAgBCgCECgCAEECRxshAQsgBEHwoAM2AgAgBSAAIAZBAEgbQQggBEEYakEEckEEQQBBACABIAMQdiEAIARBiKIDNgIAIAQsAA9BAEgEQCAEKAIEECsLIARBoKQDNgIYIARBGGoQiwEgBEEwaiQAIAAL5wEBA38jAEEwayIEJAAgACgCACEFIAAsAAshBiAEIAE2AiggBEHoowM2AhggBEEYahCJAkEAIQEgBEEANgIMIARCADcCBCAEQYiiAzYCACAEIAI2AhAgAigCAEECRwRAIAQQMSAEKAIEIARBBHIgBCwAD0EASBtBACAEKAIQKAIAQQJHGyEBCyAEQfCgAzYCACAFIAAgBkEASBtBCCAEQRhqQQRyQQNBAEEAIAEgAxB2IQAgBEGIogM2AgAgBCwAD0EASARAIAQoAgQQKwsgBEHoowM2AhggBEEYahDBASAEQTBqJAAgAAvsAQEDfyMAQTBrIgQkACAAKAIAIQUgACwACyEGIAQgATYCLCAEQbCjAzYCICAEQSBqEIcDQQAhASAEQQA2AhQgBEIANwIMIARBiKIDNgIIIAQgAjYCGCACKAIAQQJHBEAgBEEIaiIBEDEgBCgCDCABQQRyIAQsABdBAEgbQQAgBCgCGCgCAEECRxshAQsgBEHwoAM2AgggBSAAIAZBAEgbQQggBEEgakEEckECQQBBACABIAMQdiEAIARBiKIDNgIIIAQsABdBAEgEQCAEKAIMECsLIARBsKMDNgIgIARBIGoQigIgBEEwaiQAIAALtgICA38CfSMAQTBrIgYkACAAKAIAIQcgACwACyEIIAYgATYCKCAGQfiiAzYCICAGQSBqEH0gAhAwIQkgAxAwIQpBACEBIAZBADYCFCAGQgA3AgwgBkGIogM2AgggBiAENgIYIAQoAgBBAkcEQCAGQQhqIgEQMSAGKAIMIAFBBHIgBiwAF0EASBtBACAGKAIYKAIAQQJHGyEBCyAGQfCgAzYCCCMAQRBrIgIkACACIAo4AgggAiAJOAIMIAcgACAIQQBIG0EIIAZBIGpBBHIgAkEMakEAIAlDAAAAAF4bIAJBCGpBACAKQwAAAABeGyABIAVBgIAIchDSAiEAIAJBEGokACAGQYiiAzYCCCAGLAAXQQBIBEAgBigCDBArCyAGQfiiAzYCICAGQSBqEGggBkEwaiQAIAALvQIBAn8jAEEgayIGJAAgBkEANgIMIAYgAiAGQQxqELIBIAZBEGoiByAGEF8gBigCABAAIAcgAxDlAwJ/IAUoAgAiCEECRwRAQdzrBSgCACEHIAgQBSAHKAJ4EAAgByAFKAIANgJ4IAAoAgAgACAALAALQQBIGyABKAIAIAEgASwAC0EASBsgBigCECAGQRBqIAYsABtBAEgbIAMgBEHoBhDHBAwBCyAAKAIAIAAgACwAC0EASBsgASgCACABIAEsAAtBAEgbIAYoAhAgBkEQaiAGLAAbQQBIGyADIARBABDHBAshASAGIAYoAhAgBkEQaiAGLAAbQQBIGxBXIQAgBkEANgIMIAIgBkEMaiAAEPQDIAAsAAtBAEgEQCAAKAIAECsLIAYsABtBAEgEQCAGKAIQECsLIAZBIGokACABC5gBAQJ/IwBBQGoiCCQAIAhBMGoiCSABEDMgCEEgaiIBIAIQMyAIIAY2AhAgCCADNgIYIAggBzYCCCAJIAEgCEEYaiAEIAUgCEEQaiAIQQhqIAARCgAhACAIKAIIEAAgCCgCEBAAIAgoAhgQACAILAArQQBIBEAgCCgCIBArCyAILAA7QQBIBEAgCCgCMBArCyAIQUBrJAAgAAvXAgEDfyMAQSBrIgYkACAGQQA2AgwgBiABIAZBDGoQsgEgBkEQaiIHIAYQXyAGKAIAEAAgByACEOUDAn8gBSgCACIIQQJHBEBB3OsFKAIAIQcgCBAFIAcoAnwQACAHIAUoAgA2AnwgACgCACEFIAAsAAshByAGKAIQIQggBiwAGyEJIAZCADcDACAFIAAgB0EASBsgCCAGQRBqIAlBAEgbIAIgAyAGEC0gBEHnBhCbAwwBCyAAKAIAIQUgACwACyEHIAYoAhAhCCAGLAAbIQkgBkIANwMAIAUgACAHQQBIGyAIIAZBEGogCUEASBsgAiADIAYQLSAEQQAQmwMLIQIgBiAGKAIQIAZBEGogBiwAG0EASBsQVyEAIAZBADYCDCABIAZBDGogABD0AyAALAALQQBIBEAgACgCABArCyAGLAAbQQBIBEAgBigCEBArCyAGQSBqJAAgAguJAQECfyMAQTBrIggkACAIQSBqIgkgARAzIAggBDYCECAIIAI2AhggCCAGNgIIIAggBzYCACAJIAhBGGogAyAIQRBqIAUgCEEIaiAIIAARCgAhACAIKAIAEAAgCCgCCBAAIAgoAhAQACAIKAIYEAAgCCwAK0EASARAIAgoAiAQKwsgCEEwaiQAIAALnQIBAn8jAEEgayIFJAAgBUEANgIMIAUgASAFQQxqELIBIAVBEGoiBiAFEF8gBSgCABAAIAYgAhDlAwJ/IAQoAgAiB0ECRwRAQdzrBSgCACEGIAcQBSAGKAJ4EAAgBiAEKAIANgJ4IAAoAgAgACAALAALQQBIGyAFKAIQIAVBEGogBSwAG0EASBsgAiADQeYGEMgEDAELIAAoAgAgACAALAALQQBIGyAFKAIQIAVBEGogBSwAG0EASBsgAiADQQAQyAQLIQIgBSAFKAIQIAVBEGogBSwAG0EASBsQVyEAIAVBADYCDCABIAVBDGogABD0AyAALAALQQBIBEAgACgCABArCyAFLAAbQQBIBEAgBSgCEBArCyAFQSBqJAAgAgt5AQJ/IwBBMGsiByQAIAdBIGoiCCABEDMgByAFNgIQIAcgAjYCGCAHIAY2AgggCCAHQRhqIAMgBCAHQRBqIAdBCGogABELACEAIAcoAggQACAHKAIQEAAgBygCGBAAIAcsACtBAEgEQCAHKAIgECsLIAdBMGokACAAC6wXAgZ/AXwjAEHgAGsiCCQAAkACQAJAAkACQAJAAkACQAJAIAIOCgABAgMEBQgIBgcICyAAKAIAIQIgACwACyEJIAhCADcDWCABIAhB2ABqEC0hASAIQRhqIAMQgwMiAygCACEKIAhBwKcDNgIAIAggBDYCCAJ/AkAgBCgCAEECRg0AIAggBBCvAToABCAEKAIAQQJGDQAgCEEEcgwBC0EACyEEIAlBAEghCSAIQcCnAzYCSCAIIAU2AlACfwJAIAUoAgBBAkYNACAIIAUQrwE6AEwgBSgCAEECRg0AIAhByABqQQRyDAELQQALIQUgAiAAIAkbIQIgCEEANgI8IAhCADcCNCAIQYiiAzYCMCAIIAY2AkBBACEAIAYoAgBBAkcEQCAIQTBqIgAQMSAIKAI0IABBBHIgCCwAP0EASBtBACAIKAJAKAIAQQJHGyEACyAIQfCgAzYCMCACIAFBACAKIAQgBSAAIAcQmQEhCSAIQYiiAzYCMCAILAA/QQBIBEAgCCgCNBArCyADEIIDDAcLIAAoAgAhAiAALAALIQkgCEIANwNYIAEgCEHYAGoQLSEBIAhBGGogAxCBAyIDKAIAIQogCEH8pwM2AgAgCCAENgIIAn8CQCAEKAIAQQJGDQAgCCAEEK4BOgAEIAQoAgBBAkYNACAIQQRyDAELQQALIQQgCUEASCEJIAhB/KcDNgJIIAggBTYCUAJ/AkAgBSgCAEECRg0AIAggBRCuAToATCAFKAIAQQJGDQAgCEHIAGpBBHIMAQtBAAshBSACIAAgCRshAkEAIQAgCEEANgI8IAhCADcCNCAIQYiiAzYCMCAIIAY2AkAgBigCAEECRwRAIAhBMGoiABAxIAgoAjQgAEEEciAILAA/QQBIG0EAIAgoAkAoAgBBAkcbIQALIAhB8KADNgIwIAIgAUEBIAogBCAFIAAgBxCZASEJIAhBiKIDNgIwIAgsAD9BAEgEQCAIKAI0ECsLIAMQgAMMBgsgACgCACECIAAsAAshCSAIQgA3A1ggASAIQdgAahAtIQEgCEEYaiADEP8CIgMoAgAhCiAIQeCoAzYCACAIIAQ2AggCfwJAIAQoAgBBAkYNACAIIAQQrQE7AQQgBCgCAEECRg0AIAhBBHIMAQtBAAshBCAJQQBIIQkgCEHgqAM2AkggCCAFNgJQAn8CQCAFKAIAQQJGDQAgCCAFEK0BOwFMIAUoAgBBAkYNACAIQcgAakEEcgwBC0EACyEFIAIgACAJGyECQQAhACAIQQA2AjwgCEIANwI0IAhBiKIDNgIwIAggBjYCQCAGKAIAQQJHBEAgCEEwaiIAEDEgCCgCNCAAQQRyIAgsAD9BAEgbQQAgCCgCQCgCAEECRxshAAsgCEHwoAM2AjAgAiABQQIgCiAEIAUgACAHEJkBIQkgCEGIogM2AjAgCCwAP0EASARAIAgoAjQQKwsgAxD+AgwFCyAAKAIAIQIgACwACyEJIAhCADcDWCABIAhB2ABqEC0hASAIQRhqIAMQ/QIiAygCACEKIAhBxKkDNgIAIAggBDYCCAJ/AkAgBCgCAEECRg0AIAggBBCsATsBBCAEKAIAQQJGDQAgCEEEcgwBC0EACyEEIAlBAEghCSAIQcSpAzYCSCAIIAU2AlACfwJAIAUoAgBBAkYNACAIIAUQrAE7AUwgBSgCAEECRg0AIAhByABqQQRyDAELQQALIQUgAiAAIAkbIQJBACEAIAhBADYCPCAIQgA3AjQgCEGIogM2AjAgCCAGNgJAIAYoAgBBAkcEQCAIQTBqIgAQMSAIKAI0IABBBHIgCCwAP0EASBtBACAIKAJAKAIAQQJHGyEACyAIQfCgAzYCMCACIAFBAyAKIAQgBSAAIAcQmQEhCSAIQYiiAzYCMCAILAA/QQBIBEAgCCgCNBArCyADEPwCDAQLIAAoAgAhAiAALAALIQkgCEIANwNYIAEgCEHYAGoQLSEBIAhBGGogAxD7AiIDKAIAIQogCEGoqgM2AgAgCCAENgIIAn8CQCAEKAIAIgtBAkYNACALQcS4BCAIQTBqEAchDiAIKAIwEAYgCAJ/IA6ZRAAAAAAAAOBBYwRAIA6qDAELQYCAgIB4CzYCBCAEKAIAQQJGDQAgCEEEcgwBC0EACyEEIAlBAEghCSAIQaiqAzYCSCAIIAU2AlACfwJAIAUoAgAiC0ECRg0AIAtBxLgEIAhBMGoQByEOIAgoAjAQBiAIAn8gDplEAAAAAAAA4EFjBEAgDqoMAQtBgICAgHgLNgJMIAUoAgBBAkYNACAIQcgAakEEcgwBC0EACyEFIAIgACAJGyECQQAhACAIQQA2AjwgCEIANwI0IAhBiKIDNgIwIAggBjYCQCAGKAIAQQJHBEAgCEEwaiIAEDEgCCgCNCAAQQRyIAgsAD9BAEgbQQAgCCgCQCgCAEECRxshAAsgCEHwoAM2AjAgAiABQQQgCiAEIAUgACAHEJkBIQkgCEGIogM2AjAgCCwAP0EASARAIAgoAjQQKwsgAxD6AgwDCyAAKAIAIQIgACwACyEJIAhCADcDWCABIAhB2ABqEC0hASAIQRhqIAMQ+QIiAygCACEKIAhBjKsDNgIAIAggBDYCCAJ/AkAgBCgCACILQQJGDQAgC0HQuAQgCEEwahAHIQ4gCCgCMBAGIAgCfyAORAAAAAAAAPBBYyAORAAAAAAAAAAAZnEEQCAOqwwBC0EACzYCBCAEKAIAQQJGDQAgCEEEcgwBC0EACyEEIAlBAEghCSAIQYyrAzYCSCAIIAU2AlACfwJAIAUoAgAiC0ECRg0AIAtB0LgEIAhBMGoQByEOIAgoAjAQBiAIAn8gDkQAAAAAAADwQWMgDkQAAAAAAAAAAGZxBEAgDqsMAQtBAAs2AkwgBSgCAEECRg0AIAhByABqQQRyDAELQQALIQUgAiAAIAkbIQJBACEAIAhBADYCPCAIQgA3AjQgCEGIogM2AjAgCCAGNgJAIAYoAgBBAkcEQCAIQTBqIgAQMSAIKAI0IABBBHIgCCwAP0EASBtBACAIKAJAKAIAQQJHGyEACyAIQfCgAzYCMCACIAFBBSAKIAQgBSAAIAcQmQEhCSAIQYiiAzYCMCAILAA/QQBIBEAgCCgCNBArCyADEPgCDAILIAAoAgAhAiAALAALIQkgCEIANwNYIAEgCEHYAGoQLSEBIAhBGGogAxD3AiIDKAIAIQogCEHwqwM2AgAgCCAENgIIAn8CQCAEKAIAQQJGDQAgCCAEEDA4AgQgBCgCAEECRg0AIAhBBHIMAQtBAAshBCAJQQBIIQkgCEHwqwM2AkggCCAFNgJQAn8CQCAFKAIAQQJGDQAgCCAFEDA4AkwgBSgCAEECRg0AIAhByABqQQRyDAELQQALIQUgAiAAIAkbIQJBACEAIAhBADYCPCAIQgA3AjQgCEGIogM2AjAgCCAGNgJAIAYoAgBBAkcEQCAIQTBqIgAQMSAIKAI0IABBBHIgCCwAP0EASBtBACAIKAJAKAIAQQJHGyEACyAIQfCgAzYCMCACIAFBCCAKIAQgBSAAIAcQmQEhCSAIQYiiAzYCMCAILAA/QQBIBEAgCCgCNBArCyADEPYCDAELIAAoAgAhAiAALAALIQkgCEIANwNYIAEgCEHYAGoQLSEBIAhByABqIAMQ9QIiAygCACEKIAhBMGogBBC/ASIEKAIQKAIAIQsgCEEYaiAFEL8BIgwoAhAoAgAhDUEAIQUgCEEANgIMIAhCADcCBCAIQYiiAzYCACAIIAY2AhAgBigCAEECRwRAIAgQMSAIKAIEIAhBBHIgCCwAD0EASBtBACAIKAIQKAIAQQJHGyEFCyAIQfCgAzYCACACIAAgCUEASBsgAUEJIAogBEEIakEAIAtBAkcbIAxBCGpBACANQQJHGyAFIAcQmQEhCSAIQYiiAzYCACAILAAPQQBIBEAgCCgCBBArCyADEPQCCyAIQeAAaiQAIAkLnwEBAn8jAEFAaiIJJAAgCUEwaiIKIAEQMyAJIAQ2AiAgCSACNgIoIAkgBTYCGCAJIAY2AhAgCSAHNgIIIAogCUEoaiADIAlBIGogCUEYaiAJQRBqIAlBCGogCCAAEQ8AIQAgCSgCCBAAIAkoAhAQACAJKAIYEAAgCSgCIBAAIAkoAigQACAJLAA7QQBIBEAgCSgCMBArCyAJQUBrJAAgAAueAgEEfyMAQTBrIgckACAAKAIAIQggACwACyEJIAdCADcDKCABIAdBKGoQLSEKIAcgAjYCICAHQZygAzYCGCAHQRhqEJUBQQAhASAHQQA2AgwgB0IANwIEIAdBiKIDNgIAIAcgBTYCECAFKAIAQQJHBEAgBxAxIAcoAgQgB0EEciAHLAAPQQBIG0EAIAcoAhAoAgBBAkcbIQELIAdB8KADNgIAIwBBEGsiAiQAIAIgBDYCCCACIAM2AgwgCCAAIAlBAEgbIApBBCAHQRhqQQRyIAJBDGogAkEIaiABIAYQmQEhACACQRBqJAAgB0GIogM2AgAgBywAD0EASARAIAcoAgQQKwsgB0GcoAM2AhggB0EYahCDASAHQTBqJAAgAAuqAgIEfwJ9IwBBMGsiByQAIAAoAgAhCCAALAALIQkgB0IANwMoIAEgB0EoahAtIQogByACNgIgIAdB+KIDNgIYIAdBGGoQfSADEDAhCyAEEDAhDEEAIQEgB0EANgIMIAdCADcCBCAHQYiiAzYCACAHIAU2AhAgBSgCAEECRwRAIAcQMSAHKAIEIAdBBHIgBywAD0EASBtBACAHKAIQKAIAQQJHGyEBCyAHQfCgAzYCACMAQRBrIgIkACACIAw4AgggAiALOAIMIAggACAJQQBIGyAKQQggB0EYakEEciACQQxqIAJBCGogASAGEJkBIQAgAkEQaiQAIAdBiKIDNgIAIAcsAA9BAEgEQCAHKAIEECsLIAdB+KIDNgIYIAdBGGoQaCAHQTBqJAAgAAvoFgIFfwF8IwBB4ABrIgckAAJAAkACQAJAAkACQAJAAkACQCABDgoAAQIDBAUICAYHCAsgACgCACEIIAAsAAshCSAHQSBqIAIQgwMhASAHQcCnAzYCCCAHIAM2AhACfwJAIAMoAgBBAkYNACAHIAMQrwE6AAwgAygCAEECRg0AIAdBCGpBBHIMAQtBAAshAiAJQQBIIQMgB0HApwM2AlAgByAENgJYAn8CQCAEKAIAQQJGDQAgByAEEK8BOgBUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDIAdBADYCRCAHQgA3AjwgB0GIogM2AjggByAFNgJIQQAhACAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0EAIAEoAgAiAyABKAIEIANrIAIgBCAAIAYQdyEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQggMMBwsgACgCACEIIAAsAAshCSAHQSBqIAIQgQMhASAHQfynAzYCCCAHIAM2AhACfwJAIAMoAgBBAkYNACAHIAMQrgE6AAwgAygCAEECRg0AIAdBCGpBBHIMAQtBAAshAiAJQQBIIQMgB0H8pwM2AlAgByAENgJYAn8CQCAEKAIAQQJGDQAgByAEEK4BOgBUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDQQAhACAHQQA2AkQgB0IANwI8IAdBiKIDNgI4IAcgBTYCSCAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0EBIAEoAgAiAyABKAIEIANrIAIgBCAAIAYQdyEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQgAMMBgsgACgCACEIIAAsAAshCSAHQSBqIAIQ/wIhASAHQeCoAzYCCCAHIAM2AhACfwJAIAMoAgBBAkYNACAHIAMQrQE7AQwgAygCAEECRg0AIAdBCGpBBHIMAQtBAAshAiAJQQBIIQMgB0HgqAM2AlAgByAENgJYAn8CQCAEKAIAQQJGDQAgByAEEK0BOwFUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDQQAhACAHQQA2AkQgB0IANwI8IAdBiKIDNgI4IAcgBTYCSCAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0ECIAEoAgAiAyABKAIEIANrQQF1IAIgBCAAIAYQdyEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQ/gIMBQsgACgCACEIIAAsAAshCSAHQSBqIAIQ/QIhASAHQcSpAzYCCCAHIAM2AhACfwJAIAMoAgBBAkYNACAHIAMQrAE7AQwgAygCAEECRg0AIAdBCGpBBHIMAQtBAAshAiAJQQBIIQMgB0HEqQM2AlAgByAENgJYAn8CQCAEKAIAQQJGDQAgByAEEKwBOwFUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDQQAhACAHQQA2AkQgB0IANwI8IAdBiKIDNgI4IAcgBTYCSCAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0EDIAEoAgAiAyABKAIEIANrQQF1IAIgBCAAIAYQdyEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQ/AIMBAsgACgCACEIIAAsAAshCSAHQSBqIAIQ+wIhASAHQaiqAzYCCCAHIAM2AhACfwJAIAMoAgAiAkECRg0AIAJBxLgEIAdBOGoQByEMIAcoAjgQBiAHAn8gDJlEAAAAAAAA4EFjBEAgDKoMAQtBgICAgHgLNgIMIAMoAgBBAkYNACAHQQhqQQRyDAELQQALIQIgCUEASCEDIAdBqKoDNgJQIAcgBDYCWAJ/AkAgBCgCACIJQQJGDQAgCUHEuAQgB0E4ahAHIQwgBygCOBAGIAcCfyAMmUQAAAAAAADgQWMEQCAMqgwBC0GAgICAeAs2AlQgBCgCAEECRg0AIAdB0ABqQQRyDAELQQALIQQgCCAAIAMbIQNBACEAIAdBADYCRCAHQgA3AjwgB0GIogM2AjggByAFNgJIIAUoAgBBAkcEQCAHQThqIgAQMSAHKAI8IABBBHIgBywAR0EASBtBACAHKAJIKAIAQQJHGyEACyAHQfCgAzYCOCADQQQgASgCACIDIAEoAgQgA2tBAnUgAiAEIAAgBhB3IQggB0GIogM2AjggBywAR0EASARAIAcoAjwQKwsgARD6AgwDCyAAKAIAIQggACwACyEJIAdBIGogAhD5AiEBIAdBjKsDNgIIIAcgAzYCEAJ/AkAgAygCACICQQJGDQAgAkHQuAQgB0E4ahAHIQwgBygCOBAGIAcCfyAMRAAAAAAAAPBBYyAMRAAAAAAAAAAAZnEEQCAMqwwBC0EACzYCDCADKAIAQQJGDQAgB0EIakEEcgwBC0EACyECIAlBAEghAyAHQYyrAzYCUCAHIAQ2AlgCfwJAIAQoAgAiCUECRg0AIAlB0LgEIAdBOGoQByEMIAcoAjgQBiAHAn8gDEQAAAAAAADwQWMgDEQAAAAAAAAAAGZxBEAgDKsMAQtBAAs2AlQgBCgCAEECRg0AIAdB0ABqQQRyDAELQQALIQQgCCAAIAMbIQNBACEAIAdBADYCRCAHQgA3AjwgB0GIogM2AjggByAFNgJIIAUoAgBBAkcEQCAHQThqIgAQMSAHKAI8IABBBHIgBywAR0EASBtBACAHKAJIKAIAQQJHGyEACyAHQfCgAzYCOCADQQUgASgCACIDIAEoAgQgA2tBAnUgAiAEIAAgBhB3IQggB0GIogM2AjggBywAR0EASARAIAcoAjwQKwsgARD4AgwCCyAAKAIAIQggACwACyEJIAdBIGogAhD3AiEBIAdB8KsDNgIIIAcgAzYCEAJ/AkAgAygCAEECRg0AIAcgAxAwOAIMIAMoAgBBAkYNACAHQQhqQQRyDAELQQALIQIgCUEASCEDIAdB8KsDNgJQIAcgBDYCWAJ/AkAgBCgCAEECRg0AIAcgBBAwOAJUIAQoAgBBAkYNACAHQdAAakEEcgwBC0EACyEEIAggACADGyEDQQAhACAHQQA2AkQgB0IANwI8IAdBiKIDNgI4IAcgBTYCSCAFKAIAQQJHBEAgB0E4aiIAEDEgBygCPCAAQQRyIAcsAEdBAEgbQQAgBygCSCgCAEECRxshAAsgB0HwoAM2AjggA0EIIAEoAgAiAyABKAIEIANrQQJ1IAIgBCAAIAYQdyEIIAdBiKIDNgI4IAcsAEdBAEgEQCAHKAI8ECsLIAEQ9gIMAQsgACgCACEIIAAsAAshCSAHQdAAaiACEPUCIQEgB0E4aiADEL8BIgIoAhAoAgAhAyAHQSBqIAQQvwEiCigCECgCACELQQAhBCAHQQA2AhQgB0IANwIMIAdBiKIDNgIIIAcgBTYCGCAFKAIAQQJHBEAgB0EIaiIEEDEgBygCDCAEQQRyIAcsABdBAEgbQQAgBygCGCgCAEECRxshBAsgB0HwoAM2AgggCCAAIAlBAEgbQQkgASgCACIAIAEoAgQgAGtBA3UgAkEIakEAIANBAkcbIApBCGpBACALQQJHGyAEIAYQdyEIIAdBiKIDNgIIIAcsABdBAEgEQCAHKAIMECsLIAEQ9AILIAdB4ABqJAAgCAuJAQECfyMAQTBrIggkACAIQSBqIgkgARAzIAggBDYCECAIIAM2AhggCCAFNgIIIAggBjYCACAJIAIgCEEYaiAIQRBqIAhBCGogCCAHIAARCgAhACAIKAIAEAAgCCgCCBAAIAgoAhAQACAIKAIYEAAgCCwAK0EASARAIAgoAiAQKwsgCEEwaiQAIAALiwIBA38jAEEwayIGJAAgACgCACEHIAAsAAshCCAGIAE2AiwgBkGopgM2AhggBkEYahCEA0EAIQEgBkEANgIMIAZCADcCBCAGQYiiAzYCACAGIAQ2AhAgBCgCAEECRwRAIAYQMSAGKAIEIAZBBHIgBiwAD0EASBtBACAGKAIQKAIAQQJHGyEBCyAGQfCgAzYCACMAQRBrIgQkACAEIAM2AgggBCACNgIMIAcgACAIQQBIG0EEIAZBGGpBBHJBBCAEQQxqIARBCGogASAFEHchACAEQRBqJAAgBkGIogM2AgAgBiwAD0EASARAIAYoAgQQKwsgBkGopgM2AhggBkEYahCFAiAGQTBqJAAgAAuLAgEDfyMAQTBrIgYkACAAKAIAIQcgACwACyEIIAYgATYCKCAGQfClAzYCGCAGQRhqEIUDQQAhASAGQQA2AgwgBkIANwIEIAZBiKIDNgIAIAYgBDYCECAEKAIAQQJHBEAgBhAxIAYoAgQgBkEEciAGLAAPQQBIG0EAIAYoAhAoAgBBAkcbIQELIAZB8KADNgIAIwBBEGsiBCQAIAQgAzYCCCAEIAI2AgwgByAAIAhBAEgbQQQgBkEYakEEckEDIARBDGogBEEIaiABIAUQdyEAIARBEGokACAGQYiiAzYCACAGLAAPQQBIBEAgBigCBBArCyAGQfClAzYCGCAGQRhqEIYCIAZBMGokACAAC5ACAQN/IwBBMGsiBiQAIAAoAgAhByAALAALIQggBiABNgIsIAZBuKUDNgIgIAZBIGoQhgNBACEBIAZBADYCFCAGQgA3AgwgBkGIogM2AgggBiAENgIYIAQoAgBBAkcEQCAGQQhqIgEQMSAGKAIMIAFBBHIgBiwAF0EASBtBACAGKAIYKAIAQQJHGyEBCyAGQfCgAzYCCCMAQRBrIgQkACAEIAM2AgggBCACNgIMIAcgACAIQQBIG0EEIAZBIGpBBHJBAiAEQQxqIARBCGogASAFEHchACAEQRBqJAAgBkGIogM2AgggBiwAF0EASARAIAYoAgwQKwsgBkG4pQM2AiAgBkEgahCHAiAGQTBqJAAgAAvpAQEDfyMAQTBrIgYkACAAKAIAIQcgACwACyEIIAYgATYCKCAGQZygAzYCICAGQSBqEJUBQQAhASAGQQA2AhQgBkIANwIMIAZBiKIDNgIIIAYgBDYCGCAEKAIAQQJHBEAgBkEIaiIBEDEgBigCDCABQQRyIAYsABdBAEgbQQAgBigCGCgCAEECRxshAQsgBkHwoAM2AgggByAAIAhBAEgbIAZBIGpBBHIgAiADIAEgBRDOBCEAIAZBiKIDNgIIIAYsABdBAEgEQCAGKAIMECsLIAZBnKADNgIgIAZBIGoQgwEgBkEwaiQAIAALZQECfyMAQSBrIgckACAHQRBqIgggARAzIAcgBTYCACAHIAI2AgggCCAHQQhqIAMgBCAHIAYgABELACEAIAcoAgAQACAHKAIIEAAgBywAG0EASARAIAcoAhAQKwsgB0EgaiQAIAAL0wICA38CfSMAQTBrIgYkACAAKAIAIQcgACwACyEIIAYgATYCKCAGQfiiAzYCICAGQSBqEH0gAhAwIQkgAxAwIQpBACEBIAZBADYCFCAGQgA3AgwgBkGIogM2AgggBiAENgIYIAQoAgBBAkcEQCAGQQhqIgEQMSAGKAIMIAFBBHIgBiwAF0EASBtBACAGKAIYKAIAQQJHGyEBCyAGQfCgAzYCCCMAQRBrIgIkACACIAZBIGpBBHIiAyoCAEMAALRDlEPbD8lAlTgCBCACIAk4AgwgAiAKOAIIIAcgACAIQQBIG0EIIAJBBGogAkEMaiACQQhqIAFB9skAIAEbIAUQ1AIhACADIAIqAgRD2w/JQJRDAAC0Q5U4AgAgAkEQaiQAIAZBiKIDNgIIIAYsABdBAEgEQCAGKAIMECsLIAZB+KIDNgIgIAZBIGoQaCAGQTBqJAAgAAsLh7AE1gEAQYAIC4GYAUtleSAweCUwOFggVmFsdWUgeyBpOiAlZCB9ACAuLi4gfQAgfAB7AHoAU3BlY3NEaXJ0eQBCdWZEaXJ0eQBpbmZpbml0eQBTYXZlIHRvIG1lbW9yeQBTYXZlSW5pU2V0dGluZ3NUb01lbW9yeQBMb2FkSW5pU2V0dGluZ3NGcm9tTWVtb3J5AENvcHkARHVtbXkAUmFzdGVyaXplck11bHRpcGx5AENvbmZpZ1dpbmRvd3NNb3ZlRnJvbVRpdGxlQmFyT25seQBFdmVudEtleQBLZXlSZXBlYXREZWxheQBobXR4AFByaW1WdHgAUHJpbVdyaXRlVnR4AFByb2dneUNsZWFuLnR0ZiwgJWRweABNZXNoOiBFbGVtQ291bnQ6ICVkLCBWdHhPZmZzZXQ6ICslZCwgSWR4T2Zmc2V0OiArJWQsIEFyZWE6IH4lMC5mIHB4AENoZWNrYm94AEJlZ2luTGlzdEJveABFbmRMaXN0Qm94AFBhdGhGaWxsQ29udmV4ACMjaGV4AEdldEtleUluZGV4AFRhYmxlR2V0Um93SW5kZXgAVGFibGVTZXRDb2x1bW5JbmRleABUYWJsZUdldENvbHVtbkluZGV4AEFudGlBbGlhc2VkTGluZXNVc2VUZXgASGV4AFByaW1Xcml0ZUlkeAAjI21heABHZXRDbGlwUmVjdE1heABHZXRJdGVtUmVjdE1heABHZXRXaW5kb3dDb250ZW50UmVnaW9uTWF4AEdldENvbnRlbnRSZWdpb25NYXgAIyNQb3B1cF8lMDh4AC0rICAgMFgweAAtMFgrMFggMFgtMHgrMHggMHgAQmVnaW5Qb3B1cENvbnRleHRXaW5kb3cAU2hvd0Fib3V0V2luZG93AFJvb3RXaW5kb3cAUGFyZW50V2luZG93AFNob3dNZXRyaWNzV2luZG93AFNob3dEZW1vV2luZG93ACBJc1BsYXRmb3JtV2luZG93AFNob3dTdGFja1Rvb2xXaW5kb3cAIENoaWxkV2luZG93AFslMDRkXSBXaW5kb3cAQm9yZGVyU2hhZG93AFRhYmxlTmV4dFJvdwBUYWJsZUhlYWRlcnNSb3cAIyNwcmV2aWV3ACMjaHN2AE5hdgAjI3YAIyNDb250ZXh0TWVudQBCZWdpbk1lbnUARW5kTWVudQAgQ2hpbGRNZW51ACVsbHUAJXUAaW1ndWlfbG9nLnR4dAB3aW5kb3dfY29udGV4dAB2b2lkX2NvbnRleHQARGVzdHJveUNvbnRleHQAU2V0Q3VycmVudENvbnRleHQAR2V0Q3VycmVudENvbnRleHQAV3JhcEltR3VpQ29udGV4dABDcmVhdGVDb250ZXh0AENvbmZpZ0RyYWdDbGlja1RvSW5wdXRUZXh0AEJ1bGxldFRleHQATGFiZWxUZXh0AExvZ1RleHQAU2V0Q2xpcGJvYXJkVGV4dABHZXRDbGlwYm9hcmRUZXh0ACMjVGV4dAB3dABXYW50VGV4dElucHV0AERlYnVnQ2hlY2tWZXJzaW9uQW5kRGF0YUxheW91dABrZWVwY29zdABhdXRvIGVtYmluZF9pbml0X0ltR3VpKCk6Oihhbm9ueW1vdXMgY2xhc3MpOjpvcGVyYXRvcigpKGVtc2NyaXB0ZW46OnZhbCkgY29uc3QAYXV0byBlbWJpbmRfaW5pdF9JbUZvbnRDb25maWcoKTo6KGFub255bW91cyBjbGFzcyk6Om9wZXJhdG9yKCkoSW1Gb250Q29uZmlnICYsIGVtc2NyaXB0ZW46OnZhbCkgY29uc3QAYXV0byBlbWJpbmRfaW5pdF9JbUd1aSgpOjooYW5vbnltb3VzIGNsYXNzKTo6b3BlcmF0b3IoKSgpIGNvbnN0AGF1dG8gZW1iaW5kX2luaXRfSW1Gb250Q29uZmlnKCk6Oihhbm9ueW1vdXMgY2xhc3MpOjpvcGVyYXRvcigpKGNvbnN0IEltRm9udENvbmZpZyAmKSBjb25zdABHZXRXaW5kb3dEcmF3TGlzdABJbURyYXdMaXN0AEdldEJhY2tncm91bmREcmF3TGlzdABHZXRGb3JlZ3JvdW5kRHJhd0xpc3QAIyMjTmF2V2luZG93aW5nTGlzdABNb3VzZURvdWJsZUNsaWNrTWF4RGlzdABQYXRoQXJjVG9GYXN0AEdldE1haW5WaWV3cG9ydABJbUd1aVZpZXdwb3J0AHVuc2lnbmVkIHNob3J0AERpc3BsYXlTdGFydABTZWxlY3Rpb25TdGFydABHZXRLZXlQcmVzc2VkQW1vdW50AFRvdGFsVnR4Q291bnQAVG90YWxJZHhDb3VudABfQ2FsY0NpcmNsZUF1dG9TZWdtZW50Q291bnQAQ21kTGlzdHNDb3VudABHZXRDb2x1bW5zQ291bnQASXRlbXNDb3VudABTcGVjc0NvdW50AFRhYmxlR2V0Q29sdW1uQ291bnQARWxlbUNvdW50AEdldEZyYW1lQ291bnQAR2V0TW91c2VDbGlja2VkQ291bnQAQ29uZmlnRGF0YUNvdW50AERzdEZvbnQAR2V0Rm9udABQb3BGb250AEltRm9udABQdXNoRm9udABDb2RlcG9pbnQASW5wdXRUZXh0V2l0aEhpbnQAdW5zaWduZWQgaW50AENvbnRlbnQAIyNjdXJyZW50AENoYW5uZWxzU2V0Q3VycmVudABVbmluZGVudABJbmRlbnQARGVzY2VudABBc2NlbnQASW5wdXRJbnQAVlNsaWRlckludABEcmFnSW50AFJlc3VsdABBZGRGb250RGVmYXVsdABHZXRHbHlwaFJhbmdlc0RlZmF1bHQARGVidWcjI0RlZmF1bHQASXNCdWlsdABLZXlBbHQAVGFibGVSb3dCZ0FsdABDaGFubmVsc1NwbGl0AElzSXRlbURlYWN0aXZhdGVkQWZ0ZXJFZGl0AEZpeGVkRml0AE5hdkhpZ2hsaWdodABOYXZXaW5kb3dpbmdIaWdobGlnaHQAaGVpZ2h0AFdlaWdodABUZXhIZWlnaHQAR2V0V2luZG93SGVpZ2h0AEl0ZW1zSGVpZ2h0AEdldFRleHRMaW5lSGVpZ2h0AEdldEZyYW1lSGVpZ2h0AFN0eWxlQ29sb3JzTGlnaHQAVGFibGVCb3JkZXJMaWdodABLZXlTaGlmdABWdHhPZmZzZXQASWR4T2Zmc2V0AEltRHJhd1ZlcnRQb3NPZmZzZXQAU2V0Q29sdW1uT2Zmc2V0AEdldENvbHVtbk9mZnNldABJbURyYXdWZXJ0Q29sT2Zmc2V0AEdseXBoT2Zmc2V0AGJ5dGVPZmZzZXQASW1EcmF3VmVydFVWT2Zmc2V0AEJ1bGxldABCZWdpbkRyYWdEcm9wVGFyZ2V0AEVuZERyYWdEcm9wVGFyZ2V0AFNldABDb2x1bW5zUmVjdABPdXRlclJlY3QASW5uZXJSZWN0AEhvc3RDbGlwUmVjdABDb2x1bW5zQ2xpcFJlY3QASW5uZXJDbGlwUmVjdABQb3BDbGlwUmVjdABQdXNoQ2xpcFJlY3QAQmFja2dyb3VuZENsaXBSZWN0AENvbnRlbnRSZWdpb25SZWN0AFByaW1SZWN0AENvbHVtbnNXb3JrUmVjdABQYXRoUmVjdABJc01vdXNlSG92ZXJpbmdSZWN0AEFkZFJlY3QAZmxvYXQASW5wdXRGbG9hdABWU2xpZGVyRmxvYXQARHJhZ0Zsb2F0AFBvcEJ1dHRvblJlcGVhdABQdXNoQnV0dG9uUmVwZWF0AHVpbnQ2NF90AFNldHRpbmdzV2luZG93cwBNZXRyaWNzUmVuZGVyV2luZG93cwBNZXRyaWNzQWN0aXZlV2luZG93cwBDaGlsZFdpbmRvd3MAU2V0TmV4dFdpbmRvd0ZvY3VzAFNldFdpbmRvd0ZvY3VzAFNldEl0ZW1EZWZhdWx0Rm9jdXMAU2V0V2luZG93TmFtZUZvY3VzAFBvcEFsbG93S2V5Ym9hcmRGb2N1cwBQdXNoQWxsb3dLZXlib2FyZEZvY3VzAE5vTmF2SW5wdXRzAF9zZXRBdF9OYXZJbnB1dHMAX2dldEF0X05hdklucHV0cwBOb01vdXNlSW5wdXRzAEl0ZXJhdGVEcmF3TGlzdHMAVmlld3BvcnRzAENsZWFyRm9udHMASXRlcmF0ZUZvbnRzAFNldE5leHRXaW5kb3dTaXplQ29uc3RyYWludHMAU2NhbGVDbGlwUmVjdHMAX3NldEF0X0NvbG9ycwBfZ2V0QXRfQ29sb3JzAENvbmZpZ01hY09TWEJlaGF2aW9ycwBDbGVhcklucHV0Q2hhcmFjdGVycwBTZXR0aW5nc0hhbmRsZXJzAERlSW5kZXhBbGxCdWZmZXJzAEluc2VydENoYXJzAERlbGV0ZUNoYXJzAFRhYkJhcnMAUG9wdXBzAERpc3BsYXlQb3MAU2V0TmV4dFdpbmRvd1BvcwBTZXRXaW5kb3dQb3MAR2V0V2luZG93UG9zAEdldEN1cnNvclN0YXJ0UG9zAFNldEN1cnNvclBvcwBHZXRDdXJzb3JQb3MAUG9wVGV4dFdyYXBQb3MAUHVzaFRleHRXcmFwUG9zAFNldEN1cnNvclNjcmVlblBvcwBHZXRDdXJzb3JTY3JlZW5Qb3MAV29ya1BvcwBXYW50U2V0TW91c2VQb3MAR2V0TW91c2VQb3MAU2V0V2luZG93TmFtZVBvcwBfZ2V0QXRfTW91c2VDbGlja2VkUG9zAExvZ0J1dHRvbnMAU2V0Q29sb3JFZGl0T3B0aW9ucwBTZXRBbGxvY2F0b3JGdW5jdGlvbnMAJWQgdmlzaWJsZSB3aW5kb3dzLCAlZCBhY3RpdmUgYWxsb2NhdGlvbnMATWV0cmljc0FjdGl2ZUFsbG9jYXRpb25zAGNvbHVtbnMAQ29sdW1ucwBUb29scwBwaXhlbHMAU2l6ZVBpeGVscwBFcXVhbHMAdXNtYmxrcwBmc21ibGtzAGhibGtzAHVvcmRibGtzAGZvcmRibGtzAEl0ZXJhdGVHbHlwaHMAQ2xlYXIgc2V0dGluZ3MAV2FudFNhdmVJbmlTZXR0aW5ncwBDaGVja2JveEZsYWdzAEZvbnRCdWlsZGVyRmxhZ3MAVGFibGVHZXRDb2x1bW5GbGFncwBDb25maWdGbGFncwBCYWNrZW5kRmxhZ3MAU2NhbGVBbGxTaXplcwBTZXR0aW5ncyBwYWNrZWQgZGF0YTogV2luZG93czogJWQgYnl0ZXMAU2V0dGluZ3MgcGFja2VkIGRhdGE6IFRhYmxlczogJWQgYnl0ZXMAU2V0dGluZ3MgdW5wYWNrZWQgZGF0YSAoLmluaSk6ICVkIGJ5dGVzACVzOiAlZCBlbnRyaWVzLCAlZCBieXRlcwBQbG90TGluZXMAQW50aUFsaWFzZWRMaW5lcwBTaG93IHdpbmRvd3MgcmVjdGFuZ2xlcwBTaG93IHRhYmxlcyByZWN0YW5nbGVzAFNldHRpbmdzVGFibGVzAEdseXBoUmFuZ2VzAENvbmZpZ1dpbmRvd3NSZXNpemVGcm9tRWRnZXMATWV0cmljc1JlbmRlclZlcnRpY2VzAE1ldHJpY3NSZW5kZXJJbmRpY2VzAERlcwAlczogJyVzJyAlZCB2dHgsICVkIGluZGljZXMsICVkIGNtZHMASXRlcmF0ZURyYXdDbWRzAFRhYmxlR2V0U29ydFNwZWNzAEltR3VpVGFibGVTb3J0U3BlY3MASW1HdWlUYWJsZVNvcnRDb2x1bW5TcGVjcwBGb250RGF0YU93bmVkQnlBdGxhcwBJbUZvbnRBdGxhcwAlKnMlLipzAEZsYWdzOiAweCUwNFggPSVzJXMlcwBTY3JvbGw6ICglLjJmLyUuMmYsJS4yZi8lLjJmKSBTY3JvbGxiYXI6JXMlcwBQb3B1cElEOiAlMDh4LCBXaW5kb3c6ICclcyclcyVzAENvbHVtbnNHaXZlbldpZHRoOiAlLjFmLCBDb2x1bW5zQXV0b0ZpdFdpZHRoOiAlLjFmLCBJbm5lcldpZHRoOiAlLjFmJXMAJXMgMHglMDhYICglZCB0YWJzKSVzAFRhYmxlIDB4JTA4WCAoJWQgY29sdW1ucywgaW4gJyVzJyklcwAlcyAnJXMnJXMARGVhciBJbUd1aSAlcwAoJTYuMWYsJTYuMWYpICglNi4xZiwlNi4xZikgU2l6ZSAoJTYuMWYsJTYuMWYpIENvbCAlZCAlcwBOYXZMYXllcnNBY3RpdmVNYXNrOiAlWCwgTmF2TGFzdENoaWxkTmF2V2luZG93OiAlcwAlJXM6ICVzAE5hdklucHV0U291cmNlOiAlcwBBY3RpdmVJZDogMHglMDhYLzB4JTA4WCAoJS4yZiBzZWMpLCBBbGxvd092ZXJsYXA6ICVkLCBTb3VyY2U6ICVzACglNi4xZiwlNi4xZikgKCU2LjFmLCU2LjFmKSBTaXplICglNi4xZiwlNi4xZikgJXMAIElzUGxhdGZvcm1Nb25pdG9yAFNob3dTdHlsZUVkaXRvcgB2ZWN0b3IAU2hvd0ZvbnRTZWxlY3RvcgBTaG93U3R5bGVTZWxlY3RvcgBTZXBhcmF0b3IATW91c2VEcmF3Q3Vyc29yAFNldE1vdXNlQ3Vyc29yAEdldE1vdXNlQ3Vyc29yAENpcmNsZVRlc3NlbGxhdGlvbk1heEVycm9yAEFkZFJlY3RGaWxsZWRNdWx0aUNvbG9yAFRhYmxlU2V0QmdDb2xvcgBQb3BTdHlsZUNvbG9yAFB1c2hTdHlsZUNvbG9yAEFkZElucHV0Q2hhcmFjdGVyAEtleVN1cGVyAEltR3VpTGlzdENsaXBwZXIAQ29uZmlnTWVtb3J5Q29tcGFjdFRpbWVyACMjcHJldmlld2luZ19waWNrZXIAIyNwaWNrZXIARGVhciBJbUd1aSBNZXRyaWNzL0RlYnVnZ2VyAGJ1ZmZlcgBWdHhCdWZmZXIASWR4QnVmZmVyAEJvcmRlcgBCeSBkaXNwbGF5IG9yZGVyAFJlc2V0IG9yZGVyAFNob3cgd2luZG93cyBiZWdpbiBvcmRlcgBTb3J0T3JkZXIAUmVuZGVyAFRhYmxlSGVhZGVyAG51bWJlcgBJbnB1dFNjYWxhcgBWU2xpZGVyU2NhbGFyAERyYWdTY2FsYXIAdW5zaWduZWQgY2hhcgBEb3RDaGFyAEV2ZW50Q2hhcgBFbGxpcHNpc0NoYXIAUmVuZGVyQ2hhcgBGYWxsYmFja0NoYXIAUGF0aENsZWFyACMjbWVudWJhcgBQb3BTdHlsZVZhcgBQdXNoU3R5bGVWYXIAQmVnaW5NZW51QmFyAEJlZ2luTWFpbk1lbnVCYXIARW5kTWFpbk1lbnVCYXIAIyNNYWluTWVudUJhcgBFbmRNZW51QmFyAFByb2dyZXNzQmFyAEJlZ2luVGFiQmFyAEVuZFRhYkJhcgBBbHBoYSBCYXIAbWF4cABHZXRNb3VzZVBvc09uT3BlbmluZ0N1cnJlbnRQb3B1cABDbG9zZUN1cnJlbnRQb3B1cAAjI0NvbWJvUG9wdXAAQmVnaW5Qb3B1cABPcGVuUG9wdXAARW5kUG9wdXAAQmVnaW5Hcm91cABFbmRHcm91cAAgT3duZWRCeUFwcABDYXB0dXJlTW91c2VGcm9tQXBwAENhcHR1cmVLZXlib2FyZEZyb21BcHAAU3RyZXRjaFByb3AAVHJlZVBvcABTZXRUb29sdGlwAEJlZ2luVG9vbHRpcABFbmRUb29sdGlwAFJlc2l6ZUdyaXAAU3RlcABjbWFwAFNldEl0ZW1BbGxvd092ZXJsYXAAX3NldEF0X0tleU1hcABfZ2V0QXRfS2V5TWFwACh2b2lkKikweCVwAENhbGxiYWNrICVwLCB1c2VyX2RhdGEgJXAAbWFsbGluZm8AQmVnaW5Db21ibwBFbmRDb21ibwBQYXRoQmV6aWVyUXVhZHJhdGljQ3VydmVUbwBQYXRoQmV6aWVyQ3ViaWNDdXJ2ZVRvAFBhdGhMaW5lVG8AUGF0aEFyY1RvAEZvbnRObwBVbmtub3duAElzS2V5RG93bgBfc2V0QXRfS2V5c0Rvd24AX2dldEF0X0tleXNEb3duAElzQW55TW91c2VEb3duAElzTW91c2VEb3duAF9zZXRBdF9Nb3VzZURvd24AX2dldEF0X01vdXNlRG93bgAjU291cmNlRXh0ZXJuAGtlcm4AQXJyb3dCdXR0b24AIyNDb2xvckJ1dHRvbgBUYWJJdGVtQnV0dG9uAFNtYWxsQnV0dG9uAFRhYk1pbldpZHRoRm9yQ2xvc2VCdXR0b24ASW52aXNpYmxlQnV0dG9uAEltYWdlQnV0dG9uAEdldEdseXBoUmFuZ2VzQ2hpbmVzZVNpbXBsaWZpZWRDb21tb24Ac3RkOjpleGNlcHRpb24AV2luZG93TWVudUJ1dHRvblBvc2l0aW9uAENvbG9yQnV0dG9uUG9zaXRpb24AU29ydERpcmVjdGlvbgBIYXNTZWxlY3Rpb24AX2dldEF0X0tleXNEb3duRHVyYXRpb24AX2dldEF0X05hdklucHV0c0Rvd25EdXJhdGlvbgBfZ2V0QXRfTW91c2VEb3duRHVyYXRpb24AR2V0VmVyc2lvbgBBZGROZ29uAFRhYmxlTmV4dENvbHVtbgBUYWJsZVNldHVwQ29sdW1uACMjbWluAEJlZ2luAEdldENsaXBSZWN0TWluAEdldEl0ZW1SZWN0TWluAEdldFdpbmRvd0NvbnRlbnRSZWdpb25NaW4AQnV0dG9uVGV4dEFsaWduAFNlbGVjdGFibGVUZXh0QWxpZ24AV2luZG93VGl0bGVBbGlnbgBDb2x1bW5zQ29udGVudFVuZnJvemVuAENvbHVtbnNDb250ZW50RnJvemVuAElzUG9wdXBPcGVuAFNldE5leHRJdGVtT3BlbgBJc0l0ZW1Ub2dnbGVkT3BlbgBQdXNoQ2xpcFJlY3RGdWxsU2NyZWVuAEJ1ZlRleHRMZW4AbmFuAEdldEdseXBoUmFuZ2VzS29yZWFuAFNldENsaXBib2FyZFRleHRGbgBHZXRDbGlwYm9hcmRUZXh0Rm4AV2VpZ2h0PSVmJW4AT3JkZXI9JWQlbgBXaWR0aD0lZCVuAFZpc2libGU9JWQlbgBDb2x1bW4gJWQlbgBTb3J0PSVkJWMlbgBVc2VySUQ9MHglMDhYJW4AQmVnaW5Qb3B1cENvbnRleHRJdGVtAEJlZ2luVGFiSXRlbQBFbmRUYWJJdGVtAFBsb3RIaXN0b2dyYW0AS2V5Q3RybABTaG93IHN0YWNrIHRvb2wAYm9vbABEZWFyIEltR3VpIFN0YWNrIFRvb2wAQ3VydmVUZXNzZWxsYXRpb25Ub2wAR2V0R2x5cGhSYW5nZXNDaGluZXNlRnVsbABBbnRpQWxpYXNlZEZpbGwAU2l6ZSBhbGwgY29sdW1ucyB0byBkZWZhdWx0IyMjU2l6ZUFsbABTaXplIGFsbCBjb2x1bW5zIHRvIGZpdCMjI1NpemVBbGwAR2V0Q29udGVudFJlZ2lvbkF2YWlsAGJ5dGVzX3Blcl9waXhlbABHZXRGb250VGV4VXZXaGl0ZVBpeGVsAE1vdXNlV2hlZWwAZW1zY3JpcHRlbjo6dmFsACMjb3JpZ2luYWwAT3JpZ2luYWwAQ29udGVudElkZWFsAENvbHVtbnNDb250ZW50SGVhZGVyc0lkZWFsAEJlZ2luUG9wdXBNb2RhbABTYXZlIHRvIGRpc2sAQ2hlY2tNYXJrAFN0eWxlQ29sb3JzRGFyawBDb25maWdJbnB1dFRleHRDdXJzb3JCbGluawBPcGVuUG9wdXBPbkl0ZW1DbGljawBGaW5kR2x5cGhOb0ZhbGxiYWNrAEFkZENhbGxiYWNrAGltZ3VpLmluaQAjI0luaQBHZXRHbHlwaFJhbmdlc1RoYWkAUG9zPSVpLCVpAFNpemU9JWksJWkARGVmYXVsdCBEZXB0aABiYWRfYXJyYXlfbmV3X2xlbmd0aABieXRlTGVuZ3RoAHdpZHRoAFRleFdpZHRoAEdldFdpbmRvd1dpZHRoAFNldENvbHVtbldpZHRoAEdldENvbHVtbldpZHRoAFNldE5leHRJdGVtV2lkdGgAUG9wSXRlbVdpZHRoAFB1c2hJdGVtV2lkdGgAQ2FsY0l0ZW1XaWR0aABUZXhEZXNpcmVkV2lkdGgATG9nRmluaXNoAEltRm9udEdseXBoAEZhbGxiYWNrR2x5cGgARmluZEdseXBoAFRhYmxlQm9yZGVyU3Ryb25nAHVuc2lnbmVkIGxvbmcAc3RkOjp3c3RyaW5nAGJhc2ljX3N0cmluZwBzdGQ6OnN0cmluZwBzdGQ6OnUxNnN0cmluZwBzdGQ6OnUzMnN0cmluZwBTaG93IEltRHJhd0NtZCBib3VuZGluZyBib3hlcyB3aGVuIGhvdmVyaW5nAFNob3cgSW1EcmF3Q21kIG1lc2ggd2hlbiBob3ZlcmluZwBJc1dpbmRvd0FwcGVhcmluZwBGb250QWxsb3dVc2VyU2NhbGluZwBJc01vdXNlRHJhZ2dpbmcAV2luZG93Um91bmRpbmcAU2Nyb2xsYmFyUm91bmRpbmcAUG9wdXBSb3VuZGluZwBGcmFtZVJvdW5kaW5nAENoaWxkUm91bmRpbmcAR3JhYlJvdW5kaW5nAFRhYlJvdW5kaW5nAERpc3BsYXlXaW5kb3dQYWRkaW5nAENlbGxQYWRkaW5nAFRleEdseXBoUGFkZGluZwBBbGlnblRleHRUb0ZyYW1lUGFkZGluZwBUb3VjaEV4dHJhUGFkZGluZwBEaXNwbGF5U2FmZUFyZWFQYWRkaW5nAEluZGVudFNwYWNpbmcASXRlbUlubmVyU3BhY2luZwBDb2x1bW5zTWluU3BhY2luZwBJdGVtU3BhY2luZwBHZXRUcmVlTm9kZVRvTGFiZWxTcGFjaW5nAEdldFRleHRMaW5lSGVpZ2h0V2l0aFNwYWNpbmcAR2V0RnJhbWVIZWlnaHRXaXRoU3BhY2luZwBHbHlwaEV4dHJhU3BhY2luZwBJbUZvbnRDb25maWcAJS4wZiBkZWcARXZlbnRGbGFnAFdpbmRvd0JnAFRhYmxlUm93QmcAVGFibGVIZWFkZXJCZwBTY3JvbGxiYXJCZwBNZW51QmFyQmcAUG9wdXBCZwBNb2RhbFdpbmRvd0RpbUJnAE5hdldpbmRvd2luZ0RpbUJnAEZyYW1lQmcAVGl0bGVCZwBDaGlsZEJnAFRleHRTZWxlY3RlZEJnACVkOiAlOC40ZwolZDogJTguNGcAZ2x5ZgBCdWYAaW5mACVsZgAgV2VpZ2h0PSUuNGYAVjolMC4zZgBTOiUwLjNmAFI6JTAuM2YASDolMC4zZgBHOiUwLjNmAEI6JTAuM2YAQTolMC4zZgAlczogJS4zZgBIOiAlLjNmLCBTOiAlLjNmLCBWOiAlLjNmAEg6ICUuM2YsIFM6ICUuM2YsIFY6ICUuM2YsIEE6ICUuM2YAU2V0dGluZ3NEaXJ0eVRpbWVyICUuMmYAJTAyZCVjIFRhYiAweCUwOFggJyVzJyBPZmZzZXQ6ICUuMWYsIFdpZHRoOiAlLjFmLyUuMWYAQ2VsbFBhZGRpbmdYOiAlLjFmLCBDZWxsU3BhY2luZ1g6ICUuMWYvJS4xZiwgT3V0ZXJQYWRkaW5nWDogJS4xZgBNYWluIFBvczogKCUuMGYsJS4wZiksIFNpemU6ICglLjBmLCUuMGYpCldvcmtBcmVhIE9mZnNldCBMZWZ0OiAlLjBmIFRvcDogJS4wZiwgUmlnaHQ6ICUuMGYsIEJvdHRvbTogJS4wZgBSZWZTY2FsZT0lZgBBbHdheXNBdXRvUmVzaXplAERpc3BsYXlTaXplAEltRHJhd0lkeFNpemUAU2V0TmV4dFdpbmRvd1NpemUAU2V0V2luZG93U2l6ZQBHZXRXaW5kb3dTaXplAENhbGNUZXh0U2l6ZQBJbURyYXdWZXJ0U2l6ZQBHZXRGb250U2l6ZQBTZXROZXh0V2luZG93Q29udGVudFNpemUAQ3VycmVudFNpemUAR2V0SXRlbVJlY3RTaXplAFdpbmRvd0JvcmRlclNpemUAUG9wdXBCb3JkZXJTaXplAEZyYW1lQm9yZGVyU2l6ZQBDaGlsZEJvcmRlclNpemUAVGFiQm9yZGVyU2l6ZQBTY3JvbGxiYXJTaXplAFdpbmRvd01pblNpemUAR3JhYk1pblNpemUAV29ya1NpemUAQnVmU2l6ZQBTZXRXaW5kb3dOYW1lU2l6ZQBJbUd1aVN0eWxlU2l6ZQBEZXNpcmVkU2l6ZQBJbUd1aUlPU2l6ZQBJbVZlYzRTaXplAEltVmVjMlNpemUAVGFibGVTZXR1cFNjcm9sbEZyZWV6ZQBQcmltVW5yZXNlcnZlAFByaW1SZXNlcnZlAE5hdkFjdGl2ZQBTZXBhcmF0b3JBY3RpdmUASGVhZGVyQWN0aXZlAFJlc2l6ZUdyaXBBY3RpdmUAQnV0dG9uQWN0aXZlAElzQW55SXRlbUFjdGl2ZQBJc0l0ZW1BY3RpdmUARnJhbWVCZ0FjdGl2ZQBUaXRsZUJnQWN0aXZlAFRhYlVuZm9jdXNlZEFjdGl2ZQBTbGlkZXJHcmFiQWN0aXZlAFNjcm9sbGJhckdyYWJBY3RpdmUAVGFiQWN0aXZlAHRydWUAaHVlAEludGVybmFsIHN0YXRlAEZyYW1lcmF0ZQBQYXRoTGluZVRvTWVyZ2VEdXBsaWNhdGUAS2V5UmVwZWF0UmF0ZQBJbmlTYXZpbmdSYXRlAFdhbnRDYXB0dXJlTW91c2UAV2FudENhcHR1cmVNb3VzZVVubGVzc1BvcHVwQ2xvc2UAZmFsc2UAR2V0R2x5cGhSYW5nZXNKYXBhbmVzZQBHZXRHbHlwaFJhbmdlc1ZpZXRuYW1lc2UAU2V0S2V5Ym9hcmRGb2N1c0hlcmUAIyNzaG93X3dpbmRvd3NfcmVjdF90eXBlACMjc2hvd190YWJsZV9yZWN0c190eXBlAExvZ1NsaWRlckRlYWR6b25lAE5vbmUAQWRkUG9seWxpbmUASW5wdXRUZXh0TXVsdGlsaW5lAE5ld0xpbmUAU2FtZUxpbmUAQWRkTGluZQBTaXplIGNvbHVtbiB0byBmaXQjIyNTaXplT25lAEdldFRpbWUATW91c2VEb3VibGVDbGlja1RpbWUARGVsdGFUaW1lAE5ld0ZyYW1lAEVuZEZyYW1lAEJlZ2luQ2hpbGRGcmFtZQBFbmRDaGlsZEZyYW1lAEluaUZpbGVuYW1lAExvZ0ZpbGVuYW1lAFN0cmV0Y2hTYW1lAEZpeGVkU2FtZQBHZXRTdHlsZUNvbG9yTmFtZQBCYWNrZW5kUmVuZGVyZXJOYW1lAFRhYmxlR2V0Q29sdW1uTmFtZQBCYWNrZW5kUGxhdGZvcm1OYW1lAEdldERlYnVnTmFtZQBHZXRTdHlsZQBJbUd1aVN0eWxlAExvZ1RvRmlsZQBMb2cgVG8gRmlsZQBBZGRUcmlhbmdsZQBTbGlkZXJBbmdsZQBBZGRDaXJjbGUAZG91YmxlAElucHV0RG91YmxlAE5hdlZpc2libGUASXNJdGVtVmlzaWJsZQAjI3NlbGVjdGFibGUAIyN0YWJsZQBCdWlsZExvb2t1cFRhYmxlAEJlZ2luVGFibGUARW5kVGFibGUAVGV4VXZTY2FsZQBTZXRXaW5kb3dGb250U2NhbGUATW91c2VDdXJzb3JTY2FsZQBEaXNwbGF5RnJhbWVidWZmZXJTY2FsZQBGb250R2xvYmFsU2NhbGUAUGF0aFN0cm9rZQBDaGFubmVsc01lcmdlAFNldFN0YXRlU3RvcmFnZQBHZXRTdGF0ZVN0b3JhZ2UAI2ltYWdlAEFkZEltYWdlAE1lbUZyZWUATWVyZ2VNb2RlAFNob3dVc2VyR3VpZGUAQmVnaW5EcmFnRHJvcFNvdXJjZQBFbmREcmFnRHJvcFNvdXJjZQBHZXRDaGFyQWR2YW5jZQBNZXRyaWNzVG90YWxTdXJmYWNlAFdhbnRDYXB0dXJlS2V5Ym9hcmQATG9nVG9DbGlwYm9hcmQATG9nIFRvIENsaXBib2FyZAAjI0JhY2tncm91bmQAIyNGb3JlZ3JvdW5kAERpc3BsYXlFbmQAU2VsZWN0aW9uRW5kAEltRHJhd0NtZABBZGREcmF3Q21kAE1vdXNlRHJhZ1RocmVzaG9sZAAlbGxkAEJ1aWxkAEJlZ2luQ2hpbGQARW5kQ2hpbGQAdm9pZABCZWdpblBvcHVwQ29udGV4dFZvaWQASXNNb3VzZVBvc1ZhbGlkAGhibGtoZABUZXh0VW5mb3JtYXR0ZWQASXNJdGVtRWRpdGVkAElzSXRlbURlYWN0aXZhdGVkAElzSXRlbUFjdGl2YXRlZABUYWJVbmZvY3VzZWQASXNXaW5kb3dGb2N1c2VkAElzQW55SXRlbUZvY3VzZWQASXNJdGVtRm9jdXNlZABJc0tleVByZXNzZWQAU2V0TmV4dFdpbmRvd0NvbGxhcHNlZABTZXRXaW5kb3dDb2xsYXBzZWQASXNXaW5kb3dDb2xsYXBzZWQAVGl0bGVCZ0NvbGxhcHNlZABTZXRXaW5kb3dOYW1lQ29sbGFwc2VkAFNldFRhYkl0ZW1DbG9zZWQASXNLZXlSZWxlYXNlZABJc01vdXNlUmVsZWFzZWQAQ29sdW1uc0NvbnRlbnRIZWFkZXJzVXNlZABUZXh0Q29sb3JlZABJc1dpbmRvd0hvdmVyZWQAUGxvdExpbmVzSG92ZXJlZABTZXBhcmF0b3JIb3ZlcmVkAEhlYWRlckhvdmVyZWQAUmVzaXplR3JpcEhvdmVyZWQAQnV0dG9uSG92ZXJlZABJc0FueUl0ZW1Ib3ZlcmVkAElzSXRlbUhvdmVyZWQAUGxvdEhpc3RvZ3JhbUhvdmVyZWQARnJhbWVCZ0hvdmVyZWQAU2Nyb2xsYmFyR3JhYkhvdmVyZWQAVGFiSG92ZXJlZABPdXRlclJlY3RDbGlwcGVkAFRleHRXcmFwcGVkAEFkZENvbnZleFBvbHlGaWxsZWQAQWRkUmVjdEZpbGxlZABBZGROZ29uRmlsbGVkAEFkZFRyaWFuZ2xlRmlsbGVkAEFkZENpcmNsZUZpbGxlZABBZGRRdWFkRmlsbGVkAFRleHREaXNhYmxlZABCZWdpbkRpc2FibGVkAEVuZERpc2FibGVkAFRhYmxlU2V0Q29sdW1uRW5hYmxlZABMb2NrZWQASXNJdGVtQ2xpY2tlZABJc01vdXNlQ2xpY2tlZABJc01vdXNlRG91YmxlQ2xpY2tlZABTZWVkAEFkZEltYWdlUm91bmRlZABJc0xvYWRlZABBZGRJbWFnZVF1YWQAQWRkUXVhZABHYW1lcGFkAEFjY2VwdERyYWdEcm9wUGF5bG9hZABTZXREcmFnRHJvcFBheWxvYWQAR2V0RHJhZ0Ryb3BQYXlsb2FkAGhlYWQAVGV4dHVyZUlkAFY6JTNkAFM6JTNkAFI6JTNkAEg6JTNkAEc6JTNkAEI6JTNkAEE6JTNkACMjTWVudV8lMDJkACMjVG9vbHRpcF8lMDJkACMjQ29tYm9fJTAyZABDb2x1bW4gJS0yZAAgT3JkZXI9JWQAIFdpZHRoPSVkACBWaXNpYmxlPSVkADB4JTA4WCAiJXMiIFBvcyAoJWQsJWQpIFNpemUgKCVkLCVkKSBDb2xsYXBzZWQ9JWQAMHglMDhYLCVkAFZpZXdwb3J0ICMlZABBY3RpdmU6ICVkLyVkLCBXcml0ZUFjY2Vzc2VkOiAlZCwgQmVnaW5PcmRlcldpdGhpbkNvbnRleHQ6ICVkAEFwcGVhcmluZzogJWQsIEhpZGRlbjogJWQgKENhblNraXAgJWQgQ2Fubm90ICVkKSwgU2tpcEl0ZW1zOiAlZAAlczogJWQATmF2SWQ6IDB4JTA4WCwgTmF2TGF5ZXI6ICVkAE5hdkRpc2FibGVIaWdobGlnaHQ6ICVkLCBOYXZEaXNhYmxlTW91c2VIb3ZlcjogJWQASG92ZXJlZENvbHVtbkJvZHk6ICVkLCBIb3ZlcmVkQ29sdW1uQm9yZGVyOiAlZABIb3ZlcmVkSWQ6IDB4JTA4WCAoJS4yZiBzZWMpLCBBbGxvd092ZXJsYXA6ICVkAFJlc2l6ZWRDb2x1bW46ICVkLCBSZW9yZGVyQ29sdW1uOiAlZCwgSGVsZEhlYWRlckNvbHVtbjogJWQATmF2QWN0aXZlOiAlZCwgTmF2VmlzaWJsZTogJWQAQXNjAHN0ZDo6YmFkX2FsbG9jAE1lbUFsbG9jAEFkZEJlemllclF1YWRyYXRpYwBTdHlsZUNvbG9yc0NsYXNzaWMAR2V0R2x5cGhSYW5nZXNDeXJpbGxpYwBBZGRCZXppZXJDdWJpYwBHZXRTcGVjACBTb3J0PSVkJWMAcmIAIyNyZ2IAU2xpZGVyR3JhYgBTY3JvbGxiYXJHcmFiAFRhYgByd2EAUmVzZXRNb3VzZURyYWdEZWx0YQBHZXRNb3VzZURyYWdEZWx0YQBNb3VzZURlbHRhAENsZWFyVGV4RGF0YQBHZXREcmF3RGF0YQBJbURyYXdEYXRhAENsZWFyT3V0cHV0RGF0YQBDbGVhcklucHV0RGF0YQBGb250RGF0YQBCYWNrZW5kUmVuZGVyZXJVc2VyRGF0YQBCYWNrZW5kUGxhdGZvcm1Vc2VyRGF0YQBCYWNrZW5kTGFuZ3VhZ2VVc2VyRGF0YQBDbGlwYm9hcmRVc2VyRGF0YQBJbUd1aUlucHV0VGV4dENhbGxiYWNrRGF0YQBJbUd1aVNpemVDYWxsYmFja0RhdGEAU2V0dGluZ3NJbmlEYXRhAEl0ZXJhdGVDb25maWdEYXRhAEdldERyYXdMaXN0U2hhcmVkRGF0YQBhcmVuYQBhbHBoYQBTZXROZXh0V2luZG93QmdBbHBoYQBEaXNhYmxlZEFscGhhAGhoZWEAbG9jYQBbfl0AW3hdACIlcyIgW3dpbmRvd10AMHglMDhYIFtvdmVycmlkZV0AWyBdAFsAIyNaAEdldFNjcm9sbE1heFkAU3RhcnRQb3NZAFNldEN1cnNvclBvc1kAR2V0Q3Vyc29yUG9zWQBTZXRTY3JvbGxGcm9tUG9zWQBTZXRTY3JvbGxZAEdldFNjcm9sbFkAU2V0U2Nyb2xsSGVyZVkATG9nVG9UVFkATG9nIFRvIFRUWQAjU0NST0xMWQAjI1kAR2V0U2Nyb2xsTWF4WABTZXRDdXJzb3JQb3NYAEdldEN1cnNvclBvc1gAU2V0U2Nyb2xsRnJvbVBvc1gAU2V0U2Nyb2xsWABHZXRTY3JvbGxYAEFjdGl2ZUlkVXNpbmc6IFdoZWVsOiAlZCwgTmF2RGlyTWFzazogJVgsIE5hdklucHV0TWFzazogJVgsIEtleUlucHV0TWFzazogJWxsWABTZXRTY3JvbGxIZXJlWABHbHlwaE1heEFkdmFuY2VYAEdseXBoTWluQWR2YW5jZVgARmFsbGJhY2tBZHZhbmNlWAAjU0NST0xMWABDb2x1bW4gJWQgT3JkZXIgJWQgU29ydE9yZGVyICVkICVzIFZpcyAlZCAlcyAlNy4zZiBVc2VySUQgMHglMDhYAE5hdkZvY3VzU2NvcGVJZCA9IDB4JTA4WABTYXZlRmxhZ3M6IDB4JTA4WABIb3ZlcmVkSWQ6IDB4JTA4WABOYXZMYXN0SWRzWyVkXTogMHglMDhYAEhvdmVyZWRJZDogMHglMDhYLCBBY3RpdmVJZDogIDB4JTA4WAAlcy8lc18lMDhYACBVc2VySUQ9JTA4WAAlcy8lMDhYAE5hdkFjdGl2YXRlSWQvRG93bklkL1ByZXNzZWRJZC9JbnB1dElkOiAlMDhYLyUwOFgvJTA4WC8lMDhYAENvbHVtbnMgSWQ6IDB4JTA4WCwgQ291bnQ6ICVkLCBGbGFnczogMHglMDRYAE5hdkFjdGl2YXRlRmxhZ3M6ICUwNFgAIyUwMlglMDJYJTAyWCUwMlgAIyUwMlglMDJYJTAyWAAjI1gAIyNXAE92ZXJzYW1wbGVWAFByaW1SZWN0VVYAUHJpbVF1YWRVVgBDb2xvckNvbnZlcnRSR0J0b0hTVgBOQVYsRk9DVVMAR1BPUwBJVEVNUwBHZXRJTwBJbUd1aUlPAElNR1VJX1ZFUlNJT04ASU1HVUlfQ0hFQ0tWRVJTSU9OAE5BTgAlczogTlVMTABQaXhlbFNuYXBIAE92ZXJzYW1wbGVIAFdJTkRPV0lORwBDVVJSRU5UTFkgQVBQRU5ESU5HAEFkZEZvbnRGcm9tTWVtb3J5VFRGAElORgBfQ09MNEYAX0NPTDNGACNSRVNJWkUAI01PVkUAI0NPTExBUFNFACNDTE9TRQAjRk9DVVNTQ09QRQBWYWx1ZV9EAFRleElEAEdldElEAENvbHVtblVzZXJJRABQb3BJRABQdXNoSUQAUG9wVGV4dHVyZUlEAFB1c2hUZXh0dXJlSUQAMHhERERERERERABUcmVlTm9kZUV4X0MAVmFsdWVfQwBUcmVlTm9kZV9DAEdldENvbG9yVTMyX0MATGlzdEJveF9CAFRyZWVOb2RlRXhfQgBBZGRUZXh0X0IAQ29sbGFwc2luZ0hlYWRlcl9CAFJhZGlvQnV0dG9uX0IATWVudUl0ZW1fQgBUcmVlUHVzaF9CAFZhbHVlX0IASXNSZWN0VmlzaWJsZV9CAFNlbGVjdGFibGVfQgBUcmVlTm9kZV9CAEdldENvbG9yVTMyX0IAQ29sb3JDb252ZXJ0SFNWdG9SR0IAQ2FsY1dvcmRXcmFwUG9zaXRpb25BAENhbGNUZXh0U2l6ZUEATGlzdEJveF9BAFRyZWVOb2RlRXhfQQBBZGRUZXh0X0EAQ29sbGFwc2luZ0hlYWRlcl9BAFJhZGlvQnV0dG9uX0EATWVudUl0ZW1fQQBUcmVlUHVzaF9BAFZhbHVlX0EASXNSZWN0VmlzaWJsZV9BAFNlbGVjdGFibGVfQQBUcmVlTm9kZV9BAEdldENvbG9yVTMyX0EATi9BAD8/PwBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaG9ydD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgc2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgaW50PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxmbG9hdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDhfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDMyX3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDMyX3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGNoYXI+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIGNoYXI+AHN0ZDo6YmFzaWNfc3RyaW5nPHVuc2lnbmVkIGNoYXI+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHNpZ25lZCBjaGFyPgA8dW5rbm93bj4APFVua25vd24+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGxvbmc+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIGxvbmc+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGRvdWJsZT4APE5VTEw+ACMjPgAjIzwAVmVydDoAJyVzJzoAR2V0VGV4RGF0YUFzQWxwaGE4AFU4AFM4AEFkZElucHV0Q2hhcmFjdGVyc1VURjgAMS44NgBVMTYAUzE2ADAuLjI1NQBJbnB1dEludDQAU2xpZGVySW50NABEcmFnSW50NABDb2xvckVkaXQ0AElucHV0RmxvYXQ0AFNsaWRlckZsb2F0NABDb2xvckNvbnZlcnRVMzJUb0Zsb2F0NABEcmFnRmxvYXQ0AENvbG9yUGlja2VyNABHZXRTdHlsZUNvbG9yVmVjNABJbVZlYzQAVTY0AFM2NABJbnB1dEludDMAU2xpZGVySW50MwBEcmFnSW50MwBDb2xvckVkaXQzAElucHV0RmxvYXQzAFNsaWRlckZsb2F0MwBEcmFnRmxvYXQzAENvbG9yUGlja2VyMwBJbnB1dEludDIAU2xpZGVySW50MgBEcmFnSW50MgBJbnB1dEZsb2F0MgBTbGlkZXJGbG9hdDIARHJhZ0Zsb2F0MgBEcmFnSW50UmFuZ2UyAERyYWdGbG9hdFJhbmdlMgBJbVZlYzIAQ29sb3JDb252ZXJ0RmxvYXQ0VG9VMzIAUzMyAEdldFRleERhdGFBc1JHQkEzMgBZMQBYMQBWMQBVMQB2aWV3cG9ydDAAWTAAWDAAVjAAVTAATTowMDAATTowLjAwMAAwLjAwLi4xLjAwAEhvdmVyIGFuIGl0ZW0gd2l0aCB0aGUgbW91c2UgdG8gZGlzcGxheSBlbGVtZW50cyBvZiB0aGUgSUQgU3RhY2sgbGVhZGluZyB0byB0aGUgaXRlbSdzIGZpbmFsIElELgpFYWNoIGxldmVsIG9mIHRoZSBzdGFjayBjb3JyZXNwb25kIHRvIGEgUHVzaElEKCkgY2FsbC4KQWxsIGxldmVscyBvZiB0aGUgc3RhY2sgYXJlIGhhc2hlZCB0b2dldGhlciB0byBtYWtlIHRoZSBmaW5hbCBJRCBvZiBhIHdpZGdldCAoSUQgZGlzcGxheWVkIGF0IHRoZSBib3R0b20gbGV2ZWwgb2YgdGhlIHN0YWNrKS4KUmVhZCBGQVEgZW50cnkgYWJvdXQgdGhlIElEIHN0YWNrIGZvciBkZXRhaWxzLgBXaWxsIGNhbGwgdGhlIElNX0RFQlVHX0JSRUFLKCkgbWFjcm8gdG8gYnJlYWsgaW4gZGVidWdnZXIuCldhcm5pbmc6IElmIHlvdSBkb24ndCBoYXZlIGEgZGVidWdnZXIgYXR0YWNoZWQsIHRoaXMgd2lsbCBwcm9iYWJseSBjcmFzaC4AUHJlc3MgRVNDIHRvIGFib3J0IHBpY2tpbmcuAFlvdSBjYW4gYWxzbyBjYWxsIEltR3VpOjpTaG93U3RhY2tUb29sV2luZG93KCkgZnJvbSB5b3VyIGNvZGUuAE5vdGU6IHNvbWUgbWVtb3J5IGJ1ZmZlcnMgaGF2ZSBiZWVuIGNvbXBhY3RlZC9mcmVlZC4AQ29weSBhcy4uAENvbHVtbiAlZCBvcmRlciAlZCAnJXMnOiBvZmZzZXQgJSsuMmYgdG8gJSsuMmYlcwpFbmFibGVkOiAlZCwgVmlzaWJsZVgvWTogJWQvJWQsIFJlcXVlc3RPdXRwdXQ6ICVkLCBTa2lwSXRlbXM6ICVkLCBEcmF3Q2hhbm5lbHM6ICVkLCVkCldpZHRoR2l2ZW46ICUuMWYsIFJlcXVlc3QvQXV0bzogJS4xZi8lLjFmLCBTdHJldGNoV2VpZ2h0OiAlLjNmICgl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ABEAAQAIAAYACAAbAAQABgAJABQACwAbAAYARAACAAIAAQABAAEAAgABAAIAAgAHAAYACwADAAMAAQABAAMAAQACAAEAAQABAAEAAQADAAEAAQAIAAMABAABAAUABwACAAEABAAEAAgABAACAAEAAgABAAEABAAFAAYAAwAGAAIADAADAAEAAwAJAAIABAADAAQAAQAFAAMAAwABAAMABwABAAUAAQABAAEAAQACAAMABAAFAAIAAwACAAYAAQABAAIAAQAHAAEABwADAAQABQAPAAIAAgABAAUAAwAWABMAAgABAAEAAQABAAIABQABAAEAAQAGAAEAAQAMAAgAAgAJABIAFgAEAAEAAQAFAAEAEAABAAIABwAKAA8AAQABAAYAAgAEAAEAAgAEAAEABgABAAEAAwACAAQAAQAGAAQABQABAAIAAQABAAIAAQAKAAMAAQADAAIAAQAJAAMAAgAFAAcAAgATAAQAAwAGAAEAAQABAAEAAQAEAAMAAgABAAEAAQACAAUAAwABAAEAAQACAAIAAQABAAIAAQABAAIAAQADAAEAAQABAAMABwABAAQAAQABAAIAAQABAAIAAQACAAQABAADAAgAAQABAAEAAgABAAMABQABAAMAAQADAAQABgACAAIADgAEAAYABgALAAkAAQAPAAMAAQAcAAUAAgAFAAUAAwABAAMABAAFAAQABgAOAAMAAgADAAUAFQACAAcAFAAKAAEAAgATAAIABAAcABwAAgADAAIAAQAOAAQAAQAaABwAKgAMACgAAwA0AE8ABQAOABEAAwACAAIACwADAAQABgADAAEACAACABcABAAFAAgACgAEAAIABwADAAUAAQABAAYAAwABAAIAAgACAAUAHAABAAEABwAHABQABQADAB0AAwARABoAAQAIAAQAGwADAAYACwAXAAUAAwAEAAYADQAYABAABgAFAAoAGQAjAAcAAwACAAMAAwAOAAMABgACAAYAAQAEAAIAAwAIAAIAAQABAAMAAwADAAQAAQABAA0AAgACAAQABQACAAEADgAOAAEAAgACAAEABAAFAAIAAwABAA4AAwAMAAMAEQACABAABQABAAIAAQAIAAkAAwATAAQAAgACAAQAEQAZABUAFAAcAEsAAQAKAB0AZwAEAAEAAgABAAEABAACAAQAAQACAAMAGAACAAIAAgABAAEAAgABAAMACAABAAEAAQACAAEAAQADAAEAAQABAAYAAQAFAAMAAQABAAEAAwAEAAEAAQAFAAIAAQAFAAYADQAJABAAAQABAAEAAQADAAIAAwACAAQABQACAAUAAgACAAMABwANAAcAAgACAAEAAQABAAEAAgADAAMAAgABAAYABAAJAAIAAQAOAAIADgACAAEAEgADAAQADgAEAAsAKQAPABcADwAXALAAAQADAAQAAQABAAEAAQAFAAMAAQACAAMABwADAAEAAQACAAEAAgAEAAQABgACAAQAAQAJAAcAAQAKAAUACAAQAB0AAQABAAIAAgADAAEAAwAFAAIABAAFAAQAAQABAAIAAgADAAMABwABAAYACgABABEAAQAsAAQABgACAAEAAQAGAAUABAACAAoAAQAGAAkAAgAIAAEAGAABAAIADQAHAAgACAACAAEABAABAAMAAQADAAMABQACAAUACgAJAAQACQAMAAIAAQAGAAEACgABAAEABwAHAAQACgAIAAMAAQANAAQAAwABAAYAAQADAAUAAgABAAIAEQAQAAUAAgAQAAYAAQAEAAIAAQADAAMABgAIAAUACwALAAEAAwADAAIABAAGAAoACQAFAAcABAAHAAQABwABAAEABAACAAEAAwAGAAgABwABAAYACwAFAAUAAwAYAAkABAACAAcADQAFAAEACABSABAAPQABAAEAAQAEAAIAAgAQAAoAAwAIAAEAAQAGAAQAAgABAAMAAQABAAEABAADAAgABAACAAIAAQABAAEAAQABAAYAAwAFAAEAAQAEAAYACQACAAEAAQABAAIAAQAHAAIAAQAGAAEABQAEAAQAAwABAAgAAQADAAMAAQADAAIAAgACAAIAAwABAAYAAQACAAEAAgABAAMABwABAAgAAgABAAIAAQAFAAIABQADAAUACgABAAIAAQABAAMAAgAFAAsAAwAJAAMABQABAAEABQAJAAEAAgABAAUABwAJAAkACAABAAMAAwADAAYACAACAAMAAgABAAEAIAAGAAEAAgAPAAkAAwAHAA0AAQADAAoADQACAA4AAQANAAoAAgABAAMACgAEAA8AAgAPAA8ACgABAAMACQAGAAkAIAAZABoALwAHAAMAAgADAAEABgADAAQAAwACAAgABQAEAAEACQAEAAIAAgATAAoABgACAAMACAABAAIAAgAEAAIAAQAJAAQABAAEAAYABAAIAAkAAgADAAEAAQABAAEAAwAFAAUAAQADAAgABAAGAAIAAQAEAAwAAQAFAAMABwANAAIABQAIAAEABgABAAIABQAOAAYAAQAFAAIABAAIAA8ABQABABcABgA+AAIACgABAAEACAABAAIAAgAKAAQAAgACAAkAAgABAAEAAwACAAMAAQAFAAMAAwACAAEAAwAIAAEAAQABAAsAAwABAAEABAADAAcAAQAOAAEAAgADAAwABQACAAUAAQAGAAcABQAHAA4ACwABAAMAAQAIAAkADAACAAEACwAIAAQABAACAAYACgAJAA0AAQABAAMAAQAFAAEAAwACAAQABAABABIAAgADAA4ACwAEAB0ABAACAAcAAQADAA0ACQACAAIABQADAAUAFAAHABAACAAFAEgAIgAGAAQAFgAMAAwAHAAtACQACQAHACcACQC/AAEAAQABAAQACwAIAAQACQACAAMAFgABAAEAAQABAAQAEQABAAcABwABAAsAHwAKAAIABAAIAAIAAwACAAEABAACABAABAAgAAIAAwATAA0ABAAJAAEABQACAA4ACAABAAEAAwAGABMABgAFAAEAEAAGAAIACgAIAAUAAQACAAMAAQAFAAUAAQALAAYABgABAAMAAwACAAYAAwAIAAEAAQAEAAoABwAFAAcABwAFAAgACQACAAEAAwAEAAEAAQADAAEAAwADAAIABgAQAAEABAAGAAMAAQAKAAYAAQADAA8AAgAJAAIACgAZAA0ACQAQAAYAAgACAAoACwAEAAMACQABAAIABgAGAAUABAAeACgAAQAKAAcADAAOACEABgADAAYABwADAAEAAwABAAsADgAEAAkABQAMAAsAMQASADMAHwCMAB8AAgACAAEABQABAAgAAQAKAAEABAAEAAMAGAABAAoAAQADAAYABgAQAAMABAAFAAIAAQAEAAIAOQAKAAYAFgACABYAAwAHABYABgAKAAsAJAASABAAIQAkAAIABQAFAAEAAQABAAQACgABAAQADQACAAcABQACAAkAAwAEAAEABwArAAMABwADAAkADgAHAAkAAQALAAEAAQADAAcABAASAA0AAQAOAAEAAwAGAAoASQACAAIAHgAGAAEACwASABMADQAWAAMALgAqACUAWQAHAAMAEAAiAAIAAgADAAkAAQAHAAEAAQABAAIAAgAEAAoABwADAAoAAwAJAAUAHAAJAAIABgANAAcAAwABAAMACgACAAcAAgALAAMABgAVADYAVQACAAEABAACAAIAAQAnAAMAFQACAAIABQABAAEAAQAEAAEAAQADAAQADwABAAMAAgAEAAQAAgADAAgAAgAUAAEACAAHAA0ABAABABoABgACAAkAIgAEABUANAAKAAQABAABAAUADAACAAsAAQAHAAIAHgAMACwAAgAeAAEAAQADAAYAEAAJABEAJwBSAAIAAgAYAAcAAQAHAAMAEAAJAA4ALAACAAEAAgABAAIAAwAFAAIABAABAAYABwAFAAMAAgAGAAEACwAFAAsAAgABABIAEwAIAAEAAwAYAB0AAgABAAMABQACAAIAAQANAAYABQABAC4ACwADAAUAAQABAAUACAACAAoABgAMAAYAAwAHAAsAAgAEABAADQACAAUAAQABAAIAAgAFAAIAHAAFAAIAFwAKAAgABAAEABYAJwBfACYACAAOAAkABQABAA0ABQAEAAMADQAMAAsAAQAJAAEAGwAlAAIABQAEAAQAPwDTAF8AAgACAAIAAQADAAUAAgABAAEAAgACAAEAAQABAAMAAgAEAAEAAgABAAEABQACAAIAAQABAAIAAwABAAMAAQABAAEAAwABAAQAAgABAAMABgABAAEAAwAHAA8ABQADAAIABQADAAkACwAEAAIAFgABAAYAAwAIAAcAAQAEABwABAAQAAMAAwAZAAQABAAbABsAAQAEAAEAAgACAAcAAQADAAUAAgAcAAgAAgAOAAEACAAGABAAGQADAAMAAwAOAAMAAwABAAEAAgABAAQABgADAAgABAABAAEAAQACAAMABgAKAAYAAgADABIAAwACAAUABQAEAAMAAQAFAAIABQAEABcABwAGAAwABgAEABEACwAJAAUAAQABAAoABQAMAAEAAQALABoAIQAHAAMABgABABEABwABAAUADAABAAsAAgAEAAEACAAOABEAFwABAAIAAQAHAAgAEAALAAkABgAFAAIABgAEABAAAgAIAA4AAQALAAgACQABAAEAAQAJABkABAALABMABwACAA8AAgAMAAgANAAHAAUAEwACABAABAAkAAgAAQAQAAgAGAAaAAQABgACAAkABQAEACQAAwAcAAwAGQAPACUAGwARAAwAOwAmAAUAIAB/AAEAAgAJABEADgAEAAEAAgABAAEACAALADIABAAOAAIAEwAQAAQAEQAFAAQABQAaAAwALQACABcALQBoAB4ADAAIAAMACgACAAIAAwADAAEABAAUAAcAAgAJAAYADwACABQAAQADABAABAALAA8ABgCGAAIABQA7AAEAAgACAAIAAQAJABEAAwAaAIkACgDTADsAAQACAAQAAQAEAAEAAQABAAIABgACAAMAAQABAAIAAwACAAMAAQADAAQABAACAAMAAwABAAQAAwABAAcAAgACAAMAAQACAAEAAwADAAMAAgACAAMAAgABAAMADgAGAAEAAwACAAkABgAPABsACQAiAJEAAQABAAIAAQABAAEAAQACAAEAAQABAAEAAgACAAIAAwABAAIAAQABAAEAAgADAAUACAADAAUAAgAEAAEAAwACAAIAAgAMAAQAAQABAAEACgAEAAUAAQAUAAQAEAABAA8ACQAFAAwAAgAJAAIABQAEAAIAGgATAAcAAQAaAAQAHgAMAA8AKgABAAYACACsAAEAAQAEAAIAAQABAAsAAgACAAQAAgABAAIAAQAKAAgAAQACAAEABAAFAAEAAgAFAAEACAAEAAEAAwAEAAIAAQAGAAIAAQADAAQAAQACAAEAAQABAAEADAAFAAcAAgAEAAMAAQABAAEAAwADAAYAAQACAAIAAwADAAMAAgABAAIADAAOAAsABgAGAAQADAACAAgAAQAHAAoAAQAjAAcABAANAA8ABAADABcAFQAcADQABQAaAAUABgABAAcACgACAAcANQADAAIAAQABAAEAAgCjABQCAQAKAAsAAQADAAMABAAIAAIACAAGAAIAAgAXABYABAACAAIABAACAAEAAwABAAMAAwAFAAkACAACAAEAAgAIAAEACgACAAwAFQAUAA8AaQACAAMAAQABAAMAAgADAAEAAQACAAUAAQAEAA8ACwATAAEAAQABAAEABQAEAAUAAQABAAIABQADAAUADAABAAIABQABAAsAAQABAA8ACQABAAQABQADABoACAACAAEAAwABAAEADwATAAIADAABAAIABQACAAcAAgATAAIAFAAGABoABwAFAAIAAgAHACIAFQANAEYAAgCAAAEAAQACAAEAAQACAAEAAQADAAIAAgACAA8AAQAEAAEAAwAEACoACgAGAAEAMQBVAAgAAQACAAEAAQAEAAQAAgADAAYAAQAFAAcABAADANMABAABAAIAAQACAAUAAQACAAQAAgACAAYABQAGAAoAAwAEADAAZAAGAAIAEAAoAQUAGwCDAQIAAgADAAcAEAAIAAUAJgAPACcAFQAJAAoAAwAHADsADQAbABUALwAFABUABgBBkNEBCxggAP8AACBvIAAw/zDwMf8xAP/v//3//f8AQbLRAQuCLwEAAgAEAAEAAQABAAEAAgABAAMAAwACAAIAAQAFAAMABQAHAAUABgABAAIAAQAHAAIABgADAAEACAABAAEABAABAAEAEgACAAsAAgAGAAIAAQACAAEABQABAAIAAQADAAEAAgABAAIAAwADAAEAAQACAAMAAQABAAEADAAHAAkAAQAEAAUAAQABAAIAAQAKAAEAAQAJAAIAAgAEAAUABgAJAAMAAQABAAEAAQAJAAMAEgAFAAIAAgACAAIAAQAGAAMABwABAAEAAQABAAIAAgAEAAIAAQAXAAIACgAEAAMABQACAAQACgACAAQADQABAAYAAQAJAAMAAQABAAYABgAHAAYAAwABAAIACwADAAIAAgADAAIADwACAAIABQAEAAMABgAEAAEAAgAFAAIADAAQAAYADQAJAA0AAgABAAEABwAQAAQABwABABMAAQAFAAEAAgACAAcABwAIAAIABgAFAAQACQASAAcABAAFAAkADQALAAgADwACAAEAAQABAAIAAQACAAIAAQACAAIACAACAAkAAwADAAEAAQAEAAQAAQABAAEABAAJAAEABAADAAUABQACAAcABQADAAQACAACAAEADQACAAMAAwABAA4AAQABAAQABQABAAMABgABAAUAAgABAAEAAwADAAMAAwABAAEAAgAHAAYABgAHAAEABAAHAAYAAQABAAEAAQABAAwAAwADAAkABQACAAYAAQAFAAYAAQACAAMAEgACAAQADgAEAAEAAwAGAAEAAQAGAAMABQAFAAMAAgACAAIAAgAMAAMAAQAEAAIAAwACAAMACwABAAcABAABAAIAAQADABEAAQAJAAEAGAABAAEABAACAAIABAABAAIABwABAAEAAQADAAEAAgACAAQADwABAAEAAgABAAEAAgABAAUAAgAFABQAAgAFAAkAAQAKAAgABwAGAAEAAQABAAEAAQABAAYAAgABAAIACAABAAEAAQABAAUAAQABAAMAAQABAAEAAQADAAEAAQAMAAQAAQADAAEAAQABAAEAAQAKAAMAAQAHAAUADQABAAIAAwAEAAYAAQABAB4AAgAJAAkAAQAPACYACwADAAEACAAYAAcAAQAJAAgACgACAAEACQAfAAIADQAGAAIACQAEADEABQACAA8AAgABAAoAAgABAAEAAQACAAIABgAPAB4AIwADAA4AEgAIAAEAEAAKABwADAATAC0AJgABAAMAAgADAA0AAgABAAcAAwAGAAUAAwAEAAMAAQAFAAcACAABAAUAAwASAAUAAwAGAAEAFQAEABgACQAYACgAAwAOAAMAFQADAAIAAQACAAQAAgADAAEADwAPAAYABQABAAEAAwABAAUABgABAAkABwADAAMAAgABAAQAAwAIABUABQAQAAQABQACAAoACwALAAMABgADAAIACQADAAYADQABAAIAAQABAAEAAQALAAwABgAGAAEABAACAAYABQACAAEAAQADAAMABgANAAMAAQABAAUAAQACAAMAAwAOAAIAAQACAAIAAgAFAAEACQAFAAEAAQAGAAwAAwAMAAMABAANAAIADgACAAgAAQARAAUAAQAQAAQAAgACABUACAAJAAYAFwAUAAwAGQATAAkAJgAIAAMAFQAoABkAIQANAAQAAwABAAQAAQACAAQAAQACAAUAGgACAAEAAQACAAEAAwAGAAIAAQABAAEAAQABAAEAAgADAAEAAQABAAkAAgADAAEAAQABAAMABgADAAIAAQABAAYABgABAAgAAgACAAIAAQAEAAEAAgADAAIABwADAAIABAABAAIAAQACAAIAAQABAAEAAQABAAMAAQACAAUABAAKAAkABAAJAAEAAQABAAEAAQABAAUAAwACAAEABgAEAAkABgABAAoAAgAfABEACAADAAcABQAoAAEABwAHAAEABgAFAAIACgAHAAgABAAPACcAGQAGABwALwASAAoABwABAAMAAQABAAIAAQABAAEAAwADAAMAAQABAAEAAwAEAAIAAQAEAAEAAwAGAAoABwAIAAYAAgACAAEAAwADAAIABQAIAAcACQAMAAIADwABAAEABAABAAIAAQABAAEAAwACAAEAAwADAAUABgACAAMAAgAKAAEABAACAAgAAQABAAEACwAGAAEAFQAEABAAAwABAAMAAQAEAAIAAwAGAAUAAQADAAEAAQADAAMABAAGAAEAAQAKAAQAAgAHAAoABAAHAAQAAgAJAAQAAwABAAEAAQAEAAEACAADAAQAAQADAAEABgABAAQAAgABAAQABwACAAEACAABAAQABQABAAEAAgACAAQABgACAAcAAQAKAAEAAQADAAQACwAKAAgAFQAEAAYAAQADAAUAAgABAAIAHAAFAAUAAgADAA0AAQACAAMAAQAEAAIAAQAFABQAAwAIAAsAAQADAAMAAwABAAgACgAJAAIACgAJAAIAAwABAAEAAgAEAAEACAADAAYAAQAHAAgABgALAAEABAAdAAgABAADAAEAAgAHAA0AAQAEAAEABgACAAYADAAMAAIAFAADAAIAAwAGAAQACAAJAAIABwAiAAUAAQASAAYAAQABAAQABAAFAAcACQABAAIAAgAEAAMABAABAAcAAgACAAIABgACAAMAGQAFAAMABgABAAQABgAHAAQAAgABAAQAAgANAAYABAAEAAMAAQAFAAMABAAEAAMAAgABAAEABAABAAIAAQABAAMAAQALAAEABgADAAEABwADAAYAAgAIAAgABgAJAAMABAALAAMAAgAKAAwAAgAFAAsAAQAGAAQABQADAAEACAAFAAQABgAGAAMABQABAAEAAwACAAEAAgACAAYAEQAMAAEACgABAAYADAABAAYABgATAAkABgAQAAEADQAEAAQADwAHABEABgALAAkADwAMAAYABwACAAEAAgACAA8ACQADABUABAAGADEAEgAHAAMAAgADAAEABgAIAAIAAgAGAAIACQABAAMABgAEAAQAAQACABAAAgAFAAIAAQAGAAIAAwAFAAMAAQACAAUAAQACAAEACQADAAEACAAGAAQACAALAAMAAQABAAEAAQADAAEADQAIAAQAAQADAAIAAgABAAQAAQALAAEABQACAAEABQACAAUACAAGAAEAAQAHAAQAAwAIAAMAAgAHAAIAAQAFAAEABQACAAQABwAGAAIACAAFAAEACwAEAAUAAwAGABIAAQACAA0AAwADAAEAFQABAAEABAABAAQAAQABAAEACAABAAIAAgAHAAEAAgAEAAIAAgAJAAIAAQABAAEABAADAAYAAwAMAAUAAQABAAEABQAGAAMAAgAEAAgAAgACAAQAAgAHAAEACAAJAAUAAgADAAIAAQADAAIADQAHAA4ABgAFAAEAAQACAAEABAACABcAAgABAAEABgADAAEABAABAA8AAwABAAcAAwAJAA4AAQADAAEABAABAAEABQAIAAEAAwAIAAMACAAPAAsABAAOAAQABAACAAUABQABAAcAAQAGAA4ABwAHAAgABQAPAAQACAAGAAUABgACAAEADQABABQADwALAAkAAgAFAAYAAgALAAIABgACAAUAAQAFAAgABAANABMAGQAEAAEAAQALAAEAIgACAAUACQAOAAYAAgACAAYAAQABAA4AAQADAA4ADQABAAYADAAVAA4ADgAGACAAEQAIACAACQAcAAEAAgAEAAsACAADAAEADgACAAUADwABAAEAAQABAAMABgAEAAEAAwAEAAsAAwABAAEACwAeAAEABQABAAQAAQAFAAgAAQABAAMAAgAEAAMAEQAjAAIABgAMABEAAwABAAYAAgABAAEADAACAAcAAwADAAIAAQAQAAIACAADAAYABQAEAAcAAwADAAgAAQAJAAgABQABAAIAAQADAAIACAABAAIACQAMAAEAAQACAAMACAADABgADAAEAAMABwAFAAgAAwADAAMAAwADAAMAAQAXAAoAAwABAAIAAgAGAAMAAQAQAAEAEAAWAAMACgAEAAsABgAJAAcABwADAAYAAgACAAIABAAKAAIAAQABAAIACAAHAAEABgAEAAEAAwADAAMABQAKAAwADAACAAMADAAIAA8AAQABABAABgAGAAEABQAJAAsABAALAAQAAgAGAAwAAQARAAUADQABAAQACQAFAAEACwACAAEACAABAAUABwAcAAgAAwAFAAoAAgARAAMAJgAWAAEAAgASAAwACgAEACYAEgABAAQALAATAAQAAQAIAAQAAQAMAAEABAAfAAwAAQAOAAcASwAHAAUACgAGAAYADQADAAIACwALAAMAAgAFABwADwAGABIAEgAFAAYABAADABAAAQAHABIABwAkAAMABQADAAEABwABAAkAAQAKAAcAAgAEAAIABgACAAkABwAEAAMAIAAMAAMABwAKAAIAFwAQAAMAAQAMAAMAHwAEAAsAAQADAAgACQAFAAEAHgAPAAYADAADAAIAAgALABMACQAOAAIABgACAAMAEwANABEABQADAAMAGQADAA4AAQABAAEAJAABAAMAAgATAAMADQAkAAkADQAfAAYABAAQACIAAgAFAAQAAgADAAMABQABAAEAAQAEAAMAAQARAAMAAgADAAUAAwABAAMAAgADAAUABgADAAwACwABAAMAAQACABoABwAMAAcAAgAOAAMAAwAHAAcACwAZABkAHAAQAAQAJAABAAIAAQAGAAIAAQAJAAMAGwARAAQAAwAEAA0ABAABAAMAAgACAAEACgAEAAIABAAGAAMACAACAAEAEgABAAEAGAACAAIABAAhAAIAAwA/AAcAAQAGACgABwADAAQABAACAAQADwASAAEAEAABAAEACwACACkADgABAAMAEgANAAMAAgAEABAAAgARAAcADwAYAAcAEgANACwAAgACAAMABgABAAEABwAFAAEABwABAAQAAwADAAUACgAIAAIAAwABAAgAAQABABsABAACAAEADAABAAIAAQAKAAYAAQAGAAcABQACAAMABwALAAUACwADAAYABgACAAMADwAEAAkAAQABAAIAAQACAAsAAgAIAAwACAAFAAQAAgADAAEABQACAAIAAQAOAAEADAALAAQAAQALABEAEQAEAAMAAgAFAAUABwADAAEABQAJAAkACAACAAUABgAGAA0ADQACAAEAAgAGAAEAAgACADEABAAJAAEAAgAKABAABwAIAAQAAwACABcABAA6AAMAHQABAA4AEwATAAsACwACAAcABQABAAMABAAGAAIAEgAFAAwADAARABEAAwADAAIABAABAAYAAgADAAQAAwABAAEAAQABAAUAAQABAAkAAQADAAEAAwAGAAEACAABAAEAAgAGAAQADgADAAEABAALAAQAAQADACAAAQACAAQADQAEAAEAAgAEAAIAAQADAAEACwABAAQAAgABAAQABAAGAAMABQABAAYABQAHAAYAAwAXAAMABQADAAUAAwADAA0AAwAJAAoAAQAMAAoAAgADABIADQAHAKAANAAEAAIAAgADAAIADgAFAAQADAAEAAYABAABABQABAALAAYAAgAMABsAAQAEAAEAAgACAAcABAAFAAIAHAADAAcAGQAIAAMAEwADAAYACgACAAIAAQAKAAIABQAEAAEAAwAEAAEABQADAAIABgAJAAMABgACABAAAwADABAABAAFAAUAAwACAAEAAgAQAA8ACAACAAYAFQACAAQAAQAWAAUACAABAAEAFQALAAIAAQALAAsAEwANAAwABAACAAMAAgADAAYAAQAIAAsAAQAEAAIACQAFAAIAAQALAAIACQABAAEAAgAOAB8ACQADAAQAFQAOAAQACAABAAcAAgACAAIABQABAAQAFAADAAMABAAKAAEACwAJAAgAAgABAAQABQAOAAwADgACABEACQAGAB8ABAAOAAEAFAANABoABQACAAcAAwAGAA0AAgAEAAIAEwAGAAIAAgASAAkAAwAFAAwADAAOAAQABgACAAMABgAJAAUAFgAEAAUAGQAGAAQACAAFAAIABgAbAAIAIwACABAAAwAHAAgACAAGAAYABQAJABEAAgAUAAYAEwACAA0AAwABAAEAAQAEABEADAACAA4ABwABAAQAEgAMACYAIQACAAoAAQABAAIADQAOABEACwAyAAYAIQAUABoASgAQABcALQAyAA0AJgAhAAYABgAHAAQABAACAAEAAwACAAUACAAHAAgACQADAAsAFQAJAA0AAQADAAoABgAHAAEAAgACABIABQAFAAEACQAJAAIARAAJABMADQACAAUAAQAEAAQABwAEAA0AAwAJAAoAFQARAAMAGgACAAEABQACAAQABQAEAAEABwAEAAcAAwAEAAIAAQAGAAEAAQAUAAQAAQAJAAIAAgABAAMAAwACAAMAAgABAAEAAQAUAAIAAwABAAYAAgADAAYAAgAEAAgAAQADAAIACgADAAUAAwAEAAQAAwAEABAAAQAGAAEACgACAAQAAgABAAEAAgAKAAsAAgACAAMAAQAYAB8ABAAKAAoAAgAFAAwAEACkAA8ABAAQAAcACQAPABMAEQABAAIAAQABAAUAAQABAAEAAQABAAMAAQAEAAMAAQADAAEAAwABAAIAAQABAAMAAwAHAAIACAABAAIAAgACAAEAAwAEAAMABwAIAAwAXAACAAoAAwABAAMADgAFABkAEAAqAAQABwAHAAQAAgAVAAUAGwAaABsAFQAZAB4AHwACAAEABQANAAMAFgAFAAYABgALAAkADAABAAUACQAHAAUABQAWADwAAwAFAA0AAQABAAgAAQABAAMAAwACAAEACQADAAMAEgAEAAEAAgADAAcABgADAAEAAgADAAkAAQADAAEAAwACAAEAAwABAAEAAQACAAEACwADAAEABgAJAAEAAwACAAMAAQACAAEABQABAAEABAADAAQAAQACAAIABAAEAAEABwACAAEAAgACAAMABQANABIAAwAEAA4ACQAJAAQAEAADAAcABQAIAAIABgAwABwAAwABAAEABAACAA4ACAACAAkAAgABAA8AAgAEAAMAAgAKABAADAAIAAcAAQABAAMAAQABAAEAAgAHAAQAAQAGAAQAJgAnABAAFwAHAA8ADwADAAIADAAHABUAJQAbAAYABQAEAAgAAgAKAAgACAAGAAUAAQACAAEAAwAYAAEAEAARAAkAFwAKABEABgABADMANwAsAA0AJgEJAAMABgACAAQAAgACAA8AAQABAAEADQAVABEARAAOAAgACQAEAAEABAAJAAMACwAHAAEAAQABAAUABgADAAIAAQABAAEAAgADAAgAAQACAAIABAABAAUABQACAAEABAADAAcADQAEAAEABAABAAMAAQABAAEABQAFAAoAAQAGAAEABQACAAEABQACAAQAAQAEAAUABwADABIAAgAJAAsAIAAEAAMAAwACAAQABwALABAACQALAAgADQAmACAACAAEAAIAAQABAAIAAQACAAQABAABAAEAAQAEAAEAFQADAAsAAQAQAAEAAQAGAAEAAwACAAQACQAIADkABwAsAAEAAwADAA0AAwAKAAEAAQAHAAUAAgAHABUALwA/AAMADwAEAAcAAQAQAAEAAQACAAgAAgADACoADwAEAAEAHQAHABYACgADAE4AEAAMABQAEgAEAEMACwAFAAEAAwAPAAYAFQAfACAAGwASAA0ARwAjAAUAjgAEAAoAAQACADIAEwAhABAAIwAlABAAEwAbAAcAAQCFABMAAQAEAAgABwAUAAEABAAEAAEACgADAAEABgABAAIAMwAFACgADwAYACsAkFkLAAEADQCaAEYAAwABAAEABwAEAAoAAQACAAEAAQACAAEAAgABAAIAAgABAAEAAgABAAEAAQABAAEAAgABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAIAAQABAAEAAwACAAEAAQABAAEAAgABAAEAAAAgAP8AADD/MPAx/zEA/+///f/9/wBBwIACC0cgAP8AAAQvBeAt/y1App+mAAAgAP8AECBeIAAOfw4AACAA/wACAQMBEAERASgBKQFoAWkBoAGhAa8BsAGgHvkeAAD9/z8AIABBkIECC9Z+Li4tICAgICAgICAgLVhYWFhYWFgtICAgIFggICAgLSAgICAgICAgICAgWCAgICAgICAgICAgLVhYWFhYWFggICAgICAgICAgLSAgICAgICAgICBYWFhYWFhYLSAgICAgWFggICAgICAgICAgLSBYWCAgICAgICBYWCAuLi0gICAgICAgICAtWC4uLi4uWC0gICBYLlggICAtICAgICAgICAgIFguWCAgICAgICAgICAtWC4uLi4uWCAgICAgICAgICAtICAgICAgICAgIFguLi4uLlgtICAgIFguLlggICAgICAgICAtWC4uWCAgICAgWC4uWC0tLSAgICAgICAgIC1YWFguWFhYLSAgWC4uLlggIC0gICAgICAgICBYLi4uWCAgICAgICAgIC1YLi4uLlggICAgICAgICAgIC0gICAgICAgICAgIFguLi4uWC0gICAgWC4uWCAgICAgICAgIC1YLi4uWCAgIFguLi5YWCAgICAgICAgICAgLSAgWC5YICAtIFguLi4uLlggLSAgICAgICAgWC4uLi4uWCAgICAgICAgLVguLi5YICAgICAgICAgICAgLSAgICAgICAgICAgIFguLi5YLSAgICBYLi5YICAgICAgICAgLSBYLi4uWCBYLi4uWCBYWCAgICAgICAgICAtICBYLlggIC1YLi4uLi4uLlgtICAgICAgIFguLi4uLi4uWCAgICAgICAtWC4uWC5YICAgICAgICAgICAtICAgICAgICAgICBYLlguLlgtICAgIFguLlggICAgICAgICAtICBYLi4uWC4uLlggIFguWCAgICAgICAgIC0gIFguWCAgLVhYWFguWFhYWC0gICAgICAgWFhYWC5YWFhYICAgICAgIC1YLlggWC5YICAgICAgICAgIC0gICAgICAgICAgWC5YIFguWC0gICAgWC4uWFhYICAgICAgIC0gICBYLi4uLi5YICAgWC4uWCAgICAgICAgLSAgWC5YICAtICAgWC5YICAgLSAgICAgICAgICBYLlggICAgICAgICAgLVhYICAgWC5YICAgICAgICAgLSAgICAgICAgIFguWCAgIFhYLSAgICBYLi5YLi5YWFggICAgLSAgICBYLi4uWCAgICBYLi4uWCAgICAgICAtICBYLlggIC0gICBYLlggICAtICAgIFhYICAgIFguWCAgICBYWCAgICAtICAgICAgWC5YICAgICAgICAtICAgICAgICBYLlggICAgICAtICAgIFguLlguLlguLlhYICAtICAgICBYLlggICAgIFguLi4uWCAgICAgIC0gIFguWCAgLSAgIFguWCAgIC0gICBYLlggICAgWC5YICAgIFguWCAgIC0gICAgICAgWC5YICAgICAgIC0gICAgICAgWC5YICAgICAgIC0gICAgWC4uWC4uWC4uWC5YIC0gICAgWC4uLlggICAgWC4uLi4uWCAgICAgLSAgWC5YICAtICAgWC5YICAgLSAgWC4uWCAgICBYLlggICAgWC4uWCAgLSAgICAgICAgWC5YICAgICAgLSAgICAgIFguWCAgICAgICAgLVhYWCBYLi5YLi5YLi5YLi5YLSAgIFguLi4uLlggICBYLi4uLi4uWCAgICAtICBYLlggIC0gICBYLlggICAtIFguLi5YWFhYWFguWFhYWFhYLi4uWCAtICAgICAgICAgWC5YICAgWFgtWFggICBYLlggICAgICAgICAtWC4uWFguLi4uLi4uLlguLlgtICBYLi4uWC4uLlggIFguLi4uLi4uWCAgIC0gIFguWCAgLSAgIFguWCAgIC1YLi4uLi4uLi4uLi4uLi4uLi4uLi4uWC0gICAgICAgICAgWC5YIFguWC1YLlggWC5YICAgICAgICAgIC1YLi4uWC4uLi4uLi4uLi4uWC0gWC4uLlggWC4uLlggWC4uLi4uLi4uWCAgLSAgWC5YICAtICAgWC5YICAgLSBYLi4uWFhYWFhYLlhYWFhYWC4uLlggLSAgICAgICAgICAgWC5YLi5YLVguLlguWCAgICAgICAgICAgLSBYLi4uLi4uLi4uLi4uLi5YLVguLi5YICAgWC4uLlhYLi4uLi4uLi4uWCAtWFhYLlhYWC0gICBYLlggICAtICBYLi5YICAgIFguWCAgICBYLi5YICAtICAgICAgICAgICAgWC4uLlgtWC4uLlggICAgICAgICAgICAtICBYLi4uLi4uLi4uLi4uLlgtWC4uWCAgICAgWC4uWFguLi4uLi4uLi4uWC1YLi4uLi5YLSAgIFguWCAgIC0gICBYLlggICAgWC5YICAgIFguWCAgIC0gICAgICAgICAgIFguLi4uWC1YLi4uLlggICAgICAgICAgIC0gIFguLi4uLi4uLi4uLi4uWC0gWFggICAgICAgWFggWC4uLi4uLlhYWFhYLVhYWFhYWFgtICAgWC5YICAgLSAgICBYWCAgICBYLlggICAgWFggICAgLSAgICAgICAgICBYLi4uLi5YLVguLi4uLlggICAgICAgICAgLSAgIFguLi4uLi4uLi4uLi5YLS0tLS0tLS0tLS0tLS1YLi4uWC4uWCAgICAtLS0tLS0tLS0gICBYLlggICAtICAgICAgICAgIFguWCAgICAgICAgICAtICAgICAgICAgIFhYWFhYWFgtWFhYWFhYWCAgICAgICAgICAtICAgWC4uLi4uLi4uLi4uWCAtICAgICAgICAgICAgIFguLlggWC4uWCAgIC0gICAgICAgLVhYWFguWFhYWC0gICAgICAgWFhYWC5YWFhYICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gICAgWC4uLi4uLi4uLi5YIC0gICAgICAgICAgICAgWC5YICBYLi5YICAgLSAgICAgICAtWC4uLi4uLi5YLSAgICAgICBYLi4uLi4uLlggICAgICAgLSAgICBYWCAgICAgICAgICAgWFggICAgLSAgICAgICAgICAgLSAgICBYLi4uLi4uLi4uLlggLSAgICAgICAgICAgICBYWCAgICBYLi5YICAtICAgICAgIC0gWC4uLi4uWCAtICAgICAgICBYLi4uLi5YICAgICAgICAtICAgWC5YICAgICAgICAgICBYLlggICAtICAgICAgICAgICAtICAgICBYLi4uLi4uLi5YICAtICAgICAgICAgICAgICAgICAgIFguLlggIC0gICAgICAgLSAgWC4uLlggIC0gICAgICAgICBYLi4uWCAgICAgICAgIC0gIFguLlggICAgICAgICAgIFguLlggIC0gICAgICAgICAgIC0gICAgIFguLi4uLi4uLlggIC0gICAgICAgICAgICAgICAgICAgIFhYICAgLSAgICAgICAtICAgWC5YICAgLSAgICAgICAgICBYLlggICAgICAgICAgLSBYLi4uWFhYWFhYWFhYWFhYWC4uLlggLSAgICAgICAgICAgLSAgICAgWFhYWFhYWFhYWCAgLSAgICAgICAgICAgICAtLS0tLS0tLS0tLS0tICAgICAgIC0gICAgWCAgICAtICAgICAgICAgICBYICAgICAgICAgICAtWC4uLi4uLi4uLi4uLi4uLi4uLi4uLlgtICAgICAgICAgICAtLS0tLS0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gWC4uLlhYWFhYWFhYWFhYWFguLi5YIC0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSAgWC4uWCAgICAgICAgICAgWC4uWCAgLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtICAgWC5YICAgICAgICAgICBYLlggICAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gICAgWFggICAgICAgICAgIFhYICAgIC0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAA3XSkjIyMjIyMjaFYwcXMnLyMjI1spLCMjL2w6JCNRNj4jIzVbbjQyPmMtVEhgLT4+Iy9lPjExTk5WPUJ2KCo6LkY/dXUjKGdSVS5vMFhHSGAkdmhMRzFoeHQ5P1dgIyw1THNDcCMtaT4uciQ8JDZwRD5MYic7OUNyYzZ0Z1htS1ZlVTJjRDRFbzNSLzIqPl1iKE1DOyRqUGZZLjtoXmBJV005PExoMlRsUytmLXMkbzZRPEJXSGBZaVUueGZMcSROOyQwaVIvR1g6VShqY1cycC9XKnE/LXFtblVDSTtqSFNBaUZXTS5SKmtVQEM9R0g/YTl3cDhmJGUuLTReUWcxKVEtR0wobGYoci83R3JSZ3dWJU1TPUMjYDhORD5RbyN0J1gjKHYjWTl3MCMxRCRDSWY7VycjcFdVUFhPdXhYdVUoSDlNKDE8cS1VRTMxI14tVic4SVJVbzdRZi4vTD49S2UkJCc1RiUpXTBeIzBYQFUuYTxyOlFMdEZzTGNMNiMjbE9qKSMuWTU8LVImS2dMd3FKZkxnTiY7UT9nSV4jRFkydUxpQF5yTWw5dD1jV3E2IyN3ZWc+JEZCalZRVFNEZ0VLbklTN0VNOT5aWTl3MCNMOz4+I014JjRNdnQvL0xbTWtBI1dAbEsuTidbMCM3UkxfJiN3K0YlSHRHOU0jWExgTiYuLEdNNFBnOy08bkxFTmh2eD4tVnNNLk0wckpmTEgyZVRNYCpvSk1IUkNgTmtmaW1NMkosVy1qWFM6KXIwd0sjQEZnZSRVPmB3J043RyMkI2ZCIyRFXiQjOjk6aGsrZU9lLS02eClGNypFJT83NiVeR01IZVBXLVo1bCcmR2lGIyQ5NTY6clM/ZEEjZmlLOilZcitgJiMwakAnRGJHJiNeJFBHLkxsK0ROYTxYQ01LRVYqTilMTi9OKmI9JVE2cGlhLVhnOEkkPE1SJixWZEplJDwoN0c7Q2tsJyZoRjs7JDxfPVgoYi5SUyUlKSMjI01QQnV1RTFWOnYmY1gmIzJtIygmY1ZdYGs5T2hMTWJuJXMkRzIsQiRCZkQzWCpzcDUjbCwkUiNdeF9YMXhLWCViNVUqW3I1aU1mVW85VWBOOTloRyl0bSsvVXM5cEcpWFB1YDwwcy0pV1R0KGdDUnhJZyglNnNmaD1rdE1LbjNqKTw2PGI1U2tfLzAoXl1BYU4jKHAvTD4mVlo+MWklaDFTOXU1b0BZYWFXJGUrYjxUV0ZuL1o6T2goQ3gyJGxORW9OXmUpI0NGWUBASTtCT1Eqc1J3WnRaeFJjVTd1VzZDWG93MGkoPyRRW2NqT2RbUDRkKV0+Uk9QT3B4VE83U3R3aTE6OmlCMXEpQ189ZFYyNko7MixdN29wJF11UXJAX1Y3JHFeJWxRd3R1SFldPURYLG4zTCMwUEhETzRmOT5kQ0BPPkhCdUtQcFAqRSxOK2IzTCNscFIvTXJURUguSUFRay5hPkRbLmU7bWMueF1JcC5QSF4nL2FxVU8vJDFXeExvVzBbaUxBPFFUOzVIS0QrQHFRJ05RKDNfUExoRTQ4Ui5xQVBTd1EwL1dLP1osW3g/LUo7alFUV0EwWEBLSihfWThOLTovTTc0Oi8tWnBLclVzcz9kI2RacV1EQWJrVSpKcWtMK253WEBANDdgNT53PTRoKDkuYEdDUlV4SFBlUmA1TWpvbChkVVd4WmEoPlNUclBrckppV3hgNVU3RiMuZypqcm9oR2dgY2c6bFNUdkVZL0VWXzdINFE5W1olY252O0pRWVo1cS5sN1plYXM6SE9JWk9CP0c8TmFsZCRxc11AXUw8SjdiUio+Z3Y6WzdNSTJrKS4nMigkNUZOUCZFUSgsKVVdV10rZmgxOC52c2FpMDApO0QzQDRrdTVQP0RQOGFKdCs7cVVNXT0rYic4QDttVmlCS3gwREVbLWF1R2w4OlBKJkRqK002T0NdT14oKCMjXWAwaSlkclQ7LTdYYD0tSDNbaWdVblBHLU5abG8uI2tAaCM9T3JrJG0+YT4kLT9UbSRVVig/I1A2WVkjJy8jIyN4ZTdxLjczckkzKnBQLyQxPnM5KVcsSnJNN1NOXScvNEMjdiRVYDAjVi5bMD54UXNIJGZFbVBNZ1kydTdLaChHJXNpSWZMU29TK01LMmVUTSQ9NSxNOHBgQS47X1IlI3VbSyMkeDRBRzgua0svSFNCPT0tJ0llL1FUdEc/LS4qXk4tNEIvWk1fM1lsUUM3KHA3cSkmXShgNl9jKSQvKkpMKEwtXihdJHdJTWBkUHRPZEdBLFUzOncyTS0wPHEtXUxfP14pMXZ3Jy4sTVJzcVZyLkw7YU4mIy9FZ0opUEJjWy1mPitXb21YMnU3bHFNMmlFdW1NVGNzRj8tYVQ9Wi05N1VFblhnbEVuMUstYm5FT2BndUZ0KGMlPTtBbV9Rc0BqTG9vSSZOWDtdMCNqNCNGMTQ7Z2w4LUdRcGd3aHJxOCc9bF9mLWI0OSdVT3FrTHU3LSMjb0RZMkwodGUrTWNoJmdMWXRKLE1FdEpmTGgneCdNPSRDUy1aWiVQXThiWj4jUz9ZWSMlUSZxJzNeRncmP0QpVUROcm9jTTNBNzYvL29MPyNoN2dsODVbcVcvTkRPayUxNmlqOys6MWEnaU5JZGItb3U4LlAqdyx2NSNFSSRUV1M+UG90LVIqSCctU0VwQTpnKWYrTyQlJWBrQSNHPThSTW1HMSZPYD50bzhiQ11UJiQsbi5Mb08+MjlzcDNkdC01MlUlVk0jcTcnREhwZysjWjklSFtLPEwlYTJFLWdyV1ZNM0AyPS1rMjJ0TF00JCMjNldlJzhVSkNLRVtkXz0ld0k7JzZYLUdzTFg0al5TZ0okIyNSKncsdlAzd0sjaWlXJiMqaF5EJlI/anA3Ky91JiMoQVAjI1hVOGMkZlNZVy1KOTVfLURwW2c5d2NPJiNNLWgxT2NKbGMtKnZwdzB4VVgmI09RRktOWEBRSSdJb1BwN25iLFFVLy9NUSZaRGtLUClYPFdTVkwoNjh1VmwmI2MnWzAjKHMxWCZ4bSRZJUI3Kks6ZURBMzIzajk5OEdYYkEjcHdNcy1qZ0QkOVFJU0ItQV8oYU40eG9GTV5AQzU4RDArUStxM24wIzNVMUluRGpGNjgyLVNqTVhKSykoaCRoeHVhX0tddWw5MiUnQk9VJiNCUlJoLXNsZzhLRGxyOiVMNzFLYTouQTslWVVMakRQbUw8TFlzOGkjWHdKT1lhS1BLYzFoOic5S2UsZyliKSw3OD1JMzlCO3hpWSRiZ0d3LSYuWmk5SW5YRHVZYSVHKmYyQnE3bW45XiNwMXZ2JSMoV2ktOy9aNWhvOyMyOjslZCYjeDl2NjhDNWc/bnRYMFgpcFRgOyVwQjNxN21nR04pMyUoUDhuVGQ1TDdHZUEtR0xAKyVKM3UyOihZZj5ldGBlOylmI0ttOCYrREMkSTQ2PiNLcl1ddS1bPTk5dHRzMS5xYiNxNzJnMVdKTzgxcStlTicwMydlTT4mMVh4WS1jYUVuT2olMm44KSksP0lMUjVeLklibjwtWC1NcTdbYTgyTHE6RiYjY2UrUzl3c0NLKnhgNTY5RThldydIZV1oOnNJWzJMTSRbZ3VrYTNaUmQ2OnQlSUc6OyQlWWlKOk5xPT9lQXc7LzpubkRxMChDWWNNcEcpcUxONCQjIyZKPGokVXBLPFE0YTFdTXVwV14tc2pfJCVbSEslJ0YjIyMjUVJaSjo6WTNFR2w0J0AlRmtpQU9nI3BbIyNPYGd1a1RmQkhhZ0w8TEh3JXEmT1YwIyNGPTYvOmNoSW0wQGVDUDhYXTprRkklaGw4aGdPQFJjQmhTLUBRYiQlK209aFBETGcqJUs4bG4od2NmMy8nRFctJC5sUj9uW25DSC1lWE9PTlRKbGg6LlJZRiUzJ3A2c3E6VUlNQTk0NSZeSEZTODdAJEVQMmlHPC1sQ08kJWNgdUtHRDNyQyR4MEJMOGFGbi0tYGtlJSNITVAndmgxL1ImT19KOSd1bSwuPHR4W0Ald3NKayZiVVQyYDB1TXY3Z2cjcXAvaWouTDU2J2hsOy5zNUNVcnhqT003LSMjLmwrQXUnQSZPOi1UNzJMXVBgJj07Y3RwJ1hTY1gqclUuPi1YVHQsJU9WVTQpUzErUi0jZGcwL05uP0t1MV4wZiRCKlA6Um93d20tYDBQS2pZRERNJzNdZDM5VlpIRWw0LC5qJ11Qay1NLmheJjowRkFDbSRtYXEtJnNndzB0Ny82KF54dGslTHVIODhGai1la20+R0EjXz41Njh4NihPRlJsLUlacGAmYixfUCckTTxKbnE3OVZzSlcvbVdTKlBVaXE3NjtdL05NXz5oTGJ4ZmMkbWpgLE87JiVXMm1gWmg6LylVZXR3OmFKJV1LOWg6VGNGXXVfLVNqOSxWSzNNLionJjBEW0NhXUo5Z3A4LGtBV10lKD9BJVIkZjwtPlp0cydea249LV5AYzQlLXBZNnFJJUolMUlHeGZMVTlDUDhjYlBsWHYpO0M9YiksPDJtT3ZQOHVwLFVWZjM4MzlhY0FXQVctVz8jYW8vXiMlS1lvOGZSVUxOZDIuPiVtXVVLOm4lciQnc3ddSjs1cEFvT18jMm1PM24sJz1INShldEhnKmArUkxndj49NFU4Z3VEJEklRDpXPi1yNVYqJWoqVzpLdmVqLkxwJDxNLVNHWic6K1Ffayt1dk9TTGlFbyg8YUQvSzxDQ2NgJ0x4Pic/OysrTyc+KClqTFItXnU2OFBIbThaRldlK2VqOGg6OXI2TCowLy9jJmlIJlI4cFJiQSNLam0ldXBWMWc6YV8jVXI3RnVBIyh0UmgjLlk1SytAPzM8LThtMCRQRW47SjpyaDY/STZ1RzwtYHdNVSdpcmNwMExhRV9PdGxNYiYxIzZULiNGREt1IzFMdyV1JStHTStYJ2U/WUxmak1bVk8wTWJ1RnA3Oz5RJiNXSW8pMEBGJXE3YyM0WEFYTi1VJlZCPEhGRipxTCgkL1YsOyhrWFplaldPYDxbNT8/ZXdZKCo5PSV3RGM7LHU8Jzl0M1ctKEgxdGgzK0dddWNRXWtMczdkZigkLypKTF1AKnQ3QnVfRzNfN21wNzxpYVFqT0Aua0xnO3gzQjBscXA3SGYsXlplNy0jI0AvYzU4TW8oMztrbnAwJSlBNz8tVytlSSdvOCliPG5LbncnSG84Qz1ZPnBxQj4waWUmamhaWz9pTFJAQF9BdkEtaVFDKD1rc1JaUlZwN2AuPStOcEJDJXJoJjNdUjo4WERtRTVeVjhPKHg8PGFHLzFOJCNGWCQwVjVZNngnYUVySTNJJDd4JUVgdjwtQlksKSUtP1BzZipsPyVDMy5tTSg9L00wOkp4Ryc/N1doSCVvJ2E8LTgwZzBOQnhvTyhHSDxkTV1uLislcUBqSD9mLlVzSjJHZ3MmNDwtZTQ3JktsK2YvLzlAYGIrPy5UZU5fJkI4U3M/djteVHJrO2YjWXZKa2wmdyRdPi0raz8nKDxTOjY4dHEqV29EZlp1JzttTT84WFttYThXJSpgLT07RC4obmM3LzspZzpUMT1eSiQmQlJWKC1sVG1OQjZ4cUJbQDAqby5lck0qPFNXRl11Mj1zdC0qKDZ2Pl5dKEguYVJFWlNpLCMxOltJWGFaRk9tPC11aSNxVXEyJCMjUmk7dTc1T0sjKFJ0YVctSy1GYFMrY0ZddU5gLUtNUSVyUC9YcmkuTFJjQiMjPVlMM0JnTS8zTUQ/QGYmMSdCVy0pSnU8TDI1Z2w4dWhWbTFoTCQjIyo4IyMjJ0EzL0xrS1crKF5yV1g/NVdfOGcpYShtJks4UD4jYm1tV0NNa2smI1RSYEMsNWQ+ZylGO3QsNDpAX2w4Ry81aDR2VWQlJiU5NTA6VlhEJ1FkV29ZLUYkQnRVd21mZSRZcUwnOChQV1goUD9eQFBvMyQjI2BNU3M/RFdCWi9TPis0JT5mWCxWV3YvdydLRGBMUDVJYkg7clRWPm4zY0VLOFUjYlhdbC0vVitebGozO3ZsTWImWzVZUTgjcGVrWDlKUDNYVUM3MkwsLD8rTmkmY283QXBuTyo1TkssKChXLWk6JCxrcCdVREFPKEcwU3E3TVZqSnNiSXUpJ1osKls+YnI1ZlheOkZQQVdyLW0yS2dMPExVTjA5OGtURiYjbHZvNTg9L3ZqRG87LjspS2EqaExSIy9rPXJLYnh1VmA+UV9uTjYnOHVURyYjMVQ1Zyl1THY6ODczVXBUTGdIKyNGZ3BIJ19vMTc4MFBoOEtteFFKOCNINzJMNEA3NjhAVG0mUWg0Q0IvNU92bUEmLFEmUWJVb2kkYV8lM00wMUgpNHg3SV4mS1FWZ3RGblYrO1tQYz5bbTRrLy8sXTE/I2BWWVtKciozJiZzbFJmTGlWWko6XT89SzNTdz1bJD11UkI/M3hrNDhAYWVnPFonPCQjNEgpNiw+ZTBqVDYnTiMocSUuTz0/MlNddSoobTwtVjhKJygxKUddWzY4aFckNSdxW0dDJjVqYFRFP20nZXNGR05STSlqLGZmWj8tcXg4Oy0+ZzR0KjpDSVAvW1FhcDcvOScjKDFzYW83dy0ucU5VZGtKKXRDRiYjQl47eEd2bjJyOUZFUEZGRmNMQC5pRk5rVHZlJG0lI1F2UVM4VUApMlorM0s6QUtNNWlzWjg4K2RLUSlXNj5KJUNMPEtFPmAuZCooQmAtbjhEOW9LPFVwXWMkWCQoLClNOFp0Ny9bcmRrcVRnbC0wY3VHTXYnPz4tWFYxcVsnLTVrJ2NBWjY5ZTtEXz8kWlBQJnNeKzddKSQqJCNAUVlpOSw1UCYjOXIrJCVDRT02OD5LOHIwPWRTQyUlKEBwNy5tN2ppbFEwMicwLVZXQWc8YS8nJzN1Lj00TCRZKTZrL0s6X1szPSZqdkw8TDBDLzIndjpeOy1ESUJXLEI0RTY4OmtaOyU/OChROEJIPWtPNjVCVz94U0cmI0B1VSxEUyosPy4rKG8oIzF2Q1M4I0NIRj5UbEdXJ2IpVHE3VlQ5cV4qXiQkLjomTkBAJCYpV0h0UG0qNV9yTzAmZSVLJiMtMzBqKEU0IydaYi5vLyhUcG0kPksnZkBbUHZGbCxoZklOVE5VNnUnMHBhbzclWFVwOV01Lj4laGA4Xz1WWWJ4dWVsLk5UU3NKZkxhY0Z1M0InbFFTdS9tNi1PcWVtOFQrb0UtLSQwYS9rXXVqOUV3c0c+JXZlUipodl5CRnBRajpLJyNTSixzQi0nI10oai5MZzkyclR3LSpuJUAvOzM5cnJKRixsI3FWJU9ydEJlQzYvLDtxQjNlYk5XWz8sSHFqMkwuMU5QJkdqVVI9MUQ4UWFTM1VwJkAqOXdQPytsbzdiP0AlJ2s0YHAwWiQyMiVLMytpQ1pqP1hKTjRObSYrWUZddUAtVyRVJVZFUS8sLD4+IylEPGgjYCloMDo8UTY5MDl1YSsmVlUlbjI6Y0czRkotJUBCai1EZ0xyYEh3JkhBS2pLanNlSzwveEtUKilCLE45WDNda3JjMTJ0J3BnVFYoTHYtdExbeGdfJT1NX3E3YV54PzdVYmQ+IyU4Y1kjWVo/PSxgV2R4dS9hZSYjdzYpUjg5dEkjNkBzJyg2QmY3YSY/Uz1eWklfa1MmYWlgJj10RTcyTF9ELDteUik3WyRzPEVoI2MmKXEuTVhJJSN2OVJPYTVGWk8lc0Y3cTdOd2ImI3B0VUo6YXFKZSRTbDY4JS5EIyMjRUM+PD8tYUYmI1JOUXY+bzhsS04lNS8kKHZkZnE3K2ViQSN1MXBdb3ZVS1cmWSVxXSc+JDFALVt4Zm4kN1pUcDdtTSxHLEtvN2EmR3UlR1tSTXhKc1swTU0ld2NpLkxGREspKDxjYFE4TilqRUlGKis/UDJhOGclKSRxXW8yYUg4QyY8U2liQy9xLChlOnY7LWIjNlskTnREWjg0SmUyS052QiMkUDU/dFEzbnQoMGQ9ai5MUWYuL0xsMzMrKDtxM0wtdz04ZFgkI1dGJnVJSkAtYmZJPiU6X2kyQjVDc1I4JjlaJiM9bVBFbm0wZmA8JmMpUUw1dUojJXUlbEpqK0QtcjtCb0YmIzREb1M5N2g1ZylFI286JlM0d2VERiw5XkhvZWBoKkwrX2EqTnJMVy0xcEdfJjJVZEI4NmUlQi86PT4pTjR4ZVcuKndmdC07JCc1OC1FU3FyPGI/VUkoXyVAW1A0Nj4jVWAnNkFRXW0mNi9gWj4jUz9ZWSNWYztyN1UyJjMyNmQ9dyZIIyMjIz9UWmAqND8mLk1LP0xQOFZ4Zz4kW1FYYyVRSnY5Mi4oRGIqQilnYipCTTlkTSpoSk1BbypjJiNiMHY9UGplcl0kZ0cmSlhEZi0+J1N0dlU3NTA1bDkkQUZ2Z1lSSV4mPF5iNjg/aiNxOVFYNFNNJ1JPIyZzTDFJTS5ySmZMVUFqMjIxXWQjI0RXPW04M3U1OydiWXgsKlNsMGhMKFc7OyRkb0ImTy9UUTooWl54QmRMakw8TG5pOycnWC5gJCM4KzFHRDprJFlVV3NibjhvZ2g2cnhaMlo5XSVuZCs+ViMqOFVfNzJMaCsyUThDajBpOjZocCYkQy86cChISz5UOFlbZ0hRNGA0KSckQWIoTm9mJVYnOGhMJiM8TkVkdGcobic9UzFBKFExL0kmNChbJWRNYCxJdScxOl9oTD5TZkQwNyY2RDxmcDhkSE03L2crdGxQTjlKKnJLYVBjdCY/J3VCQ2VtXmpuJTlfSyk8LEM1SzNzPTVnJkdtSmIqW1NZcTdLO1RSTEdDc00tJCQ7UyU6WUByN0FLMHBwcnBMPExyaCxxN2UvJUtXSzo1MEleK20ndmlgMz8lWnArPC1kKyRMLVN2OkAubzE5biRzMCYzOTtrbjtTJUJTcSokM1dvSlNDTHdlVlthWidNUUlqTzw3O1gtWDsmK2RNTHZ1I15Vc0dFQzlXRWNbWCh3STcjMi4oRjBqViplWmY8LVF2M0otYytKNUFsckIjJHAoSDY4THZFQSdxM24wI20sW2AqOEZ0KUZjWWdFdWRdQ1dmbTY4LChhTEEkQEVGVGdMWG9CcS9VUGxwNzpkWy87cl9peD06VEZgUzVILWI8TEkmSFkoSz1oIyldTGskSzE0bFZmbTp4JEg8M15RbDxNYCRPaGFwQm5rdXAnRCNMJFBiX2BOKmddMmU7WC9EdGcsYnNqJksjMlstOmlZcidfd2dIKU5VSVI4YTFuI1M/WWVqJ2g4XjU4VWJaZCteRktEKlRAOzZBN2FRQ1tLOGQtKHY2R0kkeDpUPCYnR3A1VWY+QE0uKko6OyQtcnYyOSdNXThxTXYtdExwLCc4ODZpYUM9SGIqWUpvS0osKGolSz1IYEsudjlIZ2dxQklpWnUnUXZCVC4jPSkwdWtydVYmLikzPSheMWBvKlBqNDwtPGFOKCheNygnI1owd0sjNUdYQDd1XVtgKlNeNDM5MzNBNHJsXVtgKk80Q2dMRWxddiQxUTNBZUYzN2RiWGssLil2aiN4J2RgO3FnYlFSJUZXLDIoP0xPPXMlU2M2OCVOUCcjI0FvdGw4eD1CRSNqMVVEKFszJE0oXVVJMkxYM1JwS05AOy8jZidmLyZfbXQmRilYZEY8OXQ0KVFhLiprVEx3UScoVFRCOS54SCc+I01KK2dMcTktIyNASHVaUE4wXXU6aDcuVC4uRzo7JC9Vc2ooVDdgUTh0VDcyTG5ZbDwtcXg4Oy1IVjdRLSZYZHglMWEsaEM9MHUrSGxzVj5udUlRTC01PE4/KU5CUylRTipfSSw/JikyJ0lNJUwzSSlYKChlL2RsMiY4JzxNOl4jTSpRK1tULlhyaS5MWVMzdiVmRmA2OGg7Yi1YWy9FbidDUi5xN0UpcCcva2xlMkhNLHU7XiVPS0MtTitMbCVGOUNGPE5mJ14jdDJMLDsyN1c6ME9ANiMjVTZXNzokckpmTFdIaiQjKXdvcUJlZklaLlBLPGIqdDdlZDtwKl9tOzRFeEsjaEAmXT5fPkBrWFF0TWFjZkQubS1WQWI4O0lSZU0zJHdmMCcnaHJhKnNvNTY4J0lwJnZSczg0OSdNUllTcCU6dDpoNXFTZ3dwRXIkQj5RLDtzKEMjJClgc3ZRdUYkIyMtRCwjIyxnNjhAMltUOy5YU2ROOVFlKXJwdC5fSy0jNXdGKXNQJyMjcCNDMGMlLUdiJWhkKzwtaidBaSp4JiZITWtUXUMnT1NsIyM1UkdbSlhhSE47ZCd1QSN4Ll9VOy5gUFVAKFozZHQ0cjE1MkA6diwnUi5Taid3IzA8LTtrUEkpRmZKJiNBWUomIy8vKT4taz1tPSpYbkskPj0pNzJMXTBJJT4uRzY5MGE6JCMjPCwpOz87NzIjP3g5K2Q7XlYnOTtqWUA7KWJyI3FeWVFweDpYI1RlJFpeJz0tPWJHaExmOkQ2JmJOd1o5LVpEI25eOUhoTE1yNUc7J11kJjYnd1ltVEZtTDxMRClGXiVbdEMnODsrOUUjQyRnJSM1WT5xOXdJPlAoOW1JWz5rQy1la0xDL1ImQ0grcydCO0stTTYkRUIlaXMwMDorQTRbN3hrcy5Mck5rMCZFKXdJTFlGQDJMJzBOYiQrcHY8KDIuNzY4L0ZyWSZoJF4zaSZAK0clSlQnPC0sdmAzO18pSTlNXkFFXUNOP0NsMkFaZyslNGlUcFQzPG4tJiVIJWI8RkRqMk08aEg9JkVoPDJMZW4kYiphVFg9LThReE4pazExSU0xY15qJTlzPEw8TkZTbylCPys8LShHeHNGLF4tRWhAJDRkWGhOJCsjcnhLOCdqZSdEN2tgZTspMnBZd1BBJ19wOSZAXjE4bWwxXltAZzR0KltKT2EqWz1RcDcocUpfb09MXignN2ZCJkhxLTpzZixzTmo4eHFePiRVNE9dR0t4J205KWJAcDdZc3ZLM3deWVItQ2RRKjpJcjwoJHUmKSMoJj9MOVJnM0gpNGZpRXBeaUk5TzhLblRqLF1IP0QqcjcnTTtQd1o5SzBFXmsmLWNwSTsucC82X3Z3b0ZNVjwtPiMlWGkuTHhWbnJVKDQmOC9QKzpoTFNLaiQjVSVdNDl0J0k6cmdNaSdGTEBhOjBZLXVBWzM5JywodmJtYSpoVSU8LVNSRmBUdDo1NDJSX1ZWJHBAW3A4RFZbQSw/MTgzOUZXZEY8VGRkRjw5QWgtNiY5dFdvRGxoXSYxU3BHTXE+VGkxTypIJiMoQUw4W19QJS5NPnZeLSkpcU9UKkY1Q3EwYFllJSskQjZpOjdAMElYPE4rVCswTWxNQlBRKlZqPlNzRDxVNEpIWThrRDIpMmZVL00jJGUuKVQ0LF89OGhMaW1bJik7P1VrSycteD8nKDpzaUlmTDwkcEZNYGk8PyVXKG1HREhNJT5pV1AsIyNQYCUvTDxlWGk6QFo5Qy43bz1AKHBYZEFPL05MUThsUGwrSFBPUWE4d0Q4PV5HbFBhOFRLSTFDamhzQ1RTTEpNJy9XbD4tUyhxdyVzZi9AJSNCNjsvVTdLXXVaYmleT2NeMm48YmhQbVVrTXc+JXQ8KSdtRVZFJyduYFduSnJhJF5US3ZYNUI+O19hU0VLJywoaHdhMDppNEc/LkJjaS4oWFs/YiooJCw9LW48LlElYChYPT8rQEFtKkpzMCY9M2JoOEtdbUw8TG9Ocyc2LCc4NWAwP3QvJ19VNTlAXWRkRjwjTGRGPGVXZEY8T3VOLzQ1clk8LUxAJiMrZm0+Njk9TGIsT2NaVi8pO1RUbThWSTs/JU90SjwoYjRtcTdNNjp1P0tSZEY8Z1JAMkw9Rk5VLTxiWyg5Yy9NTDNtO1pbJG9GM2cpR0FXcXBBUmM9PFJPdTdjTDVsOy1bQV0lLytmc2Q7bCNTYWZUL2YqV10wPU8nJChUYjxbKSpAZTc3NVItOllvYiVnKj5sKjp4UD9ZYi41KSV3X0k/N3VrNUpDK0ZTKG0jaSdrLidhMGkpOTw3Yidmcyc1OWhxJCo1VWh2IyNwaV44K2hJRUJGYG52b2A7J2wwLl5TMTwtd1VLMi9Db2g1OEtLaExqTT1TTypyZk9gK3FDYFctT24uPUFKNTY+PmkyQDJMSDZBOiY1cWA/OUkzQEAnMDQmcDIvTFZhKlQtNDwtaTM7TTlVdlpkK043PmIqZUl3ZzpDQyljPD5uTyYjPElHZTtfXy50aGpabDwldyhXazJ4bXA0UUBJI0k5LERGXXU3LVA9Li1fOllKXWFTQFY/NipDKClkT3A3OldMLGImM1JnLy5jbU05JnJePiQoPi5aLUkmSihRMEhkNVElN0NvLWJgLWM8Tig2ckBpcCtBdXJLPG04NlFJdGgqI3Y7LU9CcWkrTDd3REUtSXI4S1snbStERFNMd0smLy4/LVYlVV8lMzpxS051JF9iKkIta3A3TmFEJ1FkV1FQS1lxW0A+UCloSTsqX0ZddWBSYlsuajhfUS88Jj51dStWc0gkc005VEElPykodm1KODApLFA3RT4pdGpEJTJMPS10I2ZLWyVgdj1RODxGZk5rZ2deb0liYWgqIzgvUXQkRiY6SyotKE4vJysxdk1CLHUoKS1hLlZVVSojW2UlZ0FBTyhTPldsQTIpO1NhPmdYbThZQmAxZEBLI25dNzYtYSRVLG1GPGZYXWlkcWQpPDMsXUo3Sm1XNGA2XXVrcz00LTcyTChqRWsrOmJKME1ecS04RG1fWj8wb2xQMUM5U2EmSFtkJmMkb29RVWpdRXhkKjNaTUAtV0dXMiVzJyxCLV9NJT4lVWw6Iy8neG9GTTlRWC0kLlFOJz5bJSRaJHVGNnBBNktpMk81Ojh3KnZQMTwtMWBbRywpLW0jPjBgUCYjZWIjLjNpKXJ0QjYxKG8nJD9YM0I8L1I5MDtlWl0lTmNxOy1UbF0jRj4yUWZ0XmFlXzV0S0w5TVVlOWIqc0xFUTk1QyZgPUc/QE1qPXdoKiczRT49LTwpR3QqSXcpJ1FHOmBASXdPZjcmXTFpJ1MwMUIrRXYvTmFjIzlTOz07WVFwZ182VWAqa1ZZMzl4SyxbLzZBajc6JzFCbS1fMUVZZmExK28mbzRocDdLTl9RKE9sSW9AUyU7alZkbjAnMTxWYzUyPXVgM15vLW4xJ2c0djU4SGomNl90NyQjIz9NKWM8JGJnUV8nU1koKC14a0EjWSgscCdIOXJJVlktYiwnJWJDUEY3Lko8VXBeLChkVTFWWSo1I1drVFU+aDE5dyxXUWhMSSkzUyNmJDIoZWIsanIqYjszVnddKjdOSCUkYzRWcyxlRDk+WFc4P05dbysoKnBnQyUvNzJMVi11PEhwLDNAZV45VUIxSithazktVE4vbWhLUGcrQUpZZCRNbHZBRl9qQ0sqLk8tXig2M2FkTVQtPlclaWV3UzhXNm0ycnRDcG8nUlMxUjg0PUBwYVRLdCk+PSUmMVspKnZwJ3UreCxWcndOOyZda3VPOUpEYmc9cE8kSioualZlO3UnbTBkcjlsLDwqd01LKk9lPWc4bFZfS0VCRmtPJ29VXV49Wy03OTIjb2ssKWldbFI4cVEyb0E4d2NSQ1peN3cvTmpoOz8uc3RYP1ExPlMxcTRCbiQpSzE8LXJHZE8nJFdyLkxjLkNHKSQvKkpMNHROUi8sU1ZPMyxhVXcnREpOOilTczt3R245QTMyaWp3JUZMK1owRm4uVTk7cmVTcSlibUkzMlU9PTVBTHVHJiNWZjEzOTgvcFZvMSpjLShhWTE2OG88YEpzU2JrLSwxTjskPjA6T1VhcygzOjhaOTcyTFNmRjhlYj1jLTs+U1B3Ny42aG4zbWA5XlhrbihyLnFTWzA7VCUmUWM9K1NUUnhYJ3ExQk5rMyYqZXUyOyY4cSQmeD5RI1E3XlRmKzY8KGQlWlZtajJiRGklLjNMMm4rNFcnJFBpRERHKWcsciUrPywkQD91b3U1dFNlMmFOX0FRVSo8aGBlLUdJNyk/T0syQS5kN19jKT93UTVBU0BETDNyIzdmU2tnbDYtKytEOidBLHVxN1N2bEIkcGNwSCdxM24wI18lZFkjeENwci1sPEYwTlJALSMjRkVWNk5URjYjIyRsODROMXc/QU8+J0lBT1VSUSMjVl5Gdi1YRmJHTTdGbChOPDNEaExHRiVxLjFyQyQjOlRfXyZQaTY4JTB4aV8mW3FGSig3N2pfJkpXb0YuVjczNSZULFtSKjp4RlIqSzU+PiNgYlctPzROZV8mNk5lXyY2TmVfJm5ga3ItI0dKY002WDt1TTZYO3VNKC5hLi5eMlRrTCVvUigjO3UuVCVmQXIlNHRKOCY+PDE9R0haXyttOS8jSDFGXlIjU0MjKk49QkE5KEQ/dltVaUZZPj5eOHAsS0tGLlddTDI5dUxrTGx1Lys0VDxYb0lCJmh4PVQxUGNEYUImO0hIKy1BRnI/KG05SFpWKUZLUzhKQ3c7U0Q9NlteL0RaVUxgRVVEZl1HR2xHJj53JClGLi9ebjMrcmxvK0RCOzVzSVlHTmsraTF0LTY5SmctLTBwYW83U20jSylwZEhXJjtMdUROSEBIPiMvWC1USSg7UD4jLEdjPiMwU3U+IzRgMT8jOGxDPyM8eFU/I0AuaT8jRDolQCNIRjdAI0xSSUAjUF9bQCNUa25AI1h3KkEjXS09QSNhOU9BI2Q8RiYjKjtHIyMuR1kjIzJTbCMjNmAoJCM6bDokIz54TCQjQi5gJCNGOnIkI0pGLiUjTlJAJSNSX1IlI1ZrZSUj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0XSeAFedvSqAcFIP//8+JwoAAABkAAAA6AMAABAnAACghgEAQEIPAICWmAAA4fUFGAAAADUAAABxAAAAa////877//+Sv///AAAAAAAAAAAZAAoAGRkZAAAAAAUAAAAAAAAJAAAAAAsAAAAAAAAAABkAEQoZGRkDCgcAAQAJCxgAAAkGCwAACwAGGQAAABkZGQBB4a0ECyEOAAAAAAAAAAAZAAoNGRkZAA0AAAIACQ4AAAAJAA4AAA4AQZuuBAsBDABBp64ECxUTAAAAABMAAAAACQwAAAAAAAwAAAwAQdWuBAsBEABB4a4ECxUPAAAABA8AAAAACRAAAAAAABAAABAAQY+vBAsBEgBBm68ECx4RAAAAABEAAAAACRIAAAAAABIAABIAABoAAAAaGhoAQdKvBAsOGgAAABoaGgAAAAAAAAkAQYOwBAsBFABBj7AECxUXAAAAABcAAAAACRQAAAAAABQAABQAQb2wBAsBFgBBybAEC4oMFQAAAAAVAAAAAAkWAAAAAAAWAAAWAAAwMTIzNDU2Nzg5QUJDREVG/////////////////////////////////////////////////////////////////wABAgMEBQYHCAn/////////CgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiP///////8KCwwNDg8QERITFBUWFxgZGhscHR4fICEiI/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AAQIEBwMGBQAAAAAAAAACAADAAwAAwAQAAMAFAADABgAAwAcAAMAIAADACQAAwAoAAMALAADADAAAwA0AAMAOAADADwAAwBAAAMARAADAEgAAwBMAAMAUAADAFQAAwBYAAMAXAADAGAAAwBkAAMAaAADAGwAAwBwAAMAdAADAHgAAwB8AAMAAAACzAQAAwwIAAMMDAADDBAAAwwUAAMMGAADDBwAAwwgAAMMJAADDCgAAwwsAAMMMAADDDQAA0w4AAMMPAADDAAAMuwEADMMCAAzDAwAMwwQADNtOMTBfX2N4eGFiaXYxMTZfX3NoaW1fdHlwZV9pbmZvRQAAAADQHAEATBoBAEweAQBOMTBfX2N4eGFiaXYxMTdfX2NsYXNzX3R5cGVfaW5mb0UAAADQHAEAfBoBAHAaAQBOMTBfX2N4eGFiaXYxMTdfX3BiYXNlX3R5cGVfaW5mb0UAAADQHAEArBoBAHAaAQBOMTBfX2N4eGFiaXYxMTlfX3BvaW50ZXJfdHlwZV9pbmZvRQDQHAEA3BoBANAaAQBOMTBfX2N4eGFiaXYxMjBfX2Z1bmN0aW9uX3R5cGVfaW5mb0UAAAAA0BwBAAwbAQBwGgEATjEwX19jeHhhYml2MTI5X19wb2ludGVyX3RvX21lbWJlcl90eXBlX2luZm9FAAAA0BwBAEAbAQDQGgEAAAAAAMAbAQDPAwAA0AMAANEDAADSAwAA0wMAAE4xMF9fY3h4YWJpdjEyM19fZnVuZGFtZW50YWxfdHlwZV9pbmZvRQDQHAEAmBsBAHAaAQB2AAAAhBsBAMwbAQBQdgAALB0BANgbAQAAAAAA0BsBAERuAACEGwEA7BsBAGIAAACEGwEA+BsBAGMAAACEGwEABBwBAGgAAACEGwEAEBwBAGEAAACEGwEAHBwBAHMAAACEGwEAKBwBAHQAAACEGwEANBwBAGkAAACEGwEAQBwBAGoAAACEGwEATBwBAGwAAACEGwEAWBwBAG0AAACEGwEAZBwBAHgAAACEGwEAcBwBAHkAAACEGwEAfBwBAGYAAACEGwEAiBwBAGQAAACEGwEAlBwBAAAAAACgGgEAzwMAANQDAADRAwAA0gMAANUDAADWAwAA1wMAANgDAAAAAAAAGB0BAM8DAADZAwAA0QMAANIDAADVAwAA2gMAANsDAADcAwAATjEwX19jeHhhYml2MTIwX19zaV9jbGFzc190eXBlX2luZm9FAAAAANAcAQDwHAEAoBoBAAAAAAAAGwEAzwMAAN0DAADRAwAA0gMAAN4DAAAAAAAApB0BAEMAAADfAwAA4AMAAAAAAADMHQEAQwAAAOEDAADiAwAAAAAAAIwdAQBDAAAA4wMAAOQDAABTdDlleGNlcHRpb24AAAAAqBwBAHwdAQBTdDliYWRfYWxsb2MAAAAA0BwBAJQdAQCMHQEAU3QyMGJhZF9hcnJheV9uZXdfbGVuZ3RoAAAAANAcAQCwHQEApB0BAAAAAAD8HQEAQgAAAOUDAADmAwAAU3QxMWxvZ2ljX2Vycm9yANAcAQDsHQEAjB0BAAAAAAAwHgEAQgAAAOcDAADmAwAAU3QxMmxlbmd0aF9lcnJvcgAAAADQHAEAHB4BAPwdAQBTdDl0eXBlX2luZm8AAAAAqBwBADweAQBB2LwECwkLAAAADAAAAAUAQey8BAsCyQMAQYS9BAsOxQMAAMoDAAAYdwEAAAQAQZy9BAsBAQBBrL0ECwX/////CgBB8L0ECwlgHgEAkH0CAAUAQYS+BAsCxwMAQZy+BAsLxQMAAMQDAACMfQEAQbS+BAsBAgBBxL4ECwj//////////wBBiL8ECwP4HgE=\";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}var binary=tryParseAsDataURI(file);if(binary){return binary}if(readBinary){return readBinary(file)}throw\"both async and sync fetching of the wasm failed\"}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==\"function\"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:\"same-origin\"}).then(function(response){if(!response[\"ok\"]){throw\"failed to load wasm binary file at '\"+wasmBinaryFile+\"'\"}return response[\"arrayBuffer\"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={\"a\":wasmImports};function receiveInstance(instance,module){var exports=instance.exports;Module[\"asm\"]=exports;wasmMemory=Module[\"asm\"][\"P\"];updateMemoryViews();wasmTable=Module[\"asm\"][\"T\"];addOnInit(Module[\"asm\"][\"Q\"]);removeRunDependency(\"wasm-instantiate\")}addRunDependency(\"wasm-instantiate\");function receiveInstantiationResult(result){receiveInstance(result[\"instance\"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err(\"failed to asynchronously prepare wasm: \"+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==\"function\"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch==\"function\"){return fetch(wasmBinaryFile,{credentials:\"same-origin\"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err(\"wasm streaming compile failed: \"+reason);err(\"falling back to ArrayBuffer instantiation\");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module[\"instantiateWasm\"]){try{var exports=Module[\"instantiateWasm\"](info,receiveInstance);return exports}catch(e){err(\"Module.instantiateWasm callback failed with error: \"+e);readyPromiseReject(e)}}instantiateAsync().catch(readyPromiseReject);return{}}function ExitStatus(status){this.name=\"ExitStatus\";this.message=\"Program terminated with exit(\"+status+\")\";this.status=status}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){callbacks.shift()(Module)}}function intArrayToString(array){var ret=[];for(var i=0;i255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join(\"\")}function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24;this.set_type=function(type){HEAPU32[this.ptr+4>>2]=type};this.get_type=function(){return HEAPU32[this.ptr+4>>2]};this.set_destructor=function(destructor){HEAPU32[this.ptr+8>>2]=destructor};this.get_destructor=function(){return HEAPU32[this.ptr+8>>2]};this.set_refcount=function(refcount){HEAP32[this.ptr>>2]=refcount};this.set_caught=function(caught){caught=caught?1:0;HEAP8[this.ptr+12>>0]=caught};this.get_caught=function(){return HEAP8[this.ptr+12>>0]!=0};this.set_rethrown=function(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13>>0]=rethrown};this.get_rethrown=function(){return HEAP8[this.ptr+13>>0]!=0};this.init=function(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor);this.set_refcount(0);this.set_caught(false);this.set_rethrown(false)};this.add_ref=function(){var value=HEAP32[this.ptr>>2];HEAP32[this.ptr>>2]=value+1};this.release_ref=function(){var prev=HEAP32[this.ptr>>2];HEAP32[this.ptr>>2]=prev-1;return prev===1};this.set_adjusted_ptr=function(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr};this.get_adjusted_ptr=function(){return HEAPU32[this.ptr+16>>2]};this.get_exception_ptr=function(){var isPointer=___cxa_is_pointer_type(this.get_type());if(isPointer){return HEAPU32[this.excPtr>>2]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.excPtr}}var exceptionLast=0;var uncaughtExceptionCount=0;function ___cxa_throw(ptr,type,destructor){var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw ptr}var SYSCALLS={varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;return 0}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;return 0}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs}function __embind_register_bigint(primitiveType,name,size,minRange,maxRange){}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError(\"Unknown type size: \"+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret=\"\";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return\"_unknown\"}name=name.replace(/[^a-zA-Z0-9_]/g,\"$\");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return\"_\"+name}return name}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function(\"body\",\"return function \"+name+\"() {\\n\"+' \"use strict\";'+\" return body.apply(this, arguments);\\n\"+\"};\\n\")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+\"\\n\"+stack.replace(/^Error(:[^\\n]*)?\\n/,\"\")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+\": \"+this.message}};return errorClass}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError(\"Mismatched type converter count\")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}}function registerType(rawType,registeredInstance,options={}){if(!(\"argPackAdvance\"in registeredInstance)){throw new TypeError(\"registerType registeredInstance requires argPackAdvance\")}var name=registeredInstance.name;if(!rawType){throwBindingError('type \"'+name+'\" must have a positive integer typeid pointer')}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(\"Cannot register type '\"+name+\"' twice\")}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function __embind_register_bool(rawType,name,size,trueValue,falseValue){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,\"fromWireType\":function(wt){return!!wt},\"toWireType\":function(destructors,o){return o?trueValue:falseValue},\"argPackAdvance\":8,\"readValueFromPointer\":function(pointer){var heap;if(size===1){heap=HEAP8}else if(size===2){heap=HEAP16}else if(size===4){heap=HEAP32}else{throw new TypeError(\"Unknown boolean type size: \"+name)}return this[\"fromWireType\"](heap[pointer>>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+\" instance already deleted\")}var finalizationRegistry=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}var registeredPointers={};function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj[\"delete\"]()}}var delayFunction=undefined;function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module[\"getInheritedInstanceCount\"]=getInheritedInstanceCount;Module[\"getLiveInheritedInstances\"]=getLiveInheritedInstances;Module[\"flushPendingDeletes\"]=flushPendingDeletes;Module[\"setDelayFunction\"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError(\"ptr should not be undefined\")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError(\"makeClassHandle requires ptr and ptrType\")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError(\"Both smartPtrType and smartPtr must be specified\")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance[\"clone\"]()}else{var rv=registeredInstance[\"clone\"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function attachFinalizer(handle){if(\"undefined\"===typeof FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$:$$};finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError(\"Object already scheduled for deletion\")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError(\"Object already scheduled for deletion\")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype[\"isAliasOf\"]=ClassHandle_isAliasOf;ClassHandle.prototype[\"clone\"]=ClassHandle_clone;ClassHandle.prototype[\"delete\"]=ClassHandle_delete;ClassHandle.prototype[\"isDeleted\"]=ClassHandle_isDeleted;ClassHandle.prototype[\"deleteLater\"]=ClassHandle_deleteLater}function ClassHandle(){}function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError(\"Function '\"+humanName+\"' called with an invalid number of arguments (\"+arguments.length+\") - expects one of (\"+proto[methodName].overloadTable+\")!\")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(\"Cannot register public name '\"+name+\"' twice\")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(\"Cannot register multiple overloads of a function with the same number of arguments (\"+numArguments+\")!\")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(\"Expected null or instance of \"+desiredClass.name+\", got an instance of \"+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(\"null is not a valid \"+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass \"'+embindRepr(handle)+'\" as a '+this.name)}if(!handle.$$.ptr){throwBindingError(\"Cannot pass deleted object as a pointer of type \"+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(\"null is not a valid \"+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass \"'+embindRepr(handle)+'\" as a '+this.name)}if(!handle.$$.ptr){throwBindingError(\"Cannot pass deleted object as a pointer of type \"+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(\"Cannot convert argument of type \"+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+\" to parameter type \"+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError(\"Passing raw pointer to smart pointer is illegal\")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(\"Cannot convert argument of type \"+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+\" to parameter type \"+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle[\"clone\"]();ptr=this.rawShare(ptr,Emval.toHandle(function(){clonedHandle[\"delete\"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError(\"Unsupporting sharing policy\")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(\"null is not a valid \"+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass \"'+embindRepr(handle)+'\" as a '+this.name)}if(!handle.$$.ptr){throwBindingError(\"Cannot pass deleted object as a pointer of type \"+this.name)}if(handle.$$.ptrType.isConst){throwBindingError(\"Cannot convert argument of type \"+handle.$$.ptrType.name+\" to parameter type \"+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function simpleReadValueFromPointer(pointer){return this[\"fromWireType\"](HEAP32[pointer>>2])}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle[\"delete\"]()}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype[\"argPackAdvance\"]=8;RegisteredPointer.prototype[\"readValueFromPointer\"]=simpleReadValueFromPointer;RegisteredPointer.prototype[\"deleteObject\"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype[\"fromWireType\"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this[\"toWireType\"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this[\"toWireType\"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this[\"toWireType\"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError(\"Replacing nonexistant public symbol\")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){var f=Module[\"dynCall_\"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)}function getWasmTableEntry(funcPtr){return wasmTable.get(funcPtr)}function dynCall(sig,ptr,args){if(sig.includes(\"j\")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn}function getDynCaller(sig,ptr){var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes(\"j\")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!=\"function\"){throwBindingError(\"unknown function pointer with signature \"+signature+\": \"+rawFunction)}return fp}var UnboundTypeError=undefined;function getTypeName(type){var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv}function throwUnboundTypeError(message,types){var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(message+\": \"+unboundTypes.map(getTypeName).join([\", \"]))}function __embind_register_class(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor){name=readLatin1String(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);if(upcast){upcast=embind__requireFunction(upcastSignature,upcast)}if(downcast){downcast=embind__requireFunction(downcastSignature,downcast)}rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError(\"Cannot construct \"+name+\" due to unbound types\",[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],function(base){base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(legalFunctionName,function(){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError(\"Use 'new' to construct \"+name)}if(undefined===registeredClass.constructor_body){throw new BindingError(name+\" has no accessible constructor\")}var body=registeredClass.constructor_body[arguments.length];if(undefined===body){throw new BindingError(\"Tried to invoke ctor of \"+name+\" with invalid number of parameters (\"+arguments.length+\") - expected (\"+Object.keys(registeredClass.constructor_body).toString()+\") parameters instead!\")}return body.apply(this,arguments)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+\"*\",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+\" const*\",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})}function heap32VectorToArray(count,firstElement){var array=[];for(var i=0;i>2])}return array}function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function new_(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError(\"new_ called with constructor type \"+typeof constructor+\" which is not a function\")}var dummy=createNamedFunction(constructor.name||\"unknownFunctionName\",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError(\"argTypes array size mismatch! Must at least get return value and 'this' types!\")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0?\", \":\"\")+argsListWired}invokerFnBody+=(returns?\"var rv = \":\"\")+\"invoker(fn\"+(argsListWired.length>0?\", \":\"\")+argsListWired+\");\\n\";if(needsDestructorStack){invokerFnBody+=\"runDestructors(destructors);\\n\"}else{for(var i=isClassMethodFunc?1:2;i0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=\"constructor \"+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(\"Cannot register multiple constructors with identical number of parameters (\"+(argCount-1)+\") for class '\"+classType.name+\"'! Overload resolution is currently only performed using the parameter count, not actual type info!\")}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(\"Cannot construct \"+classType.name+\" due to unbound types\",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+\".\"+methodName;if(methodName.startsWith(\"@@\")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(\"Cannot call \"+humanName+\" due to unbound types\",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}function validateThis(this_,classType,humanName){if(!(this_ instanceof Object)){throwBindingError(humanName+' with invalid \"this\": '+this_)}if(!(this_ instanceof classType.registeredClass.constructor)){throwBindingError(humanName+' incompatible with \"this\" of type '+this_.constructor.name)}if(!this_.$$.ptr){throwBindingError(\"cannot call emscripten binding method \"+humanName+\" on deleted object\")}return upcastPointer(this_.$$.ptr,this_.$$.ptrType.registeredClass,classType.registeredClass)}function __embind_register_class_property(classType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){fieldName=readLatin1String(fieldName);getter=embind__requireFunction(getterSignature,getter);whenDependentTypesAreResolved([],[classType],function(classType){classType=classType[0];var humanName=classType.name+\".\"+fieldName;var desc={get:function(){throwUnboundTypeError(\"Cannot access \"+humanName+\" due to unbound types\",[getterReturnType,setterArgumentType])},enumerable:true,configurable:true};if(setter){desc.set=()=>{throwUnboundTypeError(\"Cannot access \"+humanName+\" due to unbound types\",[getterReturnType,setterArgumentType])}}else{desc.set=v=>{throwBindingError(humanName+\" is a read-only property\")}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);whenDependentTypesAreResolved([],setter?[getterReturnType,setterArgumentType]:[getterReturnType],function(types){var getterReturnType=types[0];var desc={get:function(){var ptr=validateThis(this,classType,humanName+\" getter\");return getterReturnType[\"fromWireType\"](getter(getterContext,ptr))},enumerable:true};if(setter){setter=embind__requireFunction(setterSignature,setter);var setterArgumentType=types[1];desc.set=function(v){var ptr=validateThis(this,classType,humanName+\" setter\");var destructors=[];setter(setterContext,ptr,setterArgumentType[\"toWireType\"](destructors,v));runDestructors(destructors)}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);return[]});return[]})}function __embind_register_constant(name,type,value){name=readLatin1String(name);whenDependentTypesAreResolved([],[type],function(type){type=type[0];Module[name]=type[\"fromWireType\"](value);return[]})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i{if(!handle){throwBindingError(\"Cannot use deleted val. handle = \"+handle)}return emval_handle_array[handle].value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{var handle=emval_free_list.length?emval_free_list.pop():emval_handle_array.length;emval_handle_array[handle]={refcount:1,value:value};return handle}}}};function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,\"fromWireType\":function(handle){var rv=Emval.toValue(handle);__emval_decref(handle);return rv},\"toWireType\":function(destructors,value){return Emval.toHandle(value)},\"argPackAdvance\":8,\"readValueFromPointer\":simpleReadValueFromPointer,destructorFunction:null})}function embindRepr(v){if(v===null){return\"null\"}var t=typeof v;if(t===\"object\"||t===\"array\"||t===\"function\"){return v.toString()}else{return\"\"+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this[\"fromWireType\"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this[\"fromWireType\"](HEAPF64[pointer>>3])};default:throw new TypeError(\"Unknown float type: \"+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,\"fromWireType\":function(value){return value},\"toWireType\":function(destructors,value){return value},\"argPackAdvance\":8,\"readValueFromPointer\":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError(\"Cannot call \"+name+\" due to unbound types\",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError(\"Unknown integer type: \"+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes(\"unsigned\");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,\"fromWireType\":fromWireType,\"toWireType\":toWireType,\"argPackAdvance\":8,\"readValueFromPointer\":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(heap.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,\"fromWireType\":decodeMemoryView,\"argPackAdvance\":8,\"readValueFromPointer\":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name===\"std::string\";registerType(rawType,{name:name,\"fromWireType\":function(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError(\"String has UTF-16 code units that do not fit in 8 bits\")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str=\"\";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str=\"\";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}function __embind_register_std_wstring(rawType,charSize,name){name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>HEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,\"fromWireType\":function(value){var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},\"toWireType\":function(destructors,value){if(!(typeof value==\"string\")){throwBindingError(\"Cannot pass non-string to C++ string type \"+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},\"argPackAdvance\":8,\"readValueFromPointer\":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,\"argPackAdvance\":0,\"fromWireType\":function(){return undefined},\"toWireType\":function(destructors,o){return undefined}})}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+\" has unknown type \"+getTypeName(rawType))}return impl}function __emval_as(handle,returnType,destructorsRef){handle=Emval.toValue(handle);returnType=requireRegisteredType(returnType,\"emval::as\");var destructors=[];var rd=Emval.toHandle(destructors);HEAPU32[destructorsRef>>2]=rd;return returnType[\"toWireType\"](destructors,handle)}function emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i>2],\"parameter \"+i)}return a}function __emval_call(handle,argCount,argTypes,argv){handle=Emval.toValue(handle);var types=emval_lookupTypes(argCount,argTypes);var args=new Array(argCount);for(var i=0;i4){emval_handle_array[handle].refcount+=1}}function __emval_new_array(){return Emval.toHandle([])}function __emval_new_cstring(v){return Emval.toHandle(getStringOrSymbol(v))}function __emval_new_object(){return Emval.toHandle({})}function __emval_run_destructors(handle){var destructors=Emval.toValue(handle);runDestructors(destructors);__emval_decref(handle)}function __emval_set_property(handle,key,value){handle=Emval.toValue(handle);key=Emval.toValue(key);value=Emval.toValue(value);handle[key]=value}function __emval_strictly_equals(first,second){first=Emval.toValue(first);second=Emval.toValue(second);return first===second}function __emval_take_value(type,arg){type=requireRegisteredType(type,\"_emval_take_value\");var v=type[\"readValueFromPointer\"](arg);return Emval.toHandle(v)}function __emval_typeof(handle){handle=Emval.toValue(handle);return Emval.toHandle(typeof handle)}function _abort(){abort(\"\")}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function abortOnCannotGrowMemory(requestedSize){abort(\"OOM\")}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;abortOnCannotGrowMemory(requestedSize)}function _fd_close(fd){return 52}function _fd_read(fd,iov,iovcnt,pnum){return 52}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){return 70}var printCharBuffers=[null,[],[]];function printChar(stream,curr){var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j>2]=num;return 0}embind_init_charCodes();BindingError=Module[\"BindingError\"]=extendError(Error,\"BindingError\");InternalError=Module[\"InternalError\"]=extendError(Error,\"InternalError\");init_ClassHandle();init_embind();init_RegisteredPointer();UnboundTypeError=Module[\"UnboundTypeError\"]=extendError(Error,\"UnboundTypeError\");init_emval();var decodeBase64=typeof atob==\"function\"?atob:function(input){var keyStr=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";var output=\"\";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\\+\\/\\=]/g,\"\");do{enc1=keyStr.indexOf(input.charAt(i++));enc2=keyStr.indexOf(input.charAt(i++));enc3=keyStr.indexOf(input.charAt(i++));enc4=keyStr.indexOf(input.charAt(i++));chr1=enc1<<2|enc2>>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}while(i0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module[\"calledRun\"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module[\"onRuntimeInitialized\"])Module[\"onRuntimeInitialized\"]();postRun()}if(Module[\"setStatus\"]){Module[\"setStatus\"](\"Running...\");setTimeout(function(){setTimeout(function(){Module[\"setStatus\"](\"\")},1);doRun()},1)}else{doRun()}}if(Module[\"preInit\"]){if(typeof Module[\"preInit\"]==\"function\")Module[\"preInit\"]=[Module[\"preInit\"]];while(Module[\"preInit\"].length>0){Module[\"preInit\"].pop()()}}run();\n\n\n return Module.ready\n}\n);\n})();\nif (typeof exports === 'object' && typeof module === 'object')\n module.exports = Module;\nelse if (typeof define === 'function' && define['amd'])\n define([], function() { return Module; });\nelse if (typeof exports === 'object')\n exports[\"Module\"] = Module;\n\nexport default Module;\n","export interface XY { x: number, y: number; }\nexport interface XYZ extends XY { z: number; }\nexport interface XYZW extends XYZ { w: number; }\n\nexport interface RGB { r: number; g: number; b: number; }\nexport interface RGBA extends RGB { a: number; }\n\nimport * as Bind from \"../build/bind-imgui\";\nexport { Bind };\n\nlet bind: Bind.Module;\nexport default async function(value?: Partial): Promise {\n return new Promise((resolve: () => void) => {\n Bind.default(value).then((value: Bind.Module): void => {\n bind = value;\n resolve();\n });\n });\n}\nexport { bind };\n\nfunction import_Scalar(sca: XY | XYZ | XYZW | Bind.ImAccess | Bind.ImScalar | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): Bind.ImScalar {\n if (Array.isArray(sca)) { return [ sca[0] ]; }\n if (typeof sca === \"function\") { return [ sca() ]; }\n return [ sca.x ];\n}\n\nfunction export_Scalar(tuple: Bind.ImScalar, sca: XY | XYZ | XYZW | Bind.ImAccess | Bind.ImScalar | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): void {\n if (Array.isArray(sca)) { sca[0] = tuple[0]; return; }\n if (typeof sca === \"function\") { sca(tuple[0]); return; }\n sca.x = tuple[0];\n}\n\nfunction import_Vector2(vec: XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): Bind.ImTuple2 {\n if (Array.isArray(vec)) { return [ vec[0], vec[1] ]; }\n return [ vec.x, vec.y ];\n}\n\nfunction export_Vector2(tuple: Bind.ImTuple2, vec: XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): void {\n if (Array.isArray(vec)) { vec[0] = tuple[0]; vec[1] = tuple[1]; return; }\n vec.x = tuple[0]; vec.y = tuple[1];\n}\n\nfunction import_Vector3(vec: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): Bind.ImTuple3 {\n if (Array.isArray(vec)) { return [ vec[0], vec[1], vec[2] ]; }\n return [ vec.x, vec.y, vec.z ];\n}\n\nfunction export_Vector3(tuple: Bind.ImTuple3, vec: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): void {\n if (Array.isArray(vec)) { vec[0] = tuple[0]; vec[1] = tuple[1]; vec[2] = tuple[2]; return; }\n vec.x = tuple[0]; vec.y = tuple[1]; vec.z = tuple[2];\n}\n\nfunction import_Vector4(vec: XYZW | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): Bind.ImTuple4 {\n if (Array.isArray(vec)) { return [ vec[0], vec[1], vec[2], vec[3] || 0 ]; }\n return [ vec.x, vec.y, vec.z, vec.w ];\n}\n\nfunction export_Vector4(tuple: Bind.ImTuple4, vec: XYZW | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): void {\n if (Array.isArray(vec)) { vec[0] = tuple[0]; vec[1] = tuple[1]; vec[2] = tuple[2]; vec[3] = tuple[3]; return; }\n vec.x = tuple[0]; vec.y = tuple[1]; vec.z = tuple[2]; vec.w = tuple[3];\n}\n\nfunction import_Color3(col: RGB | RGBA | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): Bind.ImTuple3 {\n if (Array.isArray(col)) { return [ col[0], col[1], col[2] ]; }\n if (\"r\" in col) { return [ col.r, col.g, col.b ]; }\n return [ col.x, col.y, col.z ];\n}\n\nfunction export_Color3(tuple: Bind.ImTuple3, col: RGB | RGBA | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4): void {\n if (Array.isArray(col)) { col[0] = tuple[0]; col[1] = tuple[1]; col[2] = tuple[2]; return; }\n if (\"r\" in col) { col.r = tuple[0]; col.g = tuple[1]; col.b = tuple[2]; return; }\n col.x = tuple[0]; col.y = tuple[1]; col.z = tuple[2];\n}\n\nfunction import_Color4(col: RGBA | Bind.ImTuple4 | Bind.interface_ImVec4 | RGBA): Bind.ImTuple4 {\n if (Array.isArray(col)) { return [ col[0], col[1], col[2], col[3] ]; }\n if (\"r\" in col) { return [ col.r, col.g, col.b, col.a ]; }\n return [ col.x, col.y, col.z, col.w ];\n}\n\nfunction export_Color4(tuple: Bind.ImTuple4, col: RGBA | Bind.ImTuple4 | Bind.interface_ImVec4 | RGBA): void {\n if (Array.isArray(col)) { col[0] = tuple[0]; col[1] = tuple[1]; col[2] = tuple[2]; col[3] = tuple[3]; return; }\n if (\"r\" in col) { col.r = tuple[0]; col.g = tuple[1]; col.b = tuple[2]; col.a = tuple[3]; return; }\n col.x = tuple[0]; col.y = tuple[1]; col.z = tuple[2]; col.w = tuple[3];\n}\n\nimport * as config from \"./imconfig.js\";\n\nexport { IMGUI_VERSION as VERSION }\nexport const IMGUI_VERSION: string = \"1.86\"; // bind.IMGUI_VERSION;\nexport { IMGUI_VERSION_NUM as VERSION_NUM }\nexport const IMGUI_VERSION_NUM: number = 18600; // bind.IMGUI_VERSION_NUM;\n\n// #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert))\nexport { IMGUI_CHECKVERSION as CHECKVERSION }\nexport function IMGUI_CHECKVERSION(): boolean { return DebugCheckVersionAndDataLayout(IMGUI_VERSION, bind.ImGuiIOSize, bind.ImGuiStyleSize, bind.ImVec2Size, bind.ImVec4Size, bind.ImDrawVertSize, bind.ImDrawIdxSize); }\n\nexport const IMGUI_HAS_TABLE: boolean = true;\n\nexport function ASSERT(c: any): asserts c { if (!c) { throw new Error(); } }\nexport function IM_ASSERT(c: any): asserts c { if (!c) { throw new Error(); } }\n\nexport { IM_ARRAYSIZE as ARRAYSIZE }\nexport function IM_ARRAYSIZE(_ARR: ArrayLike | ImStringBuffer): number {\n if (_ARR instanceof ImStringBuffer) {\n return _ARR.size;\n } else {\n return _ARR.length;\n }\n}\n\nexport { ImStringBuffer as StringBuffer }\nexport class ImStringBuffer {\n constructor(public size: number, public buffer: string = \"\") {}\n}\n\nexport type ImAccess = Bind.ImAccess; export { ImAccess as Access }\nexport type ImScalar = Bind.ImScalar; export { ImScalar as Scalar }\nexport type ImTuple2 = Bind.ImTuple2; export { ImTuple2 as Tuple2 }\nexport type ImTuple3 = Bind.ImTuple3; export { ImTuple3 as Tuple3 }\nexport type ImTuple4 = Bind.ImTuple4; export { ImTuple4 as Tuple4 }\n\nexport { ImTextureID as TextureID }\nexport type ImTextureID = WebGLTexture;\nexport { ImGuiID as ID }\nexport type ImGuiID = Bind.ImGuiID;\n\n// Flags for ImGui::Begin()\nexport { ImGuiWindowFlags as WindowFlags };\nexport enum ImGuiWindowFlags {\n None = 0,\n NoTitleBar = 1 << 0, // Disable title-bar\n NoResize = 1 << 1, // Disable user resizing with the lower-right grip\n NoMove = 1 << 2, // Disable user moving the window\n NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programatically)\n NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set.\n NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it\n AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame\n NoBackground = 1 << 7, // Disable drawing background color (WindowBg, etc.) and outside border. Similar as using SetNextWindowBgAlpha(0.0f).\n NoSavedSettings = 1 << 8, // Never load/save settings in .ini file\n NoMouseInputs = 1 << 9, // Disable catching mouse or keyboard inputs, hovering test with pass through.\n MenuBar = 1 << 10, // Has a menu-bar\n HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the \"Horizontal Scrolling\" section.\n NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state\n NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus)\n AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y)\n AlwaysHorizontalScrollbar= 1 << 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x)\n AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient)\n NoNavInputs = 1 << 18, // No gamepad/keyboard navigation within the window\n NoNavFocus = 1 << 19, // No focusing toward this window with gamepad/keyboard navigation (e.g. skipped by CTRL+TAB)\n UnsavedDocument = 1 << 20, // Append '*' to title without affecting the ID, as a convenience to avoid using the ### operator. When used in a tab/docking context, tab is selected on closure and closure is deferred by one frame to allow code to cancel the closure (with a confirmation popup, etc.) without flicker.\n NoNav = NoNavInputs | NoNavFocus,\n NoDecoration = NoTitleBar | NoResize | NoScrollbar | NoCollapse,\n NoInputs = NoMouseInputs | NoNavInputs | NoNavFocus,\n\n // [Internal]\n NavFlattened = 1 << 23, // (WIP) Allow gamepad/keyboard navigation to cross over parent border to this child (only use on child that have no scrolling!)\n ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild()\n Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip()\n Popup = 1 << 26, // Don't use! For internal use by BeginPopup()\n Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal()\n ChildMenu = 1 << 28, // Don't use! For internal use by BeginMenu()\n}\n\n// Flags for ImGui::InputText()\nexport { ImGuiInputTextFlags as InputTextFlags };\nexport enum ImGuiInputTextFlags {\n None = 0,\n CharsDecimal = 1 << 0, // Allow 0123456789.+-*/\n CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef\n CharsUppercase = 1 << 2, // Turn a..z into A..Z\n CharsNoBlank = 1 << 3, // Filter out spaces, tabs\n AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus\n EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified)\n CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling)\n CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling)\n CallbackAlways = 1 << 8, // Call user function every time. User code may query cursor position, modify text buffer.\n CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character.\n AllowTabInput = 1 << 10, // Pressing TAB input a '\\t' character into the text field\n CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter).\n NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally\n AlwaysOverwrite = 1 << 13, // Overwrite mode\n ReadOnly = 1 << 14, // Read-only mode\n Password = 1 << 15, // Password mode, display all characters as '*'\n NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID().\n CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input)\n CallbackResize = 1 << 18, // Allow buffer capacity resize + notify when the string wants to be resized (for string types which hold a cache of their Size) (see misc/stl/imgui_stl.h for an example of using this)\n CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)\n // [Internal]\n Multiline = 1 << 20, // For internal use by InputTextMultiline()\n NoMarkEdited = 1 << 21, // For internal use by functions using InputText() before reformatting data\n}\n\n// Flags for ImGui::TreeNodeEx(), ImGui::CollapsingHeader*()\nexport { ImGuiTreeNodeFlags as TreeNodeFlags };\nexport enum ImGuiTreeNodeFlags {\n None = 0,\n Selected = 1 << 0, // Draw as selected\n Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader)\n AllowItemOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one\n NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack\n NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes)\n DefaultOpen = 1 << 5, // Default node to be open\n OpenOnDoubleClick = 1 << 6, // Need double-click to open node\n OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If OpenOnDoubleClick is also set, single-click arrow or double-click all box to open.\n Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes).\n Bullet = 1 << 9, // Display a bullet instead of arrow\n FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding().\n SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line. In the future we may refactor the hit system to be front-to-back, allowing natural overlaps and then this can become the default.\n SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (bypass the indented area).\n NavLeftJumpsBackHere = 1 << 13, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop)\n CollapsingHeader = Framed | NoTreePushOnOpen | NoAutoOpenOnLog,\n}\n\nexport { ImGuiPopupFlags as PopupFlags };\nexport enum ImGuiPopupFlags {\n None = 0,\n MouseButtonLeft = 0, // For BeginPopupContext*(): open on Left Mouse release. Guaranteed to always be == 0 (same as ImGuiMouseButton_Left)\n MouseButtonRight = 1, // For BeginPopupContext*(): open on Right Mouse release. Guaranteed to always be == 1 (same as ImGuiMouseButton_Right)\n MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranteed to always be == 2 (same as ImGuiMouseButton_Middle)\n MouseButtonMask_ = 0x1F,\n MouseButtonDefault_ = 1,\n NoOpenOverExistingPopup = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack\n NoOpenOverItems = 1 << 6, // For BeginPopupContextWindow(): don't return true when hovering items, only when hovering empty space\n AnyPopupId = 1 << 7, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup.\n AnyPopupLevel = 1 << 8, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level)\n AnyPopup = AnyPopupId | AnyPopupLevel\n}\n\n// Flags for ImGui::Selectable()\nexport { ImGuiSelectableFlags as SelectableFlags };\nexport enum ImGuiSelectableFlags {\n None = 0,\n DontClosePopups = 1 << 0, // Clicking this don't close parent popup window\n SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column)\n AllowDoubleClick = 1 << 2, // Generate press events on double clicks too\n Disabled = 1 << 3, // Cannot be selected, display greyed out text\n AllowItemOverlap = 1 << 4 // (WIP) Hit testing to allow subsequent widgets to overlap this one\n}\n\n// Flags for ImGui::BeginCombo()\nexport { ImGuiComboFlags as ComboFlags };\nexport enum ImGuiComboFlags {\n None = 0,\n PopupAlignLeft = 1 << 0, // Align the popup toward the left by default\n HeightSmall = 1 << 1, // Max ~4 items visible. Tip: If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo()\n HeightRegular = 1 << 2, // Max ~8 items visible (default)\n HeightLarge = 1 << 3, // Max ~20 items visible\n HeightLargest = 1 << 4, // As many fitting items as possible\n NoArrowButton = 1 << 5, // Display on the preview box without the square arrow button\n NoPreview = 1 << 6, // Display only a square arrow button\n HeightMask_ = HeightSmall | HeightRegular | HeightLarge | HeightLargest,\n}\n\n// Flags for ImGui::BeginTabBar()\nexport { ImGuiTabBarFlags as TabBarFlags };\nexport enum ImGuiTabBarFlags {\n None = 0,\n Reorderable = 1 << 0, // Allow manually dragging tabs to re-order them + New tabs are appended at the end of list\n AutoSelectNewTabs = 1 << 1, // Automatically select new tabs when they appear\n TabListPopupButton = 1 << 2,\n NoCloseWithMiddleMouseButton = 1 << 3, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.\n NoTabListScrollingButtons = 1 << 4,\n NoTooltip = 1 << 5, // Disable tooltips when hovering a tab\n FittingPolicyResizeDown = 1 << 6, // Resize tabs when they don't fit\n FittingPolicyScroll = 1 << 7, // Add scroll buttons when tabs don't fit\n FittingPolicyMask_ = FittingPolicyResizeDown | FittingPolicyScroll,\n FittingPolicyDefault_ = FittingPolicyResizeDown\n};\n\n// Flags for ImGui::BeginTabItem()\nexport { ImGuiTabItemFlags as TabItemFlags };\nexport enum ImGuiTabItemFlags {\n None = 0,\n UnsavedDocument = 1 << 0, // Append '*' to title without affecting the ID, as a convenience to avoid using the ### operator. Also: tab is selected on closure and closure is deferred by one frame to allow code to undo it without flicker.\n SetSelected = 1 << 1, // Trigger flag to programatically make the tab selected when calling BeginTabItem()\n NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.\n NoPushId = 1 << 3, // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem()\n NoTooltip = 1 << 4, // Disable tooltip for the given tab\n NoReorder = 1 << 5, // Disable reordering this tab or having another tab cross over this tab\n Leading = 1 << 6, // Enforce the tab position to the left of the tab bar (after the tab list popup button)\n Trailing = 1 << 7 // Enforce the tab position to the right of the tab bar (before the scrolling buttons)\n}\n\nexport { ImGuiTableFlags as TableFlags };\nexport enum ImGuiTableFlags {\n // Features\n None = 0,\n Resizable = 1 << 0, // Enable resizing columns.\n Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)\n Hideable = 1 << 2, // Enable hiding/disabling columns in context menu.\n Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.\n NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file.\n ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().\n // Decorations\n RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)\n BordersInnerH = 1 << 7, // Draw horizontal borders between rows.\n BordersOuterH = 1 << 8, // Draw horizontal borders at the top and bottom.\n BordersInnerV = 1 << 9, // Draw vertical borders between columns.\n BordersOuterV = 1 << 10, // Draw vertical borders on the left and right sides.\n BordersH = BordersInnerH | BordersOuterH, // Draw horizontal borders.\n BordersV = BordersInnerV | BordersOuterV, // Draw vertical borders.\n BordersInner = BordersInnerV | BordersInnerH, // Draw inner borders.\n BordersOuter = BordersOuterV | BordersOuterH, // Draw outer borders.\n Borders = BordersInner | BordersOuter, // Draw all borders.\n NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style\n NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style\n // Sizing Policy (read above for defaults)\n SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width.\n SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible.\n SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths.\n SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overridden by TableSetupColumn().\n // Sizing Extra Options\n NoHostExtendX = 1 << 16, // Make outer width auto-fit to columns, overriding outer_size.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.\n NoHostExtendY = 1 << 17, // Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.\n NoKeepColumnsVisible = 1 << 18, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.\n PreciseWidths = 1 << 19, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.\n // Clipping\n NoClip = 1 << 20, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().\n // Padding\n PadOuterX = 1 << 21, // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers.\n NoPadOuterX = 1 << 22, // Default if BordersOuterV is off. Disable outer-most padding.\n NoPadInnerX = 1 << 23, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).\n // Scrolling\n ScrollX = 1 << 24, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.\n ScrollY = 1 << 25, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.\n // Sorting\n SortMulti = 1 << 26, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).\n SortTristate = 1 << 27, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).\n\n // [Internal] Combinations and masks\n SizingMask_ = SizingFixedFit | SizingFixedSame | SizingStretchProp | SizingStretchSame\n}\n\n// Flags for ImGui::TableSetupColumn()\nexport { ImGuiTableColumnFlags as TableColumnFlags };\nexport enum ImGuiTableColumnFlags {\n // Input configuration flags\n None = 0,\n Disabled = 1 << 0, // Overriding/master disable flag: hide column, won't show in context menu (unlike calling TableSetColumnEnabled() which manipulates the user accessible state)\n DefaultHide = 1 << 1, // Default as a hidden/disabled column.\n DefaultSort = 1 << 2, // Default as a sorting column.\n WidthStretch = 1 << 3, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingStretchSame or _SizingStretchProp).\n WidthFixed = 1 << 4, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingFixedFit and table is resizable).\n NoResize = 1 << 5, // Disable manual resizing.\n NoReorder = 1 << 6, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.\n NoHide = 1 << 7, // Disable ability to hide/disable this column.\n NoClip = 1 << 8, // Disable clipping for this column (all NoClip columns will render in a same draw command).\n NoSort = 1 << 9, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).\n NoSortAscending = 1 << 10, // Disable ability to sort in the ascending direction.\n NoSortDescending = 1 << 11, // Disable ability to sort in the descending direction.\n NoHeaderLabel = 1 << 12, // TableHeadersRow() will not submit label for this column. Convenient for some small columns. Name will still appear in context menu.\n NoHeaderWidth = 1 << 13, // Disable header text width contribution to automatic column width.\n PreferSortAscending = 1 << 14, // Make the initial sort direction Ascending when first sorting on this column (default).\n PreferSortDescending = 1 << 15, // Make the initial sort direction Descending when first sorting on this column.\n IndentEnable = 1 << 16, // Use current Indent value when entering cell (default for column 0).\n IndentDisable = 1 << 17, // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored.\n\n // Output status flags, read-only via TableGetColumnFlags()\n IsEnabled = 1 << 24, // Status: is enabled == not hidden by user/api (referred to as \"Hide\" in _DefaultHide and _NoHide) flags.\n IsVisible = 1 << 25, // Status: is visible == is enabled AND not clipped by scrolling.\n IsSorted = 1 << 26, // Status: is currently part of the sort specs\n IsHovered = 1 << 27, // Status: is hovered by mouse\n\n // [Internal] Combinations and masks\n WidthMask_ = WidthStretch | WidthFixed,\n IndentMask_ = IndentEnable | IndentDisable,\n StatusMask_ = IsEnabled | IsVisible | IsSorted | IsHovered,\n NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)\n}\n\n// Flags for ImGui::TableNextRow()\nexport { ImGuiTableRowFlags as TableRowFlags };\nexport enum ImGuiTableRowFlags {\n None = 0,\n Headers = 1 << 0 // Identify header row (set default background color + width of its contents accounted different for auto column width)\n}\n\n// Enum for ImGui::TableSetBgColor()\n// Background colors are rendering in 3 layers:\n// - Layer 0: draw with RowBg0 color if set, otherwise draw with ColumnBg0 if set.\n// - Layer 1: draw with RowBg1 color if set, otherwise draw with ColumnBg1 if set.\n// - Layer 2: draw with CellBg color if set.\n// The purpose of the two row/columns layers is to let you decide if a background color changes should override or blend with the existing color.\n// When using ImGuiTableFlags_RowBg on the table, each row has the RowBg0 color automatically set for odd/even rows.\n// If you set the color of RowBg0 target, your color will override the existing RowBg0 color.\n// If you set the color of RowBg1 or ColumnBg1 target, your color will blend over the RowBg0 color.\nexport { ImGuiTableBgTarget as TableBgTarget };\nexport enum ImGuiTableBgTarget {\n None = 0,\n RowBg0 = 1, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used)\n RowBg1 = 2, // Set row background color 1 (generally used for selection marking)\n CellBg = 3 // Set cell background color (top-most color)\n}\n\n// Flags for ImGui::IsWindowFocused()\nexport { ImGuiFocusedFlags as FocusedFlags };\nexport enum ImGuiFocusedFlags {\n None = 0,\n ChildWindows = 1 << 0, // Return true if any children of the window is focused\n RootWindow = 1 << 1, // Test from root window (top most parent of the current hierarchy)\n AnyWindow = 1 << 2, // Return true if any window is focused. Important: If you are trying to tell how to dispatch your low-level inputs, do NOT use this. Use 'io.WantCaptureMouse' instead! Please read the FAQ!\n NoPopupHierarchy = 1 << 3, // Do not consider popup hierarchy (do not treat popup emitter as parent of popup) (when used with _ChildWindows or _RootWindow)\n //DockHierarchy = 1 << 4, // Consider docking hierarchy (treat dockspace host as parent of docked window) (when used with _ChildWindows or _RootWindow)\n RootAndChildWindows = RootWindow | ChildWindows\n}\n\n// Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered()\nexport { ImGuiHoveredFlags as HoveredFlags };\nexport enum ImGuiHoveredFlags {\n None = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them.\n ChildWindows = 1 << 0, // IsWindowHovered() only: Return true if any children of the window is hovered\n RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy)\n AnyWindow = 1 << 2, // IsWindowHovered() only: Return true if any window is hovered\n NoPopupHierarchy = 1 << 3, // IsWindowHovered() only: Do not consider popup hierarchy (do not treat popup emitter as parent of popup) (when used with _ChildWindows or _RootWindow)\n //DockHierarchy = 1 << 4, // IsWindowHovered() only: Consider docking hierarchy (treat dockspace host as parent of docked window) (when used with _ChildWindows or _RootWindow)\n AllowWhenBlockedByPopup = 1 << 5, // Return true even if a popup window is normally blocking access to this item/window\n //AllowWhenBlockedByModal = 1 << 6, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet.\n AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.\n AllowWhenOverlapped = 1 << 8, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window\n AllowWhenDisabled = 1 << 9, // IsItemHovered() only: Return true even if the item is disabled\n RectOnly = AllowWhenBlockedByPopup | AllowWhenBlockedByActiveItem | AllowWhenOverlapped,\n RootAndChildWindows = RootWindow | ChildWindows\n}\n\n// Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload()\nexport { ImGuiDragDropFlags as DragDropFlags };\nexport enum ImGuiDragDropFlags {\n // BeginDragDropSource() flags\n None = 0,\n SourceNoPreviewTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disable this behavior.\n SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item.\n SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item.\n SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit.\n SourceExtern = 1 << 4, // External source (from outside of imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously.\n SourceAutoExpirePayload = 1 << 5, // Automatically expire the payload if the source cease to be submitted (otherwise payloads are persisting while being dragged)\n // AcceptDragDropPayload() flags\n AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered.\n AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target.\n AcceptNoPreviewTooltip = 1 << 12, // Request hiding the BeginDragDropSource tooltip from the BeginDragDropTarget site.\n AcceptPeekOnly = AcceptBeforeDelivery | AcceptNoDrawDefaultRect, // For peeking ahead and inspecting the payload before delivery.\n}\n\n// Standard Drag and Drop payload types. You can define you own payload types using 12-characters long strings. Types starting with '_' are defined by Dear ImGui.\nexport const IMGUI_PAYLOAD_TYPE_COLOR_3F: string = \"_COL3F\"; // float[3] // Standard type for colors, without alpha. User code may use this type.\nexport const IMGUI_PAYLOAD_TYPE_COLOR_4F: string = \"_COL4F\"; // float[4] // Standard type for colors. User code may use this type.\n\n// A primary data type\nexport { ImGuiDataType as DataType };\nexport enum ImGuiDataType {\n S8, // char\n U8, // unsigned char\n S16, // short\n U16, // unsigned short\n S32, // int\n U32, // unsigned int\n S64, // long long, __int64\n U64, // unsigned long long, unsigned __int64\n Float, // float\n Double, // double\n COUNT\n}\n\n// A cardinal direction\nexport { ImGuiDir as Dir };\nexport enum ImGuiDir {\n None = -1,\n Left = 0,\n Right = 1,\n Up = 2,\n Down = 3,\n COUNT\n}\n\n// A sorting direction\nexport { ImGuiSortDirection as SortDirection };\nexport enum ImGuiSortDirection {\n None = 0,\n Ascending = 1, // Ascending = 0->9, A->Z etc.\n Descending = 2 // Descending = 9->0, Z->A etc.\n}\n\n\n// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array\nexport { ImGuiKey as Key };\nexport enum ImGuiKey {\n Tab,\n LeftArrow,\n RightArrow,\n UpArrow,\n DownArrow,\n PageUp,\n PageDown,\n Home,\n End,\n Insert,\n Delete,\n Backspace,\n Space,\n Enter,\n Escape,\n KeyPadEnter,\n A, // for text edit CTRL+A: select all\n C, // for text edit CTRL+C: copy\n V, // for text edit CTRL+V: paste\n X, // for text edit CTRL+X: cut\n Y, // for text edit CTRL+Y: redo\n Z, // for text edit CTRL+Z: undo\n COUNT,\n}\n\n// To test io.KeyMods (which is a combination of individual fields io.KeyCtrl, io.KeyShift, io.KeyAlt set by user/backend)\nexport { ImGuiKeyModFlags as KeyModFlags };\nexport enum ImGuiKeyModFlags {\n None = 0,\n Ctrl = 1 << 0,\n Shift = 1 << 1,\n Alt = 1 << 2,\n Super = 1 << 3\n}\n\n// [BETA] Gamepad/Keyboard directional navigation\n// Keyboard: Set io.ConfigFlags |= EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays.\n// Gamepad: Set io.ConfigFlags |= EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame().\n// Read instructions in imgui.cpp for more details.\nexport { ImGuiNavInput as NavInput };\nexport enum ImGuiNavInput\n{\n // Gamepad Mapping\n Activate, // activate / open / toggle / tweak value // e.g. Circle (PS4), A (Xbox), B (Switch), Space (Keyboard)\n Cancel, // cancel / close / exit // e.g. Cross (PS4), B (Xbox), A (Switch), Escape (Keyboard)\n Input, // text input / on-screen keyboard // e.g. Triang.(PS4), Y (Xbox), X (Switch), Return (Keyboard)\n Menu, // tap: toggle menu / hold: focus, move, resize // e.g. Square (PS4), X (Xbox), Y (Switch), Alt (Keyboard)\n DpadLeft, // move / tweak / resize window (w/ PadMenu) // e.g. D-pad Left/Right/Up/Down (Gamepads), Arrow keys (Keyboard)\n DpadRight, //\n DpadUp, //\n DpadDown, //\n LStickLeft, // scroll / move window (w/ PadMenu) // e.g. Left Analog Stick Left/Right/Up/Down\n LStickRight, //\n LStickUp, //\n LStickDown, //\n FocusPrev, // next window (w/ PadMenu) // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch)\n FocusNext, // prev window (w/ PadMenu) // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch)\n TweakSlow, // slower tweaks // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch)\n TweakFast, // faster tweaks // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch)\n\n // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them.\n // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) may be directly reading from io.KeyDown[] instead of io.NavInputs[].\n KeyLeft_, // move left // = Arrow keys\n KeyRight_, // move right\n KeyUp_, // move up\n KeyDown_, // move down\n COUNT,\n InternalStart_ = KeyLeft_,\n}\n\n// [BETA] Gamepad/Keyboard directional navigation flags, stored in io.ConfigFlags\nexport { ImGuiConfigFlags as ConfigFlags };\nexport enum ImGuiConfigFlags\n{\n None = 0,\n NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[].\n NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[].\n NavEnableSetMousePos = 1 << 2, // Request navigation to allow moving the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantMoveMouse=true. If enabled you MUST honor io.WantMoveMouse requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth.\n NavNoCaptureKeyboard = 1 << 3, // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set.\n NoMouse = 1 << 4, // Instruct imgui to clear mouse position/buttons in NewFrame(). This allows ignoring the mouse information back-end\n NoMouseCursorChange = 1 << 5, // Instruct back-end to not alter mouse cursor shape and visibility.\n\n IsSRGB = 1 << 20, // Application is SRGB-aware.\n IsTouchScreen = 1 << 21 // Application is using a touch screen instead of a mouse.\n}\n\n// Enumeration for PushStyleColor() / PopStyleColor()\nexport { ImGuiCol as Col };\nexport enum ImGuiCol {\n Text,\n TextDisabled,\n WindowBg, // Background of normal windows\n ChildBg, // Background of child windows\n PopupBg, // Background of popups, menus, tooltips windows\n Border,\n BorderShadow,\n FrameBg, // Background of checkbox, radio button, plot, slider, text input\n FrameBgHovered,\n FrameBgActive,\n TitleBg,\n TitleBgActive,\n TitleBgCollapsed,\n MenuBarBg,\n ScrollbarBg,\n ScrollbarGrab,\n ScrollbarGrabHovered,\n ScrollbarGrabActive,\n CheckMark,\n SliderGrab,\n SliderGrabActive,\n Button,\n ButtonHovered,\n ButtonActive,\n Header,\n HeaderHovered,\n HeaderActive,\n Separator,\n SeparatorHovered,\n SeparatorActive,\n ResizeGrip,\n ResizeGripHovered,\n ResizeGripActive,\n Tab,\n TabHovered,\n TabActive,\n TabUnfocused,\n TabUnfocusedActive,\n PlotLines,\n PlotLinesHovered,\n PlotHistogram,\n PlotHistogramHovered,\n TableHeaderBg, // Table header background\n TableBorderStrong, // Table outer and header borders (prefer using Alpha=1.0 here)\n TableBorderLight, // Table inner borders (prefer using Alpha=1.0 here)\n TableRowBg, // Table row background (even rows)\n TableRowBgAlt, // Table row background (odd rows)\n TextSelectedBg,\n DragDropTarget,\n NavHighlight, // Gamepad/keyboard: current highlighted item\n NavWindowingHighlight, // Highlight window when using CTRL+TAB\n NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active\n ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active\n COUNT,\n}\n\n// Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure.\n// NB: the enum only refers to fields of ImGuiStyle which makes sense to be pushed/popped inside UI code. During initialization, feel free to just poke into ImGuiStyle directly.\n// NB: if changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type.\nexport { ImGuiStyleVar as StyleVar };\nexport enum ImGuiStyleVar {\n // Enum name --------------------- // Member in ImGuiStyle structure (see ImGuiStyle for descriptions)\n Alpha, // float Alpha\n DisabledAlpha, // float DisabledAlpha\n WindowPadding, // ImVec2 WindowPadding\n WindowRounding, // float WindowRounding\n WindowBorderSize, // float WindowBorderSize\n WindowMinSize, // ImVec2 WindowMinSize\n WindowTitleAlign, // ImVec2 WindowTitleAlign\n ChildRounding, // float ChildRounding\n ChildBorderSize, // float ChildBorderSize\n PopupRounding, // float PopupRounding\n PopupBorderSize, // float PopupBorderSize\n FramePadding, // ImVec2 FramePadding\n FrameRounding, // float FrameRounding\n FrameBorderSize, // float FrameBorderSize\n ItemSpacing, // ImVec2 ItemSpacing\n ItemInnerSpacing, // ImVec2 ItemInnerSpacing\n IndentSpacing, // float IndentSpacing\n CellPadding, // ImVec2 CellPadding\n ScrollbarSize, // float ScrollbarSize\n ScrollbarRounding, // float ScrollbarRounding\n GrabMinSize, // float GrabMinSize\n GrabRounding, // float GrabRounding\n TabRounding, // float TabRounding\n ButtonTextAlign, // ImVec2 ButtonTextAlign\n SelectableTextAlign, // ImVec2 SelectableTextAlign\n COUNT\n}\n\n// Back-end capabilities flags stored in io.BackendFlags. Set by imgui_impl_xxx or custom back-end.\nexport { ImGuiBackendFlags as BackendFlags };\nexport enum ImGuiBackendFlags {\n None = 0,\n HasGamepad = 1 << 0, // Back-end has a connected gamepad.\n HasMouseCursors = 1 << 1, // Back-end can honor GetMouseCursor() values and change the OS cursor shape.\n HasSetMousePos = 1 << 2, // Back-end can honor io.WantSetMousePos and reposition the mouse (only used if ImGuiConfigFlags_NavEnableSetMousePos is set).\n RendererHasVtxOffset = 1 << 3, // Back-end Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bits indices.\n}\n\n// Flags for InvisibleButton() [extended in imgui_internal.h]\nexport { ImGuiButtonFlags as ButtonFlags };\nexport enum ImGuiButtonFlags {\n None = 0,\n MouseButtonLeft = 1 << 0, // React on left mouse button (default)\n MouseButtonRight = 1 << 1, // React on right mouse button\n MouseButtonMiddle = 1 << 2, // React on center mouse button\n\n // [Internal]\n MouseButtonMask_ = MouseButtonLeft | MouseButtonRight | MouseButtonMiddle,\n MouseButtonDefault_ = MouseButtonLeft\n}\n\n// Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton()\nexport { ImGuiColorEditFlags as ColorEditFlags };\nexport enum ImGuiColorEditFlags {\n None = 0,\n NoAlpha = 1 << 1, // // ColorEdit, ColorPicker, ColorButton: ignore Alpha component (read 3 components from the input pointer).\n NoPicker = 1 << 2, // // ColorEdit: disable picker when clicking on colored square.\n NoOptions = 1 << 3, // // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview.\n NoSmallPreview = 1 << 4, // // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs)\n NoInputs = 1 << 5, // // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square).\n NoTooltip = 1 << 6, // // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview.\n NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker).\n NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead.\n NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.\n NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default)\n // User Options (right-click on widget to change some of them). You can set application defaults using SetColorEditOptions(). The idea is that you probably don't want to override them in most of your calls, let the user choose and/or call SetColorEditOptions() during startup.\n AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.\n AlphaPreview = 1 << 17, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque.\n AlphaPreviewHalf= 1 << 18, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque.\n HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use Float flag as well).\n DisplayRGB = 1 << 20, // [Inputs] // ColorEdit: choose one among RGB/HSV/HEX. ColorPicker: choose any combination using RGB/HSV/HEX.\n DisplayHSV = 1 << 21, // [Inputs] // \"\n DisplayHex = 1 << 22, // [Inputs] // \"\n Uint8 = 1 << 23, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255.\n Float = 1 << 24, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers.\n PickerHueBar = 1 << 25, // [PickerMode] // ColorPicker: bar for Hue, rectangle for Sat/Value.\n PickerHueWheel = 1 << 26, // [PickerMode] // ColorPicker: wheel for Hue, triangle for Sat/Value.\n InputRGB = 1 << 27, // [Input] // ColorEdit, ColorPicker: input and output data in RGB format.\n InputHSV = 1 << 28, // [Input] // ColorEdit, ColorPicker: input and output data in HSV format.\n\n // Defaults Options. You can set application defaults using SetColorEditOptions(). The intent is that you probably don't want to\n // override them in most of your calls. Let the user choose via the option menu and/or call SetColorEditOptions() once during startup.\n DefaultOptions_ = Uint8|DisplayRGB|InputRGB|PickerHueBar,\n\n // [Internal] Masks\n DisplayMask_ = DisplayRGB|DisplayHSV|DisplayHex,\n DataTypeMask_ = Uint8|Float,\n PickerMask_ = PickerHueWheel|PickerHueBar,\n InputMask_ = InputRGB|InputHSV,\n}\n\n// Flags for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc.\n// We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them.\nexport { ImGuiSliderFlags as SliderFlags };\nexport enum ImGuiSliderFlags {\n None = 0,\n AlwaysClamp = 1 << 4, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.\n Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits.\n NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits)\n NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget\n InvalidMask_ = 0x7000000F // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed.\n}\n\n// Identify a mouse button.\n// Those values are guaranteed to be stable and we frequently use 0/1 directly. Named enums provided for convenience.\nexport { ImGuiMouseButton as MouseButton };\nexport enum ImGuiMouseButton {\n Left = 0,\n Right = 1,\n Middle = 2,\n COUNT = 5\n}\n\n// Enumeration for GetMouseCursor()\nexport { ImGuiMouseCursor as MouseCursor };\nexport enum ImGuiMouseCursor {\n None = -1,\n Arrow = 0,\n TextInput, // When hovering over InputText, etc.\n ResizeAll, // (Unused by imgui functions)\n ResizeNS, // When hovering over an horizontal border\n ResizeEW, // When hovering over a vertical border or a column\n ResizeNESW, // When hovering over the bottom-left corner of a window\n ResizeNWSE, // When hovering over the bottom-right corner of a window\n Hand, // (Unused by imgui functions. Use for e.g. hyperlinks)\n NotAllowed, // When hovering something with disallowed interaction. Usually a crossed circle.\n COUNT,\n}\n\n// Condition for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions\n// All those functions treat 0 as a shortcut to Always. From the point of view of the user use this as an enum (don't combine multiple values into flags).\nexport { ImGuiCond as Cond };\nexport enum ImGuiCond {\n None = 0, // No condition (always set the variable), same as _Always\n Always = 1 << 0, // Set the variable\n Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed)\n FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file)\n Appearing = 1 << 3, // Set the variable if the window is appearing after being hidden/inactive (or the first time)\n}\n\nexport { ImDrawFlags as DrawFlags };\nexport enum ImDrawFlags\n{\n None = 0,\n Closed = 1 << 0, // PathStroke(), AddPolyline(): specify that shape should be closed (Important: this is always == 1 for legacy reason)\n RoundCornersTopLeft = 1 << 4, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-left corner only (when rounding > 0.0f, we default to all corners). Was 0x01.\n RoundCornersTopRight = 1 << 5, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-right corner only (when rounding > 0.0f, we default to all corners). Was 0x02.\n RoundCornersBottomLeft = 1 << 6, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-left corner only (when rounding > 0.0f, we default to all corners). Was 0x04.\n RoundCornersBottomRight = 1 << 7, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-right corner only (when rounding > 0.0f, we default to all corners). Wax 0x08.\n RoundCornersNone = 1 << 8, // AddRect(), AddRectFilled(), PathRect(): disable rounding on all corners (when rounding > 0.0f). This is NOT zero, NOT an implicit flag!\n RoundCornersTop = RoundCornersTopLeft | RoundCornersTopRight,\n RoundCornersBottom = RoundCornersBottomLeft | RoundCornersBottomRight,\n RoundCornersLeft = RoundCornersBottomLeft | RoundCornersTopLeft,\n RoundCornersRight = RoundCornersBottomRight | RoundCornersTopRight,\n RoundCornersAll = RoundCornersTopLeft | RoundCornersTopRight | RoundCornersBottomLeft | RoundCornersBottomRight,\n RoundCornersDefault_ = RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified.\n RoundCornersMask_ = RoundCornersAll | RoundCornersNone\n}\n\nexport { ImDrawListFlags as wListFlags };\nexport enum ImDrawListFlags\n{\n None = 0,\n AntiAliasedLines = 1 << 0,\n AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering.\n AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles).\n AllowVtxOffset = 1 << 3 // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.\n}\n\nexport { ImU32 as U32 }\nexport type ImU32 = Bind.ImU32;\n\n// export { interface_ImVec2 } from \"../build/bind-imgui\";\n// export { reference_ImVec2 } from \"../build/bind-imgui\";\n\nexport { ImVec2 as Vec2 }\nexport class ImVec2 implements Bind.interface_ImVec2 {\n public static readonly ZERO: Readonly = new ImVec2(0.0, 0.0);\n public static readonly UNIT: Readonly = new ImVec2(1.0, 1.0);\n public static readonly UNIT_X: Readonly = new ImVec2(1.0, 0.0);\n public static readonly UNIT_Y: Readonly = new ImVec2(0.0, 1.0);\n\n constructor(public x: number = 0.0, public y: number = 0.0) {}\n\n public Set(x: number, y: number): this {\n this.x = x;\n this.y = y;\n return this;\n }\n\n public Copy(other: Readonly): this {\n this.x = other.x;\n this.y = other.y;\n return this;\n }\n\n public Equals(other: Readonly): boolean {\n if (this.x !== other.x) { return false; }\n if (this.y !== other.y) { return false; }\n return true;\n }\n}\n\n// export { interface_ImVec4 } from \"../build/bind-imgui\";\n// export { reference_ImVec4 } from \"../build/bind-imgui\";\n\nexport { ImVec4 as Vec4 }\nexport class ImVec4 implements Bind.interface_ImVec4 {\n public static readonly ZERO: Readonly = new ImVec4(0.0, 0.0, 0.0, 0.0);\n public static readonly UNIT: Readonly = new ImVec4(1.0, 1.0, 1.0, 1.0);\n public static readonly UNIT_X: Readonly = new ImVec4(1.0, 0.0, 0.0, 0.0);\n public static readonly UNIT_Y: Readonly = new ImVec4(0.0, 1.0, 0.0, 0.0);\n public static readonly UNIT_Z: Readonly = new ImVec4(0.0, 0.0, 1.0, 0.0);\n public static readonly UNIT_W: Readonly = new ImVec4(0.0, 0.0, 0.0, 1.0);\n public static readonly BLACK: Readonly = new ImVec4(0.0, 0.0, 0.0, 1.0);\n public static readonly WHITE: Readonly = new ImVec4(1.0, 1.0, 1.0, 1.0);\n\n constructor(public x: number = 0.0, public y: number = 0.0, public z: number = 0.0, public w: number = 1.0) {}\n\n public Set(x: number, y: number, z: number, w: number): this {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n return this;\n }\n\n public Copy(other: Readonly): this {\n this.x = other.x;\n this.y = other.y;\n this.z = other.z;\n this.w = other.w;\n return this;\n }\n\n public Equals(other: Readonly): boolean {\n if (this.x !== other.x) { return false; }\n if (this.y !== other.y) { return false; }\n if (this.z !== other.z) { return false; }\n if (this.w !== other.w) { return false; }\n return true;\n }\n}\n\n//-----------------------------------------------------------------------------\n// Helpers\n//-----------------------------------------------------------------------------\n\n// Lightweight std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug).\n// Our implementation does NOT call C++ constructors/destructors. This is intentional and we do not require it. Do not use this class as a straight std::vector replacement in your code!\nexport { ImVector as Vector }\nexport class ImVector extends Array\n{\n public get Size(): number { return this.length; }\n public Data: T[] = this;\n public empty(): boolean { return this.length === 0; }\n public clear(): void { this.length = 0; }\n public pop_back(): T | undefined { return this.pop(); }\n public push_back(value: T): void { this.push(value); }\n public front(): T { IM_ASSERT(this.Size > 0); return this.Data[0]; }\n public back(): T { IM_ASSERT(this.Size > 0); return this.Data[this.Size - 1]; }\n public size(): number { return this.Size; }\n public resize(new_size: number, v?: (index: number) => T): void {\n if (v) {\n for (let index = this.length; index < new_size; ++index) {\n this[index] = v(index);\n }\n }\n else {\n this.length = new_size;\n }\n }\n public contains(value: T): boolean {\n return this.includes(value);\n }\n public find_erase_unsorted(value: T): void {\n const index = this.indexOf(value);\n if (index !== -1) {\n this.splice(index, 1);\n }\n }\n // public:\n // int Size;\n // int Capacity;\n // T* Data;\n\n // typedef T value_type;\n // typedef value_type* iterator;\n // typedef const value_type* const_iterator;\n\n // inline ImVector() { Size = Capacity = 0; Data = NULL; }\n // inline ~ImVector() { if (Data) ImGui::MemFree(Data); }\n\n // inline bool empty() const { return Size == 0; }\n // inline int size() const { return Size; }\n // inline int capacity() const { return Capacity; }\n\n // inline value_type& operator[](int i) { IM_ASSERT(i < Size); return Data[i]; }\n // inline const value_type& operator[](int i) const { IM_ASSERT(i < Size); return Data[i]; }\n\n // inline void clear() { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } }\n // inline iterator begin() { return Data; }\n // inline const_iterator begin() const { return Data; }\n // inline iterator end() { return Data + Size; }\n // inline const_iterator end() const { return Data + Size; }\n // inline value_type& front() { IM_ASSERT(Size > 0); return Data[0]; }\n // inline const value_type& front() const { IM_ASSERT(Size > 0); return Data[0]; }\n // inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; }\n // inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size - 1]; }\n // inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }\n\n // inline int _grow_capacity(int size) const { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > size ? new_capacity : size; }\n\n // inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; }\n // inline void resize(int new_size, const T& v){ if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) Data[n] = v; Size = new_size; }\n // inline void reserve(int new_capacity)\n // {\n // if (new_capacity <= Capacity)\n // return;\n // T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T));\n // if (Data)\n // memcpy(new_data, Data, (size_t)Size * sizeof(T));\n // ImGui::MemFree(Data);\n // Data = new_data;\n // Capacity = new_capacity;\n // }\n\n // inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); Data[Size++] = v; }\n // inline void pop_back() { IM_ASSERT(Size > 0); Size--; }\n // inline void push_front(const value_type& v) { if (Size == 0) push_back(v); else insert(Data, v); }\n\n // inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; }\n // inline iterator erase(const_iterator it, const_iterator it_last){ IM_ASSERT(it >= Data && it < Data+Size && it_last > it && it_last <= Data+Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - count) * sizeof(value_type)); Size -= (int)count; return Data + off; }\n // inline iterator erase_unsorted(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; if (it < Data+Size-1) memcpy(Data + off, Data + Size - 1, sizeof(value_type)); Size--; return Data + off; }\n // inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; }\n // inline bool contains(const value_type& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; }\n}\n\n// Helper: Unicode defines\n// #define IM_UNICODE_CODEPOINT_INVALID 0xFFFD // Invalid Unicode code point (standard value).\n// #ifdef IMGUI_USE_WCHAR32\n// #define IM_UNICODE_CODEPOINT_MAX 0x10FFFF // Maximum Unicode code point supported by this build.\n// #else\n// #define IM_UNICODE_CODEPOINT_MAX 0xFFFF // Maximum Unicode code point supported by this build.\n// #endif\nexport { IM_UNICODE_CODEPOINT_MAX as UNICODE_CODEPOINT_MAX }\nexport const IM_UNICODE_CODEPOINT_MAX: number = 0xFFFF; // Maximum Unicode code point supported by this build.\n\n// Helper: Parse and apply text filters. In format \"aaaaa[,bbbb][,ccccc]\"\nexport { ImGuiTextFilter as TextFilter }\nexport class ImGuiTextFilter\n{\n // IMGUI_API ImGuiTextFilter(const char* default_filter = \"\");\n constructor(default_filter: string = \"\") {\n if (default_filter)\n {\n // ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf));\n this.InputBuf.buffer = default_filter;\n this.Build();\n }\n else\n {\n // InputBuf[0] = 0;\n this.InputBuf.buffer = \"\";\n this.CountGrep = 0;\n }\n }\n // IMGUI_API bool Draw(const char* label = \"Filter (inc,-exc)\", float width = 0.0f); // Helper calling InputText+Build\n public Draw(label: string = \"Filter (inc,-exc)\", width: number = 0.0): boolean {\n if (width !== 0.0)\n bind.PushItemWidth(width);\n const value_changed: boolean = InputText(label, this.InputBuf, IM_ARRAYSIZE(this.InputBuf));\n if (width !== 0.0)\n bind.PopItemWidth();\n if (value_changed)\n this.Build();\n return value_changed;\n }\n // IMGUI_API bool PassFilter(const char* text, const char* text_end = NULL) const;\n public PassFilter(text: string, text_end: number | null = null): boolean {\n // if (Filters.empty())\n // return true;\n\n // if (text == NULL)\n // text = \"\";\n\n // for (int i = 0; i != Filters.Size; i++)\n // {\n // const TextRange& f = Filters[i];\n // if (f.empty())\n // continue;\n // if (f.front() == '-')\n // {\n // // Subtract\n // if (ImStristr(text, text_end, f.begin()+1, f.end()) != NULL)\n // return false;\n // }\n // else\n // {\n // // Grep\n // if (ImStristr(text, text_end, f.begin(), f.end()) != NULL)\n // return true;\n // }\n // }\n\n // Implicit * grep\n if (this.CountGrep === 0)\n return true;\n\n return false;\n }\n // IMGUI_API void Build();\n public Build(): void {\n // Filters.resize(0);\n // TextRange input_range(InputBuf, InputBuf+strlen(InputBuf));\n // input_range.split(',', Filters);\n\n this.CountGrep = 0;\n // for (int i = 0; i != Filters.Size; i++)\n // {\n // Filters[i].trim_blanks();\n // if (Filters[i].empty())\n // continue;\n // if (Filters[i].front() != '-')\n // CountGrep += 1;\n // }\n }\n // void Clear() { InputBuf[0] = 0; Build(); }\n public Clear(): void { this.InputBuf.buffer = \"\"; this.Build(); }\n // bool IsActive() const { return !Filters.empty(); }\n public IsActive(): boolean { return false; }\n\n // [Internal]\n // struct TextRange\n // {\n // const char* b;\n // const char* e;\n\n // TextRange() { b = e = NULL; }\n // TextRange(const char* _b, const char* _e) { b = _b; e = _e; }\n // const char* begin() const { return b; }\n // const char* end() const { return e; }\n // bool empty() const { return b == e; }\n // char front() const { return *b; }\n // static bool is_blank(char c) { return c == ' ' || c == '\\t'; }\n // void trim_blanks() { while (b < e && is_blank(*b)) b++; while (e > b && is_blank(*(e-1))) e--; }\n // IMGUI_API void split(char separator, ImVector& out);\n // };\n\n // char InputBuf[256];\n public InputBuf: ImStringBuffer = new ImStringBuffer(256);\n // ImVector Filters;\n // int CountGrep;\n public CountGrep: number = 0;\n}\n\n// Helper: Text buffer for logging/accumulating text\nexport { ImGuiTextBuffer as TextBuffer }\nexport class ImGuiTextBuffer\n{\n // ImVector Buf;\n public Buf: string = \"\";\n public begin(): string { return this.Buf; }\n public size(): number { return this.Buf.length; }\n public clear(): void { this.Buf = \"\"; }\n public append(text: string): void { this.Buf += text; }\n\n // ImGuiTextBuffer() { Buf.push_back(0); }\n // inline char operator[](int i) { return Buf.Data[i]; }\n // const char* begin() const { return &Buf.front(); }\n // const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator\n // int size() const { return Buf.Size - 1; }\n // bool empty() { return Buf.Size <= 1; }\n // void clear() { Buf.clear(); Buf.push_back(0); }\n // void reserve(int capacity) { Buf.reserve(capacity); }\n // const char* c_str() const { return Buf.Data; }\n // IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2);\n // IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2);\n}\n\n// Helper: Simple Key->value storage\n// Typically you don't have to worry about this since a storage is held within each Window.\n// We use it to e.g. store collapse state for a tree (Int 0/1), store color edit options.\n// This is optimized for efficient reading (dichotomy into a contiguous buffer), rare writing (typically tied to user interactions)\n// You can use it as custom user storage for temporary values. Declare your own storage if, for example:\n// - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state).\n// - You want to store custom debug data easily without adding or editing structures in your code (probably not efficient, but convenient)\n// Types are NOT stored, so it is up to you to make sure your Key don't collide with different types.\nexport class ImGuiStorage\n{\n // struct Pair\n // {\n // ImGuiID key;\n // union { int val_i; float val_f; void* val_p; };\n // Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }\n // Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }\n // Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; }\n // };\n // ImVector Data;\n\n // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N)\n // - Set***() functions find pair, insertion on demand if missing.\n // - Sorted insertion is costly, paid once. A typical frame shouldn't need to insert any new pair.\n // void Clear() { Data.clear(); }\n // IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const;\n // IMGUI_API void SetInt(ImGuiID key, int val);\n // IMGUI_API bool GetBool(ImGuiID key, bool default_val = false) const;\n // IMGUI_API void SetBool(ImGuiID key, bool val);\n // IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const;\n // IMGUI_API void SetFloat(ImGuiID key, float val);\n // IMGUI_API void* GetVoidPtr(ImGuiID key) const; // default_val is NULL\n // IMGUI_API void SetVoidPtr(ImGuiID key, void* val);\n\n // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set.\n // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.\n // - A typical use case where this is convenient for quick hacking (e.g. add storage during a live Edit&Continue session if you can't modify existing struct)\n // float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat(\"var\", pvar, 0, 100.0f); some_var += *pvar;\n // IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0);\n // IMGUI_API bool* GetBoolRef(ImGuiID key, bool default_val = false);\n // IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0.0f);\n // IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL);\n\n // Use on your own storage if you know only integer are being stored (open/close all tree nodes)\n // IMGUI_API void SetAllInt(int val);\n\n // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once.\n // IMGUI_API void BuildSortByKey();\n}\n\n// Data payload for Drag and Drop operations\nexport { ImGuiPayload as Payload }\nexport interface ImGuiPayload\n{\n // Members\n // void* Data; // Data (copied and owned by dear imgui)\n Data: T;\n // int DataSize; // Data size\n\n // [Internal]\n // ImGuiID SourceId; // Source item id\n // ImGuiID SourceParentId; // Source parent id (if available)\n // int DataFrameCount; // Data timestamp\n // char DataType[12 + 1]; // Data type tag (short user-supplied string, 12 characters max)\n // bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets)\n // bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item.\n\n // ImGuiPayload() { Clear(); }\n // void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Preview = Delivery = false; }\n // bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; }\n // bool IsPreview() const { return Preview; }\n // bool IsDelivery() const { return Delivery; }\n}\n\n// Helpers macros to generate 32-bits encoded colors\nexport const IM_COL32_R_SHIFT: number = config.IMGUI_USE_BGRA_PACKED_COLOR ? 16 : 0;\nexport const IM_COL32_G_SHIFT: number = 8;\nexport const IM_COL32_B_SHIFT: number = config.IMGUI_USE_BGRA_PACKED_COLOR ? 0 : 16;\nexport const IM_COL32_A_SHIFT: number = 24;\nexport const IM_COL32_A_MASK: number = 0xFF000000;\nexport { IM_COL32 as COL32 }\nexport function IM_COL32(R: number, G: number, B: number, A: number = 255): number {\n return ((A << IM_COL32_A_SHIFT) | (B << IM_COL32_B_SHIFT) | (G << IM_COL32_G_SHIFT) | (R << IM_COL32_R_SHIFT)) >>> 0;\n}\nexport const IM_COL32_WHITE: number = IM_COL32(255, 255, 255, 255); export { IM_COL32_WHITE as COL32_WHITE } // Opaque white = 0xFFFFFFFF\nexport const IM_COL32_BLACK: number = IM_COL32(0, 0, 0, 255); export { IM_COL32_BLACK as COL32_BLACK } // Opaque black\nexport const IM_COL32_BLACK_TRANS: number = IM_COL32(0, 0, 0, 0); export { IM_COL32_BLACK_TRANS as COL32_BLACK_TRANS } // Transparent black = 0x00000000\n\n// ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)\n// Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API.\n// **Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class. MAY OBSOLETE.\n// **None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats. Explicitly cast to ImU32 or ImVec4 if needed.\nexport { ImColor as Color }\nexport class ImColor\n{\n // ImVec4 Value;\n public Value: ImVec4 = new ImVec4();\n\n // ImColor() { Value.x = Value.y = Value.z = Value.w = 0.0f; }\n // ImColor(int r, int g, int b, int a = 255) { float sc = 1.0f/255.0f; Value.x = (float)r * sc; Value.y = (float)g * sc; Value.z = (float)b * sc; Value.w = (float)a * sc; }\n // ImColor(ImU32 rgba) { float sc = 1.0f/255.0f; Value.x = (float)((rgba>>IM_COL32_R_SHIFT)&0xFF) * sc; Value.y = (float)((rgba>>IM_COL32_G_SHIFT)&0xFF) * sc; Value.z = (float)((rgba>>IM_COL32_B_SHIFT)&0xFF) * sc; Value.w = (float)((rgba>>IM_COL32_A_SHIFT)&0xFF) * sc; }\n // ImColor(float r, float g, float b, float a = 1.0f) { Value.x = r; Value.y = g; Value.z = b; Value.w = a; }\n // ImColor(const ImVec4& col) { Value = col; }\n constructor();\n constructor(r: number, g: number, b: number);\n constructor(r: number, g: number, b: number, a: number);\n constructor(rgba: Bind.ImU32);\n constructor(col: Readonly);\n constructor(r: number | Bind.ImU32 | Readonly = 0.0, g: number = 0.0, b: number = 0.0, a: number = 1.0) {\n if (typeof(r) === \"number\") {\n if (r > 255 && g === 0.0 && b === 0.0 && a === 1.0) {\n this.Value.x = Math.max(0.0, Math.min(1.0, ((r >> IM_COL32_R_SHIFT) & 0xFF) / 255));\n this.Value.y = Math.max(0.0, Math.min(1.0, ((r >> IM_COL32_G_SHIFT) & 0xFF) / 255));\n this.Value.z = Math.max(0.0, Math.min(1.0, ((r >> IM_COL32_B_SHIFT) & 0xFF) / 255));\n this.Value.w = Math.max(0.0, Math.min(1.0, ((r >> IM_COL32_A_SHIFT) & 0xFF) / 255));\n } else if (r <= 1.0 && g <= 1.0 && b <= 1.0 && a <= 1.0) {\n this.Value.x = Math.max(0.0, r);\n this.Value.y = Math.max(0.0, g);\n this.Value.z = Math.max(0.0, b);\n this.Value.w = Math.max(0.0, a);\n } else {\n this.Value.x = Math.max(0.0, Math.min(1.0, r / 255));\n this.Value.y = Math.max(0.0, Math.min(1.0, g / 255));\n this.Value.z = Math.max(0.0, Math.min(1.0, b / 255));\n if (a <= 1.0) {\n this.Value.w = Math.max(0.0, a);\n } else {\n this.Value.w = Math.max(0.0, Math.min(1.0, a / 255));\n }\n }\n } else {\n this.Value.Copy(r);\n }\n }\n // inline operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); }\n public toImU32(): Bind.ImU32 { return ColorConvertFloat4ToU32(this.Value); }\n // inline operator ImVec4() const { return Value; }\n public toImVec4(): ImVec4 { return this.Value; }\n\n // FIXME-OBSOLETE: May need to obsolete/cleanup those helpers.\n // inline void SetHSV(float h, float s, float v, float a = 1.0f){ ImGui::ColorConvertHSVtoRGB(h, s, v, Value.x, Value.y, Value.z); Value.w = a; }\n public SetHSV(h: number, s: number, v: number, a: number = 1.0): void {\n const ref_r: Bind.ImScalar = [ this.Value.x ];\n const ref_g: Bind.ImScalar = [ this.Value.y ];\n const ref_b: Bind.ImScalar = [ this.Value.z ];\n ColorConvertHSVtoRGB(h, s, v, ref_r, ref_g, ref_b);\n this.Value.x = ref_r[0];\n this.Value.y = ref_g[0];\n this.Value.z = ref_b[0];\n this.Value.w = a;\n }\n // static ImColor HSV(float h, float s, float v, float a = 1.0f) { float r,g,b; ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); return ImColor(r,g,b,a); }\n public static HSV(h: number, s: number, v: number, a: number = 1.0): ImColor {\n const color = new ImColor();\n color.SetHSV(h, s, v, a);\n return color;\n }\n}\n\nexport { ImGuiInputTextDefaultSize as InputTextDefaultSize }\nexport const ImGuiInputTextDefaultSize: number = 128;\n\nexport { ImGuiInputTextCallback as InputTextCallback }\nexport type ImGuiInputTextCallback = (data: ImGuiInputTextCallbackData) => number;\n\n// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used and the corresponding callback is triggered.\nexport { ImGuiInputTextCallbackData as InputTextCallbackData }\nexport class ImGuiInputTextCallbackData {\n constructor(public readonly native: Bind.reference_ImGuiInputTextCallbackData, public readonly UserData: T | null = null) {}\n\n // ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only\n public get EventFlag(): ImGuiInputTextFlags { return this.native.EventFlag; }\n // ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only\n public get Flags(): ImGuiInputTextFlags { return this.native.Flags; }\n // void* UserData; // What user passed to InputText() // Read-only\n // public get UserData(): any { return this.native.UserData; }\n\n // CharFilter event:\n // ImWchar EventChar; // Character input // Read-write (replace character or set to zero)\n public get EventChar(): Bind.ImWchar { return this.native.EventChar; }\n public set EventChar(value: Bind.ImWchar) { this.native.EventChar = value; }\n\n // Completion,History,Always events:\n // If you modify the buffer contents make sure you update 'BufTextLen' and set 'BufDirty' to true.\n // ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only\n public get EventKey(): ImGuiKey { return this.native.EventKey; }\n // char* Buf; // Current text buffer // Read-write (pointed data only, can't replace the actual pointer)\n public get Buf(): string { return this.native.Buf; }\n public set Buf(value: string) { this.native.Buf = value; }\n // int BufTextLen; // Current text length in bytes // Read-write\n public get BufTextLen(): number { return this.native.BufTextLen; }\n public set BufTextLen(value: number) { this.native.BufTextLen = value; }\n // int BufSize; // Maximum text length in bytes // Read-only\n public get BufSize(): number { return this.native.BufSize; }\n // bool BufDirty; // Set if you modify Buf/BufTextLen!! // Write\n public set BufDirty(value: boolean) { this.native.BufDirty = value; }\n // int CursorPos; // // Read-write\n public get CursorPos(): number { return this.native.CursorPos; }\n public set CursorPos(value: number) { this.native.CursorPos = value; }\n // int SelectionStart; // // Read-write (== to SelectionEnd when no selection)\n public get SelectionStart(): number { return this.native.SelectionStart; }\n public set SelectionStart(value: number) { this.native.SelectionStart = value; }\n // int SelectionEnd; // // Read-write\n public get SelectionEnd(): number { return this.native.SelectionEnd; }\n public set SelectionEnd(value: number) { this.native.SelectionEnd = value; }\n\n // NB: Helper functions for text manipulation. Calling those function loses selection.\n // IMGUI_API void DeleteChars(int pos, int bytes_count);\n public DeleteChars(pos: number, bytes_count: number): void { return this.native.DeleteChars(pos, bytes_count); }\n // IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL);\n public InsertChars(pos: number, text: string, text_end: number | null = null): void { return this.native.InsertChars(pos, text_end !== null ? text.substring(0, text_end) : text); }\n // void SelectAll() { SelectionStart = 0; SelectionEnd = BufTextLen; }\n public SelectAll(): void { this.native.SelectAll(); }\n // void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; }\n public ClearSelection(): void { this.native.ClearSelection(); }\n // bool HasSelection() const { return SelectionStart != SelectionEnd; }\n public HasSelection(): boolean { return this.native.HasSelection(); }\n}\n\nexport { ImGuiSizeCallback as SizeCallback }\nexport type ImGuiSizeCallback = (data: ImGuiSizeCallbackData) => void;\n\n// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin().\n// NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough.\nexport { ImGuiSizeCallbackData as SizeCallbackData }\nexport class ImGuiSizeCallbackData {\n constructor(public readonly native: Bind.reference_ImGuiSizeCallbackData, public readonly UserData: T) {}\n\n get Pos(): Readonly { return this.native.Pos; }\n get CurrentSize(): Readonly { return this.native.CurrentSize; }\n get DesiredSize(): Bind.interface_ImVec2 { return this.native.DesiredSize; }\n}\n\n// Sorting specification for one column of a table (sizeof == 12 bytes)\nexport { ImGuiTableColumnSortSpecs as TableColumnSortSpecs }\nexport class ImGuiTableColumnSortSpecs\n{\n constructor(public readonly native: Bind.reference_ImGuiTableColumnSortSpecs) {}\n get ColumnUserID(): ImGuiID { return this.native.ColumnUserID; }\n get ColumnIndex(): Bind.ImS16 { return this.native.ColumnIndex; }\n get SortOrder(): Bind.ImS16 { return this.native.SortOrder; }\n get SortDirection(): ImGuiSortDirection { return this.native.SortDirection; }\n}\n\n// Sorting specifications for a table (often handling sort specs for a single column, occasionally more)\n// Obtained by calling TableGetSortSpecs().\n// When 'SpecsDirty == true' you can sort your data. It will be true with sorting specs have changed since last call, or the first time.\n// Make sure to set 'SpecsDirty = false' after sorting, else you may wastefully sort your data every frame!\nexport { ImGuiTableSortSpecs as TableSortSpecs }\nexport class ImGuiTableSortSpecs\n{\n constructor(public readonly native: Bind.reference_ImGuiTableSortSpecs) {\n this._Specs = Array.from({length: this.SpecsCount}).map((_, i) => {\n return new ImGuiTableColumnSortSpecs(this.native.GetSpec(i));\n })\n }\n\n private _Specs: Readonly;\n get Specs(): Readonly { return this._Specs; }\n get SpecsCount(): number { return this.native.SpecsCount; }\n get SpecsDirty(): boolean { return this.native.SpecsDirty; }\n set SpecsDirty(value: boolean) { this.native.SpecsDirty = value; }\n}\n\nexport { ImGuiListClipper as ListClipper }\nexport class ImGuiListClipper\n{\n private _native: Bind.ImGuiListClipper | null = null;\n private get native(): Bind.ImGuiListClipper {\n return this._native || (this._native = new bind.ImGuiListClipper());\n }\n\n public get DisplayStart(): number { return this.native.DisplayStart; }\n public get DisplayEnd(): number { return this.native.DisplayEnd; }\n\n public get ItemsCount(): number { return this.native.ItemsCount; }\n // public get StepNo(): number { return this.native.StepNo; }\n // public get ItemsFrozen(): number { return this.native.ItemsFrozen; }\n public get ItemsHeight(): number { return this.native.ItemsHeight; }\n public get StartPosY(): number { return this.native.StartPosY; }\n\n // items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step).\n // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing().\n // If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step().\n // ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want).\n // ~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false.\n public delete(): void {\n if (this._native !== null) {\n this._native.delete();\n this._native = null;\n }\n }\n\n // IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1.\n public Begin(items_count: number, items_height: number = -1.0): void {\n this.native.Begin(items_count, items_height);\n }\n // IMGUI_API void End(); // Automatically called on the last call of Step() that returns false.\n public End(): void {\n this.native.End();\n this.delete();\n }\n // IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items.\n public Step(): boolean {\n const busy: boolean = this.native.Step();\n if (!busy) {\n this.delete();\n }\n return busy;\n }\n}\n\n//-----------------------------------------------------------------------------\n// Draw List\n// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.\n//-----------------------------------------------------------------------------\n\n// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking.\nexport const IM_DRAWLIST_TEX_LINES_WIDTH_MAX: number = 63;\n\n// Draw callbacks for advanced uses.\n// NB- You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering (you can poke into the draw list for that)\n// Draw callback may be useful for example, A) Change your GPU render state, B) render a complex 3D scene inside a UI element (without an intermediate texture/render target), etc.\n// The expected behavior from your rendering function is 'if (cmd.UserCallback != NULL) cmd.UserCallback(parent_list, cmd); else RenderTriangles()'\n// typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd);\nexport type ImDrawCallback = (parent_list: Readonly, cmd: Readonly) => void;\n\n// Special Draw callback value to request renderer back-end to reset the graphics/render state.\n// The renderer back-end needs to handle this special value, otherwise it will crash trying to call a function at this address.\n// This is useful for example if you submitted callbacks which you know have altered the render state and you want it to be restored.\n// It is not done by default because they are many perfectly useful way of altering render state for imgui contents (e.g. changing shader/blending settings before an Image call).\nexport const ImDrawCallback_ResetRenderState = -1;\n\n// Typically, 1 command = 1 GPU draw call (unless command is a callback)\n// Pre 1.71 back-ends will typically ignore the VtxOffset/IdxOffset fields. When 'io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset'\n// is enabled, those fields allow us to render meshes larger than 64K vertices while keeping 16-bits indices.\nexport { ImDrawCmd as DrawCmd }\nexport class ImDrawCmd\n{\n constructor(public readonly native: Bind.reference_ImDrawCmd) {}\n\n // unsigned int ElemCount; // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[].\n get ElemCount(): number { return this.native.ElemCount; }\n // ImVec4 ClipRect; // Clipping rectangle (x1, y1, x2, y2)\n get ClipRect(): Readonly { return this.native.ClipRect; }\n // ImTextureID TextureId; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas.\n get TextureId(): ImTextureID | null {\n return ImGuiContext.getTexture(this.native.TextureId);\n }\n // unsigned int VtxOffset; // Start offset in vertex buffer. Pre-1.71 or without ImGuiBackendFlags_RendererHasVtxOffset: always 0. With ImGuiBackendFlags_RendererHasVtxOffset: may be >0 to support meshes larger than 64K vertices with 16-bits indices.\n get VtxOffset(): number { return this.native.VtxOffset; }\n // unsigned int IdxOffset; // Start offset in index buffer. Always equal to sum of ElemCount drawn so far.\n get IdxOffset(): number { return this.native.IdxOffset; }\n // ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.\n public readonly UserCallback: ImDrawCallback | null = null; // TODO\n // void* UserCallbackData; // The draw callback code can access this.\n public readonly UserCallbackData: any = null; // TODO\n\n // ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = ClipRect.z = ClipRect.w = 0.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; }\n}\n\n// Vertex index\n// (to allow large meshes with 16-bits indices: set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset in the renderer back-end)\n// (to use 32-bits indices: override with '#define ImDrawIdx unsigned int' in imconfig.h)\n// #ifndef ImDrawIdx\n// typedef unsigned short ImDrawIdx;\n// #endif\nexport { ImDrawIdxSize as DrawIdxSize }\nexport const ImDrawIdxSize: number = 2; // bind.ImDrawIdxSize;\nexport { ImDrawIdx as DrawIdx }\nexport type ImDrawIdx = number;\n\n// Vertex layout\n// #ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT\nexport { ImDrawVertSize as DrawVertSize }\nexport const ImDrawVertSize: number = 20; // bind.ImDrawVertSize;\nexport { ImDrawVertPosOffset as DrawVertPosOffset }\nexport const ImDrawVertPosOffset: number = 0; // bind.ImDrawVertPosOffset;\nexport { ImDrawVertUVOffset as DrawVertUVOffset }\nexport const ImDrawVertUVOffset: number = 8; // bind.ImDrawVertUVOffset;\nexport { ImDrawVertColOffset as DrawVertColOffset }\nexport const ImDrawVertColOffset: number = 16; // bind.ImDrawVertColOffset;\nexport { ImDrawVert as DrawVert }\nexport class ImDrawVert\n{\n // ImVec2 pos;\n public pos: Float32Array;\n // ImVec2 uv;\n public uv: Float32Array;\n // ImU32 col;\n public col: Uint32Array;\n\n constructor(buffer: ArrayBuffer, byteOffset: number = 0) {\n this.pos = new Float32Array(buffer, byteOffset + bind.ImDrawVertPosOffset, 2);\n this.uv = new Float32Array(buffer, byteOffset + bind.ImDrawVertUVOffset, 2);\n this.col = new Uint32Array(buffer, byteOffset + bind.ImDrawVertColOffset, 1);\n }\n}\n// #else\n// You can override the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h\n// The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine.\n// The type has to be described within the macro (you can either declare the struct or use a typedef)\n// NOTE: IMGUI DOESN'T CLEAR THE STRUCTURE AND DOESN'T CALL A CONSTRUCTOR SO ANY CUSTOM FIELD WILL BE UNINITIALIZED. IF YOU ADD EXTRA FIELDS (SUCH AS A 'Z' COORDINATES) YOU WILL NEED TO CLEAR THEM DURING RENDER OR TO IGNORE THEM.\n// IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT;\n// #endif\n\n// [Internal] For use by ImDrawList\nexport class ImDrawCmdHeader\n{\n // ImVec4 ClipRect;\n // ImTextureID TextureId;\n // unsigned int VtxOffset;\n}\n\n// Draw channels are used by the Columns API to \"split\" the render list into different channels while building, so items of each column can be batched together.\n// You can also use them to simulate drawing layers and submit primitives in a different order than how they will be rendered.\nexport class ImDrawChannel\n{\n // ImVector CmdBuffer;\n // ImVector IdxBuffer;\n}\n\nexport class ImDrawListSharedData\n{\n constructor(public readonly native: Bind.reference_ImDrawListSharedData) {}\n}\n\n// Draw command list\n// This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering.\n// Each ImGui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to access the current window draw list and draw custom primitives.\n// You can interleave normal ImGui:: calls and adding primitives to the current draw list.\n// All positions are generally in pixel coordinates (top-left at (0,0), bottom-right at io.DisplaySize), however you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well)\n// Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects.\nexport { ImDrawList as DrawList }\nexport class ImDrawList\n{\n constructor(public readonly native: Bind.reference_ImDrawList) {}\n\n public IterateDrawCmds(callback: (draw_cmd: ImDrawCmd, ElemStart: number) => void): void {\n this.native.IterateDrawCmds((draw_cmd: Bind.reference_ImDrawCmd, ElemStart: number): void => {\n callback(new ImDrawCmd(draw_cmd), ElemStart);\n });\n }\n\n // This is what you have to render\n // ImVector CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback.\n // ImVector IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those\n get IdxBuffer(): Uint8Array { return this.native.IdxBuffer; }\n // ImVector VtxBuffer; // Vertex buffer.\n get VtxBuffer(): Uint8Array { return this.native.VtxBuffer; }\n // ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive.\n get Flags(): ImDrawListFlags { return this.native.Flags; }\n set Flags(value: ImDrawListFlags) { this.native.Flags = value; }\n\n // [Internal, used while building lists]\n // unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size\n // const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context)\n // const char* _OwnerName; // Pointer to owner window's name for debugging\n // ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)\n // ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)\n // ImVector _ClipRectStack; // [Internal]\n // ImVector _TextureIdStack; // [Internal]\n // ImVector _Path; // [Internal] current path building\n // int _ChannelsCurrent; // [Internal] current channel number (0)\n // int _ChannelsCount; // [Internal] number of active channels (1+)\n // ImVector _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size)\n\n // ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); }\n // ~ImDrawList() { ClearFreeMemory(); }\n // IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)\n public PushClipRect(clip_rect_min: Readonly, clip_rect_max: Readonly, intersect_with_current_clip_rect: boolean = false): void {\n this.native.PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect);\n }\n // IMGUI_API void PushClipRectFullScreen();\n public PushClipRectFullScreen(): void { this.native.PushClipRectFullScreen(); }\n // IMGUI_API void PopClipRect();\n public PopClipRect(): void { this.native.PopClipRect(); }\n // IMGUI_API void PushTextureID(ImTextureID texture_id);\n public PushTextureID(texture_id: ImTextureID): void {\n this.native.PushTextureID(ImGuiContext.setTexture(texture_id));\n }\n // IMGUI_API void PopTextureID();\n public PopTextureID(): void { this.native.PopTextureID(); }\n // inline ImVec2 GetClipRectMin() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.x, cr.y); }\n public GetClipRectMin(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 {\n return this.native.GetClipRectMin(out);\n }\n // inline ImVec2 GetClipRectMax() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.z, cr.w); }\n public GetClipRectMax(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 {\n return this.native.GetClipRectMax(out);\n }\n\n // Primitives\n // IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f);\n public AddLine(a: Readonly, b: Readonly, col: Bind.ImU32, thickness: number = 1.0): void {\n this.native.AddLine(a, b, col, thickness);\n }\n // IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int flags = ImDrawFlags_None, float thickness = 1.0f); // a: upper-left, b: lower-right, flags: 4-bits corresponding to which corner to round\n public AddRect(a: Readonly, b: Readonly, col: Bind.ImU32, rounding: number = 0.0, flags: ImDrawFlags = ImDrawFlags.None, thickness: number = 1.0): void {\n this.native.AddRect(a, b, col, rounding, flags, thickness);\n }\n // IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int flags = ImDrawFlags_None); // a: upper-left, b: lower-right\n public AddRectFilled(a: Readonly, b: Readonly, col: Bind.ImU32, rounding: number = 0.0, flags: ImDrawFlags = ImDrawFlags.None): void {\n this.native.AddRectFilled(a, b, col, rounding, flags);\n }\n // IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);\n public AddRectFilledMultiColor(a: Readonly, b: Readonly, col_upr_left: Bind.ImU32, col_upr_right: Bind.ImU32, col_bot_right: Bind.ImU32, col_bot_left: Bind.ImU32): void {\n this.native.AddRectFilledMultiColor(a, b, col_upr_left, col_upr_right, col_bot_right, col_bot_left);\n }\n // IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f);\n public AddQuad(a: Readonly, b: Readonly, c: Readonly, d: Readonly, col: Bind.ImU32, thickness: number = 1.0): void {\n this.native.AddQuad(a, b, c, d, col, thickness);\n }\n // IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col);\n public AddQuadFilled(a: Readonly, b: Readonly, c: Readonly, d: Readonly, col: Bind.ImU32): void {\n this.native.AddQuadFilled(a, b, c, d, col);\n }\n // IMGUI_API void AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness = 1.0f);\n public AddTriangle(a: Readonly, b: Readonly, c: Readonly, col: Bind.ImU32, thickness: number = 1.0): void {\n this.native.AddTriangle(a, b, c, col, thickness);\n }\n // IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);\n public AddTriangleFilled(a: Readonly, b: Readonly, c: Readonly, col: Bind.ImU32): void {\n this.native.AddTriangleFilled(a, b, c, col);\n }\n // IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f);\n public AddCircle(centre: Readonly, radius: number, col: Bind.ImU32, num_segments: number = 12, thickness: number = 1.0): void {\n this.native.AddCircle(centre, radius, col, num_segments, thickness);\n }\n // IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);\n public AddCircleFilled(centre: Readonly, radius: number, col: Bind.ImU32, num_segments: number = 12): void {\n this.native.AddCircleFilled(centre, radius, col, num_segments);\n }\n // IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);\n public AddNgon(centre: Readonly, radius: number, col: Bind.ImU32, num_segments: number, thickness: number = 1.0): void {\n this.native.AddNgon(centre, radius, col, num_segments, thickness);\n }\n // IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);\n public AddNgonFilled(centre: Readonly, radius: number, col: Bind.ImU32, num_segments: number): void {\n this.native.AddNgonFilled(centre, radius, col, num_segments);\n }\n // IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);\n // IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);\n public AddText(pos: Readonly, col: Bind.ImU32, text_begin: string, text_end?: number | null): void;\n public AddText(font: ImFont, font_size: number, pos: Readonly, col: Bind.ImU32, text_begin: string, text_end?: number | null, wrap_width?: number, cpu_fine_clip_rect?: Readonly | null): void;\n public AddText(...args: any[]): void {\n if (args[0] instanceof ImFont) {\n const font: ImFont = args[0];\n const font_size: number = args[1];\n const pos: Readonly = args[2];\n const col: Bind.ImU32 = args[3];\n const text_begin: string = args[4];\n const text_end: number | null = args[5] || null;\n const wrap_width: number = args[6] = 0.0;\n const cpu_fine_clip_rect: Readonly | null = args[7] || null;\n this.native.AddText_B(font.native, font_size, pos, col, text_end !== null ? text_begin.substring(0, text_end) : text_begin, wrap_width, cpu_fine_clip_rect);\n } else {\n const pos: Readonly = args[0];\n const col: Bind.ImU32 = args[1];\n const text_begin: string = args[2];\n const text_end: number | null = args[3] || null;\n this.native.AddText_A(pos, col, text_end !== null ? text_begin.substring(0, text_end) : text_begin);\n }\n }\n // IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, ImDrawFlags flags, float thickness);\n public AddPolyline(points: Array>, num_points: number, col: Bind.ImU32, flags: ImDrawFlags, thickness: number): void {\n this.native.AddPolyline(points, num_points, col, flags, thickness);\n }\n // IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col);\n public AddConvexPolyFilled(points: Array>, num_points: number, col: Bind.ImU32): void {\n this.native.AddConvexPolyFilled(points, num_points, col);\n }\n // IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)\n public AddBezierCubic(p1: Readonly, p2: Readonly, p3: Readonly, p4: Readonly, col: Bind.ImU32, thickness: number = 1.0, num_segments: number = 0): void {\n this.native.AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments);\n }\n // IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points)\n public AddBezierQuadratic(p1: Readonly, p2: Readonly, p3: Readonly, col: Bind.ImU32, thickness: number = 1.0, num_segments: number = 0): void {\n this.native.AddBezierQuadratic(p1, p2, p3, col, thickness, num_segments);\n }\n\n // IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF);\n public AddImage(user_texture_id: ImTextureID | null, a: Readonly, b: Readonly, uv_a: Readonly = ImVec2.ZERO, uv_b: Readonly = ImVec2.UNIT, col: Bind.ImU32 = 0xFFFFFFFF): void {\n this.native.AddImage(ImGuiContext.setTexture(user_texture_id), a, b, uv_a, uv_b, col);\n }\n // IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF);\n public AddImageQuad(user_texture_id: ImTextureID | null, a: Readonly, b: Readonly, c: Readonly, d: Readonly, uv_a: Readonly = ImVec2.ZERO, uv_b: Readonly = ImVec2.UNIT_X, uv_c: Readonly = ImVec2.UNIT, uv_d: Readonly = ImVec2.UNIT_Y, col: Bind.ImU32 = 0xFFFFFFFF): void {\n this.native.AddImageQuad(ImGuiContext.setTexture(user_texture_id), a, b, c, d, uv_a, uv_b, uv_c, uv_d, col);\n }\n // IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawFlags_None);\n public AddImageRounded(user_texture_id: ImTextureID | null, a: Readonly, b: Readonly, uv_a: Readonly, uv_b: Readonly, col: Bind.ImU32, rounding: number, flags: ImDrawFlags = ImDrawFlags.None): void {\n this.native.AddImageRounded(ImGuiContext.setTexture(user_texture_id), a, b, uv_a, uv_b, col, rounding, flags);\n }\n \n // Stateful path API, add points then finish with PathFill() or PathStroke()\n // inline void PathClear() { _Path.resize(0); }\n public PathClear(): void { this.native.PathClear(); }\n // inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); }\n public PathLineTo(pos: Readonly): void { this.native.PathLineTo(pos); }\n // inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); }\n public PathLineToMergeDuplicate(pos: Readonly): void { this.native.PathLineToMergeDuplicate(pos); }\n // inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); }\n public PathFillConvex(col: Bind.ImU32): void { this.native.PathFillConvex(col); }\n // inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); PathClear(); }\n public PathStroke(col: Bind.ImU32, flags: ImDrawFlags, thickness: number = 1.0): void { this.native.PathStroke(col, flags, thickness); }\n // IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);\n public PathArcTo(centre: Readonly, radius: number, a_min: number, a_max: number, num_segments: number = 0): void { this.native.PathArcTo(centre, radius, a_min, a_max, num_segments); }\n // IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle\n public PathArcToFast(centre: Readonly, radius: number, a_min_of_12: number, a_max_of_12: number): void { this.native.PathArcToFast(centre, radius, a_min_of_12, a_max_of_12); }\n // IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points)\n public PathBezierCubicCurveTo(p2: Readonly, p3: Readonly, p4: Readonly, num_segments: number = 0): void { this.native.PathBezierCubicCurveTo(p2, p3, p4, num_segments); }\n // IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)\n public PathBezierQuadraticCurveTo(p2: Readonly, p3: Readonly, num_segments: number = 0): void { this.native.PathBezierQuadraticCurveTo(p2, p3, num_segments); }\n // IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int flags = ImDrawFlags_None);\n public PathRect(rect_min: Readonly, rect_max: Readonly, rounding: number = 0.0, flags: ImDrawFlags = ImDrawFlags.None): void { this.native.PathRect(rect_min, rect_max, rounding, flags); }\n\n // Channels\n // - Use to simulate layers. By switching channels to can render out-of-order (e.g. submit foreground primitives before background primitives)\n // - Use to minimize draw calls (e.g. if going back-and-forth between multiple non-overlapping clipping rectangles, prefer to append into separate channels then merge at the end)\n // IMGUI_API void ChannelsSplit(int channels_count);\n public ChannelsSplit(channels_count: number): void { this.native.ChannelsSplit(channels_count); }\n // IMGUI_API void ChannelsMerge();\n public ChannelsMerge(): void { this.native.ChannelsMerge(); }\n // IMGUI_API void ChannelsSetCurrent(int channel_index);\n public ChannelsSetCurrent(channel_index: number): void { this.native.ChannelsSetCurrent(channel_index); }\n\n // Advanced\n // IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles.\n public AddCallback(callback: ImDrawCallback, callback_data: any): void {\n const _callback: Bind.ImDrawCallback = (parent_list: Readonly, draw_cmd: Readonly): void => {\n callback(new ImDrawList(parent_list), new ImDrawCmd(draw_cmd));\n };\n this.native.AddCallback(_callback, callback_data);\n }\n // IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible\n public AddDrawCmd(): void { this.native.AddDrawCmd(); }\n\n // Internal helpers\n // NB: all primitives needs to be reserved via PrimReserve() beforehand!\n // IMGUI_API void PrimReserve(int idx_count, int vtx_count);\n public PrimReserve(idx_count: number, vtx_count: number): void { this.native.PrimReserve(idx_count, vtx_count); }\n // IMGUI_API void PrimUnreserve(int idx_count, int vtx_count);\n public PrimUnreserve(idx_count: number, vtx_count: number): void { this.native.PrimUnreserve(idx_count, vtx_count); }\n // IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles)\n public PrimRect(a: Readonly, b: Readonly, col: Bind.ImU32): void { this.native.PrimRect(a, b, col); }\n // IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col);\n public PrimRectUV(a: Readonly, b: Readonly, uv_a: Readonly, uv_b: Readonly, col: Bind.ImU32): void { this.native.PrimRectUV(a, b, uv_a, uv_b, col); }\n // IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col);\n public PrimQuadUV(a: Readonly, b: Readonly, c: Readonly, d: Readonly, uv_a: Readonly, uv_b: Readonly, uv_c: Readonly, uv_d: Readonly, col: Bind.ImU32): void { this.native.PrimQuadUV(a, b, c, d, uv_a, uv_b, uv_c, uv_d, col); }\n // inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col){ _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; }\n public PrimWriteVtx(pos: Readonly, uv: Readonly, col: Bind.ImU32): void { this.native.PrimWriteVtx(pos, uv, col); }\n // inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; }\n public PrimWriteIdx(idx: ImDrawIdx): void { this.native.PrimWriteIdx(idx); }\n // inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); }\n public PrimVtx(pos: Readonly, uv: Readonly, col: Bind.ImU32): void { this.native.PrimVtx(pos, uv, col); }\n\n // IMGUI_API int _CalcCircleAutoSegmentCount(float radius) const;\n public _CalcCircleAutoSegmentCount(radius: number): number { return this.native._CalcCircleAutoSegmentCount(radius); }\n}\n\n// All draw data to render an ImGui frame\nexport { ImDrawData as DrawData }\nexport class ImDrawData\n{\n constructor(public readonly native: Bind.reference_ImDrawData) {}\n\n public IterateDrawLists(callback: (draw_list: ImDrawList) => void): void {\n this.native.IterateDrawLists((draw_list: Bind.reference_ImDrawList): void => {\n callback(new ImDrawList(draw_list));\n });\n }\n\n // bool Valid; // Only valid after Render() is called and before the next NewFrame() is called.\n get Valid(): boolean { return this.native.Valid; }\n // ImDrawList** CmdLists;\n // int CmdListsCount;\n get CmdListsCount(): number { return this.native.CmdListsCount; }\n // int TotalIdxCount; // For convenience, sum of all cmd_lists idx_buffer.Size\n get TotalIdxCount(): number { return this.native.TotalIdxCount; }\n // int TotalVtxCount; // For convenience, sum of all cmd_lists vtx_buffer.Size\n get TotalVtxCount(): number { return this.native.TotalVtxCount; }\n // ImVec2 DisplayPos; // Upper-left position of the viewport to render (== upper-left of the orthogonal projection matrix to use)\n get DisplayPos(): Readonly { return this.native.DisplayPos; }\n // ImVec2 DisplaySize; // Size of the viewport to render (== io.DisplaySize for the main viewport) (DisplayPos + DisplaySize == lower-right of the orthogonal projection matrix to use)\n get DisplaySize(): Readonly { return this.native.DisplaySize; }\n // ImVec2 FramebufferScale; // Amount of pixels for each unit of DisplaySize. Based on io.DisplayFramebufferScale. Generally (1,1) on normal display, (2,2) on OSX with Retina display.\n get FramebufferScale(): Readonly { return this.native.FramebufferScale; }\n\n // Functions\n // ImDrawData() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; }\n // IMGUI_API void DeIndexAllBuffers(); // For backward compatibility or convenience: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!\n public DeIndexAllBuffers(): void { this.native.DeIndexAllBuffers(); }\n // IMGUI_API void ScaleClipRects(const ImVec2& fb_scale); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution.\n public ScaleClipRects(fb_scale: Readonly): void {\n this.native.ScaleClipRects(fb_scale);\n }\n}\n\nexport class script_ImFontConfig implements Bind.interface_ImFontConfig\n{\n // void* FontData; // // TTF/OTF data\n // int FontDataSize; // // TTF/OTF data size\n FontData: DataView | null = null;\n // bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).\n FontDataOwnedByAtlas: boolean = true;\n // int FontNo; // 0 // Index of font within TTF/OTF file\n FontNo: number = 0;\n // float SizePixels; // // Size in pixels for rasterizer.\n SizePixels: number = 0;\n // int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.\n OversampleH: number = 3;\n OversampleV: number = 1;\n // bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.\n PixelSnapH: boolean = false;\n // ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.\n GlyphExtraSpacing: ImVec2 = new ImVec2(0, 0);\n // ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.\n GlyphOffset: ImVec2 = new ImVec2(0, 0);\n // const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE.\n GlyphRanges: number | null = null;\n // float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font\n GlyphMinAdvanceX: number = 0;\n // float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs\n GlyphMaxAdvanceX: number = Number.MAX_VALUE;\n // bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.\n MergeMode: boolean = false;\n // unsigned int FontBuilderFlags; // 0x00 // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one.\n FontBuilderFlags: number = 0;\n // float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable.\n RasterizerMultiply: number = 1.0;\n // ImWchar EllipsisChar; // -1 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.\n EllipsisChar: number = -1;\n DotChar: number = -1;\n\n // [Internal]\n // char Name[32]; // Name (strictly to ease debugging)\n Name: string = \"\";\n // ImFont* DstFont;\n DstFont: Bind.reference_ImFont | null = null;\n\n // IMGUI_API ImFontConfig();\n}\n\nexport { ImFontConfig as FontConfig }\nexport class ImFontConfig {\n constructor(public readonly internal: Bind.interface_ImFontConfig = new script_ImFontConfig()) {}\n\n // void* FontData; // // TTF/OTF data\n // int FontDataSize; // // TTF/OTF data size\n get FontData(): DataView | null { return this.internal.FontData; }\n // bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).\n get FontDataOwnedByAtlas(): boolean { return this.internal.FontDataOwnedByAtlas; }\n // int FontNo; // 0 // Index of font within TTF/OTF file\n get FontNo(): number { return this.internal.FontNo; }\n // float SizePixels; // // Size in pixels for rasterizer.\n get SizePixels(): number { return this.internal.SizePixels; }\n // int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.\n get OversampleH(): number { return this.internal.OversampleH; }\n get OversampleV(): number { return this.internal.OversampleV; }\n // bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.\n get PixelSnapH(): boolean { return this.internal.PixelSnapH; }\n // ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.\n get GlyphExtraSpacing(): ImVec2 { return this.internal.GlyphExtraSpacing; }\n // ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.\n get GlyphOffset(): ImVec2 { return this.internal.GlyphOffset; }\n // const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE.\n get GlyphRanges(): number | null { return this.internal.GlyphRanges; }\n // float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font\n get GlyphMinAdvanceX(): number { return this.internal.GlyphMinAdvanceX; }\n // float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs\n get GlyphMaxAdvanceX(): number { return this.internal.GlyphMaxAdvanceX; }\n // bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.\n get MergeMode(): boolean { return this.internal.MergeMode; }\n // unsigned int FontBuilderFlags; // 0x00 // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one.\n get FontBuilderFlags(): number { return this.internal.FontBuilderFlags; }\n // float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable.\n get RasterizerMultiply(): number { return this.internal.RasterizerMultiply; }\n\n // [Internal]\n // char Name[32]; // Name (strictly to ease debugging)\n get Name(): string { return this.internal.Name; }\n set Name(value: string) { this.internal.Name = value; }\n // ImFont* DstFont;\n get DstFont(): ImFont | null {\n const font = this.internal.DstFont;\n return font && new ImFont(font);\n }\n\n // IMGUI_API ImFontConfig();\n}\n\n// struct ImFontGlyph\nexport class script_ImFontGlyph implements Bind.interface_ImFontGlyph\n{\n // unsigned int Colored : 1; // Flag to indicate glyph is colored and should generally ignore tinting (make it usable with no shift on little-endian as this is used in loops)\n Colored: boolean = false;\n // unsigned int Visible : 1; // Flag to indicate glyph has no visible pixels (e.g. space). Allow early out when rendering.\n Visible: boolean = false;\n // unsigned int Codepoint : 30; // 0x0000..0x10FFFF\n Codepoint: number = 0;\n // float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in)\n AdvanceX: number = 0.0;\n // float X0, Y0, X1, Y1; // Glyph corners\n X0: number = 0.0;\n Y0: number = 0.0;\n X1: number = 1.0;\n Y1: number = 1.0;\n // float U0, V0, U1, V1; // Texture coordinates\n U0: number = 0.0;\n V0: number = 0.0;\n U1: number = 1.0;\n V1: number = 1.0;\n}\n\nexport { ImFontGlyph as FontGlyph }\nexport class ImFontGlyph implements Bind.interface_ImFontGlyph {\n constructor(public readonly internal: Bind.interface_ImFontGlyph = new script_ImFontGlyph()) {}\n // unsigned int Colored : 1;\n get Colored(): boolean { return this.internal.Visible; }\n // unsigned int Visible : 1; // Flag to allow early out when rendering\n get Visible(): boolean { return this.internal.Visible; }\n // unsigned int Codepoint : 31; // 0x0000..0xFFFF\n get Codepoint(): number { return this.internal.Codepoint; }\n // float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in)\n get AdvanceX(): number { return this.internal.AdvanceX; };\n // float X0, Y0, X1, Y1; // Glyph corners\n get X0(): number { return this.internal.X0; };\n get Y0(): number { return this.internal.Y0; };\n get X1(): number { return this.internal.X1; };\n get Y1(): number { return this.internal.Y1; };\n // float U0, V0, U1, V1; // Texture coordinates\n get U0(): number { return this.internal.U0; };\n get V0(): number { return this.internal.V0; };\n get U1(): number { return this.internal.U1; };\n get V1(): number { return this.internal.V1; };\n}\n\n// See ImFontAtlas::AddCustomRectXXX functions.\nexport class ImFontAtlasCustomRect\n{\n // unsigned short Width, Height; // Input // Desired rectangle dimension\n // unsigned short X, Y; // Output // Packed position in Atlas\n // unsigned int GlyphID; // Input // For custom font glyphs only (ID < 0x110000)\n // float GlyphAdvanceX; // Input // For custom font glyphs only: glyph xadvance\n // ImVec2 GlyphOffset; // Input // For custom font glyphs only: glyph display offset\n // ImFont* Font; // Input // For custom font glyphs only: target font\n // ImFontAtlasCustomRect() { Width = Height = 0; X = Y = 0xFFFF; GlyphID = 0; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0, 0); Font = NULL; }\n // bool IsPacked() const { return X != 0xFFFF; }\n}\n\nexport { ImFontAtlasFlags as FontAtlasFlags }\nexport enum ImFontAtlasFlags\n{\n None = 0,\n NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two\n NoMouseCursors = 1 << 1, // Don't build software mouse cursors into the atlas\n NoBakedLines = 1 << 2, // Don't build thick line textures into the atlas (save a little texture memory). The AntiAliasedLinesUseTex features uses them, otherwise they will be rendered using polygons (more expensive for CPU/GPU).\n}\n\n// Load and rasterize multiple TTF/OTF fonts into a same texture.\n// Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering.\n// We also add custom graphic data into the texture that serves for ImGui.\n// 1. (Optional) Call AddFont*** functions. If you don't call any, the default font will be loaded for you.\n// 2. Call GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data.\n// 3. Upload the pixels data into a texture within your graphics system.\n// 4. Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture. This value will be passed back to you during rendering to identify the texture.\n// IMPORTANT: If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persist up until the ImFont is build (when calling GetTextData*** or Build()). We only copy the pointer, not the data.\nexport { ImFontAtlas as FontAtlas }\nexport class ImFontAtlas\n{\n constructor(public readonly native: Bind.reference_ImFontAtlas) {}\n\n // IMGUI_API ImFontAtlas();\n // IMGUI_API ~ImFontAtlas();\n // IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg);\n // IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL);\n public AddFontDefault(font_cfg: Bind.interface_ImFontConfig | null = null): ImFont {\n return new ImFont(this.native.AddFontDefault(font_cfg));\n }\n // IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL);\n // IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after Build(). Set font_cfg->FontDataOwnedByAtlas to false to keep ownership.\n public AddFontFromMemoryTTF(data: ArrayBuffer, size_pixels: number, font_cfg: ImFontConfig | null = null, glyph_ranges: number | null = null): ImFont {\n return new ImFont(this.native.AddFontFromMemoryTTF(new Uint8Array(data), size_pixels, font_cfg && font_cfg.internal, glyph_ranges));\n }\n // IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp.\n // IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter.\n // IMGUI_API void ClearTexData(); // Clear the CPU-side texture data. Saves RAM once the texture has been copied to graphics memory.\n public ClearTexData(): void { this.native.ClearTexData(); }\n // IMGUI_API void ClearInputData(); // Clear the input TTF data (inc sizes, glyph ranges)\n public ClearInputData(): void { this.native.ClearInputData(); }\n // IMGUI_API void ClearFonts(); // Clear the ImGui-side font data (glyphs storage, UV coordinates)\n public ClearFonts(): void { this.native.ClearFonts(); }\n // IMGUI_API void Clear(); // Clear all\n public Clear(): void { this.native.Clear(); }\n\n // Build atlas, retrieve pixel data.\n // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID().\n // RGBA32 format is provided for convenience and compatibility, but note that unless you use CustomRect to draw color data, the RGB pixels emitted from Fonts will all be white (~75% of waste).\n // Pitch = Width * BytesPerPixels\n // IMGUI_API bool Build(); // Build pixels data. This is called automatically for you by the GetTexData*** functions.\n public Build(): boolean { return this.native.Build(); }\n // IMGUI_API bool IsBuilt() { return Fonts.Size > 0 && (TexPixelsAlpha8 != NULL || TexPixelsRGBA32 != NULL); }\n public IsBuilt(): boolean { return this.native.IsBuilt(); }\n // IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel\n public GetTexDataAsAlpha8(): { pixels: Uint8ClampedArray, width: number, height: number, bytes_per_pixel: number } {\n return this.native.GetTexDataAsAlpha8();\n }\n // IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel\n public GetTexDataAsRGBA32(): { pixels: Uint8ClampedArray, width: number, height: number, bytes_per_pixel: number } {\n return this.native.GetTexDataAsRGBA32();\n }\n // void SetTexID(ImTextureID id) { TexID = id; }\n public SetTexID(id: ImTextureID | null): void { this.TexID = id; }\n\n //-------------------------------------------\n // Glyph Ranges\n //-------------------------------------------\n\n // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list)\n // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create UTF-8 string literal using the u8\"Hello world\" syntax. See FAQ for details.\n // IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin\n GetGlyphRangesDefault(): number { return this.native.GetGlyphRangesDefault(); }\n // IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters\n GetGlyphRangesKorean(): number { return this.native.GetGlyphRangesKorean(); }\n // IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs\n GetGlyphRangesJapanese(): number { return this.native.GetGlyphRangesJapanese(); }\n // IMGUI_API const ImWchar* GetGlyphRangesChineseFull(); // Default + Half-Width + Japanese Hiragana/Katakana + full set of about 21000 CJK Unified Ideographs\n GetGlyphRangesChineseFull(): number { return this.native.GetGlyphRangesChineseFull(); }\n // IMGUI_API const ImWchar* GetGlyphRangesChineseSimplifiedCommon();// Default + Half-Width + Japanese Hiragana/Katakana + set of 2500 CJK Unified Ideographs for common simplified Chinese\n GetGlyphRangesChineseSimplifiedCommon(): number { return this.native.GetGlyphRangesChineseSimplifiedCommon(); }\n // IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters\n GetGlyphRangesCyrillic(): number { return this.native.GetGlyphRangesCyrillic(); }\n // IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters\n GetGlyphRangesThai(): number { return this.native.GetGlyphRangesThai(); }\n // IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietnamese characters\n GetGlyphRangesVietnamese(): number { return this.native.GetGlyphRangesVietnamese(); }\n\n // Helpers to build glyph ranges from text data. Feed your application strings/characters to it then call BuildRanges().\n // struct GlyphRangesBuilder\n // {\n // ImVector UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used)\n // GlyphRangesBuilder() { UsedChars.resize(0x10000 / 8); memset(UsedChars.Data, 0, 0x10000 / 8); }\n // bool GetBit(int n) const { return (UsedChars[n >> 3] & (1 << (n & 7))) != 0; }\n // void SetBit(int n) { UsedChars[n >> 3] |= 1 << (n & 7); } // Set bit 'c' in the array\n // void AddChar(ImWchar c) { SetBit(c); } // Add character\n // IMGUI_API void AddText(const char* text, const char* text_end = NULL); // Add string (each character of the UTF-8 string are added)\n // IMGUI_API void AddRanges(const ImWchar* ranges); // Add ranges, e.g. builder.AddRanges(ImFontAtlas::GetGlyphRangesDefault) to force add all of ASCII/Latin+Ext\n // IMGUI_API void BuildRanges(ImVector* out_ranges); // Output new ranges\n // };\n\n //-------------------------------------------\n // Custom Rectangles/Glyphs API\n //-------------------------------------------\n\n // You can request arbitrary rectangles to be packed into the atlas, for your own purposes. After calling Build(), you can query the rectangle position and render your pixels.\n // You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), so you can render e.g. custom colorful icons and use them as regular glyphs.\n // struct CustomRect\n // {\n // unsigned int ID; // Input // User ID. Use <0x10000 to map into a font glyph, >=0x10000 for other/internal/custom texture data.\n // unsigned short Width, Height; // Input // Desired rectangle dimension\n // unsigned short X, Y; // Output // Packed position in Atlas\n // float GlyphAdvanceX; // Input // For custom font glyphs only (ID<0x10000): glyph xadvance\n // ImVec2 GlyphOffset; // Input // For custom font glyphs only (ID<0x10000): glyph display offset\n // ImFont* Font; // Input // For custom font glyphs only (ID<0x10000): target font\n // CustomRect() { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0,0); Font = NULL; }\n // bool IsPacked() const { return X != 0xFFFF; }\n // };\n\n // IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList\n // IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); // Id needs to be < 0x10000 to register a rectangle to map into a specific font.\n // IMGUI_API void CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max);\n // const CustomRect* GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; }\n\n //-------------------------------------------\n // Members\n //-------------------------------------------\n\n // bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert.\n get Locked(): boolean { return this.native.Locked; }\n set Locked(value: boolean) { this.native.Locked = value; }\n // ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_)\n get Flags(): ImFontAtlasFlags { return this.native.Flags; }\n set Flags(value: ImFontAtlasFlags) { this.native.Flags = value; }\n // ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure.\n get TexID(): ImTextureID | null {\n return ImGuiContext.getTexture(this.native.TexID);\n }\n set TexID(value: ImTextureID | null) {\n this.native.TexID = ImGuiContext.setTexture(value);\n }\n // int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.\n get TexDesiredWidth(): number { return this.native.TexDesiredWidth; }\n set TexDesiredWidth(value: number) { this.native.TexDesiredWidth = value; }\n // int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1.\n get TexGlyphPadding(): number { return this.native.TexGlyphPadding; }\n set TexGlyphPadding(value: number) { this.native.TexGlyphPadding = value; }\n\n // [Internal]\n // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.\n // unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight\n // unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4\n // int TexWidth; // Texture width calculated during Build().\n get TexWidth(): number { return this.native.TexWidth; }\n // int TexHeight; // Texture height calculated during Build().\n get TexHeight(): number { return this.native.TexHeight; }\n // ImVec2 TexUvScale; // = (1.0f/TexWidth, 1.0f/TexHeight)\n get TexUvScale(): Readonly { return this.native.TexUvScale; }\n // ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel\n get TexUvWhitePixel(): Readonly { return this.native.TexUvWhitePixel; }\n // ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.\n get Fonts(): ImVector {\n const fonts: ImVector = new ImVector();\n this.native.IterateFonts((font: Bind.reference_ImFont) => {\n fonts.push(new ImFont(font));\n });\n return fonts;\n }\n // ImVector CustomRects; // Rectangles for packing custom texture data into the atlas.\n // ImVector ConfigData; // Internal data\n // int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList\n}\n\n// Font runtime data and rendering\n// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32().\nexport { ImFont as Font }\nexport class ImFont\n{\n constructor(public readonly native: Bind.reference_ImFont) {}\n\n // Members: Hot ~62/78 bytes\n // float FontSize; // // Height of characters, set during loading (don't change after loading)\n get FontSize(): number { return this.native.FontSize; }\n // float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()\n get Scale(): number { return this.native.Scale; }\n set Scale(value: number) { this.native.Scale = value; }\n // ImVector Glyphs; // // All glyphs.\n get Glyphs(): ImVector {\n const glyphs = new ImVector();\n this.native.IterateGlyphs((glyph: Bind.reference_ImFontGlyph): void => {\n glyphs.push(new ImFontGlyph(glyph)); // TODO: wrap native\n });\n return glyphs;\n }\n // ImVector IndexAdvanceX; // // Sparse. Glyphs->AdvanceX in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI).\n // get IndexAdvanceX(): any { return this.native.IndexAdvanceX; }\n // ImVector IndexLookup; // // Sparse. Index glyphs by Unicode code-point.\n // get IndexLookup(): any { return this.native.IndexLookup; }\n // const ImFontGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar)\n get FallbackGlyph(): ImFontGlyph | null {\n const glyph = this.native.FallbackGlyph;\n return glyph && new ImFontGlyph(glyph);\n }\n set FallbackGlyph(value: ImFontGlyph | null) {\n this.native.FallbackGlyph = value && value.internal as Bind.reference_ImFontGlyph;\n }\n // float FallbackAdvanceX; // == FallbackGlyph->AdvanceX\n get FallbackAdvanceX(): number { return this.native.FallbackAdvanceX; }\n // ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar()\n get FallbackChar(): number { return this.native.FallbackChar; }\n // ImWchar EllipsisChar; // 2 // out // = -1 // Character used for ellipsis rendering.\n get EllipsisChar(): number { return this.native.EllipsisChar; }\n get DotChar(): number { return this.native.DotChar; }\n\n // Members: Cold ~18/26 bytes\n // short ConfigDataCount; // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.\n get ConfigDataCount(): number { return this.ConfigData.length; }\n // ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData\n get ConfigData(): ImFontConfig[] {\n const cfg_data: ImFontConfig[] = [];\n this.native.IterateConfigData((cfg: Bind.interface_ImFontConfig): void => {\n cfg_data.push(new ImFontConfig(cfg));\n });\n return cfg_data;\n }\n // ImFontAtlas* ContainerAtlas; // // What we has been loaded into\n get ContainerAtlas(): ImFontAtlas | null { return null; }\n // float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]\n get Ascent(): number { return this.native.Ascent; }\n get Descent(): number { return this.native.Descent; }\n // int MetricsTotalSurface;// // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)\n get MetricsTotalSurface(): number { return this.native.MetricsTotalSurface; }\n\n // Methods\n // IMGUI_API ImFont();\n // IMGUI_API ~ImFont();\n // IMGUI_API void ClearOutputData();\n public ClearOutputData(): void { return this.native.ClearOutputData(); }\n // IMGUI_API void BuildLookupTable();\n public BuildLookupTable(): void { return this.native.BuildLookupTable(); }\n // IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const;\n public FindGlyph(c: number): Readonly | null {\n const glyph: Readonly | null = this.native.FindGlyph(c);\n return glyph && new ImFontGlyph(glyph);\n }\n // IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c) const;\n public FindGlyphNoFallback(c: number): ImFontGlyph | null {\n const glyph: Readonly | null = this.native.FindGlyphNoFallback(c);\n return glyph && new ImFontGlyph(glyph);\n }\n // IMGUI_API void SetFallbackChar(ImWchar c);\n // public SetFallbackChar(c: number): void { return this.native.SetFallbackChar(c); }\n // float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }\n public GetCharAdvance(c: number): number { return this.native.GetCharAdvance(c); }\n // bool IsLoaded() const { return ContainerAtlas != NULL; }\n public IsLoaded(): boolean { return this.native.IsLoaded(); }\n // const char* GetDebugName() const { return ConfigData ? ConfigData->Name : \"\"; }\n public GetDebugName(): string { return this.native.GetDebugName(); }\n\n // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.\n // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.\n // IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8\n public CalcTextSizeA(size: number, max_width: number, wrap_width: number, text_begin: string, text_end: number | null = null, remaining: Bind.ImScalar | null = null): Bind.interface_ImVec2 {\n return this.native.CalcTextSizeA(size, max_width, wrap_width, text_end !== null ? text_begin.substring(0, text_end) : text_begin, remaining, new ImVec2());\n }\n // IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;\n public CalcWordWrapPositionA(scale: number, text: string, text_end: number | null = null, wrap_width: number): number {\n return this.native.CalcWordWrapPositionA(scale, text_end !== null ? text.substring(0, text_end) : text, wrap_width);\n }\n // IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const;\n public RenderChar(draw_list: ImDrawList, size: number, pos: Readonly, col: Bind.ImU32, c: Bind.ImWchar): void {\n this.native.RenderChar(draw_list.native, size, pos, col, c);\n }\n // IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;\n public RenderText(draw_list: ImDrawList, size: number, pos: Readonly, col: Bind.ImU32, clip_rect: Readonly, text_begin: string, text_end: number | null = null, wrap_width: number = 0.0, cpu_fine_clip: boolean = false): void {}\n\n // [Internal]\n // IMGUI_API void GrowIndex(int new_size);\n // IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);\n // IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.\n\n // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS\n // typedef ImFontGlyph Glyph; // OBSOLETE 1.52+\n // #endif\n\n // IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last);\n public IsGlyphRangeUnused(c_begin: number, c_last: number): boolean { return false; } // TODO\n}\n\n//-----------------------------------------------------------------------------\n// [SECTION] Viewports\n//-----------------------------------------------------------------------------\n\n// Flags stored in ImGuiViewport::Flags, giving indications to the platform backends.\nexport { ImGuiViewportFlags as ViewportFlags }\nexport enum ImGuiViewportFlags\n{\n None = 0,\n IsPlatformWindow = 1 << 0, // Represent a Platform Window\n IsPlatformMonitor = 1 << 1, // Represent a Platform Monitor (unused yet)\n OwnedByApp = 1 << 2 // Platform Window: is created/managed by the application (rather than a dear imgui backend)\n};\n\n// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.\n// - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports.\n// - In the future we will extend this concept further to also represent Platform Monitor and support a \"no main platform window\" operation mode.\n// - About Main Area vs Work Area:\n// - Main Area = entire viewport.\n// - Work Area = entire viewport minus sections used by main menu bars (for platform windows), or by task bar (for platform monitor).\n// - Windows are generally trying to stay within the Work Area of their host viewport.\nexport { ImGuiViewport as Viewport }\nexport class ImGuiViewport\n{\n constructor(public readonly native: Bind.reference_ImGuiViewport) {}\n\n // ImGuiViewportFlags Flags; // See ImGuiViewportFlags_\n get Flags(): ImGuiViewportFlags { return this.native.Flags; }\n // ImVec2 Pos; // Main Area: Position of the viewport (Dear ImGui coordinates are the same as OS desktop/native coordinates)\n get Pos(): Bind.interface_ImVec2 { return this.native.Pos; }\n // ImVec2 Size; // Main Area: Size of the viewport.\n get Size(): Bind.interface_ImVec2 { return this.native.Size; }\n // ImVec2 WorkPos; // Work Area: Position of the viewport minus task bars, menus bars, status bars (>= Pos)\n get WorkPos(): Bind.interface_ImVec2 { return this.native.WorkPos; }\n // ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size)\n get WorkSize(): Bind.interface_ImVec2 { return this.native.WorkSize; }\n\n // ImGuiViewport() { memset(this, 0, sizeof(*this)); }\n\n // Helpers\n // ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }\n GetCenter(): ImVec2 { return new ImVec2(this.Pos.x + this.Size.x * 0.5, this.Pos.y + this.Size.y * 0.5) }\n // ImVec2 GetWorkCenter() const { return ImVec2(WorkPos.x + WorkSize.x * 0.5f, WorkPos.y + WorkSize.y * 0.5f); }\n GetWorkCenter(): ImVec2 { return new ImVec2(this.WorkPos.x + this.WorkSize.x * 0.5, this.WorkPos.y + this.WorkSize.y * 0.5) }\n}\n\n// a script version of Bind.ImGuiStyle with matching interface\nclass script_ImGuiStyle implements Bind.interface_ImGuiStyle {\n public Alpha: number = 1.0;\n public DisabledAlpha: number = 0.6;\n public WindowPadding: ImVec2 = new ImVec2(8, 8);\n public WindowRounding: number = 7.0;\n public WindowBorderSize: number = 0.0;\n public WindowMinSize: ImVec2 = new ImVec2(32, 32);\n public WindowTitleAlign: ImVec2 = new ImVec2(0.0, 0.5);\n public WindowMenuButtonPosition: ImGuiDir = ImGuiDir.Left;\n public ChildRounding: number = 0.0;\n public ChildBorderSize: number = 1.0;\n public PopupRounding: number = 0.0;\n public PopupBorderSize: number = 1.0;\n public FramePadding: ImVec2 = new ImVec2(4, 3);\n public FrameRounding: number = 0.0;\n public FrameBorderSize: number = 0.0;\n public ItemSpacing: ImVec2 = new ImVec2(8, 4);\n public ItemInnerSpacing: ImVec2 = new ImVec2(4, 4);\n public CellPadding: ImVec2 = new ImVec2(4, 2);\n public TouchExtraPadding: ImVec2 = new ImVec2(0, 0);\n public IndentSpacing: number = 21.0;\n public ColumnsMinSpacing: number = 6.0;\n public ScrollbarSize: number = 16.0;\n public ScrollbarRounding: number = 9.0;\n public GrabMinSize: number = 10.0;\n public GrabRounding: number = 0.0;\n public LogSliderDeadzone: number = 4.0;\n public TabRounding: number = 0.0;\n public TabBorderSize: number = 0.0;\n public TabMinWidthForCloseButton: number = 0.0;\n public ColorButtonPosition: ImGuiDir = ImGuiDir.Right;\n public ButtonTextAlign: ImVec2 = new ImVec2(0.5, 0.5);\n public SelectableTextAlign: ImVec2 = new ImVec2(0.0, 0.0);\n public DisplayWindowPadding: ImVec2 = new ImVec2(22, 22);\n public DisplaySafeAreaPadding: ImVec2 = new ImVec2(4, 4);\n public MouseCursorScale: number = 1;\n public AntiAliasedLines: boolean = true;\n public AntiAliasedLinesUseTex: boolean = true;\n public AntiAliasedFill: boolean = true;\n public CurveTessellationTol: number = 1.25;\n public CircleTessellationMaxError: number = 1.60;\n private Colors: ImVec4[] = [];\n public _getAt_Colors(index: number): Bind.interface_ImVec4 { return this.Colors[index]; }\n public _setAt_Colors(index: number, color: Readonly): boolean { this.Colors[index].Copy(color); return true; }\n\n constructor() {\n for (let i = 0; i < ImGuiCol.COUNT; ++i) {\n this.Colors[i] = new ImVec4();\n }\n const _this = new ImGuiStyle(this);\n const native = new bind.ImGuiStyle();\n const _that = new ImGuiStyle(native);\n _that.Copy(_this);\n bind.StyleColorsClassic(native);\n _this.Copy(_that);\n native.delete();\n }\n\n public ScaleAllSizes(scale_factor: number): void {\n const _this = new ImGuiStyle(this);\n const native = new bind.ImGuiStyle();\n const _that = new ImGuiStyle(native);\n _that.Copy(_this);\n native.ScaleAllSizes(scale_factor);\n _this.Copy(_that);\n native.delete();\n }\n}\n\nexport { ImGuiStyle as Style }\nexport class ImGuiStyle\n{\n constructor(public readonly internal: Bind.interface_ImGuiStyle = new script_ImGuiStyle()) {}\n\n get Alpha(): number { return this.internal.Alpha; } set Alpha(value: number) { this.internal.Alpha = value; }\n get DisabledAlpha(): number { return this.internal.DisabledAlpha; } set DisabledAlpha(value: number) { this.internal.DisabledAlpha = value; }\n get WindowPadding(): Bind.interface_ImVec2 { return this.internal.WindowPadding; }\n get WindowRounding(): number { return this.internal.WindowRounding; } set WindowRounding(value: number) { this.internal.WindowRounding = value; }\n get WindowBorderSize(): number { return this.internal.WindowBorderSize; } set WindowBorderSize(value: number) { this.internal.WindowBorderSize = value; }\n get WindowMinSize(): Bind.interface_ImVec2 { return this.internal.WindowMinSize; }\n get WindowTitleAlign(): Bind.interface_ImVec2 { return this.internal.WindowTitleAlign; }\n get WindowMenuButtonPosition(): ImGuiDir { return this.internal.WindowMenuButtonPosition; } set WindowMenuButtonPosition(value: ImGuiDir) { this.internal.WindowMenuButtonPosition = value; }\n get ChildRounding(): number { return this.internal.ChildRounding; } set ChildRounding(value: number) { this.internal.ChildRounding = value; }\n get ChildBorderSize(): number { return this.internal.ChildBorderSize; } set ChildBorderSize(value: number) { this.internal.ChildBorderSize = value; }\n get PopupRounding(): number { return this.internal.PopupRounding; } set PopupRounding(value: number) { this.internal.PopupRounding = value; }\n get PopupBorderSize(): number { return this.internal.PopupBorderSize; } set PopupBorderSize(value: number) { this.internal.PopupBorderSize = value; }\n get FramePadding(): Bind.interface_ImVec2 { return this.internal.FramePadding; }\n get FrameRounding(): number { return this.internal.FrameRounding; } set FrameRounding(value: number) { this.internal.FrameRounding = value; }\n get FrameBorderSize(): number { return this.internal.FrameBorderSize; } set FrameBorderSize(value: number) { this.internal.FrameBorderSize = value; }\n get ItemSpacing(): Bind.interface_ImVec2 { return this.internal.ItemSpacing; }\n get ItemInnerSpacing(): Bind.interface_ImVec2 { return this.internal.ItemInnerSpacing; }\n get CellPadding(): Bind.interface_ImVec2 { return this.internal.CellPadding; }\n get TouchExtraPadding(): Bind.interface_ImVec2 { return this.internal.TouchExtraPadding; }\n get IndentSpacing(): number { return this.internal.IndentSpacing; } set IndentSpacing(value: number) { this.internal.IndentSpacing = value; }\n get ColumnsMinSpacing(): number { return this.internal.ColumnsMinSpacing; } set ColumnsMinSpacing(value: number) { this.internal.ColumnsMinSpacing = value; }\n get ScrollbarSize(): number { return this.internal.ScrollbarSize; } set ScrollbarSize(value: number) { this.internal.ScrollbarSize = value; }\n get ScrollbarRounding(): number { return this.internal.ScrollbarRounding; } set ScrollbarRounding(value: number) { this.internal.ScrollbarRounding = value; }\n get GrabMinSize(): number { return this.internal.GrabMinSize; } set GrabMinSize(value: number) { this.internal.GrabMinSize = value; }\n get GrabRounding(): number { return this.internal.GrabRounding; } set GrabRounding(value: number) { this.internal.GrabRounding = value; }\n get LogSliderDeadzone(): number { return this.internal.LogSliderDeadzone; } set LogSliderDeadzone(value: number) { this.internal.LogSliderDeadzone = value; }\n get TabRounding(): number { return this.internal.TabRounding; } set TabRounding(value: number) { this.internal.TabRounding = value; }\n get TabBorderSize(): number { return this.internal.TabBorderSize; } set TabBorderSize(value: number) { this.internal.TabBorderSize = value; }\n get TabMinWidthForCloseButton(): number { return this.internal.TabMinWidthForCloseButton; } set TabMinWidthForCloseButton(value: number) { this.internal.TabMinWidthForCloseButton = value; }\n get ColorButtonPosition(): number { return this.internal.ColorButtonPosition; } set ColorButtonPosition(value: number) { this.internal.ColorButtonPosition = value; }\n get ButtonTextAlign(): Bind.interface_ImVec2 { return this.internal.ButtonTextAlign; }\n get SelectableTextAlign(): Bind.interface_ImVec2 { return this.internal.SelectableTextAlign; }\n get DisplayWindowPadding(): Bind.interface_ImVec2 { return this.internal.DisplayWindowPadding; }\n get DisplaySafeAreaPadding(): Bind.interface_ImVec2 { return this.internal.DisplaySafeAreaPadding; }\n get MouseCursorScale(): number { return this.internal.MouseCursorScale; } set MouseCursorScale(value: number) { this.internal.MouseCursorScale = value; }\n get AntiAliasedLines(): boolean { return this.internal.AntiAliasedLines; } set AntiAliasedLines(value: boolean) { this.internal.AntiAliasedLines = value; }\n get AntiAliasedLinesUseTex(): boolean { return this.internal.AntiAliasedLinesUseTex; } set AntiAliasedLinesUseTex(value: boolean) { this.internal.AntiAliasedLinesUseTex = value; }\n get AntiAliasedFill(): boolean { return this.internal.AntiAliasedFill; } set AntiAliasedFill(value: boolean) { this.internal.AntiAliasedFill = value; }\n get CurveTessellationTol(): number { return this.internal.CurveTessellationTol; } set CurveTessellationTol(value: number) { this.internal.CurveTessellationTol = value; }\n get CircleTessellationMaxError(): number { return this.internal.CircleTessellationMaxError; } set CircleTessellationMaxError(value: number) { this.internal.CircleTessellationMaxError = value; }\n public Colors: Bind.interface_ImVec4[] = new Proxy([], {\n get: (target: Bind.interface_ImVec4[], key: PropertyKey): number | Bind.interface_ImVec4 => {\n if (key === \"length\") { return ImGuiCol.COUNT; }\n return this.internal._getAt_Colors(Number(key));\n },\n set: (target: Bind.interface_ImVec4[], key: PropertyKey, value: Readonly): boolean => {\n return this.internal._setAt_Colors(Number(key), value);\n },\n });\n\n public Copy(other: Readonly): this {\n this.Alpha = other.Alpha;\n this.DisabledAlpha = other.DisabledAlpha;\n this.WindowPadding.Copy(other.WindowPadding);\n this.WindowRounding = other.WindowRounding;\n this.WindowBorderSize = other.WindowBorderSize;\n this.WindowMinSize.Copy(other.WindowMinSize);\n this.WindowTitleAlign.Copy(other.WindowTitleAlign);\n this.WindowMenuButtonPosition = other.WindowMenuButtonPosition;\n this.ChildRounding = other.ChildRounding;\n this.ChildBorderSize = other.ChildBorderSize;\n this.PopupRounding = other.PopupRounding;\n this.PopupBorderSize = other.PopupBorderSize;\n this.FramePadding.Copy(other.FramePadding);\n this.FrameRounding = other.FrameRounding;\n this.FrameBorderSize = other.FrameBorderSize;\n this.ItemSpacing.Copy(other.ItemSpacing);\n this.ItemInnerSpacing.Copy(other.ItemInnerSpacing);\n this.CellPadding.Copy(other.CellPadding);\n this.TouchExtraPadding.Copy(other.TouchExtraPadding);\n this.IndentSpacing = other.IndentSpacing;\n this.ColumnsMinSpacing = other.ColumnsMinSpacing;\n this.ScrollbarSize = other.ScrollbarSize;\n this.ScrollbarRounding = other.ScrollbarRounding;\n this.GrabMinSize = other.GrabMinSize;\n this.GrabRounding = other.GrabRounding;\n this.LogSliderDeadzone = other.LogSliderDeadzone;\n this.TabRounding = other.TabRounding;\n this.TabBorderSize = other.TabBorderSize;\n this.TabMinWidthForCloseButton = other.TabMinWidthForCloseButton;\n this.ColorButtonPosition = other.ColorButtonPosition;\n this.ButtonTextAlign.Copy(other.ButtonTextAlign);\n this.DisplayWindowPadding.Copy(other.DisplayWindowPadding);\n this.DisplaySafeAreaPadding.Copy(other.DisplaySafeAreaPadding);\n this.MouseCursorScale = other.MouseCursorScale;\n this.AntiAliasedLines = other.AntiAliasedLines;\n this.AntiAliasedLinesUseTex = other.AntiAliasedLinesUseTex;\n this.AntiAliasedFill = other.AntiAliasedFill;\n this.CurveTessellationTol = other.CurveTessellationTol;\n this.CircleTessellationMaxError = other.CircleTessellationMaxError;\n for (let i = 0; i < ImGuiCol.COUNT; ++i) {\n this.Colors[i].Copy(other.Colors[i]);\n }\n return this;\n }\n\n public ScaleAllSizes(scale_factor: number): void { this.internal.ScaleAllSizes(scale_factor); }\n}\n\n// This is where your app communicate with Dear ImGui. Access via ImGui::GetIO().\n// Read 'Programmer guide' section in .cpp file for general usage.\nexport { ImGuiIO as IO }\nexport class ImGuiIO\n{\n constructor(public readonly native: Bind.reference_ImGuiIO) {}\n\n //------------------------------------------------------------------\n // Settings (fill once) // Default value:\n //------------------------------------------------------------------\n\n // ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc.\n get ConfigFlags(): ImGuiConfigFlags { return this.native.ConfigFlags; }\n set ConfigFlags(value: ImGuiConfigFlags) { this.native.ConfigFlags = value; }\n // ImGuiBackendFlags BackendFlags; // = 0 // Set ImGuiBackendFlags_ enum. Set by imgui_impl_xxx files or custom back-end to communicate features supported by the back-end.\n get BackendFlags(): ImGuiBackendFlags { return this.native.BackendFlags; }\n set BackendFlags(value: ImGuiBackendFlags) { this.native.BackendFlags = value; }\n // ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions.\n get DisplaySize(): Bind.reference_ImVec2 { return this.native.DisplaySize; }\n // float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.\n get DeltaTime(): number { return this.native.DeltaTime; }\n set DeltaTime(value: number) { this.native.DeltaTime = value; }\n // float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds.\n get IniSavingRate(): number { return this.native.IniSavingRate; }\n set IniSavingRate(value: number) { this.native.IniSavingRate = value; }\n // const char* IniFilename; // = \"imgui.ini\" // Path to .ini file. NULL to disable .ini saving.\n get IniFilename(): string { return this.native.IniFilename; }\n set IniFilename(value: string) { this.native.IniFilename = value; }\n // const char* LogFilename; // = \"imgui_log.txt\" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified).\n get LogFilename(): string { return this.native.LogFilename; }\n set LogFilename(value: string) { this.native.LogFilename = value; }\n // float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.\n get MouseDoubleClickTime(): number { return this.native.MouseDoubleClickTime; }\n set MouseDoubleClickTime(value: number) { this.native.MouseDoubleClickTime = value; }\n // float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.\n get MouseDoubleClickMaxDist(): number { return this.native.MouseDoubleClickMaxDist; }\n set MouseDoubleClickMaxDist(value: number) { this.native.MouseDoubleClickMaxDist = value; }\n // float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging\n get MouseDragThreshold(): number { return this.native.MouseDragThreshold; }\n set MouseDragThreshold(value: number) { this.native.MouseDragThreshold = value; }\n // int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array\n public KeyMap: number[] = new Proxy([], {\n get: (target: number[], key: PropertyKey): number => {\n if (key === \"length\") { return ImGuiKey.COUNT; }\n return this.native._getAt_KeyMap(Number(key));\n },\n set: (target: number[], key: PropertyKey, value: number): boolean => {\n return this.native._setAt_KeyMap(Number(key), value);\n },\n });\n // float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.).\n get KeyRepeatDelay(): number { return this.native.KeyRepeatDelay; }\n set KeyRepeatDelay(value: number) { this.native.KeyRepeatDelay = value; }\n // float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds.\n get KeyRepeatRate(): number { return this.native.KeyRepeatRate; }\n set KeyRepeatRate(value: number) { this.native.KeyRepeatRate = value; }\n // void* UserData; // = NULL // Store your own data for retrieval by callbacks.\n get UserData(): any { return this.native.UserData; }\n set UserData(value: any) { this.native.UserData = value; }\n\n // ImFontAtlas* Fonts; // // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array.\n get Fonts(): ImFontAtlas { return new ImFontAtlas(this.native.Fonts); }\n // float FontGlobalScale; // = 1.0f // Global scale all fonts\n get FontGlobalScale(): number { return this.native.FontGlobalScale; }\n set FontGlobalScale(value: number) { this.native.FontGlobalScale = value; }\n // bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel.\n get FontAllowUserScaling(): boolean { return this.native.FontAllowUserScaling; }\n set FontAllowUserScaling(value: boolean) { this.native.FontAllowUserScaling = value; }\n // ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0].\n get FontDefault(): ImFont | null {\n const font: Bind.reference_ImFont | null = this.native.FontDefault;\n return (font === null) ? null : new ImFont(font);\n }\n set FontDefault(value: ImFont | null) {\n this.native.FontDefault = value && value.native;\n }\n // ImVec2 DisplayFramebufferScale; // = (1.0f,1.0f) // For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui.\n get DisplayFramebufferScale(): Bind.reference_ImVec2 { return this.native.DisplayFramebufferScale; }\n\n // Miscellaneous configuration options\n // bool OptMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl\n get ConfigMacOSXBehaviors(): boolean { return this.native.ConfigMacOSXBehaviors; }\n set ConfigMacOSXBehaviors(value: boolean) { this.native.ConfigMacOSXBehaviors = value; }\n // bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor, for users who consider it annoying.\n get ConfigInputTextCursorBlink(): boolean { return this.native.ConfigInputTextCursorBlink; }\n set ConfigInputTextCursorBlink(value: boolean) { this.native.ConfigInputTextCursorBlink = value; }\n // bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.\n get ConfigDragClickToInputText(): boolean { return this.native.ConfigDragClickToInputText; }\n set ConfigDragClickToInputText(value: boolean) { this.native.ConfigDragClickToInputText = value; }\n // bool ConfigWindowsResizeFromEdges; // = false // [BETA] Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be the ImGuiWindowFlags_ResizeFromAnySide flag)\n get ConfigWindowsResizeFromEdges(): boolean { return this.native.ConfigWindowsResizeFromEdges; }\n set ConfigWindowsResizeFromEdges(value: boolean) { this.native.ConfigWindowsResizeFromEdges = value; }\n // bool ConfigWindowsMoveFromTitleBarOnly;// = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected.\n get ConfigWindowsMoveFromTitleBarOnly(): boolean { return this.native.ConfigWindowsMoveFromTitleBarOnly; }\n set ConfigWindowsMoveFromTitleBarOnly(value: boolean) { this.native.ConfigWindowsMoveFromTitleBarOnly = value; }\n // float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.\n get ConfigMemoryCompactTimer(): number { return this.native.ConfigMemoryCompactTimer; }\n set ConfigMemoryCompactTimer(value: number) { this.native.ConfigMemoryCompactTimer = value; }\n\n //------------------------------------------------------------------\n // Settings (User Functions)\n //------------------------------------------------------------------\n\n // Optional: Platform/Renderer back-end name (informational only! will be displayed in About Window) + User data for back-end/wrappers to store their own stuff.\n // const char* BackendPlatformName; // = NULL\n get BackendPlatformName(): string | null { return this.native.BackendPlatformName; }\n set BackendPlatformName(value: string | null) { this.native.BackendPlatformName = value; }\n // const char* BackendRendererName; // = NULL\n get BackendRendererName(): string | null { return this.native.BackendRendererName; }\n set BackendRendererName(value: string | null) { this.native.BackendRendererName = value; }\n // void* BackendPlatformUserData; // = NULL\n get BackendPlatformUserData(): string | null { return this.native.BackendPlatformUserData; }\n set BackendPlatformUserData(value: string | null) { this.native.BackendPlatformUserData = value; }\n // void* BackendRendererUserData; // = NULL\n get BackendRendererUserData(): string | null { return this.native.BackendRendererUserData; }\n set BackendRendererUserData(value: string | null) { this.native.BackendRendererUserData = value; }\n // void* BackendLanguageUserData; // = NULL\n get BackendLanguageUserData(): string | null { return this.native.BackendLanguageUserData; }\n set BackendLanguageUserData(value: string | null) { this.native.BackendLanguageUserData = value; }\n\n // Optional: access OS clipboard\n // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures)\n // const char* (*GetClipboardTextFn)(void* user_data);\n get GetClipboardTextFn(): ((user_data: any) => string) | null { return this.native.GetClipboardTextFn; }\n set GetClipboardTextFn(value: ((user_data: any) => string) | null) { this.native.GetClipboardTextFn = value; }\n // void (*SetClipboardTextFn)(void* user_data, const char* text);\n get SetClipboardTextFn(): ((user_data: any, text: string) => void) | null { return this.native.SetClipboardTextFn; }\n set SetClipboardTextFn(value: ((user_data: any, text: string) => void) | null) { this.native.SetClipboardTextFn = value; }\n // void* ClipboardUserData;\n get ClipboardUserData(): any { return this.native.ClipboardUserData; }\n set ClipboardUserData(value: any) { this.native.ClipboardUserData = value; }\n\n // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer.\n // (default to posix malloc/free)\n // void* (*MemAllocFn)(size_t sz);\n // void (*MemFreeFn)(void* ptr);\n\n // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows)\n // (default to use native imm32 api on Windows)\n // void (*ImeSetInputScreenPosFn)(int x, int y);\n // void* ImeWindowHandle; // (Windows) Set this to your HWND to get automatic IME cursor positioning.\n\n //------------------------------------------------------------------\n // Input - Fill before calling NewFrame()\n //------------------------------------------------------------------\n\n // ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.)\n get MousePos(): Bind.reference_ImVec2 { return this.native.MousePos; }\n // bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API.\n public MouseDown: boolean[] = new Proxy([], {\n get: (target: boolean[], key: PropertyKey): number | boolean => {\n if (key === \"length\") { return 5; }\n return this.native._getAt_MouseDown(Number(key));\n },\n set: (target: boolean[], key: PropertyKey, value: boolean): boolean => {\n return this.native._setAt_MouseDown(Number(key), value);\n },\n });\n // float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text.\n public get MouseWheel(): number { return this.native.MouseWheel; }\n public set MouseWheel(value: number) { this.native.MouseWheel = value; }\n // float MouseWheelH; // Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends.\n public get MouseWheelH(): number { return this.native.MouseWheelH; }\n public set MouseWheelH(value: number) { this.native.MouseWheelH = value; }\n // bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor).\n get MouseDrawCursor(): boolean { return this.native.MouseDrawCursor; } set MouseDrawCursor(value: boolean) { this.native.MouseDrawCursor = value; }\n // bool KeyCtrl; // Keyboard modifier pressed: Control\n get KeyCtrl(): boolean { return this.native.KeyCtrl; } set KeyCtrl(value: boolean) { this.native.KeyCtrl = value; }\n // bool KeyShift; // Keyboard modifier pressed: Shift\n get KeyShift(): boolean { return this.native.KeyShift; } set KeyShift(value: boolean) { this.native.KeyShift = value; }\n // bool KeyAlt; // Keyboard modifier pressed: Alt\n get KeyAlt(): boolean { return this.native.KeyAlt; } set KeyAlt(value: boolean) { this.native.KeyAlt = value; }\n // bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows\n get KeySuper(): boolean { return this.native.KeySuper; } set KeySuper(value: boolean) { this.native.KeySuper = value; }\n // bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data)\n public KeysDown: boolean[] = new Proxy([], {\n get: (target: boolean[], key: PropertyKey): number | boolean => {\n if (key === \"length\") { return 512; }\n return this.native._getAt_KeysDown(Number(key));\n },\n set: (target: boolean[], key: PropertyKey, value: boolean): boolean => {\n return this.native._setAt_KeysDown(Number(key), value);\n },\n });\n // float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs (keyboard keys will be auto-mapped and be written here by ImGui::NewFrame)\n public NavInputs: number[] = new Proxy([], {\n get: (target: number[], key: PropertyKey): number => {\n if (key === \"length\") { return ImGuiNavInput.COUNT; }\n return this.native._getAt_NavInputs(Number(key));\n },\n set: (target: number[], key: PropertyKey, value: number): boolean => {\n return this.native._setAt_NavInputs(Number(key), value);\n },\n });\n\n // Functions\n // IMGUI_API void AddInputCharacter(ImWchar c); // Add new character into InputCharacters[]\n public AddInputCharacter(c: number): void { this.native.AddInputCharacter(c); }\n // IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue new character input from an UTF-16 character, it can be a surrogate\n public AddInputCharacterUTF16(c: number): void { this.native.AddInputCharacterUTF16(c); }\n // IMGUI_API void AddInputCharactersUTF8(const char* utf8_chars); // Add new characters into InputCharacters[] from an UTF-8 string\n public AddInputCharactersUTF8(utf8_chars: string): void { this.native.AddInputCharactersUTF8(utf8_chars); }\n // inline void ClearInputCharacters() { InputCharacters[0] = 0; } // Clear the text input buffer manually\n public ClearInputCharacters(): void { this.native.ClearInputCharacters(); }\n\n //------------------------------------------------------------------\n // Output - Retrieve after calling NewFrame()\n //------------------------------------------------------------------\n\n // bool WantCaptureMouse; // When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. This is set by ImGui when it wants to use your mouse (e.g. unclicked mouse is hovering a window, or a widget is active).\n get WantCaptureMouse(): boolean { return this.native.WantCaptureMouse; } set WantCaptureMouse(value: boolean) { this.native.WantCaptureMouse = value; }\n // bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. This is set by ImGui when it wants to use your keyboard inputs.\n get WantCaptureKeyboard(): boolean { return this.native.WantCaptureKeyboard; } set WantCaptureKeyboard(value: boolean) { this.native.WantCaptureKeyboard = value; }\n // bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active).\n get WantTextInput(): boolean { return this.native.WantTextInput; } set WantTextInput(value: boolean) { this.native.WantTextInput = value; }\n // bool WantSetMousePos; // [BETA-NAV] MousePos has been altered, back-end should reposition mouse on next frame. Set only when 'NavMovesMouse=true'.\n get WantSetMousePos(): boolean { return this.native.WantSetMousePos; } set WantSetMousePos(value: boolean) { this.native.WantSetMousePos = value; }\n // bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. IMPORTANT: You need to clear io.WantSaveIniSettings yourself.\n get WantSaveIniSettings(): boolean { return this.native.WantSaveIniSettings; } set WantSaveIniSettings(value: boolean) { this.native.WantSaveIniSettings = value; }\n // bool NavActive; // Directional navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag.\n get NavActive(): boolean { return this.native.NavActive; } set NavActive(value: boolean) { this.native.NavActive = value; }\n // bool NavVisible; // Directional navigation is visible and allowed (will handle ImGuiKey_NavXXX events).\n get NavVisible(): boolean { return this.native.NavVisible; } set NavVisible(value: boolean) { this.native.NavVisible = value; }\n // float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames\n get Framerate(): number { return this.native.Framerate; }\n // int MetricsRenderVertices; // Vertices output during last call to Render()\n get MetricsRenderVertices(): number { return this.native.MetricsRenderVertices; }\n // int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3\n get MetricsRenderIndices(): number { return this.native.MetricsRenderIndices; }\n // int MetricsRenderWindows; // Number of visible windows\n get MetricsRenderWindows(): number { return this.native.MetricsRenderWindows; }\n // int MetricsActiveWindows; // Number of visible root windows (exclude child windows)\n get MetricsActiveWindows(): number { return this.native.MetricsActiveWindows; }\n // int MetricsActiveAllocations; // Number of active allocations, updated by MemAlloc/MemFree based on current context. May be off if you have multiple imgui contexts.\n get MetricsActiveAllocations(): number { return this.native.MetricsActiveAllocations; }\n // ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta.\n get MouseDelta(): Readonly { return this.native.MouseDelta; }\n\n //------------------------------------------------------------------\n // [Internal] ImGui will maintain those fields. Forward compatibility not guaranteed!\n //------------------------------------------------------------------\n\n get WantCaptureMouseUnlessPopupClose(): boolean { return this.native.WantCaptureMouseUnlessPopupClose; } set WantCaptureMouseUnlessPopupClose(value: boolean) { this.native.WantCaptureMouseUnlessPopupClose = value; }\n // ImGuiKeyModFlags KeyMods; // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame()\n // ImVec2 MousePosPrev; // Previous mouse position temporary storage (nb: not for public use, set to MousePos in NewFrame())\n // ImVec2 MouseClickedPos[5]; // Position at time of clicking\n public MouseClickedPos: Array> = new Proxy([], {\n get: (target: Array>, key: PropertyKey): number | Readonly => {\n if (key === \"length\") { return 5; }\n return this.native._getAt_MouseClickedPos(Number(key));\n },\n });\n // float MouseClickedTime[5]; // Time of last click (used to figure out double-click)\n // bool MouseClicked[5]; // Mouse button went from !Down to Down\n // bool MouseDoubleClicked[5]; // Has mouse button been double-clicked?\n // bool MouseReleased[5]; // Mouse button went from Down to !Down\n // bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds.\n // float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked)\n public MouseDownDuration: number[] = new Proxy([], {\n get: (target: number[], key: PropertyKey): number => {\n if (key === \"length\") { return 5; }\n return this.native._getAt_MouseDownDuration(Number(key));\n },\n });\n // float MouseDownDurationPrev[5]; // Previous time the mouse button has been down\n // ImVec2 MouseDragMaxDistanceAbs[5]; // Maximum distance, absolute, on each axis, of how much mouse has traveled from the clicking point\n // float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point\n // float KeysDownDuration[512]; // Duration the keyboard key has been down (0.0f == just pressed)\n public KeysDownDuration: number[] = new Proxy([], {\n get: (target: number[], key: PropertyKey): number => {\n if (key === \"length\") { return 512; }\n return this.native._getAt_KeysDownDuration(Number(key));\n },\n });\n // float KeysDownDurationPrev[512]; // Previous duration the key has been down\n // float NavInputsDownDuration[ImGuiNavInput_COUNT];\n public NavInputsDownDuration: number[] = new Proxy([], {\n get: (target: number[], key: PropertyKey): number => {\n if (key === \"length\") { return ImGuiNavInput.COUNT; }\n return this.native._getAt_NavInputsDownDuration(Number(key));\n },\n });\n // float NavInputsDownDurationPrev[ImGuiNavInput_COUNT];\n // float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui.\n // ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16\n // ImVector InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper.\n\n // IMGUI_API ImGuiIO();\n}\n\n// Context creation and access\n// Each context create its own ImFontAtlas by default. You may instance one yourself and pass it to CreateContext() to share a font atlas between imgui contexts.\n// None of those functions is reliant on the current context.\n// IMGUI_API ImGuiContext* CreateContext(ImFontAtlas* shared_font_atlas = NULL);\n// IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = destroy current context\n// IMGUI_API ImGuiContext* GetCurrentContext();\n// IMGUI_API void SetCurrentContext(ImGuiContext* ctx);\nexport class ImGuiContext {\n public static current_ctx: ImGuiContext | null = null;\n public static getTexture(index: number): ImTextureID | null {\n if (ImGuiContext.current_ctx === null) { throw new Error(); }\n return ImGuiContext.current_ctx._getTexture(index);\n }\n public static setTexture(texture: ImTextureID | null): number {\n if (ImGuiContext.current_ctx === null) { throw new Error(); }\n return ImGuiContext.current_ctx._setTexture(texture);\n }\n\n private static textures: Array = [];\n constructor(public readonly native: Bind.WrapImGuiContext) {}\n private _getTexture(index: number): ImTextureID | null {\n return ImGuiContext.textures[index] || null;\n }\n private _setTexture(texture: ImTextureID | null): number {\n let index = ImGuiContext.textures.indexOf(texture);\n if (index === -1) {\n for (let i = 0; i < ImGuiContext.textures.length; ++i) {\n if (ImGuiContext.textures[i] === null) {\n ImGuiContext.textures[i] = texture;\n return i;\n }\n }\n index = ImGuiContext.textures.length;\n ImGuiContext.textures.push(texture);\n }\n return index;\n }\n}\nexport function CreateContext(shared_font_atlas: ImFontAtlas | null = null): ImGuiContext | null {\n const ctx: ImGuiContext = new ImGuiContext(bind.CreateContext(shared_font_atlas !== null ? shared_font_atlas.native : null));\n if (ImGuiContext.current_ctx === null) {\n ImGuiContext.current_ctx = ctx;\n }\n return ctx;\n}\nexport function DestroyContext(ctx: ImGuiContext | null = null): void {\n if (ctx === null) {\n ctx = ImGuiContext.current_ctx;\n ImGuiContext.current_ctx = null;\n }\n bind.DestroyContext((ctx === null) ? null : ctx.native);\n}\nexport function GetCurrentContext(): ImGuiContext | null {\n // const ctx_native: Bind.ImGuiContext | null = bind.GetCurrentContext();\n return ImGuiContext.current_ctx;\n}\nexport function SetCurrentContext(ctx: ImGuiContext | null): void {\n bind.SetCurrentContext((ctx === null) ? null : ctx.native);\n ImGuiContext.current_ctx = ctx;\n}\n\n// Main\n// IMGUI_API ImGuiIO& GetIO(); // access the IO structure (mouse/keyboard/gamepad inputs, time, various configuration options/flags)\n// IMGUI_API ImGuiStyle& GetStyle(); // access the Style structure (colors, sizes). Always use PushStyleCol(), PushStyleVar() to modify style mid-frame!\n// IMGUI_API void NewFrame(); // start a new Dear ImGui frame, you can submit any command from this point until Render()/EndFrame().\n// IMGUI_API void EndFrame(); // ends the Dear ImGui frame. automatically called by Render(). If you don't need to render data (skipping rendering) you may call EndFrame() without Render()... but you'll have wasted CPU already! If you don't need to render, better to not create any windows and not call NewFrame() at all!\n// IMGUI_API void Render(); // ends the Dear ImGui frame, finalize the draw data. You can then get call GetDrawData().\n// IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render.\nexport function GetIO(): ImGuiIO { return new ImGuiIO(bind.GetIO()); }\nexport function GetStyle(): ImGuiStyle { return new ImGuiStyle(bind.GetStyle()); }\nexport function NewFrame(): void { bind.NewFrame(); }\nexport function EndFrame(): void { bind.EndFrame(); }\nexport function Render(): void { bind.Render(); }\nexport function GetDrawData(): ImDrawData | null {\n const draw_data: Bind.reference_ImDrawData | null = bind.GetDrawData();\n return (draw_data === null) ? null : new ImDrawData(draw_data);\n}\n\n// Demo, Debug, Information\n// IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application!\n// IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Metrics/Debugger window. display Dear ImGui internals: windows, draw commands, various internal state, etc.\n// IMGUI_API void ShowStackToolWindow(bool* p_open = NULL); // create Stack Tool window. hover items with mouse to query information about the source of their unique ID.\n// IMGUI_API void ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information.\n// IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style)\n// IMGUI_API bool ShowStyleSelector(const char* label); // add style selector block (not a window), essentially a combo listing the default styles.\n// IMGUI_API void ShowFontSelector(const char* label); // add font selector block (not a window), essentially a combo listing the loaded fonts.\n// IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls).\n// IMGUI_API const char* GetVersion(); // get the compiled version string e.g. \"1.80 WIP\" (essentially the value for IMGUI_VERSION from the compiled version of imgui.cpp)\nexport function ShowDemoWindow(p_open: Bind.ImScalar | null = null): void { bind.ShowDemoWindow(p_open); }\nexport function ShowMetricsWindow(p_open: Bind.ImScalar | Bind.ImAccess | null = null): void {\n if (p_open === null) {\n bind.ShowMetricsWindow(null);\n } else if (Array.isArray(p_open)) {\n bind.ShowMetricsWindow(p_open);\n } else {\n const ref_open: Bind.ImScalar = [ p_open() ];\n bind.ShowMetricsWindow(ref_open);\n p_open(ref_open[0]);\n }\n}\nexport function ShowStackToolWindow(p_open: Bind.ImScalar | Bind.ImAccess | null = null): void {\n if (p_open === null) {\n bind.ShowStackToolWindow(null);\n } else if (Array.isArray(p_open)) {\n bind.ShowStackToolWindow(p_open);\n } else {\n const ref_open: Bind.ImScalar = [ p_open() ];\n bind.ShowStackToolWindow(ref_open);\n p_open(ref_open[0]);\n }\n}\nexport function ShowAboutWindow(p_open: Bind.ImScalar | Bind.ImAccess | null = null): void {\n if (p_open === null) {\n bind.ShowAboutWindow(null);\n } else if (Array.isArray(p_open)) {\n bind.ShowAboutWindow(p_open);\n } else {\n const ref_open: Bind.ImScalar = [ p_open() ];\n bind.ShowAboutWindow(ref_open);\n p_open(ref_open[0]);\n }\n}\nexport function ShowStyleEditor(ref: ImGuiStyle | null = null): void {\n if (ref === null) {\n bind.ShowStyleEditor(null);\n } else if (ref.internal instanceof bind.ImGuiStyle) {\n bind.ShowStyleEditor(ref.internal);\n } else {\n const native = new bind.ImGuiStyle();\n const wrap = new ImGuiStyle(native);\n wrap.Copy(ref);\n bind.ShowStyleEditor(native);\n ref.Copy(wrap);\n native.delete();\n }\n}\nexport function ShowStyleSelector(label: string): boolean { return bind.ShowStyleSelector(label); }\nexport function ShowFontSelector(label: string): void { bind.ShowFontSelector(label); }\nexport function ShowUserGuide(): void { bind.ShowUserGuide(); }\nexport function GetVersion(): string { return bind.GetVersion(); }\n\n// Styles\n// IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // new, recommended style (default)\n// IMGUI_API void StyleColorsLight(ImGuiStyle* dst = NULL); // best used with borders and a custom, thicker font\n// IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // classic imgui style\nexport function StyleColorsDark(dst: ImGuiStyle | null = null): void {\n if (dst === null) {\n bind.StyleColorsDark(null);\n } else if (dst.internal instanceof bind.ImGuiStyle) {\n bind.StyleColorsDark(dst.internal);\n } else {\n const native = new bind.ImGuiStyle();\n const wrap = new ImGuiStyle(native);\n wrap.Copy(dst);\n bind.StyleColorsDark(native);\n dst.Copy(wrap);\n native.delete();\n }\n}\nexport function StyleColorsLight(dst: ImGuiStyle | null = null): void {\n if (dst === null) {\n bind.StyleColorsLight(null);\n } else if (dst.internal instanceof bind.ImGuiStyle) {\n bind.StyleColorsLight(dst.internal);\n } else {\n const native = new bind.ImGuiStyle();\n const wrap = new ImGuiStyle(native);\n wrap.Copy(dst);\n bind.StyleColorsLight(native);\n dst.Copy(wrap);\n native.delete();\n }\n}\nexport function StyleColorsClassic(dst: ImGuiStyle | null = null): void {\n if (dst === null) {\n bind.StyleColorsClassic(null);\n } else if (dst.internal instanceof bind.ImGuiStyle) {\n bind.StyleColorsClassic(dst.internal);\n } else {\n const native = new bind.ImGuiStyle();\n const wrap = new ImGuiStyle(native);\n wrap.Copy(dst);\n bind.StyleColorsClassic(native);\n dst.Copy(wrap);\n native.delete();\n }\n}\n\n// Windows\n// - Begin() = push window to the stack and start appending to it. End() = pop window from the stack.\n// - Passing 'bool* p_open != NULL' shows a window-closing widget in the upper-right corner of the window,\n// which clicking will set the boolean to false when clicked.\n// - You may append multiple times to the same window during the same frame by calling Begin()/End() pairs multiple times.\n// Some information such as 'flags' or 'p_open' will only be considered by the first call to Begin().\n// - Begin() return false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting\n// anything to the window. Always call a matching End() for each Begin() call, regardless of its return value!\n// [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu,\n// BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function\n// returned true. Begin and BeginChild are the only odd ones out. Will be fixed in a future update.]\n// - Note that the bottom of window stack always contains a window called \"Debug\".\n// IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0);\n// IMGUI_API void End();\nexport function Begin(name: string, open: Bind.ImScalar | Bind.ImAccess | null = null, flags: ImGuiWindowFlags = 0): boolean {\n if (open === null) {\n return bind.Begin(name, null, flags);\n } else if (Array.isArray(open)) {\n return bind.Begin(name, open, flags);\n } else {\n const ref_open: Bind.ImScalar = [ open() ];\n const opened: boolean = bind.Begin(name, ref_open, flags);\n open(ref_open[0]);\n return opened;\n }\n}\nexport function End(): void { bind.End(); }\n\n// Child Windows\n// - Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window. Child windows can embed their own child.\n// - For each independent axis of 'size': ==0.0f: use remaining host window size / >0.0f: fixed size / <0.0f: use remaining window size minus abs(size) / Each axis can use a different mode, e.g. ImVec2(0,400).\n// - BeginChild() returns false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting anything to the window.\n// Always call a matching EndChild() for each BeginChild() call, regardless of its return value.\n// [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu,\n// BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function\n// returned true. Begin and BeginChild are the only odd ones out. Will be fixed in a future update.]\n// IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0);\n// IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0);\n// IMGUI_API void EndChild();\nexport function BeginChild(id: string | ImGuiID, size: Readonly = ImVec2.ZERO, border: boolean = false, flags: ImGuiWindowFlags = 0): boolean {\n return bind.BeginChild(id, size, border, flags);\n}\nexport function EndChild(): void { bind.EndChild(); }\n\n// Windows Utilities\n// - 'current window' = the window we are appending into while inside a Begin()/End() block. 'next window' = next window we will Begin() into.\n// IMGUI_API bool IsWindowAppearing();\n// IMGUI_API bool IsWindowCollapsed();\n// IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags=0); // is current window focused? or its root/child, depending on flags. see flags for options.\n// IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags=0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. NB: If you are trying to check whether your mouse should be dispatched to imgui or to your app, you should use the 'io.WantCaptureMouse' boolean for that! Please read the FAQ!\n// IMGUI_API ImDrawList* GetWindowDrawList(); // get draw list associated to the current window, to append your own drawing primitives\n// IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList API)\n// IMGUI_API ImVec2 GetWindowSize(); // get current window size\n// IMGUI_API float GetWindowWidth(); // get current window width (shortcut for GetWindowSize().x)\n// IMGUI_API float GetWindowHeight(); // get current window height (shortcut for GetWindowSize().y)\nexport function IsWindowAppearing(): boolean { return bind.IsWindowAppearing(); }\nexport function IsWindowCollapsed(): boolean { return bind.IsWindowCollapsed(); }\nexport function IsWindowFocused(flags: ImGuiFocusedFlags = 0): boolean { return bind.IsWindowFocused(flags); }\nexport function IsWindowHovered(flags: ImGuiHoveredFlags = 0): boolean { return bind.IsWindowHovered(flags); }\nexport function GetWindowDrawList(): ImDrawList { return new ImDrawList(bind.GetWindowDrawList()); }\nexport function GetWindowPos(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetWindowPos(out); }\nexport function GetWindowSize(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetWindowSize(out); }\nexport function GetWindowWidth(): number { return bind.GetWindowWidth(); }\nexport function GetWindowHeight(): number { return bind.GetWindowHeight(); }\n\n// Prefer using SetNextXXX functions (before Begin) rather that SetXXX functions (after Begin).\n// IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0, 0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc.\n// IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin()\n// IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Sizes will be rounded down. Use callback to apply non-trivial programmatic constraints.\n// IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ scrollable client area, which enforce the range of scrollbars). Not including window decorations (title bar, menu bar, etc.) nor WindowPadding. set an axis to 0.0f to leave it automatic. call before Begin()\n// IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin()\n// IMGUI_API void SetNextWindowFocus(); // set next window to be focused / top-most. call before Begin()\n// IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily override the Alpha component of ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground.\n// IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects.\n// IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0, 0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects.\n// IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed().\n// IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / top-most. prefer using SetNextWindowFocus().\n// IMGUI_API void SetWindowFontScale(float scale); // set font scale. Adjust IO.FontGlobalScale if you want to scale all windows. This is an old API! For correct scaling, prefer to reload font + rebuild ImFontAtlas + call style.ScaleAllSizes().\n// IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond = 0); // set named window position.\n// IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis.\n// IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state\n// IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / top-most. use NULL to remove focus.\nexport function SetNextWindowPos(pos: Readonly, cond: ImGuiCond = 0, pivot: Readonly = ImVec2.ZERO): void { bind.SetNextWindowPos(pos, cond, pivot); }\nexport function SetNextWindowSize(pos: Readonly, cond: ImGuiCond = 0): void { bind.SetNextWindowSize(pos, cond); }\nexport function SetNextWindowSizeConstraints(size_min: Readonly, size_max: Readonly): void;\nexport function SetNextWindowSizeConstraints(size_min: Readonly, size_max: Readonly, custom_callback: ImGuiSizeCallback, custom_callback_data?: T): void;\nexport function SetNextWindowSizeConstraints(size_min: Readonly, size_max: Readonly, custom_callback: ImGuiSizeCallback | null = null, custom_callback_data: T | null = null): void {\n if (custom_callback) {\n bind.SetNextWindowSizeConstraints(size_min, size_max, (data: Bind.reference_ImGuiSizeCallbackData): void => {\n custom_callback(new ImGuiSizeCallbackData(data, custom_callback_data));\n }, null);\n } else {\n bind.SetNextWindowSizeConstraints(size_min, size_max, null, null);\n }\n}\nexport function SetNextWindowContentSize(size: Readonly): void { bind.SetNextWindowContentSize(size); }\nexport function SetNextWindowCollapsed(collapsed: boolean, cond: ImGuiCond = 0): void { bind.SetNextWindowCollapsed(collapsed, cond); }\nexport function SetNextWindowFocus(): void { bind.SetNextWindowFocus(); }\nexport function SetNextWindowBgAlpha(alpha: number): void { bind.SetNextWindowBgAlpha(alpha); }\nexport function SetWindowPos(name_or_pos: string | Readonly, pos_or_cond: Readonly | ImGuiCond = 0, cond: ImGuiCond = 0): void {\n if (typeof(name_or_pos) === \"string\") {\n bind.SetWindowNamePos(name_or_pos, pos_or_cond as Readonly, cond);\n return;\n } else {\n bind.SetWindowPos(name_or_pos, pos_or_cond as ImGuiCond);\n }\n}\nexport function SetWindowSize(name_or_size: string | Readonly, size_or_cond: Readonly | ImGuiCond = 0, cond: ImGuiCond = 0): void {\n if (typeof(name_or_size) === \"string\") {\n bind.SetWindowNamePos(name_or_size, size_or_cond as Readonly, cond);\n } else {\n bind.SetWindowSize(name_or_size, size_or_cond as ImGuiCond);\n }\n}\nexport function SetWindowCollapsed(name_or_collapsed: string | boolean, collapsed_or_cond: boolean | ImGuiCond = 0, cond: ImGuiCond = 0): void {\n if (typeof(name_or_collapsed) === \"string\") {\n bind.SetWindowNameCollapsed(name_or_collapsed, collapsed_or_cond as boolean, cond);\n } else {\n bind.SetWindowCollapsed(name_or_collapsed, collapsed_or_cond as ImGuiCond);\n }\n}\nexport function SetWindowFocus(name?: string): void {\n if (typeof(name) === \"string\") {\n bind.SetWindowNameFocus(name);\n } else {\n bind.SetWindowFocus();\n }\n}\nexport function SetWindowFontScale(scale: number): void { bind.SetWindowFontScale(scale); }\n\n// Content region\n// - Retrieve available space from a given point. GetContentRegionAvail() is frequently useful.\n// - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion)\n// IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos()\n// IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates\n// IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates\n// IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates\n// IMGUI_API float GetWindowContentRegionWidth(); //\nexport function GetContentRegionAvail(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetContentRegionAvail(out); }\nexport function GetContentRegionMax(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetContentRegionMax(out); }\nexport function GetWindowContentRegionMin(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetWindowContentRegionMin(out); }\nexport function GetWindowContentRegionMax(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetWindowContentRegionMax(out); }\n// export function GetWindowContentRegionWidth(): number { return bind.GetWindowContentRegionWidth(); }\n\n// Windows Scrolling\n// IMGUI_API float GetScrollX(); // get scrolling amount [0 .. GetScrollMaxX()]\n// IMGUI_API float GetScrollY(); // get scrolling amount [0 .. GetScrollMaxY()]\n// IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0 .. GetScrollMaxX()]\n// IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0 .. GetScrollMaxY()]\n// IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.x - WindowSize.x - DecorationsSize.x\n// IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.y - WindowSize.y - DecorationsSize.y\n// IMGUI_API void SetScrollHereX(float center_x_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_x_ratio=0.0: left, 0.5: center, 1.0: right. When using to make a \"default/current item\" visible, consider using SetItemDefaultFocus() instead.\n// IMGUI_API void SetScrollHereY(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a \"default/current item\" visible, consider using SetItemDefaultFocus() instead.\n// IMGUI_API void SetScrollFromPosX(float local_x, float center_x_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position.\n// IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position.\nexport function GetScrollX(): number { return bind.GetScrollX(); }\nexport function GetScrollY(): number { return bind.GetScrollY(); }\nexport function SetScrollX(scroll_x: number): void { bind.SetScrollX(scroll_x); }\nexport function SetScrollY(scroll_y: number): void { bind.SetScrollY(scroll_y); }\nexport function GetScrollMaxX(): number { return bind.GetScrollMaxX(); }\nexport function GetScrollMaxY(): number { return bind.GetScrollMaxY(); }\nexport function SetScrollHereX(center_x_ratio: number = 0.5): void { bind.SetScrollHereX(center_x_ratio); }\nexport function SetScrollHereY(center_y_ratio: number = 0.5): void { bind.SetScrollHereY(center_y_ratio); }\nexport function SetScrollFromPosX(pos_x: number, center_x_ratio: number = 0.5): void { bind.SetScrollFromPosX(pos_x, center_x_ratio); }\nexport function SetScrollFromPosY(pos_y: number, center_y_ratio: number = 0.5): void { bind.SetScrollFromPosY(pos_y, center_y_ratio); }\n\n// Parameters stacks (shared)\n// IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font\n// IMGUI_API void PopFont();\n// IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); // modify a style color. always use this if you modify the style after NewFrame().\n// IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col);\n// IMGUI_API void PopStyleColor(int count = 1);\n// IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); // modify a style float variable. always use this if you modify the style after NewFrame().\n// IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); // modify a style ImVec2 variable. always use this if you modify the style after NewFrame().\n// IMGUI_API void PopStyleVar(int count = 1);\n// IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets\n// IMGUI_API void PopAllowKeyboardFocus();\n// IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame.\n// IMGUI_API void PopButtonRepeat();\nexport function PushFont(font: ImFont | null): void { bind.PushFont(font ? font.native : null); }\nexport function PopFont(): void { bind.PopFont(); }\nexport function PushStyleColor(idx: ImGuiCol, col: Bind.ImU32 | Readonly | Readonly): void {\n if (col instanceof ImColor) {\n bind.PushStyleColor(idx, col.Value);\n } else {\n bind.PushStyleColor(idx, col as (Bind.ImU32 | Readonly));\n }\n}\nexport function PopStyleColor(count: number = 1): void { bind.PopStyleColor(count); }\nexport function PushStyleVar(idx: ImGuiStyleVar, val: number | Readonly): void { bind.PushStyleVar(idx, val); }\nexport function PopStyleVar(count: number = 1): void { bind.PopStyleVar(count); }\nexport function PushAllowKeyboardFocus(allow_keyboard_focus: boolean): void { bind.PushAllowKeyboardFocus(allow_keyboard_focus); }\nexport function PopAllowKeyboardFocus(): void { bind.PopAllowKeyboardFocus(); }\nexport function PushButtonRepeat(repeat: boolean): void { bind.PushButtonRepeat(repeat); }\nexport function PopButtonRepeat(): void { bind.PopButtonRepeat(); }\n\n// Parameters stacks (current window)\n// IMGUI_API void PushItemWidth(float item_width); // push width of items for common large \"item+label\" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side). 0.0f = default to ~2/3 of windows width,\n// IMGUI_API void PopItemWidth();\n// IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large \"item+label\" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side)\n// IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.\n// IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // push word-wrapping position for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space\n// IMGUI_API void PopTextWrapPos();\nexport function PushItemWidth(item_width: number): void { bind.PushItemWidth(item_width); }\nexport function PopItemWidth(): void { bind.PopItemWidth(); }\nexport function SetNextItemWidth(item_width: number): void { bind.SetNextItemWidth(item_width); } // set width of the _next_ common large \"item+label\" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side)\nexport function CalcItemWidth(): number { return bind.CalcItemWidth(); }\nexport function PushTextWrapPos(wrap_pos_x: number = 0.0): void { bind.PushTextWrapPos(wrap_pos_x); }\nexport function PopTextWrapPos(): void { bind.PopTextWrapPos(); }\n\n// Style read access\n// IMGUI_API ImFont* GetFont(); // get current font\n// IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied\n// IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API\n// IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier, packed as a 32-bit value suitable for ImDrawList\n// IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList\n// IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList\n// IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwise use GetColorU32() to get style color with style alpha baked in.\nexport function GetFont(): ImFont { return new ImFont(bind.GetFont()); }\nexport function GetFontSize(): number { return bind.GetFontSize(); }\nexport function GetFontTexUvWhitePixel(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetFontTexUvWhitePixel(out); }\nexport function GetColorU32(idx: ImGuiCol, alpha_mul?: number): Bind.ImU32;\nexport function GetColorU32(col: Readonly): Bind.ImU32;\nexport function GetColorU32(col: Bind.ImU32): Bind.ImU32;\nexport function GetColorU32(...args: any[]): Bind.ImU32 {\n if (args.length === 1) {\n if (typeof(args[0]) === \"number\") {\n if (0 <= args[0] && args[0] < ImGuiCol.COUNT) {\n const idx: ImGuiCol = args[0];\n return bind.GetColorU32_A(idx, 1.0);\n }\n else {\n const col: Bind.ImU32 = args[0];\n return bind.GetColorU32_C(col);\n }\n } else {\n const col: Readonly = args[0];\n return bind.GetColorU32_B(col);\n }\n } else {\n const idx: ImGuiCol = args[0];\n const alpha_mul: number = args[1];\n return bind.GetColorU32_A(idx, alpha_mul);\n }\n}\nexport function GetStyleColorVec4(idx: ImGuiCol): Readonly { return bind.GetStyleColorVec4(idx); }\n\n// Cursor / Layout\n// - By \"cursor\" we mean the current output position.\n// - The typical widget behavior is to output themselves at the current cursor position, then move the cursor one line down.\n// - You can call SameLine() between widgets to undo the last carriage return and output at the right of the preceding widget.\n// - Attention! We currently have inconsistencies between window-local and absolute positions we will aim to fix with future API:\n// Window-local coordinates: SameLine(), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), GetWindowContentRegion*(), PushTextWrapPos()\n// Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions.\n// IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator.\n// IMGUI_API void SameLine(float offset_from_start_x=0.0f, float spacing=-1.0f); // call between widgets or groups to layout them horizontally. X position given in window coordinates.\n// IMGUI_API void NewLine(); // undo a SameLine() or force a new line when in an horizontal-layout context.\n// IMGUI_API void Spacing(); // add vertical spacing.\n// IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size. unlike InvisibleButton(), Dummy() won't take the mouse click or be navigable into.\n// IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by indent_w, or style.IndentSpacing if indent_w <= 0\n// IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by indent_w, or style.IndentSpacing if indent_w <= 0\n// IMGUI_API void BeginGroup(); // lock horizontal starting position\n// IMGUI_API void EndGroup(); // unlock horizontal starting position + capture the whole group bounding box into one \"item\" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.)\n// IMGUI_API ImVec2 GetCursorPos(); // cursor position in window coordinates (relative to window position)\n// IMGUI_API float GetCursorPosX(); // (some functions are using window-relative coordinates, such as: GetCursorPos, GetCursorStartPos, GetContentRegionMax, GetWindowContentRegion* etc.\n// IMGUI_API float GetCursorPosY(); // other functions such as GetCursorScreenPos or everything in ImDrawList::\n// IMGUI_API void SetCursorPos(const ImVec2& local_pos); // are using the main, absolute coordinate system.\n// IMGUI_API void SetCursorPosX(float local_x); // GetWindowPos() + GetCursorPos() == GetCursorScreenPos() etc.)\n// IMGUI_API void SetCursorPosY(float local_y); //\n// IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position in window coordinates\n// IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] (useful to work with ImDrawList API)\n// IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize]\n// IMGUI_API void AlignTextToFramePadding(); // vertically align upcoming text baseline to FramePadding.y so that it will align properly to regularly framed items (call if you have text on a line before a framed item)\n// IMGUI_API float GetTextLineHeight(); // ~ FontSize\n// IMGUI_API float GetTextLineHeightWithSpacing(); // ~ FontSize + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of text)\n// IMGUI_API float GetFrameHeight(); // ~ FontSize + style.FramePadding.y * 2\n// IMGUI_API float GetFrameHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets)\nexport function Separator(): void { bind.Separator(); }\nexport function SameLine(pos_x: number = 0.0, spacing_w: number = -1.0): void { bind.SameLine(pos_x, spacing_w); }\nexport function NewLine(): void { bind.NewLine(); }\nexport function Spacing(): void { bind.Spacing(); }\nexport function Dummy(size: Readonly): void { bind.Dummy(size); }\nexport function Indent(indent_w: number = 0.0) { bind.Indent(indent_w); }\nexport function Unindent(indent_w: number = 0.0) { bind.Unindent(indent_w); }\nexport function BeginGroup(): void { bind.BeginGroup(); }\nexport function EndGroup(): void { bind.EndGroup(); }\nexport function GetCursorPos(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetCursorPos(out); }\nexport function GetCursorPosX(): number { return bind.GetCursorPosX(); }\nexport function GetCursorPosY(): number { return bind.GetCursorPosY(); }\nexport function SetCursorPos(local_pos: Readonly): void { bind.SetCursorPos(local_pos); }\nexport function SetCursorPosX(x: number): void { bind.SetCursorPosX(x); }\nexport function SetCursorPosY(y: number): void { bind.SetCursorPosY(y); }\nexport function GetCursorStartPos(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetCursorStartPos(out); }\nexport function GetCursorScreenPos(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetCursorScreenPos(out); }\nexport function SetCursorScreenPos(pos: Readonly): void { bind.SetCursorScreenPos(pos); }\nexport function AlignTextToFramePadding(): void { bind.AlignTextToFramePadding(); }\nexport function GetTextLineHeight(): number { return bind.GetTextLineHeight(); }\nexport function GetTextLineHeightWithSpacing(): number { return bind.GetTextLineHeightWithSpacing(); }\nexport function GetFrameHeight(): number { return bind.GetFrameHeight(); }\nexport function GetFrameHeightWithSpacing(): number { return bind.GetFrameHeightWithSpacing(); }\n\n// ID stack/scopes\n// - Read the FAQ for more details about how ID are handled in dear imgui. If you are creating widgets in a loop you most\n// likely want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them.\n// - The resulting ID are hashes of the entire stack.\n// - You can also use the \"Label##foobar\" syntax within widget label to distinguish them from each others.\n// - In this header file we use the \"label\"/\"name\" terminology to denote a string that will be displayed and used as an ID,\n// whereas \"str_id\" denote a string that is only used as an ID and not normally displayed.\n// IMGUI_API void PushID(const char* str_id); // push string into the ID stack (will hash string).\n// IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string).\n// IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer).\n// IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer).\n// IMGUI_API void PopID(); // pop from the ID stack.\n// IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself\n// IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end);\n// IMGUI_API ImGuiID GetID(const void* ptr_id);\nexport function PushID(id: string | number): void { bind.PushID(id); }\nexport function PopID(): void { bind.PopID(); }\nexport function GetID(id: string | number): ImGuiID { return bind.GetID(id); }\n\n// Widgets: Text\n// IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text(\"%s\", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text.\n// IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // formatted text\n// IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1);\n// IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();\n// IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args) IM_FMTLIST(2);\n// IMGUI_API void TextDisabled(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); Text(fmt, ...); PopStyleColor();\n// IMGUI_API void TextDisabledV(const char* fmt, va_list args) IM_FMTLIST(1);\n// IMGUI_API void TextWrapped(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();. Note that this won't work on an auto-resizing window if there's no other widgets to extend the window width, yoy may need to set a size using SetNextWindowSize().\n// IMGUI_API void TextWrappedV(const char* fmt, va_list args) IM_FMTLIST(1);\n// IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_FMTARGS(2); // display text+label aligned the same way as value+label widgets\n// IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2);\n// IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text()\n// IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1);\nexport function TextUnformatted(text: string, text_end: number | null = null): void { bind.TextUnformatted(text_end !== null ? text.substring(0, text_end) : text); }\nexport function Text(text: string): void { bind.Text(text); }\nexport function TextColored(col: Readonly | Readonly, text: string): void { bind.TextColored((col instanceof ImColor) ? col.Value : col as Readonly, text); }\nexport function TextDisabled(text: string): void { bind.TextDisabled(text); }\nexport function TextWrapped(text: string): void { bind.TextWrapped(text); }\nexport function LabelText(label: string, text: string): void { bind.LabelText(label, text); }\nexport function BulletText(text: string): void { bind.BulletText(text); }\n\n// Widgets: Main\n// - Most widgets return true when the value has been changed or when pressed/selected\n// - You may also use one of the many IsItemXXX functions (e.g. IsItemActive, IsItemHovered, etc.) to query widget state.\n// IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0, 0)); // button\n// IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text\n// IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags = 0); // flexible button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)\n// IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape\n// IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));\n// IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding\n// IMGUI_API bool Checkbox(const char* label, bool* v);\n// IMGUI_API bool CheckboxFlags(const char* label, int* flags, int flags_value);\n// IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);\n// IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton(\"one\", my_value==1)) { my_value = 1; }\n// IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer\n// IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-FLT_MIN, 0), const char* overlay = NULL);\n// IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses\nexport function Button(label: string, size: Readonly = ImVec2.ZERO): boolean { return bind.Button(label, size); }\nexport function SmallButton(label: string): boolean { return bind.SmallButton(label); }\nexport function ArrowButton(str_id: string, dir: ImGuiDir): boolean { return bind.ArrowButton(str_id, dir); }\nexport function InvisibleButton(str_id: string, size: Readonly, flags: ImGuiButtonFlags = 0): boolean { return bind.InvisibleButton(str_id, size, flags); }\nexport function Image(user_texture_id: ImTextureID | null, size: Readonly, uv0: Readonly = ImVec2.ZERO, uv1: Readonly = ImVec2.UNIT, tint_col: Readonly = ImVec4.WHITE, border_col: Readonly = ImVec4.ZERO): void {\n bind.Image(ImGuiContext.setTexture(user_texture_id), size, uv0, uv1, tint_col, border_col);\n}\nexport function ImageButton(user_texture_id: ImTextureID | null, size: Readonly = new ImVec2(Number.MIN_SAFE_INTEGER, 0), uv0: Readonly = ImVec2.ZERO, uv1: Readonly = ImVec2.UNIT, frame_padding: number = -1, bg_col: Readonly = ImVec4.ZERO, tint_col: Readonly = ImVec4.WHITE): boolean {\n return bind.ImageButton(ImGuiContext.setTexture(user_texture_id), size, uv0, uv1, frame_padding, bg_col, tint_col);\n}\nexport function Checkbox(label: string, v: Bind.ImScalar | Bind.ImAccess): boolean {\n if (Array.isArray(v)) {\n return bind.Checkbox(label, v);\n } else {\n const ref_v: Bind.ImScalar = [ v() ];\n const ret = bind.Checkbox(label, ref_v);\n v(ref_v[0]);\n return ret;\n }\n}\nexport function CheckboxFlags(label: string, flags: Bind.ImAccess | Bind.ImScalar, flags_value: number): boolean {\n if (Array.isArray(flags)) {\n return bind.CheckboxFlags(label, flags, flags_value);\n } else {\n const ref_flags: Bind.ImScalar = [ flags() ];\n const ret = bind.CheckboxFlags(label, ref_flags, flags_value);\n flags(ref_flags[0]);\n return ret;\n }\n}\nexport function RadioButton(label: string, active: boolean): boolean;\nexport function RadioButton(label: string, v: Bind.ImAccess | Bind.ImScalar, v_button: number): boolean;\nexport function RadioButton(label: string, ...args: any[]): boolean {\n if (typeof(args[0]) === \"boolean\") {\n const active: boolean = args[0];\n return bind.RadioButton_A(label, active);\n } else {\n const v: Bind.ImAccess | Bind.ImScalar = args[0];\n const v_button: number = args[1];\n const _v: Bind.ImScalar = Array.isArray(v) ? v : [ v() ];\n const ret = bind.RadioButton_B(label, _v, v_button);\n if (!Array.isArray(v)) { v(_v[0]); }\n return ret;\n }\n}\nexport function ProgressBar(fraction: number, size_arg: Readonly = new ImVec2(-1, 0), overlay: string | null = null): void {\n bind.ProgressBar(fraction, size_arg, overlay);\n}\nexport function Bullet(): void { bind.Bullet(); }\n\n// Widgets: Combo Box\n// - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items.\n// - The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose.\n// IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0);\n// IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true!\n// IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1);\n// IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \\0 within a string, end item-list with \\0\\0. e.g. \"One\\0Two\\0Three\\0\"\n// IMGUI_API bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1);\nexport function BeginCombo(label: string, preview_value: string | null = null, flags: ImGuiComboFlags = 0): boolean { return bind.BeginCombo(label, preview_value, flags); }\nexport function EndCombo(): void { bind.EndCombo(); }\nexport type ComboValueGetter = (data: T, idx: number, out_text: [string]) => boolean;\nexport function Combo(label: string, current_item: Bind.ImAccess | Bind.ImScalar, items: string[], items_count?: number, popup_max_height_in_items?: number): boolean;\nexport function Combo(label: string, current_item: Bind.ImAccess | Bind.ImScalar, items_separated_by_zeros: string, popup_max_height_in_items?: number): boolean;\nexport function Combo(label: string, current_item: Bind.ImAccess | Bind.ImScalar, items_getter: ComboValueGetter, data: T, items_count: number, popup_max_height_in_items?: number): boolean;\nexport function Combo(label: string, current_item: Bind.ImAccess | Bind.ImScalar, ...args: any[]): boolean {\n let ret = false;\n const _current_item: Bind.ImScalar = Array.isArray(current_item) ? current_item : [ current_item() ];\n if (Array.isArray(args[0])) {\n const items: string[] = args[0];\n const items_count = typeof(args[1]) === \"number\" ? args[1] : items.length;\n const popup_max_height_in_items: number = typeof(args[2]) === \"number\" ? args[2] : -1;\n const items_getter = (data: null, idx: number, out_text: [string]): boolean => { out_text[0] = items[idx]; return true; };\n ret = bind.Combo(label, _current_item, items_getter, null, items_count, popup_max_height_in_items);\n } else if (typeof(args[0]) === \"string\") {\n const items_separated_by_zeros: string = args[0]\n const popup_max_height_in_items: number = typeof(args[1]) === \"number\" ? args[1] : -1;\n const items: string[] = items_separated_by_zeros.replace(/^\\0+|\\0+$/g, \"\").split(\"\\0\");\n const items_count: number = items.length;\n const items_getter = (data: null, idx: number, out_text: [string]): boolean => { out_text[0] = items[idx]; return true; };\n ret = bind.Combo(label, _current_item, items_getter, null, items_count, popup_max_height_in_items);\n } else {\n const items_getter: (data: T, idx: number, out_text: [string]) => boolean = args[0];\n const data: T = args[1];\n const items_count = args[2];\n const popup_max_height_in_items: number = typeof(args[3]) === \"number\" ? args[3] : -1;\n ret = bind.Combo(label, _current_item, items_getter, data, items_count, popup_max_height_in_items);\n }\n if (!Array.isArray(current_item)) { current_item(_current_item[0]); }\n return ret;\n}\n\n// Widgets: Drag Sliders\n// - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped and can go off-bounds.\n// - For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x\n// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. \"%.3f\" -> 1.234; \"%5.2f secs\" -> 01.23 secs; \"Biscuit: %.0f\" -> Biscuit: 1; etc.\n// - Format string may also be set to NULL or use the default format (\"%f\" or \"%d\").\n// - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision).\n// - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits.\n// - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum.\n// - We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them.\n// - Legacy: Pre-1.78 there are DragXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument.\n// If you get a warning converting a float to ImGuiSliderFlags, read https://github.com/ocornut/imgui/issues/3361\n// IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0); // If v_min >= v_max we have no bound\n// IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = \"%.3f\", const char* format_max = NULL, ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = \"%d\", ImGuiSliderFlags flags = 0); // If v_min >= v_max we have no bound\n// IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = \"%d\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = \"%d\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = \"%d\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = \"%d\", const char* format_max = NULL, ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0);\n// IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0);\nexport function DragFloat(label: string, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_speed: number = 1.0, v_min: number = 0.0, v_max: number = 0.0, display_format: string | null = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.DragFloat(label, _v, v_speed, v_min, v_max, display_format, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function DragFloat2(label: string, v: XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4 | ImVec2, v_speed: number = 1.0, v_min: number = 0.0, v_max: number = 0.0, display_format: string = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector2(v);\n const ret = bind.DragFloat2(label, _v, v_speed, v_min, v_max, display_format, flags);\n export_Vector2(_v, v);\n return ret;\n}\nexport function DragFloat3(label: string, v: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4, v_speed: number = 1.0, v_min: number = 0.0, v_max: number = 0.0, display_format: string = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector3(v);\n const ret = bind.DragFloat3(label, _v, v_speed, v_min, v_max, display_format, flags);\n export_Vector3(_v, v);\n return ret;\n}\nexport function DragFloat4(label: string, v: XYZW | Bind.ImTuple4 | ImVec4, v_speed: number = 1.0, v_min: number = 0.0, v_max: number = 0.0, display_format: string = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector4(v);\n const ret = bind.DragFloat4(label, _v, v_speed, v_min, v_max, display_format, flags);\n export_Vector4(_v, v);\n return ret;\n}\nexport function DragFloatRange2(label: string, v_current_min: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_current_max: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_speed: number = 1.0, v_min: number = 0.0, v_max: number = 0.0, display_format: string = \"%.3f\", display_format_max: string | null = null, flags: ImGuiSliderFlags = 0): boolean {\n const _v_current_min = import_Scalar(v_current_min);\n const _v_current_max = import_Scalar(v_current_max);\n const ret = bind.DragFloatRange2(label, _v_current_min, _v_current_max, v_speed, v_min, v_max, display_format, display_format_max, flags);\n export_Scalar(_v_current_min, v_current_min);\n export_Scalar(_v_current_max, v_current_max);\n return ret;\n}\nexport function DragInt(label: string, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_speed: number = 1.0, v_min: number = 0, v_max: number = 0, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.DragInt(label, _v, v_speed, v_min, v_max, format, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function DragInt2(label: string, v: XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_speed: number = 1.0, v_min: number = 0, v_max: number = 0, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector2(v);\n const ret = bind.DragInt2(label, _v, v_speed, v_min, v_max, format, flags);\n export_Vector2(_v, v);\n return ret;\n}\nexport function DragInt3(label: string, v: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4, v_speed: number = 1.0, v_min: number = 0, v_max: number = 0, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector3(v);\n const ret = bind.DragInt3(label, _v, v_speed, v_min, v_max, format, flags);\n export_Vector3(_v, v);\n return ret;\n}\nexport function DragInt4(label: string, v: XYZW | Bind.ImTuple4, v_speed: number = 1.0, v_min: number = 0, v_max: number = 0, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector4(v);\n const ret = bind.DragInt4(label, _v, v_speed, v_min, v_max, format, flags);\n export_Vector4(_v, v);\n return ret;\n}\nexport function DragIntRange2(label: string, v_current_min: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_current_max: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_speed: number = 1.0, v_min: number = 0, v_max: number = 0, format: string = \"%d\", format_max: string | null = null, flags: ImGuiSliderFlags = 0): boolean {\n const _v_current_min = import_Scalar(v_current_min);\n const _v_current_max = import_Scalar(v_current_max);\n const ret = bind.DragIntRange2(label, _v_current_min, _v_current_max, v_speed, v_min, v_max, format, format_max, flags);\n export_Scalar(_v_current_min, v_current_min);\n export_Scalar(_v_current_max, v_current_max);\n return ret;\n}\nexport function DragScalar(label: string, v: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array, v_speed: number = 1.0, v_min: number | null = null, v_max: number | null = null, format: string | null = null, flags: ImGuiSliderFlags = 0): boolean {\n if (v instanceof Int8Array) { return bind.DragScalar(label, ImGuiDataType.S8, v, v_speed, v_min, v_max, format, flags); }\n if (v instanceof Uint8Array) { return bind.DragScalar(label, ImGuiDataType.U8, v, v_speed, v_min, v_max, format, flags); }\n if (v instanceof Int16Array) { return bind.DragScalar(label, ImGuiDataType.S16, v, v_speed, v_min, v_max, format, flags); }\n if (v instanceof Uint16Array) { return bind.DragScalar(label, ImGuiDataType.U16, v, v_speed, v_min, v_max, format, flags); }\n if (v instanceof Int32Array) { return bind.DragScalar(label, ImGuiDataType.S32, v, v_speed, v_min, v_max, format, flags); }\n if (v instanceof Uint32Array) { return bind.DragScalar(label, ImGuiDataType.U32, v, v_speed, v_min, v_max, format, flags); }\n // if (v instanceof Int64Array) { return bind.DragScalar(label, ImGuiDataType.S64, v, v_speed, v_min, v_max, format, flags); }\n // if (v instanceof Uint64Array) { return bind.DragScalar(label, ImGuiDataType.U64, v, v_speed, v_min, v_max, format, flags); }\n if (v instanceof Float32Array) { return bind.DragScalar(label, ImGuiDataType.Float, v, v_speed, v_min, v_max, format, flags); }\n if (v instanceof Float64Array) { return bind.DragScalar(label, ImGuiDataType.Double, v, v_speed, v_min, v_max, format, flags); }\n throw new Error();\n}\n\n// Widgets: Regular Sliders\n// - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped and can go off-bounds.\n// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. \"%.3f\" -> 1.234; \"%5.2f secs\" -> 01.23 secs; \"Biscuit: %.0f\" -> Biscuit: 1; etc.\n// - Format string may also be set to NULL or use the default format (\"%f\" or \"%d\").\n// - Legacy: Pre-1.78 there are SliderXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument.\n// If you get a warning converting a float to ImGuiSliderFlags, read https://github.com/ocornut/imgui/issues/3361\n// IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0); // adjust format to decorate the value with a prefix or a suffix for in-slider labels or unit display.\n// IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f, const char* format = \"%.0f deg\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* format = \"%d\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format = \"%d\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format = \"%d\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format = \"%d\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0);\n// IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0);\n// IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format = \"%.3f\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format = \"%d\", ImGuiSliderFlags flags = 0);\n// IMGUI_API bool VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0);\nexport function SliderFloat(label: string, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_min: number, v_max: number, format: string = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.SliderFloat(label, _v, v_min, v_max, format, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function SliderFloat2(label: string, v: XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec2, v_min: number, v_max: number, format: string = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector2(v);\n const ret = bind.SliderFloat2(label, _v, v_min, v_max, format, flags);\n export_Vector2(_v, v);\n return ret;\n}\nexport function SliderFloat3(label: string, v: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4, v_min: number, v_max: number, format: string = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector3(v);\n const ret = bind.SliderFloat3(label, _v, v_min, v_max, format, flags);\n export_Vector3(_v, v);\n return ret;\n}\nexport function SliderFloat4(label: string, v: XYZW | Bind.ImTuple4 | XYZW, v_min: number, v_max: number, format: string = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector4(v);\n const ret = bind.SliderFloat4(label, _v, v_min, v_max, format, flags);\n export_Vector4(_v, v);\n return ret;\n}\nexport function SliderAngle(label: string, v_rad: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_degrees_min: number = -360.0, v_degrees_max: number = +360.0, format: string = \"%.0f deg\", flags: ImGuiSliderFlags = 0): boolean {\n const _v_rad = import_Scalar(v_rad);\n const ret = bind.SliderAngle(label, _v_rad, v_degrees_min, v_degrees_max, format, flags);\n export_Scalar(_v_rad, v_rad);\n return ret;\n}\nexport function SliderAngle3(label: string, v_rad: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4, v_degrees_min: number = -360.0, v_degrees_max: number = +360.0, format: string = \"%.0f deg\", flags: ImGuiSliderFlags = 0): boolean {\n const _v_rad = import_Vector3(v_rad);\n _v_rad[0] = Math.floor(_v_rad[0] * 180 / Math.PI);\n _v_rad[1] = Math.floor(_v_rad[1] * 180 / Math.PI);\n _v_rad[2] = Math.floor(_v_rad[2] * 180 / Math.PI);\n const ret = bind.SliderInt3(label, _v_rad, v_degrees_min, v_degrees_max, format, flags);\n _v_rad[0] = _v_rad[0] * Math.PI / 180;\n _v_rad[1] = _v_rad[1] * Math.PI / 180;\n _v_rad[2] = _v_rad[2] * Math.PI / 180;\n export_Vector3(_v_rad, v_rad);\n return ret;\n}\nexport function SliderInt(label: string, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_min: number, v_max: number, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.SliderInt(label, _v, v_min, v_max, format, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function SliderInt2(label: string, v: XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_min: number, v_max: number, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector2(v);\n const ret = bind.SliderInt2(label, _v, v_min, v_max, format, flags);\n export_Vector2(_v, v);\n return ret;\n}\nexport function SliderInt3(label: string, v: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4, v_min: number, v_max: number, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector3(v);\n const ret = bind.SliderInt3(label, _v, v_min, v_max, format, flags);\n export_Vector3(_v, v);\n return ret;\n}\nexport function SliderInt4(label: string, v: XYZW | Bind.ImTuple4, v_min: number, v_max: number, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Vector4(v);\n const ret = bind.SliderInt4(label, _v, v_min, v_max, format, flags);\n export_Vector4(_v, v);\n return ret;\n}\nexport function SliderScalar(label: string, v: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array, v_min: number, v_max: number, format: string | null = null, flags: ImGuiSliderFlags = 0): boolean {\n if (v instanceof Int8Array) { return bind.SliderScalar(label, ImGuiDataType.S8, v, v_min, v_max, format, flags); }\n if (v instanceof Uint8Array) { return bind.SliderScalar(label, ImGuiDataType.U8, v, v_min, v_max, format, flags); }\n if (v instanceof Int16Array) { return bind.SliderScalar(label, ImGuiDataType.S16, v, v_min, v_max, format, flags); }\n if (v instanceof Uint16Array) { return bind.SliderScalar(label, ImGuiDataType.U16, v, v_min, v_max, format, flags); }\n if (v instanceof Int32Array) { return bind.SliderScalar(label, ImGuiDataType.S32, v, v_min, v_max, format, flags); }\n if (v instanceof Uint32Array) { return bind.SliderScalar(label, ImGuiDataType.U32, v, v_min, v_max, format, flags); }\n // if (v instanceof Int64Array) { return bind.SliderScalar(label, ImGuiDataType.S64, v, v_min, v_max, format, flags); }\n // if (v instanceof Uint64Array) { return bind.SliderScalar(label, ImGuiDataType.U64, v, v_min, v_max, format, flags); }\n if (v instanceof Float32Array) { return bind.SliderScalar(label, ImGuiDataType.Float, v, v_min, v_max, format, flags); }\n if (v instanceof Float64Array) { return bind.SliderScalar(label, ImGuiDataType.Double, v, v_min, v_max, format, flags); }\n throw new Error();\n}\nexport function VSliderFloat(label: string, size: Readonly, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_min: number, v_max: number, format: string = \"%.3f\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.VSliderFloat(label, size, _v, v_min, v_max, format, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function VSliderInt(label: string, size: Readonly, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, v_min: number, v_max: number, format: string = \"%d\", flags: ImGuiSliderFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.VSliderInt(label, size, _v, v_min, v_max, format, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function VSliderScalar(label: string, size: Readonly, data_type: ImGuiDataType, v: Bind.ImAccess | Bind.ImScalar, v_min: number, v_max: number, format: string | null = null, flags: ImGuiSliderFlags = 0): boolean {\n if (v instanceof Int8Array) { return bind.VSliderScalar(label, size, ImGuiDataType.S8, v, v_min, v_max, format, flags); }\n if (v instanceof Uint8Array) { return bind.VSliderScalar(label, size, ImGuiDataType.U8, v, v_min, v_max, format, flags); }\n if (v instanceof Int16Array) { return bind.VSliderScalar(label, size, ImGuiDataType.S16, v, v_min, v_max, format, flags); }\n if (v instanceof Uint16Array) { return bind.VSliderScalar(label, size, ImGuiDataType.U16, v, v_min, v_max, format, flags); }\n if (v instanceof Int32Array) { return bind.VSliderScalar(label, size, ImGuiDataType.S32, v, v_min, v_max, format, flags); }\n if (v instanceof Uint32Array) { return bind.VSliderScalar(label, size, ImGuiDataType.U32, v, v_min, v_max, format, flags); }\n // if (v instanceof Int64Array) { return bind.VSliderScalar(label, size, ImGuiDataType.S64, v, v_min, v_max, format, flags); }\n // if (v instanceof Uint64Array) { return bind.VSliderScalar(label, size, ImGuiDataType.U64, v, v_min, v_max, format, flags); }\n if (v instanceof Float32Array) { return bind.VSliderScalar(label, size, ImGuiDataType.Float, v, v_min, v_max, format, flags); }\n if (v instanceof Float64Array) { return bind.VSliderScalar(label, size, ImGuiDataType.Double, v, v_min, v_max, format, flags); }\n throw new Error();\n}\n\n// Widgets: Input with Keyboard\n// - If you want to use InputText() with std::string or any custom dynamic string type, see misc/cpp/imgui_stdlib.h and comments in imgui_demo.cpp.\n// - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc.\n// IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);\n// IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);\n// IMGUI_API bool InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);\n// IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = \"%.3f\", ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputFloat2(const char* label, float v[2], const char* format = \"%.3f\", ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputFloat3(const char* label, float v[3], const char* format = \"%.3f\", ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputFloat4(const char* label, float v[4], const char* format = \"%.3f\", ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputDouble(const char* label, double* v, double step = 0.0, double step_fast = 0.0, const char* format = \"%.6f\", ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step = NULL, const void* p_step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0);\n// IMGUI_API bool InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step = NULL, const void* p_step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0);\nexport function InputText(label: string, buf: ImStringBuffer | Bind.ImAccess | Bind.ImScalar, buf_size: number = buf instanceof ImStringBuffer ? buf.size : ImGuiInputTextDefaultSize, flags: ImGuiInputTextFlags = 0, callback: ImGuiInputTextCallback | null = null, user_data: T | null = null): boolean {\n const _callback = callback && ((data: Bind.reference_ImGuiInputTextCallbackData): number => callback(new ImGuiInputTextCallbackData(data, user_data))) || null;\n if (Array.isArray(buf)) {\n return bind.InputText(label, buf, buf_size, flags, _callback, null);\n } else if (buf instanceof ImStringBuffer) {\n const ref_buf: Bind.ImScalar = [ buf.buffer ];\n const _buf_size: number = Math.min(buf_size, buf.size);\n const ret: boolean = bind.InputText(label, ref_buf, _buf_size, flags, _callback, null);\n buf.buffer = ref_buf[0];\n return ret;\n } else {\n const ref_buf: Bind.ImScalar = [ buf() ];\n const ret: boolean = bind.InputText(label, ref_buf, buf_size + 1, flags, _callback, null);\n buf(ref_buf[0]);\n return ret;\n }\n}\nexport function InputTextMultiline(label: string, buf: ImStringBuffer | Bind.ImAccess | Bind.ImScalar, buf_size: number = buf instanceof ImStringBuffer ? buf.size : ImGuiInputTextDefaultSize, size: Readonly = ImVec2.ZERO, flags: ImGuiInputTextFlags = 0, callback: ImGuiInputTextCallback | null = null, user_data: T | null = null): boolean {\n const _callback = callback && ((data: Bind.reference_ImGuiInputTextCallbackData): number => callback(new ImGuiInputTextCallbackData(data, user_data))) || null;\n if (Array.isArray(buf)) {\n return bind.InputTextMultiline(label, buf, buf_size, size, flags, _callback, null);\n } else if (buf instanceof ImStringBuffer) {\n const ref_buf: Bind.ImScalar = [ buf.buffer ];\n const _buf_size: number = Math.min(buf_size, buf.size);\n const ret: boolean = bind.InputTextMultiline(label, ref_buf, _buf_size, size, flags, _callback, null);\n buf.buffer = ref_buf[0];\n return ret;\n } else {\n const ref_buf: Bind.ImScalar = [ buf() ];\n const ret: boolean = bind.InputTextMultiline(label, ref_buf, buf_size, size, flags, _callback, null);\n buf(ref_buf[0]);\n return ret;\n }\n}\nexport function InputTextWithHint(label: string, hint: string, buf: ImStringBuffer | Bind.ImAccess | Bind.ImScalar, buf_size: number = buf instanceof ImStringBuffer ? buf.size : ImGuiInputTextDefaultSize, flags: ImGuiInputTextFlags = 0, callback: ImGuiInputTextCallback | null = null, user_data: T | null = null): boolean {\n const _callback = callback && ((data: Bind.reference_ImGuiInputTextCallbackData): number => callback(new ImGuiInputTextCallbackData(data, user_data))) || null;\n if (Array.isArray(buf)) {\n return bind.InputTextWithHint(label, hint, buf, buf_size, flags, _callback, null);\n } else if (buf instanceof ImStringBuffer) {\n const ref_buf: Bind.ImScalar = [ buf.buffer ];\n const _buf_size: number = Math.min(buf_size, buf.size);\n const ret: boolean = bind.InputTextWithHint(label, hint, ref_buf, _buf_size, flags, _callback, null);\n buf.buffer = ref_buf[0];\n return ret;\n } else {\n const ref_buf: Bind.ImScalar = [ buf() ];\n const ret: boolean = bind.InputTextWithHint(label, hint, ref_buf, buf_size, flags, _callback, null);\n buf(ref_buf[0]);\n return ret;\n }\n}\nexport function InputFloat(label: string, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, step: number = 0.0, step_fast: number = 0.0, format: string = \"%.3f\", flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.InputFloat(label, _v, step, step_fast, format, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function InputFloat2(label: string, v: XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, format: string = \"%.3f\", flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Vector2(v);\n const ret = bind.InputFloat2(label, _v, format, flags);\n export_Vector2(_v, v);\n return ret;\n}\nexport function InputFloat3(label: string, v: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4, format: string = \"%.3f\", flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Vector3(v);\n const ret = bind.InputFloat3(label, _v, format, flags);\n export_Vector3(_v, v);\n return ret;\n}\nexport function InputFloat4(label: string, v: XYZW | Bind.ImTuple4, format: string = \"%.3f\", flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Vector4(v);\n const ret = bind.InputFloat4(label, _v, format, flags);\n export_Vector4(_v, v);\n return ret;\n}\nexport function InputInt(label: string, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, step: number = 1, step_fast: number = 100, flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.InputInt(label, _v, step, step_fast, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function InputInt2(label: string, v: XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Vector2(v);\n const ret = bind.InputInt2(label, _v, flags);\n export_Vector2(_v, v);\n return ret;\n}\nexport function InputInt3(label: string, v: XYZ | XYZW | Bind.ImTuple3 | Bind.ImTuple4, flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Vector3(v);\n const ret = bind.InputInt3(label, _v, flags);\n export_Vector3(_v, v);\n return ret;\n}\nexport function InputInt4(label: string, v: XYZW | Bind.ImTuple4, flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Vector4(v);\n const ret = bind.InputInt4(label, _v, flags);\n export_Vector4(_v, v);\n return ret;\n}\nexport function InputDouble(label: string, v: Bind.ImAccess | Bind.ImScalar | XY | XYZ | XYZW | Bind.ImTuple2 | Bind.ImTuple3 | Bind.ImTuple4, step: number = 0.0, step_fast: number = 0.0, format: string = \"%.6f\", flags: ImGuiInputTextFlags = 0): boolean {\n const _v = import_Scalar(v);\n const ret = bind.InputDouble(label, _v, step, step_fast, format, flags);\n export_Scalar(_v, v);\n return ret;\n}\nexport function InputScalar(label: string, v: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array, step: number | null = null, step_fast: number | null = null, format: string | null = null, flags: ImGuiInputTextFlags = 0): boolean {\n if (v instanceof Int8Array) { return bind.InputScalar(label, ImGuiDataType.S8, v, step, step_fast, format, flags); }\n if (v instanceof Uint8Array) { return bind.InputScalar(label, ImGuiDataType.U8, v, step, step_fast, format, flags); }\n if (v instanceof Int16Array) { return bind.InputScalar(label, ImGuiDataType.S16, v, step, step_fast, format, flags); }\n if (v instanceof Uint16Array) { return bind.InputScalar(label, ImGuiDataType.U16, v, step, step_fast, format, flags); }\n if (v instanceof Int32Array) { return bind.InputScalar(label, ImGuiDataType.S32, v, step, step_fast, format, flags); }\n if (v instanceof Uint32Array) { return bind.InputScalar(label, ImGuiDataType.U32, v, step, step_fast, format, flags); }\n // if (v instanceof Int64Array) { return bind.InputScalar(label, ImGuiDataType.S64, v, step, step_fast, format, flags); }\n // if (v instanceof Uint64Array) { return bind.InputScalar(label, ImGuiDataType.U64, v, step, step_fast, format, flags); }\n if (v instanceof Float32Array) { return bind.InputScalar(label, ImGuiDataType.Float, v, step, step_fast, format, flags); }\n if (v instanceof Float64Array) { return bind.InputScalar(label, ImGuiDataType.Double, v, step, step_fast, format, flags); }\n throw new Error();\n}\n\n// Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little color square that can be left-clicked to open a picker, and right-clicked to open an option menu.)\n// - Note that in C++ a 'float v[X]' function argument is the _same_ as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible.\n// - You can pass the address of a first float element out of a contiguous structure, e.g. &myvector.x\n// IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0);\n// IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0);\n// IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0);\n// IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL);\n// IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0, 0)); // display a color square/button, hover for details, return true when pressed.\n// IMGUI_API void SetColorEditOptions(ImGuiColorEditFlags flags); // initialize current options (generally on application startup) if you want to select a default format, picker type, etc. User will be able to change many settings, unless you pass the _NoOptions flag to your calls.\nexport function ColorEdit3(label: string, col: RGB | RGBA | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4, flags: ImGuiColorEditFlags = 0): boolean {\n const _col = import_Color3(col);\n const ret = bind.ColorEdit3(label, _col, flags);\n export_Color3(_col, col);\n return ret;\n}\nexport function ColorEdit4(label: string, col: RGBA | Bind.ImTuple4 | Bind.interface_ImVec4, flags: ImGuiColorEditFlags = 0): boolean {\n const _col = import_Color4(col);\n const ret = bind.ColorEdit4(label, _col, flags);\n export_Color4(_col, col);\n return ret;\n}\nexport function ColorPicker3(label: string, col: RGB | RGBA | Bind.ImTuple3 | Bind.ImTuple4 | Bind.interface_ImVec4, flags: ImGuiColorEditFlags = 0): boolean {\n const _col = import_Color3(col);\n const ret = bind.ColorPicker3(label, _col, flags);\n export_Color3(_col, col);\n return ret;\n}\nexport function ColorPicker4(label: string, col: RGBA | Bind.ImTuple4 | Bind.interface_ImVec4, flags: ImGuiColorEditFlags = 0, ref_col: Bind.ImTuple4 | Bind.interface_ImVec4 | null = null): boolean {\n const _col = import_Color4(col);\n const _ref_col = ref_col ? import_Color4(ref_col) : null;\n const ret = bind.ColorPicker4(label, _col, flags, _ref_col);\n export_Color4(_col, col);\n if (_ref_col && ref_col) { export_Color4(_ref_col, ref_col); }\n return ret;\n}\nexport function ColorButton(desc_id: string, col: Readonly, flags: ImGuiColorEditFlags = 0, size: Readonly = ImVec2.ZERO): boolean {\n return bind.ColorButton(desc_id, col, flags, size);\n}\nexport function SetColorEditOptions(flags: ImGuiColorEditFlags): void {\n bind.SetColorEditOptions(flags);\n}\n\n// Widgets: Trees\n// - TreeNode functions return true when the node is open, in which case you need to also call TreePop() when you are finished displaying the tree node contents.\n// IMGUI_API bool TreeNode(const char* label);\n// IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // helper variation to easily decorelate the id from the displayed string. Read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet().\n// IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(2); // \"\n// IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(2);\n// IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(2);\n// IMGUI_API bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0);\n// IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3);\n// IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3);\n// IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3);\n// IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3);\n// IMGUI_API void TreePush(const char* str_id); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call TreePush/TreePop yourself if desired.\n// IMGUI_API void TreePush(const void* ptr_id = NULL); // \"\n// IMGUI_API void TreePop(); // ~ Unindent()+PopId()\n// IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode\n// IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop().\n// IMGUI_API bool CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags = 0); // when 'p_visible != NULL': if '*p_visible==true' display an additional small close button on upper right of the header which will set the bool to false when clicked, if '*p_visible==false' don't display the header.\n// IMGUI_API void SetNextItemOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state.\nexport function TreeNode(label: string): boolean;\nexport function TreeNode(label: string, fmt: string): boolean;\nexport function TreeNode(label: number, fmt: string): boolean;\nexport function TreeNode(...args: any[]): boolean {\n if (typeof(args[0]) === \"string\") {\n if (args.length === 1) {\n const label: string = args[0];\n return bind.TreeNode_A(label);\n } else {\n const str_id: string = args[0];\n const fmt: string = args[1];\n return bind.TreeNode_B(str_id, fmt);\n }\n } else {\n const ptr_id: number = args[0];\n const fmt: string = args[1];\n return bind.TreeNode_C(ptr_id, fmt);\n }\n}\nexport function TreeNodeEx(label: string, flags?: ImGuiTreeNodeFlags): boolean;\nexport function TreeNodeEx(str_id: string, flags: ImGuiTreeNodeFlags, fmt: string): boolean;\nexport function TreeNodeEx(ptr_id: number, flags: ImGuiTreeNodeFlags, fmt: string): boolean;\nexport function TreeNodeEx(...args: any[]): boolean {\n if (typeof(args[0]) === \"string\") {\n if (args.length < 3) {\n const label: string = args[0];\n const flags: ImGuiTreeNodeFlags = args[1] || 0;\n return bind.TreeNodeEx_A(label, flags);\n } else {\n const str_id: string = args[0];\n const flags: ImGuiTreeNodeFlags = args[1];\n const fmt: string = args[2];\n return bind.TreeNodeEx_B(str_id, flags, fmt);\n }\n } else {\n const ptr_id: number = args[0];\n const flags: ImGuiTreeNodeFlags = args[1];\n const fmt: string = args[2];\n return bind.TreeNodeEx_C(ptr_id, flags, fmt);\n }\n}\nexport function TreePush(str_id: string): void;\nexport function TreePush(ptr_id: number): void;\nexport function TreePush(...args: any[]): void {\n if (typeof(args[0]) === \"string\") {\n const str_id: string = args[0];\n bind.TreePush_A(str_id);\n } else {\n const ptr_id: number = args[0];\n bind.TreePush_B(ptr_id);\n }\n}\nexport function TreePop(): void { bind.TreePop(); }\nexport function GetTreeNodeToLabelSpacing(): number { return bind.GetTreeNodeToLabelSpacing(); }\nexport function CollapsingHeader(label: string, flags?: ImGuiTreeNodeFlags): boolean;\nexport function CollapsingHeader(label: string, p_open: Bind.ImScalar | Bind.ImAccess, flags?: ImGuiTreeNodeFlags): boolean;\nexport function CollapsingHeader(label: string, ...args: any[]): boolean {\n if (args.length === 0) {\n return bind.CollapsingHeader_A(label, 0);\n } else {\n if (typeof(args[0]) === \"number\") {\n const flags: ImGuiTreeNodeFlags = args[0];\n return bind.CollapsingHeader_A(label, flags);\n } else {\n const p_open: Bind.ImScalar | Bind.ImAccess = args[0];\n const flags: ImGuiTreeNodeFlags = args[1] || 0;\n const ref_open: Bind.ImScalar = Array.isArray(p_open) ? p_open : [ p_open() ];\n const ret = bind.CollapsingHeader_B(label, ref_open, flags);\n if (!Array.isArray(p_open)) { p_open(ref_open[0]); }\n return ret;\n }\n }\n}\nexport function SetNextItemOpen(is_open: boolean, cond: ImGuiCond = 0): void {\n bind.SetNextItemOpen(is_open, cond);\n}\n\n// Widgets: Selectables\n// - A selectable highlights when hovered, and can display another color when selected.\n// - Neighbors selectable extend their highlight bounds in order to leave no gap between them. This is so a series of selected Selectable appear contiguous.\n// IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // \"bool selected\" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height\n// IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // \"bool* p_selected\" point to the selection state (read-write), as a convenient helper.\nexport function Selectable(label: string, selected?: boolean, flags?: ImGuiSelectableFlags, size?: Readonly): boolean;\nexport function Selectable(label: string, p_selected: Bind.ImScalar | Bind.ImAccess, flags?: ImGuiSelectableFlags, size?: Readonly): boolean;\nexport function Selectable(label: string, ...args: any[]): boolean {\n if (args.length === 0) {\n return bind.Selectable_A(label, false, 0, ImVec2.ZERO);\n } else {\n if (typeof(args[0]) === \"boolean\") {\n const selected: boolean = args[0];\n const flags: ImGuiSelectableFlags = args[1] || 0;\n const size: Readonly = args[2] || ImVec2.ZERO;\n return bind.Selectable_A(label, selected, flags, size);\n } else {\n const p_selected: Bind.ImScalar | Bind.ImAccess = args[0];\n const flags: ImGuiSelectableFlags = args[1] || 0;\n const size: Readonly = args[2] || ImVec2.ZERO;\n const ref_selected: Bind.ImScalar = Array.isArray(p_selected) ? p_selected : [ p_selected() ];\n const ret = bind.Selectable_B(label, ref_selected, flags, size);\n if (!Array.isArray(p_selected)) { p_selected(ref_selected[0]); }\n return ret;\n }\n }\n}\n\n// Widgets: List Boxes\n// - FIXME: To be consistent with all the newer API, ListBoxHeader/ListBoxFooter should in reality be called BeginListBox/EndListBox. Will rename them.\n// IMGUI_API bool BeginListBox(const char* label, const ImVec2& size = ImVec2(0, 0)); // open a framed scrolling region\n// IMGUI_API void EndListBox(); // only call EndListBox() if BeginListBox() returned true!\n// IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1);\n// IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);\nexport function BeginListBox(label: string, size: Readonly = new ImVec2(0, 0)): boolean {\n return bind.BeginListBox(label, size);\n}\nexport function EndListBox(): void { bind.EndListBox(); }\nexport type ListBoxItemGetter = (data: T, idx: number, out_text: [string]) => boolean;\nexport function ListBox(label: string, current_item: Bind.ImAccess | Bind.ImScalar, items: string[], items_count?: number, height_in_items?: number): boolean;\nexport function ListBox(label: string, current_item: Bind.ImAccess | Bind.ImScalar, items_getter: ListBoxItemGetter, data: T, items_count: number, height_in_items?: number): boolean;\nexport function ListBox(label: string, current_item: Bind.ImAccess | Bind.ImScalar, ...args: any[]): boolean {\n let ret: boolean = false;\n const _current_item: Bind.ImScalar = Array.isArray(current_item) ? current_item : [ current_item() ];\n if (Array.isArray(args[0])) {\n const items: string[] = args[0];\n const items_count: number = typeof(args[1]) === \"number\" ? args[1] : items.length;\n const height_in_items: number = typeof(args[2]) === \"number\" ? args[2] : -1;\n ret = bind.ListBox_A(label, _current_item, items, items_count, height_in_items);\n } else {\n const items_getter: ListBoxItemGetter = args[0];\n const data: any = args[1];\n const items_count: number = args[2];\n const height_in_items: number = typeof(args[3]) === \"number\" ? args[3] : -1;\n ret = bind.ListBox_B(label, _current_item, items_getter, data, items_count, height_in_items);\n }\n if (!Array.isArray(current_item)) { current_item(_current_item[0]); }\n return ret;\n}\n\n// Widgets: Data Plotting\n// IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));\n// IMGUI_API void PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0));\n// IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));\n// IMGUI_API void PlotHistogram(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0));\nexport type PlotLinesValueGetter = (data: T, idx: number) => number;\nexport function PlotLines(label: string, values: ArrayLike, values_count?: number, value_offset?: number, overlay_text?: string | null, scale_min?: number, scale_max?: number, graph_size?: Readonly, stride?: number): void;\nexport function PlotLines(label: string, values_getter: PlotLinesValueGetter, data: T, values_count?: number, value_offset?: number, overlay_text?: string | null, scale_min?: number, scale_max?: number, graph_size?: Readonly): void;\nexport function PlotLines(label: string, ...args: any[]): void {\n if (Array.isArray(args[0])) {\n const values: ArrayLike = args[0];\n const values_getter: PlotLinesValueGetter = (data: null, idx: number): number => values[idx * stride];\n const values_count: number = typeof(args[1]) === \"number\" ? args[1] : values.length;\n const values_offset: number = typeof(args[2]) === \"number\" ? args[2] : 0;\n const overlay_text: string | null = typeof(args[3]) === \"string\" ? args[3] : null;\n const scale_min: number = typeof(args[4]) === \"number\" ? args[4] : Number.MAX_VALUE;\n const scale_max: number = typeof(args[5]) === \"number\" ? args[5] : Number.MAX_VALUE;\n const graph_size: Readonly = args[6] || ImVec2.ZERO;\n const stride: number = typeof(args[7]) === \"number\" ? args[7] : 1;\n bind.PlotLines(label, values_getter, null, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);\n } else {\n const values_getter: PlotLinesValueGetter = args[0];\n const data: any = args[1];\n const values_count: number = args[2];\n const values_offset: number = typeof(args[3]) === \"number\" ? args[3] : 0;\n const overlay_text: string | null = typeof(args[4]) === \"string\" ? args[4] : null;\n const scale_min: number = typeof(args[5]) === \"number\" ? args[5] : Number.MAX_VALUE;\n const scale_max: number = typeof(args[6]) === \"number\" ? args[6] : Number.MAX_VALUE;\n const graph_size: Readonly = args[7] || ImVec2.ZERO;\n bind.PlotLines(label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);\n }\n}\nexport type PlotHistogramValueGetter = (data: T, idx: number) => number;\nexport function PlotHistogram(label: string, values: ArrayLike, values_count?: number, value_offset?: number, overlay_text?: string | null, scale_min?: number, scale_max?: number, graph_size?: Readonly, stride?: number): void;\nexport function PlotHistogram(label: string, values_getter: PlotHistogramValueGetter, data: T, values_count?: number, value_offset?: number, overlay_text?: string | null, scale_min?: number, scale_max?: number, graph_size?: Readonly): void;\nexport function PlotHistogram(label: string, ...args: any[]): void {\n if (Array.isArray(args[0])) {\n const values: ArrayLike = args[0];\n const values_getter: PlotHistogramValueGetter = (data: null, idx: number): number => values[idx * stride];\n const values_count: number = typeof(args[1]) === \"number\" ? args[1] : values.length;\n const values_offset: number = typeof(args[2]) === \"number\" ? args[2] : 0;\n const overlay_text: string | null = typeof(args[3]) === \"string\" ? args[3] : null;\n const scale_min: number = typeof(args[4]) === \"number\" ? args[4] : Number.MAX_VALUE;\n const scale_max: number = typeof(args[5]) === \"number\" ? args[5] : Number.MAX_VALUE;\n const graph_size: Readonly = args[6] || ImVec2.ZERO;\n const stride: number = typeof(args[7]) === \"number\" ? args[7] : 1;\n bind.PlotHistogram(label, values_getter, null, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);\n } else {\n const values_getter: PlotHistogramValueGetter = args[0];\n const data: T = args[1];\n const values_count: number = args[2];\n const values_offset: number = typeof(args[3]) === \"number\" ? args[3] : 0;\n const overlay_text: string | null = typeof(args[4]) === \"string\" ? args[4] : null;\n const scale_min: number = typeof(args[5]) === \"number\" ? args[5] : Number.MAX_VALUE;\n const scale_max: number = typeof(args[6]) === \"number\" ? args[6] : Number.MAX_VALUE;\n const graph_size: Readonly = args[7] || ImVec2.ZERO;\n bind.PlotHistogram(label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);\n }\n}\n\n// Widgets: Value() Helpers.\n// - Those are merely shortcut to calling Text() with a format string. Output single value in \"name: value\" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace)\n// IMGUI_API void Value(const char* prefix, bool b);\n// IMGUI_API void Value(const char* prefix, int v);\n// IMGUI_API void Value(const char* prefix, unsigned int v);\n// IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL);\nexport function Value(prefix: string, b: boolean): void;\nexport function Value(prefix: string, v: number): void;\nexport function Value(prefix: string, v: number, float_format?: string | null): void;\nexport function Value(prefix: string, v: any): void;\nexport function Value(prefix: string, ...args: any[]): void {\n if (typeof(args[0]) === \"boolean\") {\n bind.Value_A(prefix, args[0]);\n } else if (typeof(args[0]) === \"number\") {\n if (Number.isInteger(args[0])) {\n bind.Value_B(prefix, args[0]);\n } else {\n bind.Value_D(prefix, args[0], typeof(args[1]) === \"string\" ? args[1] : null);\n }\n } else {\n bind.Text(prefix + String(args[0]));\n }\n}\n\n// Widgets: Menus\n// - Use BeginMenuBar() on a window ImGuiWindowFlags_MenuBar to append to its menu bar.\n// - Use BeginMainMenuBar() to create a menu bar at the top of the screen and append to it.\n// - Use BeginMenu() to create a menu. You can call BeginMenu() multiple time with the same identifier to append more items to it.\n// IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window).\n// IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true!\n// IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar.\n// IMGUI_API void EndMainMenuBar(); // only call EndMainMenuBar() if BeginMainMenuBar() returns true!\n// IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true!\n// IMGUI_API void EndMenu(); // only call EndMenu() if BeginMenu() returns true!\n// IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment\n// IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL\nexport function BeginMenuBar(): boolean { return bind.BeginMenuBar(); }\nexport function EndMenuBar(): void { bind.EndMenuBar(); }\nexport function BeginMainMenuBar(): boolean { return bind.BeginMainMenuBar(); }\nexport function EndMainMenuBar(): void { bind.EndMainMenuBar(); }\nexport function BeginMenu(label: string, enabled: boolean = true): boolean { return bind.BeginMenu(label, enabled); }\nexport function EndMenu(): void { bind.EndMenu(); }\nexport function MenuItem(label: string, shortcut?: string | null, selected?: boolean, enabled?: boolean): boolean;\nexport function MenuItem(label: string, shortcut: string | null, p_selected: Bind.ImScalar | Bind.ImAccess | null, enabled?: boolean): boolean;\nexport function MenuItem(label: string, ...args: any[]): boolean {\n if (args.length === 0) {\n return bind.MenuItem_A(label, null, false, true);\n } else if (args.length === 1) {\n const shortcut: string | null = args[0];\n return bind.MenuItem_A(label, shortcut, false, true);\n } else {\n const shortcut: string | null = args[0];\n if (typeof(args[1]) === \"boolean\") {\n const selected: boolean = args[1];\n const enabled: boolean = typeof(args[2]) === \"boolean\" ? args[2] : true;\n return bind.MenuItem_A(label, shortcut, selected, enabled);\n } else {\n const p_selected: Bind.ImScalar | Bind.ImAccess = args[1];\n const enabled: boolean = typeof(args[2]) === \"boolean\" ? args[2] : true;\n const ref_selected: Bind.ImScalar = Array.isArray(p_selected) ? p_selected : [ p_selected() ];\n const ret = bind.MenuItem_B(label, shortcut, ref_selected, enabled);\n if (!Array.isArray(p_selected)) { p_selected(ref_selected[0]); }\n return ret;\n }\n }\n}\n\n// Tooltips\n// - Tooltip are windows following the mouse. They do not take focus away.\n// IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items).\n// IMGUI_API void EndTooltip();\n// IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). override any previous call to SetTooltip().\n// IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);\nexport function BeginTooltip(): void { bind.BeginTooltip(); }\nexport function EndTooltip(): void { bind.EndTooltip(); }\nexport function SetTooltip(fmt: string): void { bind.SetTooltip(fmt); }\n\n// Popups, Modals\n// - They block normal mouse hovering detection (and therefore most mouse interactions) behind them.\n// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.\n// - Their visibility state (~bool) is held internally instead of being held by the programmer as we are used to with regular Begin*() calls.\n// - The 3 properties above are related: we need to retain popup visibility state in the library because popups may be closed as any time.\n// - You can bypass the hovering restriction by using ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered().\n// - IMPORTANT: Popup identifiers are relative to the current ID stack, so OpenPopup and BeginPopup generally needs to be at the same level of the stack.\n// This is sometimes leading to confusing mistakes. May rework this in the future.\n// Popups: begin/end functions\n// - BeginPopup(): query popup state, if open start appending into the window. Call EndPopup() afterwards. ImGuiWindowFlags are forwarded to the window.\n// - BeginPopupModal(): block every interactions behind the window, cannot be closed by user, add a dimming background, has a title bar.\n// IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it.\n// IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // return true if the modal is open, and you can start outputting to it.\n// IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true!\nexport function BeginPopup(str_id: string, flags: ImGuiWindowFlags = 0): boolean { return bind.BeginPopup(str_id, flags); }\nexport function BeginPopupModal(str_id: string, p_open: Bind.ImScalar | Bind.ImAccess | null = null, flags: ImGuiWindowFlags = 0): boolean {\n if (Array.isArray(p_open)) {\n return bind.BeginPopupModal(str_id, p_open, flags);\n } else if (typeof(p_open) === \"function\") {\n const _p_open: Bind.ImScalar = [ p_open() ];\n const ret = bind.BeginPopupModal(str_id, _p_open, flags);\n p_open(_p_open[0]);\n return ret;\n } else {\n return bind.BeginPopupModal(str_id, null, flags);\n }\n}\nexport function EndPopup(): void { bind.EndPopup(); }\n// Popups: open/close functions\n// - OpenPopup(): set popup state to open. ImGuiPopupFlags are available for opening options.\n// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.\n// - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually.\n// - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options).\n// - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup().\n// IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).\n// IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. return true when just opened. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)\n// IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into.\nexport function OpenPopup(str_id: string, popup_flags: ImGuiPopupFlags = 0): void { bind.OpenPopup(str_id, popup_flags); }\nexport function OpenPopupOnItemClick(str_id: string | null = null, popup_flags: ImGuiPopupFlags = 1): void { bind.OpenPopupOnItemClick(str_id, popup_flags); }\nexport function CloseCurrentPopup(): void { bind.CloseCurrentPopup(); }\n// Popups: open+begin combined functions helpers\n// - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking.\n// - They are convenient to easily create context menus, hence the name.\n// - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future.\n// - IMPORTANT: we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight.\n// IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!\n// IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window.\n// IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows).\nexport function BeginPopupContextItem(str_id: string | null = null, popup_flags: ImGuiPopupFlags = 1): boolean { return bind.BeginPopupContextItem(str_id, popup_flags); }\nexport function BeginPopupContextWindow(str_id: string | null = null, popup_flags: ImGuiPopupFlags = 1): boolean { return bind.BeginPopupContextWindow(str_id, popup_flags); }\nexport function BeginPopupContextVoid(str_id: string | null = null, popup_flags: ImGuiPopupFlags = 1): boolean { return bind.BeginPopupContextVoid(str_id, popup_flags); }\n// Popups: test function\n// - IsPopupOpen(): return true if the popup is open at the current BeginPopup() level of the popup stack.\n// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId: return true if any popup is open at the current BeginPopup() level of the popup stack.\n// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId + ImGuiPopupFlags_AnyPopupLevel: return true if any popup is open.\n// IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open.\nexport function IsPopupOpen(str_id: string, flags: ImGuiPopupFlags = 0): boolean { return bind.IsPopupOpen(str_id, flags); }\n\n// Tables\n// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!\n// - Full-featured replacement for old Columns API.\n// - See Demo->Tables for demo code.\n// - See top of imgui_tables.cpp for general commentary.\n// - See ImGuiTableFlags_ and ImGuiTableColumnFlags_ enums for a description of available flags.\n// The typical call flow is:\n// - 1. Call BeginTable().\n// - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults.\n// - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows.\n// - 4. Optionally call TableHeadersRow() to submit a header row. Names are pulled from TableSetupColumn() data.\n// - 5. Populate contents:\n// - In most situations you can use TableNextRow() + TableSetColumnIndex(N) to start appending into a column.\n// - If you are using tables as a sort of grid, where every columns is holding the same type of contents,\n// you may prefer using TableNextColumn() instead of TableNextRow() + TableSetColumnIndex().\n// TableNextColumn() will automatically wrap-around into the next row if needed.\n// - IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column!\n// - Summary of possible call flow:\n// --------------------------------------------------------------------------------------------------------\n// TableNextRow() -> TableSetColumnIndex(0) -> Text(\"Hello 0\") -> TableSetColumnIndex(1) -> Text(\"Hello 1\") // OK\n// TableNextRow() -> TableNextColumn() -> Text(\"Hello 0\") -> TableNextColumn() -> Text(\"Hello 1\") // OK\n// TableNextColumn() -> Text(\"Hello 0\") -> TableNextColumn() -> Text(\"Hello 1\") // OK: TableNextColumn() automatically gets to next row!\n// TableNextRow() -> Text(\"Hello 0\") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!\n// --------------------------------------------------------------------------------------------------------\n// - 5. Call EndTable()\n// IMGUI_API bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);\n// IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true!\n// IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row.\n// IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible.\n// IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible.\nexport function BeginTable(str_id: string, column: number, flags: ImGuiTableFlags = 0, outer_size: Bind.interface_ImVec2 = ImVec2.ZERO, inner_width: number = 0.0): boolean { return bind.BeginTable(str_id, column, flags, outer_size, inner_width); }\nexport function EndTable(): void { bind.EndTable(); }\nexport function TableNextRow(row_flags: ImGuiTableRowFlags = 0, min_row_height: number = 0.0): void { bind.TableNextRow(row_flags, min_row_height); }\nexport function TableNextColumn(): boolean { return bind.TableNextColumn(); }\nexport function TableSetColumnIndex(column_n: number): boolean { return bind.TableSetColumnIndex(column_n); }\n// Tables: Headers & Columns declaration\n// - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc.\n// - Use TableHeadersRow() to create a header row and automatically submit a TableHeader() for each column.\n// Headers are required to perform: reordering, sorting, and opening the context menu.\n// The context menu can also be made available in columns body using ImGuiTableFlags_ContextMenuInBody.\n// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in\n// some advanced use cases (e.g. adding custom widgets in header row).\n// - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled.\n// IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImU32 user_id = 0);\n// IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled.\n// IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu\n// IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used)\nexport function TableSetupColumn(label: string, flags: ImGuiTableColumnFlags = 0, init_width_or_weight: number = 0.0, user_id: Bind.ImGuiID = 0): void { bind.TableSetupColumn(label, flags, init_width_or_weight, user_id); }\nexport function TableSetupScrollFreeze(cols: number, rows: number): void { bind.TableSetupScrollFreeze(cols, rows); }\nexport function TableHeadersRow(): void { bind.TableHeadersRow(); }\nexport function TableHeader(label: string): void { bind.TableHeader(label); }\n// Tables: Sorting\n// - Call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting.\n// - When 'SpecsDirty == true' you should sort your data. It will be true when sorting specs have changed\n// since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may\n// wastefully sort your data every frame!\n// - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().\n// IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting).\nexport function TableGetSortSpecs(): ImGuiTableSortSpecs | null {\n const sort_specs: Bind.reference_ImGuiTableSortSpecs | null = bind.TableGetSortSpecs();\n return (sort_specs === null) ? null : new ImGuiTableSortSpecs(sort_specs);\n}\n// Tables: Miscellaneous functions\n// - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index.\n// IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable)\n// IMGUI_API int TableGetColumnIndex(); // return current column index.\n// IMGUI_API int TableGetRowIndex(); // return current row index.\n// IMGUI_API const char* TableGetColumnName(int column_n = -1); // return \"\" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column.\n// IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column.\n// IMGUI_API void TableSetColumnEnabled(int column_n, bool v);// change user accessible enabled/disabled state of a column. Set to false to hide the column. User can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody)\n// IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.\nexport function TableGetColumnCount(): number { return bind.TableGetColumnCount(); }\nexport function TableGetColumnIndex(): number { return bind.TableGetColumnIndex(); }\nexport function TableGetRowIndex(): number { return bind.TableGetRowIndex(); }\nexport function TableGetColumnName(column_n: number = -1): string { return bind.TableGetColumnName(column_n); }\nexport function TableGetColumnFlags(column_n: number = -1): ImGuiTableColumnFlags { return bind.TableGetColumnFlags(column_n); }\nexport function TableSetColumnEnabled(column_n: number, v: boolean): void { bind.TableSetColumnEnabled(column_n, v); }\nexport function TableSetBgColor(target: ImGuiTableBgTarget, color: Bind.ImU32, column_n: number = -1) { bind.TableSetBgColor(target, color, column_n); }\n\n// Legacy Columns API (2020: prefer using Tables!)\n// - You can also use SameLine(pos_x) to mimic simplified columns.\n// IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true);\n// IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished\n// IMGUI_API int GetColumnIndex(); // get current column index\n// IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column\n// IMGUI_API void SetColumnWidth(int column_index, float width); // set column width (in pixels). pass -1 to use current column\n// IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is typically 0.0f\n// IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column\n// IMGUI_API int GetColumnsCount();\nexport function Columns(count: number = 1, id: string | null = null, border: boolean = true): void { bind.Columns(count, id, border); }\nexport function NextColumn(): void { bind.NextColumn(); }\nexport function GetColumnIndex(): number { return bind.GetColumnIndex(); }\nexport function GetColumnWidth(column_index: number = -1): number { return bind.GetColumnWidth(column_index); }\nexport function SetColumnWidth(column_index: number, width: number): void { bind.SetColumnWidth(column_index, width); }\nexport function GetColumnOffset(column_index: number = -1): number { return bind.GetColumnOffset(column_index); }\nexport function SetColumnOffset(column_index: number, offset_x: number): void { bind.SetColumnOffset(column_index, offset_x); }\nexport function GetColumnsCount(): number { return bind.GetColumnsCount(); }\n\n// Tab Bars, Tabs\n// IMGUI_API bool BeginTabBar(const char* str_id, ImGuiTabBarFlags flags = 0); // create and append into a TabBar\n// IMGUI_API void EndTabBar(); // only call EndTabBar() if BeginTabBar() returns true!\n// IMGUI_API bool BeginTabItem(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0); // create a Tab. Returns true if the Tab is selected.\n// IMGUI_API void EndTabItem(); // only call EndTabItem() if BeginTabItem() returns true!\n// IMGUI_API bool TabItemButton(const char* label, ImGuiTabItemFlags flags = 0); // create a Tab behaving like a button. return true when clicked. cannot be selected in the tab bar.\n// IMGUI_API void SetTabItemClosed(const char* tab_or_docked_window_label); // notify TabBar or Docking system of a closed tab/window ahead (useful to reduce visual flicker on reorderable tab bars). For tab-bar: call after BeginTabBar() and before Tab submissions. Otherwise call with a window name.\nexport function BeginTabBar(str_id: string, flags: ImGuiTabBarFlags = 0): boolean { return bind.BeginTabBar(str_id, flags); }\nexport function EndTabBar(): void { bind.EndTabBar(); }\nexport function BeginTabItem(label: string, p_open: Bind.ImScalar | Bind.ImAccess | null = null, flags: ImGuiTabItemFlags = 0): boolean {\n if (p_open === null) {\n return bind.BeginTabItem(label, null, flags);\n } else if (Array.isArray(p_open)) {\n return bind.BeginTabItem(label, p_open, flags);\n } else {\n const ref_open: Bind.ImScalar = [ p_open() ];\n const ret = bind.BeginTabItem(label, ref_open, flags);\n p_open(ref_open[0]);\n return ret;\n }\n}\nexport function EndTabItem(): void { bind.EndTabItem(); }\nexport function TabItemButton(label: string, flags: ImGuiTabItemFlags = 0): boolean { return bind.TabItemButton(label, flags); }\nexport function SetTabItemClosed(tab_or_docked_window_label: string): void { bind.SetTabItemClosed(tab_or_docked_window_label); }\n\n// Logging/Capture\n// - All text output from the interface can be captured into tty/file/clipboard. By default, tree nodes are automatically opened during logging.\n// IMGUI_API void LogToTTY(int auto_open_depth = -1); // start logging to tty (stdout)\n// IMGUI_API void LogToFile(int auto_open_depth = -1, const char* filename = NULL); // start logging to file\n// IMGUI_API void LogToClipboard(int auto_open_depth = -1); // start logging to OS clipboard\n// IMGUI_API void LogFinish(); // stop logging (close file, etc.)\n// IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard\n// IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed)\nexport function LogToTTY(max_depth: number = -1): void { bind.LogToTTY(max_depth); }\nexport function LogToFile(max_depth: number = -1, filename: string | null = null): void { bind.LogToFile(max_depth, filename); }\nexport function LogToClipboard(max_depth: number = -1): void { bind.LogToClipboard(max_depth); }\nexport function LogFinish(): void { bind.LogFinish(); }\nexport function LogButtons(): void { bind.LogButtons(); }\nexport function LogText(fmt: string): void { bind.LogText(fmt); }\n\n// Drag and Drop\n// - If you stop calling BeginDragDropSource() the payload is preserved however it won't have a preview tooltip (we currently display a fallback \"...\" tooltip as replacement)\n// IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource()\n// IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui.\n// IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true!\n// IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive a payload. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget()\n// IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released.\n// IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true!\n// IMGUI_API const ImGuiPayload* GetDragDropPayload(); // peek directly into the current payload from anywhere. may return NULL. use ImGuiPayload::IsDataType() to test for the payload type.\nconst _ImGui_DragDropPayload_data: {[key: string]: any} = {};\nexport function BeginDragDropSource(flags: ImGuiDragDropFlags = 0): boolean {\n return bind.BeginDragDropSource(flags);\n}\nexport function SetDragDropPayload(type: string, data: T, cond: ImGuiCond = 0): boolean {\n _ImGui_DragDropPayload_data[type] = data;\n return bind.SetDragDropPayload(type, data, 0, cond);\n}\nexport function EndDragDropSource(): void {\n bind.EndDragDropSource();\n}\nexport function BeginDragDropTarget(): boolean {\n return bind.BeginDragDropTarget();\n}\nexport function AcceptDragDropPayload(type: string, flags: ImGuiDragDropFlags = 0): ImGuiPayload | null {\n const data: T = _ImGui_DragDropPayload_data[type];\n return bind.AcceptDragDropPayload(type, flags) ? { Data: data } : null;\n}\nexport function EndDragDropTarget(): void {\n bind.EndDragDropTarget();\n}\nexport function GetDragDropPayload(): ImGuiPayload | null {\n return bind.GetDragDropPayload();\n}\n\n// Disabling [BETA API]\n// - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors)\n// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)\n// - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it.\n// IMGUI_API void BeginDisabled(bool disabled = true);\n// IMGUI_API void EndDisabled();\nexport function BeginDisabled(disabled: boolean = true): void { bind.BeginDisabled(disabled); }\nexport function EndDisabled(): void { bind.EndDisabled(); }\n\n// Clipping\n// - Mouse hovering is affected by ImGui::PushClipRect() calls, unlike direct calls to ImDrawList::PushClipRect() which are render only.\n// IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);\n// IMGUI_API void PopClipRect();\nexport function PushClipRect(clip_rect_min: Readonly, clip_rect_max: Readonly, intersect_with_current_clip_rect: boolean): void {\n bind.PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect);\n}\nexport function PopClipRect(): void {\n bind.PopClipRect();\n}\n\n// Focus, Activation\n// - Prefer using \"SetItemDefaultFocus()\" over \"if (IsWindowAppearing()) SetScrollHereY()\" when applicable to signify \"this is the default item\"\n// IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window.\n// IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget.\nexport function SetItemDefaultFocus(): void { bind.SetItemDefaultFocus(); }\nexport function SetKeyboardFocusHere(offset: number = 0): void { bind.SetKeyboardFocusHere(offset); }\n\n// Item/Widgets Utilities\n// - Most of the functions are referring to the last/previous item we submitted.\n// - See Demo Window under \"Widgets->Querying Status\" for an interactive visualization of most of those functions.\n// IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options.\n// IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited. This will continuously return true while holding mouse button on an item. Items that don't interact will always return false)\n// IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation?\n// IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) == IsMouseClicked(mouse_button) && IsItemHovered()\n// IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling)\n// IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the \"bool\" return value of many widgets.\n// IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive).\n// IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing.\n// IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item).\n// IMGUI_API bool IsItemToggledOpen(); // was the last item open state toggled? set by TreeNode().\n// IMGUI_API bool IsAnyItemHovered(); // is any item hovered?\n// IMGUI_API bool IsAnyItemActive(); // is any item active?\n// IMGUI_API bool IsAnyItemFocused(); // is any item focused?\n// IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space)\n// IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space)\n// IMGUI_API ImVec2 GetItemRectSize(); // get size of last item\n// IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area.\nexport function IsItemHovered(flags: ImGuiHoveredFlags = 0): boolean { return bind.IsItemHovered(flags); }\nexport function IsItemActive(): boolean { return bind.IsItemActive(); }\nexport function IsItemFocused(): boolean { return bind.IsItemFocused(); }\nexport function IsItemClicked(mouse_button: ImGuiMouseButton = 0): boolean { return bind.IsItemClicked(mouse_button); }\nexport function IsItemVisible(): boolean { return bind.IsItemVisible(); }\nexport function IsItemEdited(): boolean { return bind.IsItemEdited(); }\nexport function IsItemActivated(): boolean { return bind.IsItemActivated(); }\nexport function IsItemDeactivated(): boolean { return bind.IsItemDeactivated(); }\nexport function IsItemDeactivatedAfterEdit(): boolean { return bind.IsItemDeactivatedAfterEdit(); }\nexport function IsItemToggledOpen(): boolean { return bind.IsItemToggledOpen(); }\nexport function IsAnyItemHovered(): boolean { return bind.IsAnyItemHovered(); }\nexport function IsAnyItemActive(): boolean { return bind.IsAnyItemActive(); }\nexport function IsAnyItemFocused(): boolean { return bind.IsAnyItemFocused(); }\nexport function GetItemRectMin(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetItemRectMin(out); }\nexport function GetItemRectMax(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetItemRectMax(out); }\nexport function GetItemRectSize(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetItemRectSize(out); }\nexport function SetItemAllowOverlap(): void { bind.SetItemAllowOverlap(); }\n\n\n// Viewports\n// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.\n// - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports.\n// - In the future we will extend this concept further to also represent Platform Monitor and support a \"no main platform window\" operation mode.\n// IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport. This can never be NULL.\nexport function GetMainViewport(): ImGuiViewport { return new ImGuiViewport(bind.GetMainViewport()); }\n\n// Miscellaneous Utilities\n// IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped.\n// IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side.\n// IMGUI_API double GetTime(); // get global imgui time. incremented by io.DeltaTime every frame.\n// IMGUI_API int GetFrameCount(); // get global imgui frame count. incremented by 1 every frame.\n// IMGUI_API ImDrawList* GetBackgroundDrawList(); // this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.\n// IMGUI_API ImDrawList* GetForegroundDrawList(); // this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.\n// IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); // you may use this when creating your own ImDrawList instances.\n// IMGUI_API const char* GetStyleColorName(ImGuiCol idx); // get a string corresponding to the enum value (for display, saving, etc.).\n// IMGUI_API void SetStateStorage(ImGuiStorage* storage); // replace current window storage with our own (if you want to manipulate it yourself, typically clear subsection of it)\n// IMGUI_API ImGuiStorage* GetStateStorage();\n// IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can.\n// IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame\n// IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window)\nexport function IsRectVisible(size: Readonly): boolean;\nexport function IsRectVisible(rect_min: Readonly, rect_max: Readonly): boolean;\nexport function IsRectVisible(...args: any[]): boolean {\n if (args.length === 1) {\n const size: Readonly = args[0];\n return bind.IsRectVisible_A(size);\n } else {\n const rect_min: Readonly = args[0];\n const rect_max: Readonly = args[1];\n return bind.IsRectVisible_B(rect_min, rect_max);\n }\n}\nexport function GetTime(): number { return bind.GetTime(); }\nexport function GetFrameCount(): number { return bind.GetFrameCount(); }\nexport function GetBackgroundDrawList(): ImDrawList {\n return new ImDrawList(bind.GetBackgroundDrawList());\n}\nexport function GetForegroundDrawList(): ImDrawList {\n return new ImDrawList(bind.GetForegroundDrawList());\n}\nexport function GetDrawListSharedData(): ImDrawListSharedData {\n return new ImDrawListSharedData(bind.GetDrawListSharedData());\n}\nexport function GetStyleColorName(idx: ImGuiCol): string { return bind.GetStyleColorName(idx); }\n// IMGUI_API void SetStateStorage(ImGuiStorage* tree);\n// IMGUI_API ImGuiStorage* GetStateStorage();\n// export function CalcListClipping(items_count: number, items_height: number, out_items_display_start: Bind.ImScalar, out_items_display_end: Bind.ImScalar): void {\n// return bind.CalcListClipping(items_count, items_height, out_items_display_start, out_items_display_end);\n// }\nexport function BeginChildFrame(id: ImGuiID, size: Readonly, flags: ImGuiWindowFlags = 0): boolean { return bind.BeginChildFrame(id, size, flags); }\nexport function EndChildFrame(): void { bind.EndChildFrame(); }\n\n// Text Utilities\n// IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);\nexport function CalcTextSize(text: string, text_end: number | null = null, hide_text_after_double_hash: boolean = false, wrap_width: number = -1, out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 {\n return bind.CalcTextSize(text_end !== null ? text.substring(0, text_end) : text, hide_text_after_double_hash, wrap_width, out);\n}\n\n// Color Utilities\n// IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in);\n// IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in);\n// IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v);\n// IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b);\nexport function ColorConvertU32ToFloat4(in_: Bind.ImU32, out: Bind.interface_ImVec4 = new ImVec4()): Bind.interface_ImVec4 { return bind.ColorConvertU32ToFloat4(in_, out); }\nexport function ColorConvertFloat4ToU32(in_: Readonly): Bind.ImU32 { return bind.ColorConvertFloat4ToU32(in_); }\nexport function ColorConvertRGBtoHSV(r: number, g: number, b: number, out_h: Bind.ImScalar, out_s: Bind.ImScalar, out_v: Bind.ImScalar): void { bind.ColorConvertRGBtoHSV(r, g, b, out_h, out_s, out_v); }\nexport function ColorConvertHSVtoRGB(h: number, s: number, v: number, out_r: Bind.ImScalar, out_g: Bind.ImScalar, out_b: Bind.ImScalar): void { bind.ColorConvertHSVtoRGB(h, s, v, out_r, out_g, out_b); }\n\n// Inputs Utilities: Keyboard\n// - For 'int user_key_index' you can use your own indices/enums according to how your backend/engine stored them in io.KeysDown[].\n// - We don't know the meaning of those value. You can use GetKeyIndex() to map a ImGuiKey_ value into the user index.\n// IMGUI_API int GetKeyIndex(ImGuiKey imgui_key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key]\n// IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index].\n// IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate\n// IMGUI_API bool IsKeyReleased(int user_key_index); // was key released (went from Down to !Down)?\n// IMGUI_API int GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate\n// IMGUI_API void CaptureKeyboardFromApp(bool want_capture_keyboard_value = true); // attention: misleading name! manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application to handle). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting \"io.WantCaptureKeyboard = want_capture_keyboard_value\"; after the next NewFrame() call.\nexport function GetKeyIndex(imgui_key: ImGuiKey): number { return bind.GetKeyIndex(imgui_key); }\nexport function IsKeyDown(user_key_index: number): boolean { return bind.IsKeyDown(user_key_index); }\nexport function IsKeyPressed(user_key_index: number, repeat: boolean = true): boolean { return bind.IsKeyPressed(user_key_index, repeat); }\nexport function IsKeyReleased(user_key_index: number): boolean { return bind.IsKeyReleased(user_key_index); }\nexport function GetKeyPressedAmount(user_key_index: number, repeat_delay: number, rate: number): number { return bind.GetKeyPressedAmount(user_key_index, repeat_delay, rate); }\nexport function CaptureKeyboardFromApp(capture: boolean = true) { return bind.CaptureKeyboardFromApp(capture); }\n\n// Inputs Utilities: Mouse\n// - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right.\n// - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle.\n// - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold')\n// IMGUI_API bool IsMouseDown(ImGuiMouseButton button); // is mouse button held?\n// IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down)\n// IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down)\n// IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? (note that a double-click will also report IsMouseClicked() == true)\n// IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0).\n// IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.\n// IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available\n// IMGUI_API bool IsAnyMouseDown(); // is any mouse button held?\n// IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls\n// IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve mouse position at the time of opening popup we have BeginPopup() into (helper to avoid user backing that value themselves)\n// IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold)\n// IMGUI_API ImVec2 GetMouseDragDelta(ImGuiMouseButton button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position while the mouse button is pressed or was just released. This is locked and return 0.0f until the mouse moves past a distance threshold at least once (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold)\n// IMGUI_API void ResetMouseDragDelta(ImGuiMouseButton button = 0); //\n// IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you\n// IMGUI_API void SetMouseCursor(ImGuiMouseCursor cursor_type); // set desired cursor type\n// IMGUI_API void CaptureMouseFromApp(bool want_capture_mouse_value = true); // attention: misleading name! manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application to handle). This is equivalent to setting \"io.WantCaptureMouse = want_capture_mouse_value;\" after the next NewFrame() call.\nexport function IsMouseDown(button: number): boolean { return bind.IsMouseDown(button); }\nexport function IsMouseClicked(button: number, repeat: boolean = false): boolean { return bind.IsMouseClicked(button, repeat); }\nexport function IsMouseDoubleClicked(button: number): boolean { return bind.IsMouseDoubleClicked(button); }\nexport function GetMouseClickedCount(button: number): number { return bind.GetMouseClickedCount(button); }\nexport function IsMouseReleased(button: number): boolean { return bind.IsMouseReleased(button); }\nexport function IsMouseHoveringRect(r_min: Readonly, r_max: Readonly, clip: boolean = true): boolean { return bind.IsMouseHoveringRect(r_min, r_max, clip); }\nexport function IsMousePosValid(mouse_pos: Readonly | null = null): boolean { return bind.IsMousePosValid(mouse_pos); }\nexport function IsAnyMouseDown(): boolean { return bind.IsAnyMouseDown(); }\nexport function GetMousePos(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetMousePos(out); }\nexport function GetMousePosOnOpeningCurrentPopup(out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetMousePosOnOpeningCurrentPopup(out); }\nexport function IsMouseDragging(button: number = 0, lock_threshold: number = -1.0): boolean { return bind.IsMouseDragging(button, lock_threshold); }\nexport function GetMouseDragDelta(button: number = 0, lock_threshold: number = -1.0, out: Bind.interface_ImVec2 = new ImVec2()): Bind.interface_ImVec2 { return bind.GetMouseDragDelta(button, lock_threshold, out); }\nexport function ResetMouseDragDelta(button: number = 0): void { bind.ResetMouseDragDelta(button); }\nexport function GetMouseCursor(): ImGuiMouseCursor { return bind.GetMouseCursor(); }\nexport function SetMouseCursor(type: ImGuiMouseCursor): void { bind.SetMouseCursor(type); }\nexport function CaptureMouseFromApp(capture: boolean = true): void { bind.CaptureMouseFromApp(capture); }\n\n// Clipboard Utilities\n// - Also see the LogToClipboard() function to capture GUI into clipboard, or easily output text data to the clipboard.\n// IMGUI_API const char* GetClipboardText();\n// IMGUI_API void SetClipboardText(const char* text);\nexport function GetClipboardText(): string { return bind.GetClipboardText(); }\nexport function SetClipboardText(text: string): void { bind.SetClipboardText(text); }\n\n// Settings/.Ini Utilities\n// - The disk functions are automatically called if io.IniFilename != NULL (default is \"imgui.ini\").\n// - Set io.IniFilename to NULL to load/save manually. Read io.WantSaveIniSettings description about handling .ini saving manually.\n// IMGUI_API void LoadIniSettingsFromDisk(const char* ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename).\n// IMGUI_API void LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size=0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source.\n// IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename); // this is automatically called (if io.IniFilename is not empty) a few seconds after any modification that should be reflected in the .ini file (and also by DestroyContext).\n// IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings.\nexport function LoadIniSettingsFromDisk(ini_filename: string): void { throw new Error(); } // TODO\nexport function LoadIniSettingsFromMemory(ini_data: string, ini_size: number = 0): void { bind.LoadIniSettingsFromMemory(ini_data); }\nexport function SaveIniSettingsToDisk(ini_filename: string): void { throw new Error(); } // TODO\nexport function SaveIniSettingsToMemory(out_ini_size: Bind.ImScalar | null = null): string { return bind.SaveIniSettingsToMemory(); }\n\n// Debug Utilities\n// IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); // This is called by IMGUI_CHECKVERSION() macro.\nexport function DebugCheckVersionAndDataLayout(version_str: string, sz_io: number, sz_style: number, sz_vec2: number, sz_vec4: number, sz_draw_vert: number, sz_draw_idx: number): boolean {\n return bind.DebugCheckVersionAndDataLayout(version_str, sz_io, sz_style, sz_vec2, sz_vec4, sz_draw_vert, sz_draw_idx);\n}\n\n// Memory Allocators\n// - All those functions are not reliant on the current context.\n// - If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again because we use global storage for those.\n// IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);\n// IMGUI_API void* MemAlloc(size_t size);\n// IMGUI_API void MemFree(void* ptr);\nexport function SetAllocatorFunctions(alloc_func: (sz: number, user_data: any) => number, free_func: (ptr: number, user_data: any) => void, user_data: any = null): void {\n bind.SetAllocatorFunctions(alloc_func, free_func, user_data);\n}\nexport function MemAlloc(sz: number): void { bind.MemAlloc(sz); }\nexport function MemFree(ptr: any): void { bind.MemFree(ptr); }\n","import { ImGui } from \"imgui-js\";\n\nlet clipboard_text: string = \"\";\n\nlet canvas: HTMLCanvasElement | null = null;\n\nexport let gl: WebGL2RenderingContext | WebGLRenderingContext | null = null;\nlet g_ShaderHandle: WebGLProgram | null = null;\nlet g_VertHandle: WebGLShader | null = null;\nlet g_FragHandle: WebGLShader | null = null;\nlet g_AttribLocationTex: WebGLUniformLocation | null = null;\nlet g_AttribLocationProjMtx: WebGLUniformLocation | null = null;\nlet g_AttribLocationPosition: GLint = -1;\nlet g_AttribLocationUV: GLint = -1;\nlet g_AttribLocationColor: GLint = -1;\nlet g_VboHandle: WebGLBuffer | null = null;\nlet g_ElementsHandle: WebGLBuffer | null = null;\nlet g_FontTexture: WebGLTexture | null = null;\n\nexport let ctx: CanvasRenderingContext2D | null = null;\n\nlet prev_time: number = 0;\n\nfunction document_on_copy(event: ClipboardEvent): void {\n if (event.clipboardData) {\n event.clipboardData.setData(\"text/plain\", clipboard_text);\n }\n // console.log(`${event.type}: \"${clipboard_text}\"`);\n event.preventDefault();\n}\n\nfunction document_on_cut(event: ClipboardEvent): void {\n if (event.clipboardData) {\n event.clipboardData.setData(\"text/plain\", clipboard_text);\n }\n // console.log(`${event.type}: \"${clipboard_text}\"`);\n event.preventDefault();\n}\n\nfunction document_on_paste(event: ClipboardEvent): void {\n if (event.clipboardData) {\n clipboard_text = event.clipboardData.getData(\"text/plain\");\n }\n // console.log(`${event.type}: \"${clipboard_text}\"`);\n event.preventDefault();\n}\n\nfunction window_on_resize(): void {\n if (canvas !== null) {\n canvas.width = canvas.scrollWidth;\n canvas.height = canvas.scrollHeight;\n }\n}\n\nfunction window_on_gamepadconnected(event: any /* GamepadEvent */): void {\n console.log(\"Gamepad connected at index %d: %s. %d buttons, %d axes.\",\n event.gamepad.index, event.gamepad.id,\n event.gamepad.buttons.length, event.gamepad.axes.length);\n}\n\nfunction window_on_gamepaddisconnected(event: any /* GamepadEvent */): void {\n console.log(\"Gamepad disconnected at index %d: %s.\",\n event.gamepad.index, event.gamepad.id);\n}\n\nfunction canvas_on_blur(event: FocusEvent): void {\n const io = ImGui.GetIO();\n io.KeyCtrl = false;\n io.KeyShift = false;\n io.KeyAlt = false;\n io.KeySuper = false;\n for (let i = 0; i < io.KeysDown.length; ++i) {\n io.KeysDown[i] = false;\n }\n for (let i = 0; i < io.MouseDown.length; ++i) {\n io.MouseDown[i] = false;\n }\n}\n\nconst key_code_to_index: Record = {\n \"NumpadEnter\": 176,\n};\n\nfunction canvas_on_keydown(event: KeyboardEvent): void {\n // console.log(event.type, event.key, event.code, event.keyCode);\n const io = ImGui.GetIO();\n io.KeyCtrl = event.ctrlKey;\n io.KeyShift = event.shiftKey;\n io.KeyAlt = event.altKey;\n io.KeySuper = event.metaKey;\n const key_index: number = key_code_to_index[event.code] || event.keyCode;\n ImGui.ASSERT(key_index >= 0 && key_index < ImGui.ARRAYSIZE(io.KeysDown));\n io.KeysDown[key_index] = true;\n // forward to the keypress event\n if (/*io.WantCaptureKeyboard ||*/ event.key === \"Tab\") {\n event.preventDefault();\n }\n}\n\nfunction canvas_on_keyup(event: KeyboardEvent): void {\n // console.log(event.type, event.key, event.code, event.keyCode);\n const io = ImGui.GetIO();\n io.KeyCtrl = event.ctrlKey;\n io.KeyShift = event.shiftKey;\n io.KeyAlt = event.altKey;\n io.KeySuper = event.metaKey;\n const key_index: number = key_code_to_index[event.code] || event.keyCode;\n ImGui.ASSERT(key_index >= 0 && key_index < ImGui.ARRAYSIZE(io.KeysDown));\n io.KeysDown[key_index] = false;\n if (io.WantCaptureKeyboard) {\n event.preventDefault();\n }\n}\n\nfunction canvas_on_keypress(event: KeyboardEvent): void {\n // console.log(event.type, event.key, event.code, event.keyCode);\n const io = ImGui.GetIO();\n io.AddInputCharacter(event.charCode);\n if (io.WantCaptureKeyboard) {\n event.preventDefault();\n }\n}\n\nfunction canvas_on_pointermove(event: PointerEvent): void {\n const io = ImGui.GetIO();\n io.MousePos.x = event.offsetX;\n io.MousePos.y = event.offsetY;\n if (io.WantCaptureMouse) {\n event.preventDefault();\n }\n}\n\n// MouseEvent.button\n// A number representing a given button:\n// 0: Main button pressed, usually the left button or the un-initialized state\n// 1: Auxiliary button pressed, usually the wheel button or the middle button (if present)\n// 2: Secondary button pressed, usually the right button\n// 3: Fourth button, typically the Browser Back button\n// 4: Fifth button, typically the Browser Forward button\nconst mouse_button_map: number[] = [ 0, 2, 1, 3, 4 ];\n\nfunction canvas_on_pointerdown(event: PointerEvent): void {\n const io = ImGui.GetIO();\n io.MousePos.x = event.offsetX;\n io.MousePos.y = event.offsetY;\n io.MouseDown[mouse_button_map[event.button]] = true;\n // if (io.WantCaptureMouse) {\n // event.preventDefault();\n // }\n}\nfunction canvas_on_contextmenu(event: Event): void {\n const io = ImGui.GetIO();\n if (io.WantCaptureMouse) {\n event.preventDefault();\n }\n}\n\nfunction canvas_on_pointerup(event: PointerEvent): void {\n const io = ImGui.GetIO();\n io.MouseDown[mouse_button_map[event.button]] = false;\n if (io.WantCaptureMouse) {\n event.preventDefault();\n }\n}\n\nfunction canvas_on_wheel(event: WheelEvent): void {\n const io = ImGui.GetIO();\n let scale: number = 1.0;\n switch (event.deltaMode) {\n case event.DOM_DELTA_PIXEL: scale = 0.01; break;\n case event.DOM_DELTA_LINE: scale = 0.2; break;\n case event.DOM_DELTA_PAGE: scale = 1.0; break;\n }\n io.MouseWheelH = event.deltaX * scale;\n io.MouseWheel = -event.deltaY * scale; // Mouse wheel: 1 unit scrolls about 5 lines text.\n if (io.WantCaptureMouse) {\n event.preventDefault();\n }\n}\n\nexport function Init(value: HTMLCanvasElement | WebGL2RenderingContext | WebGLRenderingContext | CanvasRenderingContext2D | null): void {\n const io = ImGui.GetIO();\n\n if (typeof(window) !== \"undefined\") {\n io.BackendPlatformName = \"imgui_impl_browser\";\n ImGui.LoadIniSettingsFromMemory(window.localStorage.getItem(\"imgui.ini\") || \"\");\n }\n else {\n io.BackendPlatformName = \"imgui_impl_console\";\n }\n\n if (typeof(navigator) !== \"undefined\") {\n io.ConfigMacOSXBehaviors = navigator.platform.match(/Mac/) !== null;\n }\n\n if (typeof(document) !== \"undefined\") {\n document.body.addEventListener(\"copy\", document_on_copy);\n document.body.addEventListener(\"cut\", document_on_cut);\n document.body.addEventListener(\"paste\", document_on_paste);\n }\n\n io.SetClipboardTextFn = (user_data: any, text: string): void => {\n clipboard_text = text;\n // console.log(`set clipboard_text: \"${clipboard_text}\"`);\n if (typeof navigator !== \"undefined\" && typeof (navigator as any).clipboard !== \"undefined\") {\n // console.log(`clipboard.writeText: \"${clipboard_text}\"`);\n (navigator as any).clipboard.writeText(clipboard_text).then((): void => {\n // console.log(`clipboard.writeText: \"${clipboard_text}\" done.`);\n });\n }\n };\n io.GetClipboardTextFn = (user_data: any): string => {\n // if (typeof navigator !== \"undefined\" && typeof (navigator as any).clipboard !== \"undefined\") {\n // console.log(`clipboard.readText: \"${clipboard_text}\"`);\n // (navigator as any).clipboard.readText().then((text: string): void => {\n // clipboard_text = text;\n // console.log(`clipboard.readText: \"${clipboard_text}\" done.`);\n // });\n // }\n // console.log(`get clipboard_text: \"${clipboard_text}\"`);\n return clipboard_text;\n };\n io.ClipboardUserData = null;\n\n if (typeof(window) !== \"undefined\") {\n window.addEventListener(\"resize\", window_on_resize);\n window.addEventListener(\"gamepadconnected\", window_on_gamepadconnected);\n window.addEventListener(\"gamepaddisconnected\", window_on_gamepaddisconnected);\n }\n\n if (typeof(window) !== \"undefined\") {\n if (value instanceof(HTMLCanvasElement)) {\n canvas = value;\n value = canvas.getContext(\"webgl2\", { alpha: false }) || canvas.getContext(\"webgl\", { alpha: false }) || canvas.getContext(\"2d\");\n }\n if (typeof WebGL2RenderingContext !== \"undefined\" && value instanceof(WebGL2RenderingContext)) {\n io.BackendRendererName = \"imgui_impl_webgl2\";\n canvas = canvas || value.canvas as HTMLCanvasElement;\n gl = value;\n }\n else if (typeof WebGLRenderingContext !== \"undefined\" && value instanceof(WebGLRenderingContext)) {\n io.BackendRendererName = \"imgui_impl_webgl\";\n canvas = canvas || value.canvas as HTMLCanvasElement;\n gl = value;\n }\n else if (typeof CanvasRenderingContext2D !== \"undefined\" && value instanceof(CanvasRenderingContext2D)) {\n io.BackendRendererName = \"imgui_impl_2d\";\n canvas = canvas || value.canvas;\n ctx = value;\n }\n }\n\n if (canvas !== null) {\n window_on_resize();\n canvas.style.touchAction = \"none\"; // Disable browser handling of all panning and zooming gestures.\n canvas.addEventListener(\"blur\", canvas_on_blur);\n canvas.addEventListener(\"keydown\", canvas_on_keydown);\n canvas.addEventListener(\"keyup\", canvas_on_keyup);\n canvas.addEventListener(\"keypress\", canvas_on_keypress);\n canvas.addEventListener(\"pointermove\", canvas_on_pointermove);\n canvas.addEventListener(\"pointerdown\", canvas_on_pointerdown);\n canvas.addEventListener(\"contextmenu\", canvas_on_contextmenu);\n canvas.addEventListener(\"pointerup\", canvas_on_pointerup);\n canvas.addEventListener(\"wheel\", canvas_on_wheel);\n }\n\n // Setup back-end capabilities flags\n io.BackendFlags |= ImGui.BackendFlags.HasMouseCursors; // We can honor GetMouseCursor() values (optional)\n\n // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.\n io.KeyMap[ImGui.Key.Tab] = 9;\n io.KeyMap[ImGui.Key.LeftArrow] = 37;\n io.KeyMap[ImGui.Key.RightArrow] = 39;\n io.KeyMap[ImGui.Key.UpArrow] = 38;\n io.KeyMap[ImGui.Key.DownArrow] = 40;\n io.KeyMap[ImGui.Key.PageUp] = 33;\n io.KeyMap[ImGui.Key.PageDown] = 34;\n io.KeyMap[ImGui.Key.Home] = 36;\n io.KeyMap[ImGui.Key.End] = 35;\n io.KeyMap[ImGui.Key.Insert] = 45;\n io.KeyMap[ImGui.Key.Delete] = 46;\n io.KeyMap[ImGui.Key.Backspace] = 8;\n io.KeyMap[ImGui.Key.Space] = 32;\n io.KeyMap[ImGui.Key.Enter] = 13;\n io.KeyMap[ImGui.Key.Escape] = 27;\n io.KeyMap[ImGui.Key.KeyPadEnter] = key_code_to_index[\"NumpadEnter\"];\n io.KeyMap[ImGui.Key.A] = 65;\n io.KeyMap[ImGui.Key.C] = 67;\n io.KeyMap[ImGui.Key.V] = 86;\n io.KeyMap[ImGui.Key.X] = 88;\n io.KeyMap[ImGui.Key.Y] = 89;\n io.KeyMap[ImGui.Key.Z] = 90;\n\n CreateDeviceObjects();\n}\n\nexport function Shutdown(): void {\n DestroyDeviceObjects();\n\n if (canvas !== null) {\n canvas.removeEventListener(\"blur\", canvas_on_blur);\n canvas.removeEventListener(\"keydown\", canvas_on_keydown);\n canvas.removeEventListener(\"keyup\", canvas_on_keyup);\n canvas.removeEventListener(\"keypress\", canvas_on_keypress);\n canvas.removeEventListener(\"pointermove\", canvas_on_pointermove);\n canvas.removeEventListener(\"pointerdown\", canvas_on_pointerdown);\n canvas.removeEventListener(\"contextmenu\", canvas_on_contextmenu);\n canvas.removeEventListener(\"pointerup\", canvas_on_pointerup);\n canvas.removeEventListener(\"wheel\", canvas_on_wheel);\n }\n\n gl = null;\n ctx = null;\n canvas = null;\n\n if (typeof(window) !== \"undefined\") {\n window.removeEventListener(\"resize\", window_on_resize);\n window.removeEventListener(\"gamepadconnected\", window_on_gamepadconnected);\n window.removeEventListener(\"gamepaddisconnected\", window_on_gamepaddisconnected);\n }\n\n if (typeof(document) !== \"undefined\") {\n document.body.removeEventListener(\"copy\", document_on_copy);\n document.body.removeEventListener(\"cut\", document_on_cut);\n document.body.removeEventListener(\"paste\", document_on_paste);\n }\n}\n\nexport function NewFrame(time: number): void {\n const io = ImGui.GetIO();\n\n if (io.WantSaveIniSettings) {\n io.WantSaveIniSettings = false;\n if (typeof(window) !== \"undefined\") {\n window.localStorage.setItem(\"imgui.ini\", ImGui.SaveIniSettingsToMemory());\n }\n }\n\n const w: number = canvas && canvas.scrollWidth || 640;\n const h: number = canvas && canvas.scrollHeight || 480;\n const display_w: number = gl && gl.drawingBufferWidth || w;\n const display_h: number = gl && gl.drawingBufferHeight || h;\n io.DisplaySize.x = w;\n io.DisplaySize.y = h;\n io.DisplayFramebufferScale.x = w > 0 ? (display_w / w) : 0;\n io.DisplayFramebufferScale.y = h > 0 ? (display_h / h) : 0;\n\n const dt: number = time - prev_time;\n prev_time = time;\n io.DeltaTime = dt / 1000;\n\n if (io.WantSetMousePos) {\n console.log(\"TODO: MousePos\", io.MousePos.x, io.MousePos.y);\n }\n\n if (typeof(document) !== \"undefined\") {\n if (io.MouseDrawCursor) {\n document.body.style.cursor = \"none\";\n } else {\n switch (ImGui.GetMouseCursor()) {\n case ImGui.MouseCursor.None: document.body.style.cursor = \"none\"; break;\n default: case ImGui.MouseCursor.Arrow: document.body.style.cursor = \"default\"; break;\n case ImGui.MouseCursor.TextInput: document.body.style.cursor = \"text\"; break; // When hovering over InputText, etc.\n case ImGui.MouseCursor.ResizeAll: document.body.style.cursor = \"all-scroll\"; break; // Unused\n case ImGui.MouseCursor.ResizeNS: document.body.style.cursor = \"ns-resize\"; break; // When hovering over an horizontal border\n case ImGui.MouseCursor.ResizeEW: document.body.style.cursor = \"ew-resize\"; break; // When hovering over a vertical border or a column\n case ImGui.MouseCursor.ResizeNESW: document.body.style.cursor = \"nesw-resize\"; break; // When hovering over the bottom-left corner of a window\n case ImGui.MouseCursor.ResizeNWSE: document.body.style.cursor = \"nwse-resize\"; break; // When hovering over the bottom-right corner of a window\n case ImGui.MouseCursor.Hand: document.body.style.cursor = \"move\"; break;\n case ImGui.MouseCursor.NotAllowed: document.body.style.cursor = \"not-allowed\"; break;\n }\n }\n }\n\n // Gamepad navigation mapping [BETA]\n for (let i = 0; i < io.NavInputs.length; ++i) {\n // TODO: This is currently causing an issue and I have no gamepad to test with.\n // The error is: ''set' on proxy: trap returned falsish for property '21'\n // I think that the NavInputs are zeroed out by ImGui at the start of each frame anyway\n // so I am not sure if the following is even necessary.\n //io.NavInputs[i] = 0.0;\n }\n if (io.ConfigFlags & ImGui.ConfigFlags.NavEnableGamepad) {\n // Update gamepad inputs\n const gamepads: (Gamepad | null)[] = (typeof(navigator) !== \"undefined\" && typeof(navigator.getGamepads) === \"function\") ? navigator.getGamepads() : [];\n for (let i = 0; i < gamepads.length; ++i) {\n const gamepad: Gamepad | null = gamepads[i];\n if (!gamepad) { continue; }\n io.BackendFlags |= ImGui.BackendFlags.HasGamepad;\n const buttons_count: number = gamepad.buttons.length;\n const axes_count: number = gamepad.axes.length;\n function MAP_BUTTON(NAV_NO: number, BUTTON_NO: number): void {\n if (!gamepad) { return; }\n if (buttons_count > BUTTON_NO && gamepad.buttons[BUTTON_NO].pressed)\n io.NavInputs[NAV_NO] = 1.0;\n }\n function MAP_ANALOG(NAV_NO: number, AXIS_NO: number, V0: number, V1: number): void {\n if (!gamepad) { return; }\n let v: number = (axes_count > AXIS_NO) ? gamepad.axes[AXIS_NO] : V0;\n v = (v - V0) / (V1 - V0);\n if (v > 1.0) v = 1.0;\n if (io.NavInputs[NAV_NO] < v) io.NavInputs[NAV_NO] = v;\n }\n // TODO: map input based on vendor and product id\n // https://developer.mozilla.org/en-US/docs/Web/API/Gamepad/id\n const match: RegExpMatchArray | null = gamepad.id.match(/^([0-9a-f]{4})-([0-9a-f]{4})-.*$/);\n const match_chrome: RegExpMatchArray | null = gamepad.id.match(/^.*\\(.*Vendor: ([0-9a-f]{4}) Product: ([0-9a-f]{4})\\).*$/);\n const vendor: string = (match && match[1]) || (match_chrome && match_chrome[1]) || \"0000\";\n const product: string = (match && match[2]) || (match_chrome && match_chrome[2]) || \"0000\";\n switch (vendor + product) {\n case \"046dc216\": // Logitech Logitech Dual Action (Vendor: 046d Product: c216)\n MAP_BUTTON(ImGui.NavInput.Activate, 1); // Cross / A\n MAP_BUTTON(ImGui.NavInput.Cancel, 2); // Circle / B\n MAP_BUTTON(ImGui.NavInput.Menu, 0); // Square / X\n MAP_BUTTON(ImGui.NavInput.Input, 3); // Triangle / Y\n MAP_ANALOG(ImGui.NavInput.DpadLeft, 4, -0.3, -0.9); // D-Pad Left\n MAP_ANALOG(ImGui.NavInput.DpadRight, 4, +0.3, +0.9); // D-Pad Right\n MAP_ANALOG(ImGui.NavInput.DpadUp, 5, -0.3, -0.9); // D-Pad Up\n MAP_ANALOG(ImGui.NavInput.DpadDown, 5, +0.3, +0.9); // D-Pad Down\n MAP_BUTTON(ImGui.NavInput.FocusPrev, 4); // L1 / LB\n MAP_BUTTON(ImGui.NavInput.FocusNext, 5); // R1 / RB\n MAP_BUTTON(ImGui.NavInput.TweakSlow, 6); // L2 / LT\n MAP_BUTTON(ImGui.NavInput.TweakFast, 7); // R2 / RT\n MAP_ANALOG(ImGui.NavInput.LStickLeft, 0, -0.3, -0.9);\n MAP_ANALOG(ImGui.NavInput.LStickRight, 0, +0.3, +0.9);\n MAP_ANALOG(ImGui.NavInput.LStickUp, 1, -0.3, -0.9);\n MAP_ANALOG(ImGui.NavInput.LStickDown, 1, +0.3, +0.9);\n break;\n case \"046dc21d\": // Logitech Gamepad F310 (STANDARD GAMEPAD Vendor: 046d Product: c21d)\n MAP_BUTTON(ImGui.NavInput.Activate, 0); // Cross / A\n MAP_BUTTON(ImGui.NavInput.Cancel, 1); // Circle / B\n MAP_BUTTON(ImGui.NavInput.Menu, 2); // Square / X\n MAP_BUTTON(ImGui.NavInput.Input, 3); // Triangle / Y\n MAP_BUTTON(ImGui.NavInput.DpadLeft, 14); // D-Pad Left\n MAP_BUTTON(ImGui.NavInput.DpadRight, 15); // D-Pad Right\n MAP_BUTTON(ImGui.NavInput.DpadUp, 12); // D-Pad Up\n MAP_BUTTON(ImGui.NavInput.DpadDown, 13); // D-Pad Down\n MAP_BUTTON(ImGui.NavInput.FocusPrev, 4); // L1 / LB\n MAP_BUTTON(ImGui.NavInput.FocusNext, 5); // R1 / RB\n MAP_ANALOG(ImGui.NavInput.TweakSlow, 6, +0.3, +0.9); // L2 / LT\n MAP_ANALOG(ImGui.NavInput.TweakFast, 7, +0.3, +0.9); // R2 / RT\n MAP_ANALOG(ImGui.NavInput.LStickLeft, 0, -0.3, -0.9);\n MAP_ANALOG(ImGui.NavInput.LStickRight, 0, +0.3, +0.9);\n MAP_ANALOG(ImGui.NavInput.LStickUp, 1, -0.3, -0.9);\n MAP_ANALOG(ImGui.NavInput.LStickDown, 1, +0.3, +0.9);\n break;\n case \"2dc86001\": // 8Bitdo SN30 Pro 8Bitdo SN30 Pro (Vendor: 2dc8 Product: 6001)\n case \"2dc86101\": // 8Bitdo SN30 Pro (Vendor: 2dc8 Product: 6101)\n MAP_BUTTON(ImGui.NavInput.Activate, 1); // Cross / A\n MAP_BUTTON(ImGui.NavInput.Cancel, 0); // Circle / B\n MAP_BUTTON(ImGui.NavInput.Menu, 4); // Square / X\n MAP_BUTTON(ImGui.NavInput.Input, 3); // Triangle / Y\n MAP_ANALOG(ImGui.NavInput.DpadLeft, 6, -0.3, -0.9); // D-Pad Left\n MAP_ANALOG(ImGui.NavInput.DpadRight, 6, +0.3, +0.9); // D-Pad Right\n MAP_ANALOG(ImGui.NavInput.DpadUp, 7, -0.3, -0.9); // D-Pad Up\n MAP_ANALOG(ImGui.NavInput.DpadDown, 7, +0.3, +0.9); // D-Pad Down\n MAP_BUTTON(ImGui.NavInput.FocusPrev, 6); // L1 / LB\n MAP_BUTTON(ImGui.NavInput.FocusNext, 7); // R1 / RB\n MAP_BUTTON(ImGui.NavInput.TweakSlow, 8); // L2 / LT\n MAP_BUTTON(ImGui.NavInput.TweakFast, 9); // R2 / RT\n MAP_ANALOG(ImGui.NavInput.LStickLeft, 0, -0.3, -0.9);\n MAP_ANALOG(ImGui.NavInput.LStickRight, 0, +0.3, +0.9);\n MAP_ANALOG(ImGui.NavInput.LStickUp, 1, -0.3, -0.9);\n MAP_ANALOG(ImGui.NavInput.LStickDown, 1, +0.3, +0.9);\n break;\n default: // standard gamepad: https://w3c.github.io/gamepad/#remapping\n MAP_BUTTON(ImGui.NavInput.Activate, 0); // Cross / A\n MAP_BUTTON(ImGui.NavInput.Cancel, 1); // Circle / B\n MAP_BUTTON(ImGui.NavInput.Menu, 2); // Square / X\n MAP_BUTTON(ImGui.NavInput.Input, 3); // Triangle / Y\n MAP_BUTTON(ImGui.NavInput.DpadLeft, 14); // D-Pad Left\n MAP_BUTTON(ImGui.NavInput.DpadRight, 15); // D-Pad Right\n MAP_BUTTON(ImGui.NavInput.DpadUp, 12); // D-Pad Up\n MAP_BUTTON(ImGui.NavInput.DpadDown, 13); // D-Pad Down\n MAP_BUTTON(ImGui.NavInput.FocusPrev, 4); // L1 / LB\n MAP_BUTTON(ImGui.NavInput.FocusNext, 5); // R1 / RB\n MAP_BUTTON(ImGui.NavInput.TweakSlow, 6); // L2 / LT\n MAP_BUTTON(ImGui.NavInput.TweakFast, 7); // R2 / RT\n MAP_ANALOG(ImGui.NavInput.LStickLeft, 0, -0.3, -0.9);\n MAP_ANALOG(ImGui.NavInput.LStickRight, 0, +0.3, +0.9);\n MAP_ANALOG(ImGui.NavInput.LStickUp, 1, -0.3, -0.9);\n MAP_ANALOG(ImGui.NavInput.LStickDown, 1, +0.3, +0.9);\n break;\n }\n }\n }\n}\n\nexport function RenderDrawData(draw_data: ImGui.DrawData | null = ImGui.GetDrawData()): void {\n const io = ImGui.GetIO();\n if (draw_data === null) { throw new Error(); }\n\n gl || ctx || console.log(draw_data);\n\n // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)\n const fb_width: number = io.DisplaySize.x * io.DisplayFramebufferScale.x;\n const fb_height: number = io.DisplaySize.y * io.DisplayFramebufferScale.y;\n if (fb_width === 0 || fb_height === 0) {\n return;\n }\n draw_data.ScaleClipRects(io.DisplayFramebufferScale);\n\n const gl2: WebGL2RenderingContext | null = typeof WebGL2RenderingContext !== \"undefined\" && gl instanceof WebGL2RenderingContext && gl || null;\n const gl_vao: OES_vertex_array_object | null = gl && gl.getExtension(\"OES_vertex_array_object\") || null;\n\n // Backup GL state\n const last_active_texture: GLenum | null = gl && gl.getParameter(gl.ACTIVE_TEXTURE) || null;\n const last_program: WebGLProgram | null = gl && gl.getParameter(gl.CURRENT_PROGRAM) || null;\n const last_texture: WebGLTexture | null = gl && gl.getParameter(gl.TEXTURE_BINDING_2D) || null;\n const last_array_buffer: WebGLBuffer | null = gl && gl.getParameter(gl.ARRAY_BUFFER_BINDING) || null;\n const last_element_array_buffer: WebGLBuffer | null = gl && gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING) || null;\n const last_vertex_array_object: WebGLVertexArrayObject | WebGLVertexArrayObjectOES | null = gl2 && gl2.getParameter(gl2.VERTEX_ARRAY_BINDING) || gl && gl_vao && gl.getParameter(gl_vao.VERTEX_ARRAY_BINDING_OES) || null;\n // GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);\n const last_viewport: Int32Array | null = gl && gl.getParameter(gl.VIEWPORT) || null;\n const last_scissor_box: Int32Array | null = gl && gl.getParameter(gl.SCISSOR_BOX) || null;\n const last_blend_src_rgb: GLenum | null = gl && gl.getParameter(gl.BLEND_SRC_RGB) || null;\n const last_blend_dst_rgb: GLenum | null = gl && gl.getParameter(gl.BLEND_DST_RGB) || null;\n const last_blend_src_alpha: GLenum | null = gl && gl.getParameter(gl.BLEND_SRC_ALPHA) || null;\n const last_blend_dst_alpha: GLenum | null = gl && gl.getParameter(gl.BLEND_DST_ALPHA) || null;\n const last_blend_equation_rgb: GLenum | null = gl && gl.getParameter(gl.BLEND_EQUATION_RGB) || null;\n const last_blend_equation_alpha: GLenum | null = gl && gl.getParameter(gl.BLEND_EQUATION_ALPHA) || null;\n const last_enable_blend: GLboolean | null = gl && gl.getParameter(gl.BLEND) || null;\n const last_enable_cull_face: GLboolean | null = gl && gl.getParameter(gl.CULL_FACE) || null;\n const last_enable_depth_test: GLboolean | null = gl && gl.getParameter(gl.DEPTH_TEST) || null;\n const last_enable_scissor_test: GLboolean | null = gl && gl.getParameter(gl.SCISSOR_TEST) || null;\n\n // Setup desired GL state\n // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)\n // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.\n const vertex_array_object: WebGLVertexArrayObject | WebGLVertexArrayObjectOES | null = gl2 && gl2.createVertexArray() || gl_vao && gl_vao.createVertexArrayOES();\n\n // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill\n gl && gl.enable(gl.BLEND);\n gl && gl.blendEquation(gl.FUNC_ADD);\n gl && gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl && gl.disable(gl.CULL_FACE);\n gl && gl.disable(gl.DEPTH_TEST);\n gl && gl.enable(gl.SCISSOR_TEST);\n // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);\n\n // Setup viewport, orthographic projection matrix\n // Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps.\n gl && gl.viewport(0, 0, fb_width, fb_height);\n const L: number = draw_data.DisplayPos.x;\n const R: number = draw_data.DisplayPos.x + draw_data.DisplaySize.x;\n const T: number = draw_data.DisplayPos.y;\n const B: number = draw_data.DisplayPos.y + draw_data.DisplaySize.y;\n const ortho_projection: Float32Array = new Float32Array([\n 2.0 / (R - L), 0.0, 0.0, 0.0,\n 0.0, 2.0 / (T - B), 0.0, 0.0,\n 0.0, 0.0, -1.0, 0.0,\n (R + L) / (L - R), (T + B) / (B - T), 0.0, 1.0,\n ]);\n gl && gl.useProgram(g_ShaderHandle);\n gl && gl.uniform1i(g_AttribLocationTex, 0);\n gl && g_AttribLocationProjMtx && gl.uniformMatrix4fv(g_AttribLocationProjMtx, false, ortho_projection);\n\n gl2 && gl2.bindVertexArray(vertex_array_object) || gl_vao && gl_vao.bindVertexArrayOES(vertex_array_object);\n\n // Render command lists\n gl && gl.bindBuffer(gl.ARRAY_BUFFER, g_VboHandle);\n gl && gl.enableVertexAttribArray(g_AttribLocationPosition);\n gl && gl.enableVertexAttribArray(g_AttribLocationUV);\n gl && gl.enableVertexAttribArray(g_AttribLocationColor);\n\n gl && gl.vertexAttribPointer(g_AttribLocationPosition, 2, gl.FLOAT, false, ImGui.DrawVertSize, ImGui.DrawVertPosOffset);\n gl && gl.vertexAttribPointer(g_AttribLocationUV, 2, gl.FLOAT, false, ImGui.DrawVertSize, ImGui.DrawVertUVOffset);\n gl && gl.vertexAttribPointer(g_AttribLocationColor, 4, gl.UNSIGNED_BYTE, true, ImGui.DrawVertSize, ImGui.DrawVertColOffset);\n\n // Draw\n const pos = draw_data.DisplayPos;\n const idx_buffer_type: GLenum = gl && ((ImGui.DrawIdxSize === 4) ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT) || 0;\n draw_data.IterateDrawLists((draw_list: ImGui.DrawList): void => {\n gl || ctx || console.log(draw_list);\n gl || ctx || console.log(\"VtxBuffer.length\", draw_list.VtxBuffer.length);\n gl || ctx || console.log(\"IdxBuffer.length\", draw_list.IdxBuffer.length);\n \n gl && gl.bindBuffer(gl.ARRAY_BUFFER, g_VboHandle);\n gl && gl.bufferData(gl.ARRAY_BUFFER, draw_list.VtxBuffer, gl.STREAM_DRAW);\n gl && gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, g_ElementsHandle);\n gl && gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, draw_list.IdxBuffer, gl.STREAM_DRAW);\n\n draw_list.IterateDrawCmds((draw_cmd: ImGui.DrawCmd): void => {\n gl || ctx || console.log(draw_cmd);\n gl || ctx || console.log(\"ElemCount\", draw_cmd.ElemCount);\n gl || ctx || console.log(\"ClipRect\", draw_cmd.ClipRect.x, fb_height - draw_cmd.ClipRect.w, draw_cmd.ClipRect.z - draw_cmd.ClipRect.x, draw_cmd.ClipRect.w - draw_cmd.ClipRect.y);\n gl || ctx || console.log(\"TextureId\", draw_cmd.TextureId);\n if (!gl && !ctx) {\n console.log(\"i: pos.x pos.y uv.x uv.y col\");\n for (let i = 0; i < Math.min(3, draw_cmd.ElemCount); ++i) {\n const view: ImGui.DrawVert = new ImGui.DrawVert(draw_list.VtxBuffer.buffer, draw_list.VtxBuffer.byteOffset + i * ImGui.DrawVertSize);\n console.log(`${i}: ${view.pos[0].toFixed(2)} ${view.pos[1].toFixed(2)} ${view.uv[0].toFixed(5)} ${view.uv[1].toFixed(5)} ${(\"00000000\" + view.col[0].toString(16)).substr(-8)}`);\n }\n }\n\n if (draw_cmd.UserCallback !== null) {\n // User callback (registered via ImDrawList::AddCallback)\n draw_cmd.UserCallback(draw_list, draw_cmd);\n } else {\n const clip_rect = new ImGui.Vec4(draw_cmd.ClipRect.x - pos.x, draw_cmd.ClipRect.y - pos.y, draw_cmd.ClipRect.z - pos.x, draw_cmd.ClipRect.w - pos.y);\n if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0 && clip_rect.w >= 0.0) {\n // Apply scissor/clipping rectangle\n gl && gl.scissor(clip_rect.x, fb_height - clip_rect.w, clip_rect.z - clip_rect.x, clip_rect.w - clip_rect.y);\n\n // Bind texture, Draw\n gl && gl.activeTexture(gl.TEXTURE0);\n gl && gl.bindTexture(gl.TEXTURE_2D, draw_cmd.TextureId);\n gl && gl.drawElements(gl.TRIANGLES, draw_cmd.ElemCount, idx_buffer_type, draw_cmd.IdxOffset * ImGui.DrawIdxSize);\n\n if (ctx) {\n ctx.save();\n ctx.beginPath();\n ctx.rect(clip_rect.x, clip_rect.y, clip_rect.z - clip_rect.x, clip_rect.w - clip_rect.y);\n ctx.clip();\n const idx = ImGui.DrawIdxSize === 4 ? \n new Uint32Array(draw_list.IdxBuffer.buffer, draw_list.IdxBuffer.byteOffset + draw_cmd.IdxOffset * ImGui.DrawIdxSize) : \n new Uint16Array(draw_list.IdxBuffer.buffer, draw_list.IdxBuffer.byteOffset + draw_cmd.IdxOffset * ImGui.DrawIdxSize);\n for (let i = 0; i < draw_cmd.ElemCount; i += 3) {\n const i0: number = idx[i + 0];\n const i1: number = idx[i + 1];\n const i2: number = idx[i + 2];\n const v0: ImGui.DrawVert = new ImGui.DrawVert(draw_list.VtxBuffer.buffer, draw_list.VtxBuffer.byteOffset + i0 * ImGui.DrawVertSize);\n const v1: ImGui.DrawVert = new ImGui.DrawVert(draw_list.VtxBuffer.buffer, draw_list.VtxBuffer.byteOffset + i1 * ImGui.DrawVertSize);\n const v2: ImGui.DrawVert = new ImGui.DrawVert(draw_list.VtxBuffer.buffer, draw_list.VtxBuffer.byteOffset + i2 * ImGui.DrawVertSize);\n const i3: number = idx[i + 3];\n const i4: number = idx[i + 4];\n const i5: number = idx[i + 5];\n const v3: ImGui.DrawVert = new ImGui.DrawVert(draw_list.VtxBuffer.buffer, draw_list.VtxBuffer.byteOffset + i3 * ImGui.DrawVertSize);\n const v4: ImGui.DrawVert = new ImGui.DrawVert(draw_list.VtxBuffer.buffer, draw_list.VtxBuffer.byteOffset + i4 * ImGui.DrawVertSize);\n const v5: ImGui.DrawVert = new ImGui.DrawVert(draw_list.VtxBuffer.buffer, draw_list.VtxBuffer.byteOffset + i5 * ImGui.DrawVertSize);\n let quad = true;\n let minmin: ImGui.DrawVert = v0;\n let minmax: ImGui.DrawVert = v0;\n let maxmin: ImGui.DrawVert = v0;\n let maxmax: ImGui.DrawVert = v0;\n for (const v of [ v1, v2, v3, v4, v5 ]) {\n let found = false;\n if (v.pos[0] <= minmin.pos[0] && v.pos[1] <= minmin.pos[1]) { minmin = v; found = true; }\n if (v.pos[0] <= minmax.pos[0] && v.pos[1] >= minmax.pos[1]) { minmax = v; found = true; }\n if (v.pos[0] >= maxmin.pos[0] && v.pos[1] <= maxmin.pos[1]) { maxmin = v; found = true; }\n if (v.pos[0] >= maxmax.pos[0] && v.pos[1] >= maxmax.pos[1]) { maxmax = v; found = true; }\n if (!found) { quad = false; }\n }\n quad = quad && (minmin.pos[0] === minmax.pos[0]);\n quad = quad && (maxmin.pos[0] === maxmax.pos[0]);\n quad = quad && (minmin.pos[1] === maxmin.pos[1]);\n quad = quad && (minmax.pos[1] === maxmax.pos[1]);\n if (quad) {\n if (minmin.uv[0] === maxmax.uv[0] || minmin.uv[1] === maxmax.uv[1]) {\n // one vertex color\n ctx.beginPath();\n ctx.rect(minmin.pos[0], minmin.pos[1], maxmax.pos[0] - minmin.pos[0], maxmax.pos[1] - minmin.pos[1]);\n ctx.fillStyle = `rgba(${v0.col[0] >> 0 & 0xff}, ${v0.col[0] >> 8 & 0xff}, ${v0.col[0] >> 16 & 0xff}, ${(v0.col[0] >> 24 & 0xff) / 0xff})`;\n ctx.fill();\n } else {\n // no vertex color\n const image = draw_cmd.TextureId as CanvasImageSource; // HACK\n const width = image instanceof HTMLVideoElement ? image.videoWidth : image.width as number;\n const height = image instanceof HTMLVideoElement ? image.videoHeight : image.height as number;\n image && ctx.drawImage(image,\n minmin.uv[0] * width, minmin.uv[1] * height,\n (maxmax.uv[0] - minmin.uv[0]) * width, (maxmax.uv[1] - minmin.uv[1]) * height,\n minmin.pos[0], minmin.pos[1], \n maxmax.pos[0] - minmin.pos[0], maxmax.pos[1] - minmin.pos[1]);\n // ctx.beginPath();\n // ctx.rect(minmin.pos[0], minmin.pos[1], maxmax.pos[0] - minmin.pos[0], maxmax.pos[1] - minmin.pos[1]);\n // ctx.strokeStyle = \"yellow\";\n // ctx.stroke();\n }\n i += 3;\n } else {\n // one vertex color, no texture\n ctx.beginPath();\n ctx.moveTo(v0.pos[0], v0.pos[1]);\n ctx.lineTo(v1.pos[0], v1.pos[1]);\n ctx.lineTo(v2.pos[0], v2.pos[1]);\n ctx.closePath();\n ctx.fillStyle = `rgba(${v0.col[0] >> 0 & 0xff}, ${v0.col[0] >> 8 & 0xff}, ${v0.col[0] >> 16 & 0xff}, ${(v0.col[0] >> 24 & 0xff) / 0xff})`;\n ctx.fill();\n }\n }\n ctx.restore();\n }\n }\n }\n });\n });\n\n // Destroy the temporary VAO\n gl2 && gl2.deleteVertexArray(vertex_array_object) || gl_vao && gl_vao.deleteVertexArrayOES(vertex_array_object);\n\n // Restore modified GL state\n gl && (last_program !== null) && gl.useProgram(last_program);\n gl && (last_texture !== null) && gl.bindTexture(gl.TEXTURE_2D, last_texture);\n gl && (last_active_texture !== null) && gl.activeTexture(last_active_texture);\n gl2 && gl2.bindVertexArray(last_vertex_array_object) || gl_vao && gl_vao.bindVertexArrayOES(last_vertex_array_object);\n gl && (last_array_buffer !== null) && gl.bindBuffer(gl.ARRAY_BUFFER, last_array_buffer);\n gl && (last_element_array_buffer !== null) && gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, last_element_array_buffer);\n gl && (last_blend_equation_rgb !== null && last_blend_equation_alpha !== null) && gl.blendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);\n gl && (last_blend_src_rgb !== null && last_blend_src_alpha !== null && last_blend_dst_rgb !== null && last_blend_dst_alpha !== null) && gl.blendFuncSeparate(last_blend_src_rgb, last_blend_src_alpha, last_blend_dst_rgb, last_blend_dst_alpha);\n gl && (last_enable_blend ? gl.enable(gl.BLEND) : gl.disable(gl.BLEND));\n gl && (last_enable_cull_face ? gl.enable(gl.CULL_FACE) : gl.disable(gl.CULL_FACE));\n gl && (last_enable_depth_test ? gl.enable(gl.DEPTH_TEST) : gl.disable(gl.DEPTH_TEST));\n gl && (last_enable_scissor_test ? gl.enable(gl.SCISSOR_TEST) : gl.disable(gl.SCISSOR_TEST));\n // glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);\n gl && (last_viewport !== null) && gl.viewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3]);\n gl && (last_scissor_box !== null) && gl.scissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3]);\n}\n\nexport function CreateFontsTexture(): void {\n const io = ImGui.GetIO();\n\n // Backup GL state\n const last_texture: WebGLTexture | null = gl && gl.getParameter(gl.TEXTURE_BINDING_2D);\n\n // Build texture atlas\n // const width: number = 256;\n // const height: number = 256;\n // const pixels: Uint8Array = new Uint8Array(4 * width * height).fill(0xff);\n const { width, height, pixels } = io.Fonts.GetTexDataAsRGBA32(); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.\n // console.log(`font texture ${width} x ${height} @ ${pixels.length}`);\n\n // Upload texture to graphics system\n g_FontTexture = gl && gl.createTexture();\n gl && gl.bindTexture(gl.TEXTURE_2D, g_FontTexture);\n gl && gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl && gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n // gl && gl.pixelStorei(gl.UNPACK_ROW_LENGTH); // WebGL2\n gl && gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n\n // Store our identifier\n io.Fonts.TexID = g_FontTexture || { foo: \"bar\" };\n // console.log(\"font texture id\", g_FontTexture);\n\n if (ctx) {\n const image_canvas: HTMLCanvasElement = document.createElement(\"canvas\");\n image_canvas.width = width;\n image_canvas.height = height;\n const image_ctx = image_canvas.getContext(\"2d\");\n if (image_ctx === null) { throw new Error(); }\n const image_data = image_ctx.getImageData(0, 0, width, height);\n image_data.data.set(pixels);\n image_ctx.putImageData(image_data, 0, 0);\n io.Fonts.TexID = image_canvas;\n }\n\n // Restore modified GL state\n gl && last_texture && gl.bindTexture(gl.TEXTURE_2D, last_texture);\n}\n\nexport function DestroyFontsTexture(): void {\n const io = ImGui.GetIO();\n io.Fonts.TexID = null;\n gl && gl.deleteTexture(g_FontTexture); g_FontTexture = null;\n}\n\nexport function CreateDeviceObjects(): void {\n const vertex_shader: string[] = [\n \"uniform mat4 ProjMtx;\",\n \"attribute vec2 Position;\",\n \"attribute vec2 UV;\",\n \"attribute vec4 Color;\",\n \"varying vec2 Frag_UV;\",\n \"varying vec4 Frag_Color;\",\n \"void main() {\",\n \"\tFrag_UV = UV;\",\n \"\tFrag_Color = Color;\",\n \"\tgl_Position = ProjMtx * vec4(Position.xy,0,1);\",\n \"}\",\n ];\n\n const fragment_shader: string[] = [\n \"precision mediump float;\", // WebGL requires precision specifiers\n \"uniform sampler2D Texture;\",\n \"varying vec2 Frag_UV;\",\n \"varying vec4 Frag_Color;\",\n \"void main() {\",\n \"\tgl_FragColor = Frag_Color * texture2D(Texture, Frag_UV);\",\n \"}\",\n ];\n\n g_ShaderHandle = gl && gl.createProgram();\n g_VertHandle = gl && gl.createShader(gl.VERTEX_SHADER);\n g_FragHandle = gl && gl.createShader(gl.FRAGMENT_SHADER);\n gl && gl.shaderSource(g_VertHandle as WebGLShader, vertex_shader.join(\"\\n\"));\n gl && gl.shaderSource(g_FragHandle as WebGLShader, fragment_shader.join(\"\\n\"));\n gl && gl.compileShader(g_VertHandle as WebGLShader);\n gl && gl.compileShader(g_FragHandle as WebGLShader);\n gl && gl.attachShader(g_ShaderHandle as WebGLProgram, g_VertHandle as WebGLShader);\n gl && gl.attachShader(g_ShaderHandle as WebGLProgram, g_FragHandle as WebGLShader);\n gl && gl.linkProgram(g_ShaderHandle as WebGLProgram);\n\n g_AttribLocationTex = gl && gl.getUniformLocation(g_ShaderHandle as WebGLProgram, \"Texture\");\n g_AttribLocationProjMtx = gl && gl.getUniformLocation(g_ShaderHandle as WebGLProgram, \"ProjMtx\");\n g_AttribLocationPosition = gl && gl.getAttribLocation(g_ShaderHandle as WebGLProgram, \"Position\") || 0;\n g_AttribLocationUV = gl && gl.getAttribLocation(g_ShaderHandle as WebGLProgram, \"UV\") || 0;\n g_AttribLocationColor = gl && gl.getAttribLocation(g_ShaderHandle as WebGLProgram, \"Color\") || 0;\n\n g_VboHandle = gl && gl.createBuffer();\n g_ElementsHandle = gl && gl.createBuffer();\n\n CreateFontsTexture();\n}\n\nexport function DestroyDeviceObjects(): void {\n DestroyFontsTexture();\n\n gl && gl.deleteBuffer(g_VboHandle); g_VboHandle = null;\n gl && gl.deleteBuffer(g_ElementsHandle); g_ElementsHandle = null;\n\n g_AttribLocationTex = null;\n g_AttribLocationProjMtx = null;\n g_AttribLocationPosition = -1;\n g_AttribLocationUV = -1;\n g_AttribLocationColor = -1;\n\n gl && gl.deleteProgram(g_ShaderHandle); g_ShaderHandle = null;\n gl && gl.deleteShader(g_VertHandle); g_VertHandle = null;\n gl && gl.deleteShader(g_FragHandle); g_FragHandle = null;\n}\n","import { defineSystem } from \"bitecs\";\nimport { World } from \"../factory/world\";\nimport { ImGui } from \"imgui-js\";\n\nexport function createTimeSystem() {\n\tlet frames = 0;\n\tlet prevTime = 0;\n\n\tlet fps = 0;\n\tlet ms = 0;\n\treturn defineSystem((world: World) => {\n\t\tframes++;\n\n\t\tconst now = performance.now();\n\t\tworld.time.delta = now - world.time.last;\n\t\tworld.time.elapsed += world.time.delta;\n\t\tworld.time.last = now;\n\n\t\tif (ImGui.bind !== undefined && world.editor.enabled) {\n\t\t\tImGui.SetNextWindowPos(\n\t\t\t\tnew ImGui.ImVec2(\n\t\t\t\t\tworld.renderer.domElement.getBoundingClientRect().right -\n\t\t\t\t\t\t69 * 2,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t\tImGui.SetNextWindowSize(\n\t\t\t\tnew ImGui.ImVec2(69 * 2, 100),\n\t\t\t\tImGui.Cond.Appearing,\n\t\t\t);\n\t\t\tImGui.SetNextWindowCollapsed(true, ImGui.Cond.Appearing);\n\t\t\tImGui.SetNextWindowSizeConstraints(\n\t\t\t\tnew ImGui.ImVec2(-1, 100),\n\t\t\t\tnew ImGui.ImVec2(-1, Infinity),\n\t\t\t);\n\t\t\tImGui.Begin(\"Debug\", null, ImGui.WindowFlags.NoMove);\n\t\t\tImGui.TextWrapped(\n\t\t\t\t`Hello, Whirled!\\n\\n[fps]: ${fps.toFixed()}\\n[ms]: ${ms.toFixed()}\\n[imgui]: v.${ImGui.VERSION}`,\n\t\t\t);\n\t\t\tif (now >= prevTime + 1000) {\n\t\t\t\tfps = (frames * 1000) / (now - prevTime);\n\t\t\t\tms = world.time.delta;\n\t\t\t\tprevTime = now;\n\t\t\t\tframes = 0;\n\t\t\t}\n\t\t}\n\t\treturn world;\n\t});\n}\n","/**\n * Full-screen textured quad shader\n */\n\nconst CopyShader = {\n\n\tuniforms: {\n\n\t\t'tDiffuse': { value: null },\n\t\t'opacity': { value: 1.0 }\n\n\t},\n\n\tvertexShader: /* glsl */`\n\n\t\tvarying vec2 vUv;\n\n\t\tvoid main() {\n\n\t\t\tvUv = uv;\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t}`,\n\n\tfragmentShader: /* glsl */`\n\n\t\tuniform float opacity;\n\n\t\tuniform sampler2D tDiffuse;\n\n\t\tvarying vec2 vUv;\n\n\t\tvoid main() {\n\n\t\t\tgl_FragColor = texture2D( tDiffuse, vUv );\n\t\t\tgl_FragColor.a *= opacity;\n\n\n\t\t}`\n\n};\n\nexport { CopyShader };\n","import {\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tOrthographicCamera,\n\tMesh\n} from 'three';\n\nclass Pass {\n\n\tconstructor() {\n\n\t\t// if set to true, the pass is processed by the composer\n\t\tthis.enabled = true;\n\n\t\t// if set to true, the pass indicates to swap read and write buffer after rendering\n\t\tthis.needsSwap = true;\n\n\t\t// if set to true, the pass clears its buffer before rendering\n\t\tthis.clear = false;\n\n\t\t// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.\n\t\tthis.renderToScreen = false;\n\n\t}\n\n\tsetSize( /* width, height */ ) {}\n\n\trender( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {\n\n\t\tconsole.error( 'THREE.Pass: .render() must be implemented in derived pass.' );\n\n\t}\n\n}\n\n// Helper for passes that need to fill the viewport with a single quad.\n\nconst _camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n// https://github.com/mrdoob/three.js/pull/21358\n\nconst _geometry = new BufferGeometry();\n_geometry.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );\n_geometry.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );\n\nclass FullScreenQuad {\n\n\tconstructor( material ) {\n\n\t\tthis._mesh = new Mesh( _geometry, material );\n\n\t}\n\n\tdispose() {\n\n\t\tthis._mesh.geometry.dispose();\n\n\t}\n\n\trender( renderer ) {\n\n\t\trenderer.render( this._mesh, _camera );\n\n\t}\n\n\tget material() {\n\n\t\treturn this._mesh.material;\n\n\t}\n\n\tset material( value ) {\n\n\t\tthis._mesh.material = value;\n\n\t}\n\n}\n\nexport { Pass, FullScreenQuad };\n","import {\n\tShaderMaterial,\n\tUniformsUtils\n} from 'three';\nimport { Pass, FullScreenQuad } from './Pass.js';\n\nclass ShaderPass extends Pass {\n\n\tconstructor( shader, textureID ) {\n\n\t\tsuper();\n\n\t\tthis.textureID = ( textureID !== undefined ) ? textureID : 'tDiffuse';\n\n\t\tif ( shader instanceof ShaderMaterial ) {\n\n\t\t\tthis.uniforms = shader.uniforms;\n\n\t\t\tthis.material = shader;\n\n\t\t} else if ( shader ) {\n\n\t\t\tthis.uniforms = UniformsUtils.clone( shader.uniforms );\n\n\t\t\tthis.material = new ShaderMaterial( {\n\n\t\t\t\tdefines: Object.assign( {}, shader.defines ),\n\t\t\t\tuniforms: this.uniforms,\n\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\tfragmentShader: shader.fragmentShader\n\n\t\t\t} );\n\n\t\t}\n\n\t\tthis.fsQuad = new FullScreenQuad( this.material );\n\n\t}\n\n\trender( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {\n\n\t\tif ( this.uniforms[ this.textureID ] ) {\n\n\t\t\tthis.uniforms[ this.textureID ].value = readBuffer.texture;\n\n\t\t}\n\n\t\tthis.fsQuad.material = this.material;\n\n\t\tif ( this.renderToScreen ) {\n\n\t\t\trenderer.setRenderTarget( null );\n\t\t\tthis.fsQuad.render( renderer );\n\n\t\t} else {\n\n\t\t\trenderer.setRenderTarget( writeBuffer );\n\t\t\t// TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600\n\t\t\tif ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );\n\t\t\tthis.fsQuad.render( renderer );\n\n\t\t}\n\n\t}\n\n}\n\nexport { ShaderPass };\n","import { Pass } from './Pass.js';\n\nclass MaskPass extends Pass {\n\n\tconstructor( scene, camera ) {\n\n\t\tsuper();\n\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\n\t\tthis.clear = true;\n\t\tthis.needsSwap = false;\n\n\t\tthis.inverse = false;\n\n\t}\n\n\trender( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {\n\n\t\tconst context = renderer.getContext();\n\t\tconst state = renderer.state;\n\n\t\t// don't update color or depth\n\n\t\tstate.buffers.color.setMask( false );\n\t\tstate.buffers.depth.setMask( false );\n\n\t\t// lock buffers\n\n\t\tstate.buffers.color.setLocked( true );\n\t\tstate.buffers.depth.setLocked( true );\n\n\t\t// set up stencil\n\n\t\tlet writeValue, clearValue;\n\n\t\tif ( this.inverse ) {\n\n\t\t\twriteValue = 0;\n\t\t\tclearValue = 1;\n\n\t\t} else {\n\n\t\t\twriteValue = 1;\n\t\t\tclearValue = 0;\n\n\t\t}\n\n\t\tstate.buffers.stencil.setTest( true );\n\t\tstate.buffers.stencil.setOp( context.REPLACE, context.REPLACE, context.REPLACE );\n\t\tstate.buffers.stencil.setFunc( context.ALWAYS, writeValue, 0xffffffff );\n\t\tstate.buffers.stencil.setClear( clearValue );\n\t\tstate.buffers.stencil.setLocked( true );\n\n\t\t// draw into the stencil buffer\n\n\t\trenderer.setRenderTarget( readBuffer );\n\t\tif ( this.clear ) renderer.clear();\n\t\trenderer.render( this.scene, this.camera );\n\n\t\trenderer.setRenderTarget( writeBuffer );\n\t\tif ( this.clear ) renderer.clear();\n\t\trenderer.render( this.scene, this.camera );\n\n\t\t// unlock color and depth buffer for subsequent rendering\n\n\t\tstate.buffers.color.setLocked( false );\n\t\tstate.buffers.depth.setLocked( false );\n\n\t\t// only render where stencil is set to 1\n\n\t\tstate.buffers.stencil.setLocked( false );\n\t\tstate.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n\t\tstate.buffers.stencil.setOp( context.KEEP, context.KEEP, context.KEEP );\n\t\tstate.buffers.stencil.setLocked( true );\n\n\t}\n\n}\n\nclass ClearMaskPass extends Pass {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.needsSwap = false;\n\n\t}\n\n\trender( renderer /*, writeBuffer, readBuffer, deltaTime, maskActive */ ) {\n\n\t\trenderer.state.buffers.stencil.setLocked( false );\n\t\trenderer.state.buffers.stencil.setTest( false );\n\n\t}\n\n}\n\nexport { MaskPass, ClearMaskPass };\n","import {\n\tBufferGeometry,\n\tClock,\n\tFloat32BufferAttribute,\n\tMesh,\n\tOrthographicCamera,\n\tVector2,\n\tWebGLRenderTarget\n} from 'three';\nimport { CopyShader } from '../shaders/CopyShader.js';\nimport { ShaderPass } from './ShaderPass.js';\nimport { MaskPass } from './MaskPass.js';\nimport { ClearMaskPass } from './MaskPass.js';\n\nclass EffectComposer {\n\n\tconstructor( renderer, renderTarget ) {\n\n\t\tthis.renderer = renderer;\n\n\t\tif ( renderTarget === undefined ) {\n\n\t\t\tconst size = renderer.getSize( new Vector2() );\n\t\t\tthis._pixelRatio = renderer.getPixelRatio();\n\t\t\tthis._width = size.width;\n\t\t\tthis._height = size.height;\n\n\t\t\trenderTarget = new WebGLRenderTarget( this._width * this._pixelRatio, this._height * this._pixelRatio );\n\t\t\trenderTarget.texture.name = 'EffectComposer.rt1';\n\n\t\t} else {\n\n\t\t\tthis._pixelRatio = 1;\n\t\t\tthis._width = renderTarget.width;\n\t\t\tthis._height = renderTarget.height;\n\n\t\t}\n\n\t\tthis.renderTarget1 = renderTarget;\n\t\tthis.renderTarget2 = renderTarget.clone();\n\t\tthis.renderTarget2.texture.name = 'EffectComposer.rt2';\n\n\t\tthis.writeBuffer = this.renderTarget1;\n\t\tthis.readBuffer = this.renderTarget2;\n\n\t\tthis.renderToScreen = true;\n\n\t\tthis.passes = [];\n\n\t\t// dependencies\n\n\t\tif ( CopyShader === undefined ) {\n\n\t\t\tconsole.error( 'THREE.EffectComposer relies on CopyShader' );\n\n\t\t}\n\n\t\tif ( ShaderPass === undefined ) {\n\n\t\t\tconsole.error( 'THREE.EffectComposer relies on ShaderPass' );\n\n\t\t}\n\n\t\tthis.copyPass = new ShaderPass( CopyShader );\n\n\t\tthis.clock = new Clock();\n\n\t}\n\n\tswapBuffers() {\n\n\t\tconst tmp = this.readBuffer;\n\t\tthis.readBuffer = this.writeBuffer;\n\t\tthis.writeBuffer = tmp;\n\n\t}\n\n\taddPass( pass ) {\n\n\t\tthis.passes.push( pass );\n\t\tpass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );\n\n\t}\n\n\tinsertPass( pass, index ) {\n\n\t\tthis.passes.splice( index, 0, pass );\n\t\tpass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );\n\n\t}\n\n\tremovePass( pass ) {\n\n\t\tconst index = this.passes.indexOf( pass );\n\n\t\tif ( index !== - 1 ) {\n\n\t\t\tthis.passes.splice( index, 1 );\n\n\t\t}\n\n\t}\n\n\tisLastEnabledPass( passIndex ) {\n\n\t\tfor ( let i = passIndex + 1; i < this.passes.length; i ++ ) {\n\n\t\t\tif ( this.passes[ i ].enabled ) {\n\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn true;\n\n\t}\n\n\trender( deltaTime ) {\n\n\t\t// deltaTime value is in seconds\n\n\t\tif ( deltaTime === undefined ) {\n\n\t\t\tdeltaTime = this.clock.getDelta();\n\n\t\t}\n\n\t\tconst currentRenderTarget = this.renderer.getRenderTarget();\n\n\t\tlet maskActive = false;\n\n\t\tfor ( let i = 0, il = this.passes.length; i < il; i ++ ) {\n\n\t\t\tconst pass = this.passes[ i ];\n\n\t\t\tif ( pass.enabled === false ) continue;\n\n\t\t\tpass.renderToScreen = ( this.renderToScreen && this.isLastEnabledPass( i ) );\n\t\t\tpass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive );\n\n\t\t\tif ( pass.needsSwap ) {\n\n\t\t\t\tif ( maskActive ) {\n\n\t\t\t\t\tconst context = this.renderer.getContext();\n\t\t\t\t\tconst stencil = this.renderer.state.buffers.stencil;\n\n\t\t\t\t\t//context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\t\t\t\t\tstencil.setFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n\t\t\t\t\tthis.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime );\n\n\t\t\t\t\t//context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\t\t\t\t\tstencil.setFunc( context.EQUAL, 1, 0xffffffff );\n\n\t\t\t\t}\n\n\t\t\t\tthis.swapBuffers();\n\n\t\t\t}\n\n\t\t\tif ( MaskPass !== undefined ) {\n\n\t\t\t\tif ( pass instanceof MaskPass ) {\n\n\t\t\t\t\tmaskActive = true;\n\n\t\t\t\t} else if ( pass instanceof ClearMaskPass ) {\n\n\t\t\t\t\tmaskActive = false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.renderer.setRenderTarget( currentRenderTarget );\n\n\t}\n\n\treset( renderTarget ) {\n\n\t\tif ( renderTarget === undefined ) {\n\n\t\t\tconst size = this.renderer.getSize( new Vector2() );\n\t\t\tthis._pixelRatio = this.renderer.getPixelRatio();\n\t\t\tthis._width = size.width;\n\t\t\tthis._height = size.height;\n\n\t\t\trenderTarget = this.renderTarget1.clone();\n\t\t\trenderTarget.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );\n\n\t\t}\n\n\t\tthis.renderTarget1.dispose();\n\t\tthis.renderTarget2.dispose();\n\t\tthis.renderTarget1 = renderTarget;\n\t\tthis.renderTarget2 = renderTarget.clone();\n\n\t\tthis.writeBuffer = this.renderTarget1;\n\t\tthis.readBuffer = this.renderTarget2;\n\n\t}\n\n\tsetSize( width, height ) {\n\n\t\tthis._width = width;\n\t\tthis._height = height;\n\n\t\tconst effectiveWidth = this._width * this._pixelRatio;\n\t\tconst effectiveHeight = this._height * this._pixelRatio;\n\n\t\tthis.renderTarget1.setSize( effectiveWidth, effectiveHeight );\n\t\tthis.renderTarget2.setSize( effectiveWidth, effectiveHeight );\n\n\t\tfor ( let i = 0; i < this.passes.length; i ++ ) {\n\n\t\t\tthis.passes[ i ].setSize( effectiveWidth, effectiveHeight );\n\n\t\t}\n\n\t}\n\n\tsetPixelRatio( pixelRatio ) {\n\n\t\tthis._pixelRatio = pixelRatio;\n\n\t\tthis.setSize( this._width, this._height );\n\n\t}\n\n}\n\n\nclass Pass {\n\n\tconstructor() {\n\n\t\t// if set to true, the pass is processed by the composer\n\t\tthis.enabled = true;\n\n\t\t// if set to true, the pass indicates to swap read and write buffer after rendering\n\t\tthis.needsSwap = true;\n\n\t\t// if set to true, the pass clears its buffer before rendering\n\t\tthis.clear = false;\n\n\t\t// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.\n\t\tthis.renderToScreen = false;\n\n\t}\n\n\tsetSize( /* width, height */ ) {}\n\n\trender( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {\n\n\t\tconsole.error( 'THREE.Pass: .render() must be implemented in derived pass.' );\n\n\t}\n\n}\n\n// Helper for passes that need to fill the viewport with a single quad.\n\nconst _camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n// https://github.com/mrdoob/three.js/pull/21358\n\nconst _geometry = new BufferGeometry();\n_geometry.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );\n_geometry.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );\n\nclass FullScreenQuad {\n\n\tconstructor( material ) {\n\n\t\tthis._mesh = new Mesh( _geometry, material );\n\n\t}\n\n\tdispose() {\n\n\t\tthis._mesh.geometry.dispose();\n\n\t}\n\n\trender( renderer ) {\n\n\t\trenderer.render( this._mesh, _camera );\n\n\t}\n\n\tget material() {\n\n\t\treturn this._mesh.material;\n\n\t}\n\n\tset material( value ) {\n\n\t\tthis._mesh.material = value;\n\n\t}\n\n}\n\nexport { EffectComposer, Pass, FullScreenQuad };\n","import {\n\tColor\n} from 'three';\nimport { Pass } from './Pass.js';\n\nclass RenderPass extends Pass {\n\n\tconstructor( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n\n\t\tsuper();\n\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\n\t\tthis.overrideMaterial = overrideMaterial;\n\n\t\tthis.clearColor = clearColor;\n\t\tthis.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0;\n\n\t\tthis.clear = true;\n\t\tthis.clearDepth = false;\n\t\tthis.needsSwap = false;\n\t\tthis._oldClearColor = new Color();\n\n\t}\n\n\trender( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {\n\n\t\tconst oldAutoClear = renderer.autoClear;\n\t\trenderer.autoClear = false;\n\n\t\tlet oldClearAlpha, oldOverrideMaterial;\n\n\t\tif ( this.overrideMaterial !== undefined ) {\n\n\t\t\toldOverrideMaterial = this.scene.overrideMaterial;\n\n\t\t\tthis.scene.overrideMaterial = this.overrideMaterial;\n\n\t\t}\n\n\t\tif ( this.clearColor ) {\n\n\t\t\trenderer.getClearColor( this._oldClearColor );\n\t\t\toldClearAlpha = renderer.getClearAlpha();\n\n\t\t\trenderer.setClearColor( this.clearColor, this.clearAlpha );\n\n\t\t}\n\n\t\tif ( this.clearDepth ) {\n\n\t\t\trenderer.clearDepth();\n\n\t\t}\n\n\t\trenderer.setRenderTarget( this.renderToScreen ? null : readBuffer );\n\n\t\t// TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600\n\t\tif ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );\n\t\trenderer.render( this.scene, this.camera );\n\n\t\tif ( this.clearColor ) {\n\n\t\t\trenderer.setClearColor( this._oldClearColor, oldClearAlpha );\n\n\t\t}\n\n\t\tif ( this.overrideMaterial !== undefined ) {\n\n\t\t\tthis.scene.overrideMaterial = oldOverrideMaterial;\n\n\t\t}\n\n\t\trenderer.autoClear = oldAutoClear;\n\n\t}\n\n}\n\nexport { RenderPass };\n","import {\n\tAdditiveBlending,\n\tColor,\n\tDoubleSide,\n\tMatrix4,\n\tMeshDepthMaterial,\n\tNoBlending,\n\tRGBADepthPacking,\n\tShaderMaterial,\n\tUniformsUtils,\n\tVector2,\n\tVector3,\n\tWebGLRenderTarget\n} from 'three';\nimport { Pass, FullScreenQuad } from './Pass.js';\nimport { CopyShader } from '../shaders/CopyShader.js';\n\nclass OutlinePass extends Pass {\n\n\tconstructor( resolution, scene, camera, selectedObjects ) {\n\n\t\tsuper();\n\n\t\tthis.renderScene = scene;\n\t\tthis.renderCamera = camera;\n\t\tthis.selectedObjects = selectedObjects !== undefined ? selectedObjects : [];\n\t\tthis.visibleEdgeColor = new Color( 1, 1, 1 );\n\t\tthis.hiddenEdgeColor = new Color( 0.1, 0.04, 0.02 );\n\t\tthis.edgeGlow = 0.0;\n\t\tthis.usePatternTexture = false;\n\t\tthis.edgeThickness = 1.0;\n\t\tthis.edgeStrength = 3.0;\n\t\tthis.downSampleRatio = 2;\n\t\tthis.pulsePeriod = 0;\n\n\t\tthis._visibilityCache = new Map();\n\n\n\t\tthis.resolution = ( resolution !== undefined ) ? new Vector2( resolution.x, resolution.y ) : new Vector2( 256, 256 );\n\n\t\tconst resx = Math.round( this.resolution.x / this.downSampleRatio );\n\t\tconst resy = Math.round( this.resolution.y / this.downSampleRatio );\n\n\t\tthis.renderTargetMaskBuffer = new WebGLRenderTarget( this.resolution.x, this.resolution.y );\n\t\tthis.renderTargetMaskBuffer.texture.name = 'OutlinePass.mask';\n\t\tthis.renderTargetMaskBuffer.texture.generateMipmaps = false;\n\n\t\tthis.depthMaterial = new MeshDepthMaterial();\n\t\tthis.depthMaterial.side = DoubleSide;\n\t\tthis.depthMaterial.depthPacking = RGBADepthPacking;\n\t\tthis.depthMaterial.blending = NoBlending;\n\n\t\tthis.prepareMaskMaterial = this.getPrepareMaskMaterial();\n\t\tthis.prepareMaskMaterial.side = DoubleSide;\n\t\tthis.prepareMaskMaterial.fragmentShader = replaceDepthToViewZ( this.prepareMaskMaterial.fragmentShader, this.renderCamera );\n\n\t\tthis.renderTargetDepthBuffer = new WebGLRenderTarget( this.resolution.x, this.resolution.y );\n\t\tthis.renderTargetDepthBuffer.texture.name = 'OutlinePass.depth';\n\t\tthis.renderTargetDepthBuffer.texture.generateMipmaps = false;\n\n\t\tthis.renderTargetMaskDownSampleBuffer = new WebGLRenderTarget( resx, resy );\n\t\tthis.renderTargetMaskDownSampleBuffer.texture.name = 'OutlinePass.depthDownSample';\n\t\tthis.renderTargetMaskDownSampleBuffer.texture.generateMipmaps = false;\n\n\t\tthis.renderTargetBlurBuffer1 = new WebGLRenderTarget( resx, resy );\n\t\tthis.renderTargetBlurBuffer1.texture.name = 'OutlinePass.blur1';\n\t\tthis.renderTargetBlurBuffer1.texture.generateMipmaps = false;\n\t\tthis.renderTargetBlurBuffer2 = new WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ) );\n\t\tthis.renderTargetBlurBuffer2.texture.name = 'OutlinePass.blur2';\n\t\tthis.renderTargetBlurBuffer2.texture.generateMipmaps = false;\n\n\t\tthis.edgeDetectionMaterial = this.getEdgeDetectionMaterial();\n\t\tthis.renderTargetEdgeBuffer1 = new WebGLRenderTarget( resx, resy );\n\t\tthis.renderTargetEdgeBuffer1.texture.name = 'OutlinePass.edge1';\n\t\tthis.renderTargetEdgeBuffer1.texture.generateMipmaps = false;\n\t\tthis.renderTargetEdgeBuffer2 = new WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ) );\n\t\tthis.renderTargetEdgeBuffer2.texture.name = 'OutlinePass.edge2';\n\t\tthis.renderTargetEdgeBuffer2.texture.generateMipmaps = false;\n\n\t\tconst MAX_EDGE_THICKNESS = 4;\n\t\tconst MAX_EDGE_GLOW = 4;\n\n\t\tthis.separableBlurMaterial1 = this.getSeperableBlurMaterial( MAX_EDGE_THICKNESS );\n\t\tthis.separableBlurMaterial1.uniforms[ 'texSize' ].value.set( resx, resy );\n\t\tthis.separableBlurMaterial1.uniforms[ 'kernelRadius' ].value = 1;\n\t\tthis.separableBlurMaterial2 = this.getSeperableBlurMaterial( MAX_EDGE_GLOW );\n\t\tthis.separableBlurMaterial2.uniforms[ 'texSize' ].value.set( Math.round( resx / 2 ), Math.round( resy / 2 ) );\n\t\tthis.separableBlurMaterial2.uniforms[ 'kernelRadius' ].value = MAX_EDGE_GLOW;\n\n\t\t// Overlay material\n\t\tthis.overlayMaterial = this.getOverlayMaterial();\n\n\t\t// copy material\n\t\tif ( CopyShader === undefined ) console.error( 'THREE.OutlinePass relies on CopyShader' );\n\n\t\tconst copyShader = CopyShader;\n\n\t\tthis.copyUniforms = UniformsUtils.clone( copyShader.uniforms );\n\t\tthis.copyUniforms[ 'opacity' ].value = 1.0;\n\n\t\tthis.materialCopy = new ShaderMaterial( {\n\t\t\tuniforms: this.copyUniforms,\n\t\t\tvertexShader: copyShader.vertexShader,\n\t\t\tfragmentShader: copyShader.fragmentShader,\n\t\t\tblending: NoBlending,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\ttransparent: true\n\t\t} );\n\n\t\tthis.enabled = true;\n\t\tthis.needsSwap = false;\n\n\t\tthis._oldClearColor = new Color();\n\t\tthis.oldClearAlpha = 1;\n\n\t\tthis.fsQuad = new FullScreenQuad( null );\n\n\t\tthis.tempPulseColor1 = new Color();\n\t\tthis.tempPulseColor2 = new Color();\n\t\tthis.textureMatrix = new Matrix4();\n\n\t\tfunction replaceDepthToViewZ( string, camera ) {\n\n\t\t\tconst type = camera.isPerspectiveCamera ? 'perspective' : 'orthographic';\n\n\t\t\treturn string.replace( /DEPTH_TO_VIEW_Z/g, type + 'DepthToViewZ' );\n\n\t\t}\n\n\t}\n\n\tdispose() {\n\n\t\tthis.renderTargetMaskBuffer.dispose();\n\t\tthis.renderTargetDepthBuffer.dispose();\n\t\tthis.renderTargetMaskDownSampleBuffer.dispose();\n\t\tthis.renderTargetBlurBuffer1.dispose();\n\t\tthis.renderTargetBlurBuffer2.dispose();\n\t\tthis.renderTargetEdgeBuffer1.dispose();\n\t\tthis.renderTargetEdgeBuffer2.dispose();\n\n\t}\n\n\tsetSize( width, height ) {\n\n\t\tthis.renderTargetMaskBuffer.setSize( width, height );\n\t\tthis.renderTargetDepthBuffer.setSize( width, height );\n\n\t\tlet resx = Math.round( width / this.downSampleRatio );\n\t\tlet resy = Math.round( height / this.downSampleRatio );\n\t\tthis.renderTargetMaskDownSampleBuffer.setSize( resx, resy );\n\t\tthis.renderTargetBlurBuffer1.setSize( resx, resy );\n\t\tthis.renderTargetEdgeBuffer1.setSize( resx, resy );\n\t\tthis.separableBlurMaterial1.uniforms[ 'texSize' ].value.set( resx, resy );\n\n\t\tresx = Math.round( resx / 2 );\n\t\tresy = Math.round( resy / 2 );\n\n\t\tthis.renderTargetBlurBuffer2.setSize( resx, resy );\n\t\tthis.renderTargetEdgeBuffer2.setSize( resx, resy );\n\n\t\tthis.separableBlurMaterial2.uniforms[ 'texSize' ].value.set( resx, resy );\n\n\t}\n\n\tchangeVisibilityOfSelectedObjects( bVisible ) {\n\n\t\tconst cache = this._visibilityCache;\n\n\t\tfunction gatherSelectedMeshesCallBack( object ) {\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( bVisible === true ) {\n\n\t\t\t\t\tobject.visible = cache.get( object );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcache.set( object, object.visible );\n\t\t\t\t\tobject.visible = bVisible;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( let i = 0; i < this.selectedObjects.length; i ++ ) {\n\n\t\t\tconst selectedObject = this.selectedObjects[ i ];\n\t\t\tselectedObject.traverse( gatherSelectedMeshesCallBack );\n\n\t\t}\n\n\t}\n\n\tchangeVisibilityOfNonSelectedObjects( bVisible ) {\n\n\t\tconst cache = this._visibilityCache;\n\t\tconst selectedMeshes = [];\n\n\t\tfunction gatherSelectedMeshesCallBack( object ) {\n\n\t\t\tif ( object.isMesh ) selectedMeshes.push( object );\n\n\t\t}\n\n\t\tfor ( let i = 0; i < this.selectedObjects.length; i ++ ) {\n\n\t\t\tconst selectedObject = this.selectedObjects[ i ];\n\t\t\tselectedObject.traverse( gatherSelectedMeshesCallBack );\n\n\t\t}\n\n\t\tfunction VisibilityChangeCallBack( object ) {\n\n\t\t\tif ( object.isMesh || object.isSprite ) {\n\n\t\t\t\t// only meshes and sprites are supported by OutlinePass\n\n\t\t\t\tlet bFound = false;\n\n\t\t\t\tfor ( let i = 0; i < selectedMeshes.length; i ++ ) {\n\n\t\t\t\t\tconst selectedObjectId = selectedMeshes[ i ].id;\n\n\t\t\t\t\tif ( selectedObjectId === object.id ) {\n\n\t\t\t\t\t\tbFound = true;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( bFound === false ) {\n\n\t\t\t\t\tconst visibility = object.visible;\n\n\t\t\t\t\tif ( bVisible === false || cache.get( object ) === true ) {\n\n\t\t\t\t\t\tobject.visible = bVisible;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcache.set( object, visibility );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints || object.isLine ) {\n\n\t\t\t\t// the visibilty of points and lines is always set to false in order to\n\t\t\t\t// not affect the outline computation\n\n\t\t\t\tif ( bVisible === true ) {\n\n\t\t\t\t\tobject.visible = cache.get( object ); // restore\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcache.set( object, object.visible );\n\t\t\t\t\tobject.visible = bVisible;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.renderScene.traverse( VisibilityChangeCallBack );\n\n\t}\n\n\tupdateTextureMatrix() {\n\n\t\tthis.textureMatrix.set( 0.5, 0.0, 0.0, 0.5,\n\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t0.0, 0.0, 0.0, 1.0 );\n\t\tthis.textureMatrix.multiply( this.renderCamera.projectionMatrix );\n\t\tthis.textureMatrix.multiply( this.renderCamera.matrixWorldInverse );\n\n\t}\n\n\trender( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {\n\n\t\tif ( this.selectedObjects.length > 0 ) {\n\n\t\t\trenderer.getClearColor( this._oldClearColor );\n\t\t\tthis.oldClearAlpha = renderer.getClearAlpha();\n\t\t\tconst oldAutoClear = renderer.autoClear;\n\n\t\t\trenderer.autoClear = false;\n\n\t\t\tif ( maskActive ) renderer.state.buffers.stencil.setTest( false );\n\n\t\t\trenderer.setClearColor( 0xffffff, 1 );\n\n\t\t\t// Make selected objects invisible\n\t\t\tthis.changeVisibilityOfSelectedObjects( false );\n\n\t\t\tconst currentBackground = this.renderScene.background;\n\t\t\tthis.renderScene.background = null;\n\n\t\t\t// 1. Draw Non Selected objects in the depth buffer\n\t\t\tthis.renderScene.overrideMaterial = this.depthMaterial;\n\t\t\trenderer.setRenderTarget( this.renderTargetDepthBuffer );\n\t\t\trenderer.clear();\n\t\t\trenderer.render( this.renderScene, this.renderCamera );\n\n\t\t\t// Make selected objects visible\n\t\t\tthis.changeVisibilityOfSelectedObjects( true );\n\t\t\tthis._visibilityCache.clear();\n\n\t\t\t// Update Texture Matrix for Depth compare\n\t\t\tthis.updateTextureMatrix();\n\n\t\t\t// Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects\n\t\t\tthis.changeVisibilityOfNonSelectedObjects( false );\n\t\t\tthis.renderScene.overrideMaterial = this.prepareMaskMaterial;\n\t\t\tthis.prepareMaskMaterial.uniforms[ 'cameraNearFar' ].value.set( this.renderCamera.near, this.renderCamera.far );\n\t\t\tthis.prepareMaskMaterial.uniforms[ 'depthTexture' ].value = this.renderTargetDepthBuffer.texture;\n\t\t\tthis.prepareMaskMaterial.uniforms[ 'textureMatrix' ].value = this.textureMatrix;\n\t\t\trenderer.setRenderTarget( this.renderTargetMaskBuffer );\n\t\t\trenderer.clear();\n\t\t\trenderer.render( this.renderScene, this.renderCamera );\n\t\t\tthis.renderScene.overrideMaterial = null;\n\t\t\tthis.changeVisibilityOfNonSelectedObjects( true );\n\t\t\tthis._visibilityCache.clear();\n\n\t\t\tthis.renderScene.background = currentBackground;\n\n\t\t\t// 2. Downsample to Half resolution\n\t\t\tthis.fsQuad.material = this.materialCopy;\n\t\t\tthis.copyUniforms[ 'tDiffuse' ].value = this.renderTargetMaskBuffer.texture;\n\t\t\trenderer.setRenderTarget( this.renderTargetMaskDownSampleBuffer );\n\t\t\trenderer.clear();\n\t\t\tthis.fsQuad.render( renderer );\n\n\t\t\tthis.tempPulseColor1.copy( this.visibleEdgeColor );\n\t\t\tthis.tempPulseColor2.copy( this.hiddenEdgeColor );\n\n\t\t\tif ( this.pulsePeriod > 0 ) {\n\n\t\t\t\tconst scalar = ( 1 + 0.25 ) / 2 + Math.cos( performance.now() * 0.01 / this.pulsePeriod ) * ( 1.0 - 0.25 ) / 2;\n\t\t\t\tthis.tempPulseColor1.multiplyScalar( scalar );\n\t\t\t\tthis.tempPulseColor2.multiplyScalar( scalar );\n\n\t\t\t}\n\n\t\t\t// 3. Apply Edge Detection Pass\n\t\t\tthis.fsQuad.material = this.edgeDetectionMaterial;\n\t\t\tthis.edgeDetectionMaterial.uniforms[ 'maskTexture' ].value = this.renderTargetMaskDownSampleBuffer.texture;\n\t\t\tthis.edgeDetectionMaterial.uniforms[ 'texSize' ].value.set( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height );\n\t\t\tthis.edgeDetectionMaterial.uniforms[ 'visibleEdgeColor' ].value = this.tempPulseColor1;\n\t\t\tthis.edgeDetectionMaterial.uniforms[ 'hiddenEdgeColor' ].value = this.tempPulseColor2;\n\t\t\trenderer.setRenderTarget( this.renderTargetEdgeBuffer1 );\n\t\t\trenderer.clear();\n\t\t\tthis.fsQuad.render( renderer );\n\n\t\t\t// 4. Apply Blur on Half res\n\t\t\tthis.fsQuad.material = this.separableBlurMaterial1;\n\t\t\tthis.separableBlurMaterial1.uniforms[ 'colorTexture' ].value = this.renderTargetEdgeBuffer1.texture;\n\t\t\tthis.separableBlurMaterial1.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionX;\n\t\t\tthis.separableBlurMaterial1.uniforms[ 'kernelRadius' ].value = this.edgeThickness;\n\t\t\trenderer.setRenderTarget( this.renderTargetBlurBuffer1 );\n\t\t\trenderer.clear();\n\t\t\tthis.fsQuad.render( renderer );\n\t\t\tthis.separableBlurMaterial1.uniforms[ 'colorTexture' ].value = this.renderTargetBlurBuffer1.texture;\n\t\t\tthis.separableBlurMaterial1.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionY;\n\t\t\trenderer.setRenderTarget( this.renderTargetEdgeBuffer1 );\n\t\t\trenderer.clear();\n\t\t\tthis.fsQuad.render( renderer );\n\n\t\t\t// Apply Blur on quarter res\n\t\t\tthis.fsQuad.material = this.separableBlurMaterial2;\n\t\t\tthis.separableBlurMaterial2.uniforms[ 'colorTexture' ].value = this.renderTargetEdgeBuffer1.texture;\n\t\t\tthis.separableBlurMaterial2.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionX;\n\t\t\trenderer.setRenderTarget( this.renderTargetBlurBuffer2 );\n\t\t\trenderer.clear();\n\t\t\tthis.fsQuad.render( renderer );\n\t\t\tthis.separableBlurMaterial2.uniforms[ 'colorTexture' ].value = this.renderTargetBlurBuffer2.texture;\n\t\t\tthis.separableBlurMaterial2.uniforms[ 'direction' ].value = OutlinePass.BlurDirectionY;\n\t\t\trenderer.setRenderTarget( this.renderTargetEdgeBuffer2 );\n\t\t\trenderer.clear();\n\t\t\tthis.fsQuad.render( renderer );\n\n\t\t\t// Blend it additively over the input texture\n\t\t\tthis.fsQuad.material = this.overlayMaterial;\n\t\t\tthis.overlayMaterial.uniforms[ 'maskTexture' ].value = this.renderTargetMaskBuffer.texture;\n\t\t\tthis.overlayMaterial.uniforms[ 'edgeTexture1' ].value = this.renderTargetEdgeBuffer1.texture;\n\t\t\tthis.overlayMaterial.uniforms[ 'edgeTexture2' ].value = this.renderTargetEdgeBuffer2.texture;\n\t\t\tthis.overlayMaterial.uniforms[ 'patternTexture' ].value = this.patternTexture;\n\t\t\tthis.overlayMaterial.uniforms[ 'edgeStrength' ].value = this.edgeStrength;\n\t\t\tthis.overlayMaterial.uniforms[ 'edgeGlow' ].value = this.edgeGlow;\n\t\t\tthis.overlayMaterial.uniforms[ 'usePatternTexture' ].value = this.usePatternTexture;\n\n\n\t\t\tif ( maskActive ) renderer.state.buffers.stencil.setTest( true );\n\n\t\t\trenderer.setRenderTarget( readBuffer );\n\t\t\tthis.fsQuad.render( renderer );\n\n\t\t\trenderer.setClearColor( this._oldClearColor, this.oldClearAlpha );\n\t\t\trenderer.autoClear = oldAutoClear;\n\n\t\t}\n\n\t\tif ( this.renderToScreen ) {\n\n\t\t\tthis.fsQuad.material = this.materialCopy;\n\t\t\tthis.copyUniforms[ 'tDiffuse' ].value = readBuffer.texture;\n\t\t\trenderer.setRenderTarget( null );\n\t\t\tthis.fsQuad.render( renderer );\n\n\t\t}\n\n\t}\n\n\tgetPrepareMaskMaterial() {\n\n\t\treturn new ShaderMaterial( {\n\n\t\t\tuniforms: {\n\t\t\t\t'depthTexture': { value: null },\n\t\t\t\t'cameraNearFar': { value: new Vector2( 0.5, 0.5 ) },\n\t\t\t\t'textureMatrix': { value: null }\n\t\t\t},\n\n\t\t\tvertexShader:\n\t\t\t\t`#include \n\t\t\t\t#include \n\n\t\t\t\tvarying vec4 projTexCoord;\n\t\t\t\tvarying vec4 vPosition;\n\t\t\t\tuniform mat4 textureMatrix;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t\tvPosition = mvPosition;\n\t\t\t\t\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n\t\t\t\t\tprojTexCoord = textureMatrix * worldPosition;\n\n\t\t\t\t}`,\n\n\t\t\tfragmentShader:\n\t\t\t\t`#include \n\t\t\t\tvarying vec4 vPosition;\n\t\t\t\tvarying vec4 projTexCoord;\n\t\t\t\tuniform sampler2D depthTexture;\n\t\t\t\tuniform vec2 cameraNearFar;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tfloat depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));\n\t\t\t\t\tfloat viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );\n\t\t\t\t\tfloat depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;\n\t\t\t\t\tgl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);\n\n\t\t\t\t}`\n\n\t\t} );\n\n\t}\n\n\tgetEdgeDetectionMaterial() {\n\n\t\treturn new ShaderMaterial( {\n\n\t\t\tuniforms: {\n\t\t\t\t'maskTexture': { value: null },\n\t\t\t\t'texSize': { value: new Vector2( 0.5, 0.5 ) },\n\t\t\t\t'visibleEdgeColor': { value: new Vector3( 1.0, 1.0, 1.0 ) },\n\t\t\t\t'hiddenEdgeColor': { value: new Vector3( 1.0, 1.0, 1.0 ) },\n\t\t\t},\n\n\t\t\tvertexShader:\n\t\t\t\t`varying vec2 vUv;\n\n\t\t\t\tvoid main() {\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\t\t\t\t}`,\n\n\t\t\tfragmentShader:\n\t\t\t\t`varying vec2 vUv;\n\n\t\t\t\tuniform sampler2D maskTexture;\n\t\t\t\tuniform vec2 texSize;\n\t\t\t\tuniform vec3 visibleEdgeColor;\n\t\t\t\tuniform vec3 hiddenEdgeColor;\n\n\t\t\t\tvoid main() {\n\t\t\t\t\tvec2 invSize = 1.0 / texSize;\n\t\t\t\t\tvec4 uvOffset = vec4(1.0, 0.0, 0.0, 1.0) * vec4(invSize, invSize);\n\t\t\t\t\tvec4 c1 = texture2D( maskTexture, vUv + uvOffset.xy);\n\t\t\t\t\tvec4 c2 = texture2D( maskTexture, vUv - uvOffset.xy);\n\t\t\t\t\tvec4 c3 = texture2D( maskTexture, vUv + uvOffset.yw);\n\t\t\t\t\tvec4 c4 = texture2D( maskTexture, vUv - uvOffset.yw);\n\t\t\t\t\tfloat diff1 = (c1.r - c2.r)*0.5;\n\t\t\t\t\tfloat diff2 = (c3.r - c4.r)*0.5;\n\t\t\t\t\tfloat d = length( vec2(diff1, diff2) );\n\t\t\t\t\tfloat a1 = min(c1.g, c2.g);\n\t\t\t\t\tfloat a2 = min(c3.g, c4.g);\n\t\t\t\t\tfloat visibilityFactor = min(a1, a2);\n\t\t\t\t\tvec3 edgeColor = 1.0 - visibilityFactor > 0.001 ? visibleEdgeColor : hiddenEdgeColor;\n\t\t\t\t\tgl_FragColor = vec4(edgeColor, 1.0) * vec4(d);\n\t\t\t\t}`\n\t\t} );\n\n\t}\n\n\tgetSeperableBlurMaterial( maxRadius ) {\n\n\t\treturn new ShaderMaterial( {\n\n\t\t\tdefines: {\n\t\t\t\t'MAX_RADIUS': maxRadius,\n\t\t\t},\n\n\t\t\tuniforms: {\n\t\t\t\t'colorTexture': { value: null },\n\t\t\t\t'texSize': { value: new Vector2( 0.5, 0.5 ) },\n\t\t\t\t'direction': { value: new Vector2( 0.5, 0.5 ) },\n\t\t\t\t'kernelRadius': { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader:\n\t\t\t\t`varying vec2 vUv;\n\n\t\t\t\tvoid main() {\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\t\t\t\t}`,\n\n\t\t\tfragmentShader:\n\t\t\t\t`#include \n\t\t\t\tvarying vec2 vUv;\n\t\t\t\tuniform sampler2D colorTexture;\n\t\t\t\tuniform vec2 texSize;\n\t\t\t\tuniform vec2 direction;\n\t\t\t\tuniform float kernelRadius;\n\n\t\t\t\tfloat gaussianPdf(in float x, in float sigma) {\n\t\t\t\t\treturn 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\t\t\t\t\tvec2 invSize = 1.0 / texSize;\n\t\t\t\t\tfloat weightSum = gaussianPdf(0.0, kernelRadius);\n\t\t\t\t\tvec4 diffuseSum = texture2D( colorTexture, vUv) * weightSum;\n\t\t\t\t\tvec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);\n\t\t\t\t\tvec2 uvOffset = delta;\n\t\t\t\t\tfor( int i = 1; i <= MAX_RADIUS; i ++ ) {\n\t\t\t\t\t\tfloat w = gaussianPdf(uvOffset.x, kernelRadius);\n\t\t\t\t\t\tvec4 sample1 = texture2D( colorTexture, vUv + uvOffset);\n\t\t\t\t\t\tvec4 sample2 = texture2D( colorTexture, vUv - uvOffset);\n\t\t\t\t\t\tdiffuseSum += ((sample1 + sample2) * w);\n\t\t\t\t\t\tweightSum += (2.0 * w);\n\t\t\t\t\t\tuvOffset += delta;\n\t\t\t\t\t}\n\t\t\t\t\tgl_FragColor = diffuseSum/weightSum;\n\t\t\t\t}`\n\t\t} );\n\n\t}\n\n\tgetOverlayMaterial() {\n\n\t\treturn new ShaderMaterial( {\n\n\t\t\tuniforms: {\n\t\t\t\t'maskTexture': { value: null },\n\t\t\t\t'edgeTexture1': { value: null },\n\t\t\t\t'edgeTexture2': { value: null },\n\t\t\t\t'patternTexture': { value: null },\n\t\t\t\t'edgeStrength': { value: 1.0 },\n\t\t\t\t'edgeGlow': { value: 1.0 },\n\t\t\t\t'usePatternTexture': { value: 0.0 }\n\t\t\t},\n\n\t\t\tvertexShader:\n\t\t\t\t`varying vec2 vUv;\n\n\t\t\t\tvoid main() {\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\t\t\t\t}`,\n\n\t\t\tfragmentShader:\n\t\t\t\t`varying vec2 vUv;\n\n\t\t\t\tuniform sampler2D maskTexture;\n\t\t\t\tuniform sampler2D edgeTexture1;\n\t\t\t\tuniform sampler2D edgeTexture2;\n\t\t\t\tuniform sampler2D patternTexture;\n\t\t\t\tuniform float edgeStrength;\n\t\t\t\tuniform float edgeGlow;\n\t\t\t\tuniform bool usePatternTexture;\n\n\t\t\t\tvoid main() {\n\t\t\t\t\tvec4 edgeValue1 = texture2D(edgeTexture1, vUv);\n\t\t\t\t\tvec4 edgeValue2 = texture2D(edgeTexture2, vUv);\n\t\t\t\t\tvec4 maskColor = texture2D(maskTexture, vUv);\n\t\t\t\t\tvec4 patternColor = texture2D(patternTexture, 6.0 * vUv);\n\t\t\t\t\tfloat visibilityFactor = 1.0 - maskColor.g > 0.0 ? 1.0 : 0.5;\n\t\t\t\t\tvec4 edgeValue = edgeValue1 + edgeValue2 * edgeGlow;\n\t\t\t\t\tvec4 finalColor = edgeStrength * maskColor.r * edgeValue;\n\t\t\t\t\tif(usePatternTexture)\n\t\t\t\t\t\tfinalColor += + visibilityFactor * (1.0 - maskColor.r) * (1.0 - patternColor.r);\n\t\t\t\t\tgl_FragColor = finalColor;\n\t\t\t\t}`,\n\t\t\tblending: AdditiveBlending,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\ttransparent: true\n\t\t} );\n\n\t}\n\n}\n\nOutlinePass.BlurDirectionX = new Vector2( 1.0, 0.0 );\nOutlinePass.BlurDirectionY = new Vector2( 0.0, 1.0 );\n\nexport { OutlinePass };\n","import {\n\tdefineQuery,\n\tdefineSystem,\n\tenterQuery,\n\texitQuery,\n\tremoveEntity,\n} from \"bitecs\";\nimport { World } from \"../factory/world\";\nimport {\n\tNameplateComponent,\n\tObjectComponent,\n\tObjectOutlineComponent,\n\tPlayerComponent,\n} from \"../components\";\n\nimport * as THREE from \"three\";\nimport { CopyShader } from \"three/examples/jsm/shaders/CopyShader.js\";\nimport { FXAAShader } from \"three/examples/jsm/shaders/FXAAShader.js\";\nimport { EffectComposer } from \"three/examples/jsm/postprocessing/EffectComposer.js\";\nimport { RenderPass } from \"three/examples/jsm/postprocessing/RenderPass.js\";\nimport { ShaderPass } from \"three/examples/jsm/postprocessing/ShaderPass.js\";\nimport { OutlinePass } from \"three/examples/jsm/postprocessing/OutlinePass.js\";\n\nimport { ImGui, ImGui_Impl } from \"imgui-js\";\n\nconst objectLeaveQuery = exitQuery(defineQuery([ObjectComponent]));\nconst playerLeaveQuery = exitQuery(defineQuery([PlayerComponent]));\nconst nameplateQuery = defineQuery([NameplateComponent]);\n\nconst enterOutlinePlayerQuery = enterQuery(\n\tdefineQuery([PlayerComponent, ObjectOutlineComponent]),\n);\nconst exitOutlinePlayerQuery = exitQuery(\n\tdefineQuery([PlayerComponent, ObjectOutlineComponent]),\n);\nconst enterOutlineObjectQuery = enterQuery(\n\tdefineQuery([ObjectComponent, ObjectOutlineComponent]),\n);\nconst exitOutlineObjectQuery = exitQuery(\n\tdefineQuery([ObjectComponent, ObjectOutlineComponent]),\n);\n\nexport function createRenderSystem(world: World) {\n\tconst canvas = world.renderer.domElement;\n\tconst composer = new EffectComposer(world.renderer);\n\n\tcanvas.style.imageRendering = \"optimizeSpeed\";\n\n\tconst renderPass = new RenderPass(world.scene, world.camera);\n\tcomposer.addPass(renderPass);\n\n\tconst outlinePass = new OutlinePass(\n\t\tnew THREE.Vector2(window.innerWidth, window.innerHeight),\n\t\tworld.scene,\n\t\tworld.camera,\n\t);\n\toutlinePass.visibleEdgeColor.set(0x57aed1);\n\toutlinePass.hiddenEdgeColor.set(0x57aed1);\n\toutlinePass.overlayMaterial.blending = THREE.CustomBlending;\n\tcomposer.addPass(outlinePass);\n\n\tworld.composer = composer;\n\n\tconst setGameSize = () => {\n\t\t{\n\t\t\t// https://threejs.org/manual/#en/responsive\n\t\t\t// https://stackoverflow.com/a/60506772\n\t\t\tconst dpr = window.devicePixelRatio || 1;\n\t\t\tconst aspect = canvas.clientWidth / canvas.clientHeight;\n\n\t\t\tif (world.camera instanceof THREE.PerspectiveCamera) {\n\t\t\t\tworld.camera.aspect = aspect;\n\t\t\t\tworld.camera.updateProjectionMatrix();\n\t\t\t} else if (world.camera instanceof THREE.OrthographicCamera) {\n\t\t\t\t//@ts-ignore\n\t\t\t\tconst fov = world.camera.fov ?? 1000;\n\t\t\t\tworld.camera.left = (-fov * aspect) / 2;\n\t\t\t\tworld.camera.right = (fov * aspect) / 2;\n\t\t\t\tworld.camera.top = fov / 2;\n\t\t\t\tworld.camera.bottom = -fov / 2;\n\t\t\t\tworld.camera.updateProjectionMatrix();\n\t\t\t}\n\n\t\t\tconst width = Math.floor(window.innerWidth * dpr);\n\t\t\tconst height = Math.floor(canvas.parentElement!.clientHeight * dpr);\n\n\t\t\tworld.renderer.setSize(width, height, false);\n\t\t\tworld.composer?.setSize(width, height);\n\n\t\t\t// https://stackoverflow.com/a/21809242\n\t\t\tworld.renderer.setViewport(\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tcanvas.parentElement!.clientWidth,\n\t\t\t\tcanvas.parentElement!.clientHeight,\n\t\t\t);\n\t\t}\n\t};\n\n\twindow.addEventListener(\"resize\", setGameSize);\n\tsetTimeout(function () {\n\t\tsetGameSize();\n\t}, 1);\n\tvar observer = new window.ResizeObserver(() => {\n\t\twindow.dispatchEvent(new Event(\"resize\"));\n\t});\n\tobserver.observe(canvas.parentElement!);\n\n\treturn defineSystem((world: World) => {\n\t\t// handle player nameplates\n\t\tconst nameplates = nameplateQuery(world);\n\t\tfor (let x = 0; x < nameplates.length; x++) {\n\t\t\tconst ent = world.players.get(\n\t\t\t\tNameplateComponent.owner[nameplates[x]],\n\t\t\t);\n\t\t\tconst player = ent?.player;\n\t\t\tconst nameplate = ent?.nameplate;\n\n\t\t\tif (player !== undefined && nameplate !== undefined) {\n\t\t\t\tnameplate.position.setFromMatrixPosition(player.matrixWorld);\n\t\t\t\tnameplate.position.project(world.camera);\n\n\t\t\t\tconst canvas = world.renderer.domElement;\n\t\t\t\tconst rect = canvas.getBoundingClientRect();\n\t\t\t\tconst widthHalf = rect.width / 2;\n\t\t\t\tconst heightHalf = rect.height / 2;\n\n\t\t\t\tnameplate.position.x =\n\t\t\t\t\tnameplate.position.x * widthHalf + widthHalf + rect.left;\n\t\t\t\tnameplate.position.y =\n\t\t\t\t\t-nameplate.position.y * heightHalf + heightHalf;\n\n\t\t\t\tconst xOffset = nameplate.getBoundingClientRect().width / 2;\n\t\t\t\tnameplate.style.top = `${nameplate.position.y}px`;\n\t\t\t\tnameplate.style.left = `${nameplate.position.x - xOffset}px`;\n\t\t\t}\n\t\t}\n\n\t\t// handle cleanup of player entities\n\t\tconst playerLeave = playerLeaveQuery(world);\n\t\tfor (let x = 0; x < playerLeave.length; x++) {\n\t\t\tconst player = {\n\t\t\t\teid: playerLeave[x],\n\t\t\t\tentity: world.players.get(playerLeave[x])?.player,\n\t\t\t};\n\t\t\tif (player.entity !== undefined) {\n\t\t\t\t// remove player entity\n\t\t\t\tworld.scene.remove(player.entity);\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"Unable to cleanup player entity\", player.eid);\n\t\t\t}\n\n\t\t\tconst nameplate = world.players.get(playerLeave[x])?.nameplate;\n\t\t\tif (nameplate !== undefined) {\n\t\t\t\tremoveEntity(world, nameplate.eid);\n\t\t\t\tnameplate.remove();\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"Unable to cleanup player nameplate\", player.eid);\n\t\t\t}\n\t\t}\n\n\t\t// handle cleanup of object entities\n\t\tconst objectLeave = objectLeaveQuery(world);\n\t\tfor (let x = 0; x < objectLeave.length; x++) {\n\t\t\tconst object = {\n\t\t\t\teid: objectLeave[x],\n\t\t\t\tentity: world.objects.get(objectLeave[x]),\n\t\t\t};\n\t\t\tif (object.entity !== undefined) {\n\t\t\t\t// remove object entity\n\t\t\t\tworld.scene.remove(object.entity);\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"Unable to cleanup object entity\", object.eid);\n\t\t\t}\n\t\t}\n\n\t\tif (!world.composer) {\n\t\t\tworld.renderer.render(world.scene, world.camera);\n\t\t\treturn world;\n\t\t}\n\n\t\t// handle postprocessing\n\t\t{\n\t\t\tconst enterOutlines = enterOutlinePlayerQuery(world);\n\t\t\tfor (let i = 0; i < enterOutlines.length; i++) {\n\t\t\t\t// handle adding player outlines\n\t\t\t\tconst player = world.players.get(enterOutlines[i])!.player;\n\t\t\t\tconst outline = outlinePass.selectedObjects.indexOf(player);\n\t\t\t\tif (outline === -1) outlinePass.selectedObjects.push(player);\n\t\t\t}\n\t\t\tconst exitOutlines = exitOutlinePlayerQuery(world);\n\t\t\tfor (let i = 0; i < exitOutlines.length; i++) {\n\t\t\t\t// handle removing player outlines\n\t\t\t\tconst player = world.players.get(exitOutlines[i])!.player;\n\t\t\t\tconst outline = outlinePass.selectedObjects.indexOf(player);\n\t\t\t\tif (outline !== -1)\n\t\t\t\t\toutlinePass.selectedObjects.splice(outline, 1);\n\t\t\t}\n\t\t}\n\t\t{\n\t\t\tconst enterOutlines = enterOutlineObjectQuery(world);\n\t\t\tfor (let i = 0; i < enterOutlines.length; i++) {\n\t\t\t\t// handle adding object outlines\n\t\t\t\tconst object = world.objects.get(enterOutlines[i])!;\n\t\t\t\tconst outline = outlinePass.selectedObjects.indexOf(object);\n\t\t\t\tif (outline === -1) outlinePass.selectedObjects.push(object);\n\t\t\t}\n\t\t\tconst exitOutlines = exitOutlineObjectQuery(world);\n\t\t\tfor (let i = 0; i < exitOutlines.length; i++) {\n\t\t\t\t// handle adding object outlines\n\t\t\t\tconst object = world.objects.get(exitOutlines[i])!;\n\t\t\t\tconst outline = outlinePass.selectedObjects.indexOf(object);\n\t\t\t\tif (outline !== -1)\n\t\t\t\t\toutlinePass.selectedObjects.splice(outline, 1);\n\t\t\t}\n\t\t}\n\n\t\tif (ImGui.bind === undefined) {\n\t\t\treturn world;\n\t\t}\n\n\t\tImGui.End();\n\t\tImGui.EndFrame();\n\t\tImGui.Render();\n\n\t\tworld.composer.render();\n\n\t\tImGui_Impl.RenderDrawData(ImGui.GetDrawData());\n\t\treturn world;\n\t});\n}\n","\"use strict\";\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nexports.VERSION = void 0;\r\n// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\r\nexports.VERSION = \"0.0.6\";\r\n//# sourceMappingURL=version.js.map","\"use strict\";\r\n/**\r\n * @package npmjs.com/package/@yandeu/events (events.min.js)\r\n *\r\n * @author Arnout Kazemier (https://github.com/3rd-Eden)\r\n * @copyright Copyright (c) 2014 Arnout Kazemier\r\n * @license {@link https://github.com/primus/eventemitter3/blob/master/LICENSE|MIT}\r\n *\r\n * @author Yannick Deubel (https://github.com/yandeu)\r\n * @copyright Copyright (c) 2021 Yannick Deubel; Project Url: https://github.com/yandeu/events\r\n * @license {@link https://github.com/yandeu/events/blob/master/LICENSE|MIT}\r\n */\r\nvar __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nexports.Events = void 0;\r\nvar version_1 = require(\"./version\");\r\nvar EE = /** @class */ (function () {\r\n function EE(fn, context, once) {\r\n if (once === void 0) { once = false; }\r\n this.fn = fn;\r\n this.context = context;\r\n this.once = once;\r\n }\r\n return EE;\r\n}());\r\nvar addListener = function (emitter, event, fn, context, once) {\r\n if (typeof fn !== 'function') {\r\n throw new TypeError('The listener must be a function');\r\n }\r\n var listener = new EE(fn, context || emitter, once);\r\n if (!emitter._events.has(event))\r\n emitter._events.set(event, listener), emitter._eventsCount++;\r\n else if (!emitter._events.get(event).fn)\r\n emitter._events.get(event).push(listener);\r\n else\r\n emitter._events.set(event, [emitter._events.get(event), listener]);\r\n return emitter;\r\n};\r\nvar clearEvent = function (emitter, event) {\r\n if (--emitter._eventsCount === 0)\r\n emitter._events = new Map();\r\n else\r\n emitter._events.delete(event);\r\n};\r\nvar Events = /** @class */ (function () {\r\n function Events() {\r\n this._events = new Map();\r\n this._eventsCount = 0;\r\n }\r\n Object.defineProperty(Events, \"VERSION\", {\r\n get: function () {\r\n return version_1.VERSION;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n Events.prototype.eventNames = function () {\r\n return Array.from(this._events.keys());\r\n };\r\n Events.prototype.listeners = function (event) {\r\n var handlers = this._events.get(event);\r\n if (!handlers)\r\n return [];\r\n if (handlers.fn)\r\n return [handlers.fn];\r\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\r\n ee[i] = handlers[i].fn;\r\n }\r\n return ee;\r\n };\r\n Events.prototype.listenerCount = function (event) {\r\n var listeners = this._events.get(event);\r\n if (!listeners)\r\n return 0;\r\n if (listeners.fn)\r\n return 1;\r\n return listeners.length;\r\n };\r\n Events.prototype.emit = function (event) {\r\n var _a, _b;\r\n var args = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n args[_i - 1] = arguments[_i];\r\n }\r\n if (!this._events.has(event))\r\n return false;\r\n var listeners = this._events.get(event);\r\n var i;\r\n if (listeners.fn) {\r\n if (listeners.once)\r\n this.removeListener(event, listeners.fn, undefined, true);\r\n return (_a = listeners.fn).call.apply(_a, __spreadArray([listeners.context], args, false)), true;\r\n }\r\n else {\r\n var length_1 = listeners.length;\r\n for (i = 0; i < length_1; i++) {\r\n if (listeners[i].once)\r\n this.removeListener(event, listeners[i].fn, undefined, true);\r\n (_b = listeners[i].fn).call.apply(_b, __spreadArray([listeners[i].context], args, false));\r\n }\r\n }\r\n return true;\r\n };\r\n Events.prototype.on = function (event, fn, context) {\r\n return addListener(this, event, fn, context, false);\r\n };\r\n Events.prototype.once = function (event, fn, context) {\r\n return addListener(this, event, fn, context, true);\r\n };\r\n Events.prototype.removeListener = function (event, fn, context, once) {\r\n if (!this._events.has(event))\r\n return this;\r\n if (!fn) {\r\n clearEvent(this, event);\r\n return this;\r\n }\r\n var listeners = this._events.get(event);\r\n if (listeners.fn) {\r\n if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {\r\n clearEvent(this, event);\r\n }\r\n }\r\n else {\r\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\r\n if (listeners[i].fn !== fn || (once && !listeners[i].once) || (context && listeners[i].context !== context)) {\r\n events.push(listeners[i]);\r\n }\r\n }\r\n // Reset the array, or remove it completely if we have no more listeners.\r\n if (events.length)\r\n this._events.set(event, events.length === 1 ? events[0] : events);\r\n else\r\n clearEvent(this, event);\r\n }\r\n return this;\r\n };\r\n Events.prototype.removeAllListeners = function (event) {\r\n if (event) {\r\n if (this._events.delete(event))\r\n clearEvent(this, event);\r\n }\r\n else {\r\n this._events = new Map();\r\n this._eventsCount = 0;\r\n }\r\n return this;\r\n };\r\n Object.defineProperty(Events.prototype, \"off\", {\r\n // alias\r\n get: function () {\r\n return this.removeListener;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n Object.defineProperty(Events.prototype, \"addListener\", {\r\n // alias\r\n get: function () {\r\n return this.on;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n return Events;\r\n}());\r\nexports.Events = Events;\r\n/** TESTING SECTION */\r\n// type Colors = 'red' | 'blue' | 'yellow'\r\n// interface EventMap {\r\n// signal: () => void\r\n// error: (err: string) => void\r\n// something: (a: number, b: { colors?: Colors[] }, c: [number, number, string]) => void\r\n// }\r\n// const test = new Events()\r\n// const listener: EventListener = (a, b, c) => {\r\n// console.log(a, b.colors, c)\r\n// }\r\n// test.on('something', listener)\r\n// setTimeout(() => {\r\n// test.removeListener('something', listener)\r\n// }, 5000)\r\n// test.once('error', err => {\r\n// console.log('error:', err)\r\n// })\r\n// console.log(test.eventNames())\r\n// test.emit('error', 'ok')\r\n// test.emit('error', 'failed')\r\n// test.emit('something', 1234, { colors: ['blue'] }, [3, 3, 'k'])\r\n//# sourceMappingURL=index.js.map","import { Events } from '@yandeu/events';\nexport class Bridge {\n constructor() {\n this.eventEmitter = new Events();\n }\n emit(eventName, data, connection = {}) {\n this.eventEmitter.emit(eventName, data, connection);\n }\n on(eventName, cb) {\n return this.eventEmitter.on(eventName, (data, options) => {\n cb(data, options);\n });\n }\n removeAllListeners() {\n this.eventEmitter.removeAllListeners();\n }\n}\nconst bridge = new Bridge();\nexport { bridge };\n//# sourceMappingURL=bridge.js.map","const EVENTS = {\n CONNECT: 'connect',\n CONNECTION: 'connection',\n DATA_CHANNEL_IS_OPEN: 'dataChannelIsOpen',\n DISCONNECT: 'disconnect',\n DISCONNECTED: 'disconnected',\n DROP: 'dropped',\n ERROR: 'error',\n RAW_MESSAGE: 'rawMessage',\n RECEIVED_FROM_DATA_CHANNEL: 'receiveFromDataChannel',\n SEND_OVER_DATA_CHANNEL: 'sendOverDataChannel'\n};\nconst ERRORS = {\n BROWSER_NOT_SUPPORTED: 'BROWSER_NOT_SUPPORTED',\n COULD_NOT_PARSE_MESSAGE: 'COULD_NOT_PARSE_MESSAGE',\n DROPPED_FROM_BUFFERING: 'DROPPED_FROM_BUFFERING',\n MAX_MESSAGE_SIZE_EXCEEDED: 'MAX_MESSAGE_SIZE_EXCEEDED'\n};\nexport { EVENTS, ERRORS };\n//# sourceMappingURL=constants.js.map","const ArrayBufferView = Object.getPrototypeOf(Object.getPrototypeOf(new Uint8Array())).constructor;\nexport { ArrayBufferView };\n//# sourceMappingURL=types.js.map","import { ArrayBufferView } from './types.js';\n// const isRawMessage = (data: Data | RawMessage) => {\n// return typeof data === 'string' || isBufferMessage(data)\n// }\n// https://dev.to/nikosanif/create-promises-with-timeout-error-in-typescript-fmm\n/** create a promise with a timeout */\nexport const promiseWithTimeout = (promise, ms, timeoutError = new Error('Promise timed out')) => {\n // create a promise that rejects in milliseconds\n const timeout = new Promise((_, reject) => {\n setTimeout(() => {\n reject(timeout);\n }, ms);\n });\n // returns a race between timeout and the passed promise\n return Promise.race([promise, timeout]);\n};\n/** make a small promise-based pause */\nexport const pause = (ms = 0) => {\n return new Promise(resolve => {\n setTimeout(() => {\n resolve();\n }, ms);\n });\n};\n/** creates a new Task using setTimeout() */\nexport const task = (task) => setTimeout(task, 0);\n/** creates a new Microtask using Promise() */\nexport const tick = typeof Promise == 'function' ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout;\nconst isStringMessage = (data) => {\n return typeof data === 'string';\n};\nconst isBufferMessage = (data) => {\n return data instanceof ArrayBuffer || data instanceof ArrayBufferView;\n};\nconst isJSONMessage = (data) => {\n try {\n // check if it is a string\n if (typeof data !== 'string')\n return false;\n // check if it is a number as a string\n if (!isNaN(parseInt(data)))\n return false;\n // check if it is a JSON object\n JSON.parse(data);\n return true;\n }\n catch (error) {\n return false;\n }\n};\nexport { isStringMessage, isBufferMessage, isJSONMessage };\n//# sourceMappingURL=helpers.js.map","import { ERRORS, EVENTS } from './constants.js';\nimport { isBufferMessage, isJSONMessage, isStringMessage } from './helpers.js';\nconst ParseMessage = (ev) => {\n let { data } = ev;\n if (!data)\n data = ev;\n const isBuffer = isBufferMessage(data);\n const isJson = isJSONMessage(data);\n const isString = isStringMessage(data);\n // if (!data && isRaw) return { key: EVENTS.RAW_MESSAGE, data }\n // // probably server-side\n // if (!data) {\n // if (isRawMessage(data)) {\n // return { key: EVENTS.RAW_MESSAGE, data: data }\n // } else {\n // const json = JSON.parse(data as any)\n // const key = Object.keys(json)[0]\n // const value = Object.values(json)[0]\n // return { key: key, data: value }\n // }\n // }\n if (isJson) {\n const object = JSON.parse(data);\n const key = Object.keys(object)[0];\n const value = object[key];\n return { key: key, data: value };\n }\n if (isBuffer) {\n return { key: EVENTS.RAW_MESSAGE, data: data };\n }\n if (isString) {\n return { key: EVENTS.RAW_MESSAGE, data: data };\n }\n return { key: 'error', data: new Error(ERRORS.COULD_NOT_PARSE_MESSAGE) };\n};\nexport { ParseMessage };\n//# sourceMappingURL=parseMessage.js.map","import { isBufferMessage, isStringMessage } from './helpers.js';\nimport { EVENTS } from './constants.js';\nconst SendMessage = (dataChannel, maxMessageSize, eventName, data = null) => {\n var _a;\n const send = (data, isBuffer) => {\n var _a;\n const bytes = (_a = data.byteLength) !== null && _a !== void 0 ? _a : data.length * 2; // (times 2 for characters that uses 2 bytes per char)\n if (typeof maxMessageSize === 'number' && bytes > maxMessageSize) {\n throw new Error(`maxMessageSize of ${maxMessageSize} exceeded`);\n }\n else {\n Promise.resolve()\n .then(() => {\n // server-side (send() does not exist on the server side)\n if (dataChannel.send)\n dataChannel.send(data);\n else {\n if (!isBuffer)\n dataChannel.sendMessage(data);\n else\n dataChannel.sendMessageBinary(Buffer.from(data));\n }\n })\n .catch(error => {\n console.log('error', error);\n });\n }\n };\n if (!dataChannel)\n return;\n if (dataChannel.readyState === 'open' || ((_a = dataChannel.isOpen) === null || _a === void 0 ? void 0 : _a.call(dataChannel))) {\n try {\n if (eventName === EVENTS.RAW_MESSAGE && data !== null && (isStringMessage(data) || isBufferMessage(data))) {\n send(data, isBufferMessage(data));\n }\n else {\n send(JSON.stringify({ [eventName]: data }), false);\n }\n }\n catch (error) {\n console.error('Error in sendMessage.ts: ', error.message);\n return error;\n }\n }\n};\nexport { SendMessage };\n//# sourceMappingURL=sendMessage.js.map","import { Bridge } from '@geckos.io/common/lib/bridge.js';\nimport { ParseMessage } from '@geckos.io/common/lib/parseMessage.js';\nimport { SendMessage } from '@geckos.io/common/lib/sendMessage.js';\nexport default class ConnectionsManagerClient {\n emit(eventName, data = null) {\n SendMessage(this.dataChannel, this.maxMessageSize, eventName, data);\n }\n constructor(url, authorization, label, rtcConfiguration // eslint-disable-line no-undef\n ) {\n this.url = url;\n this.authorization = authorization;\n this.label = label;\n this.rtcConfiguration = rtcConfiguration;\n this.bridge = new Bridge();\n this.onDataChannel = (ev) => {\n const { channel } = ev;\n if (channel.label !== this.label)\n return;\n this.dataChannel = channel;\n // set default binaryType to arraybuffer\n // https://github.com/node-webrtc/node-webrtc/issues/441\n this.dataChannel.binaryType = 'arraybuffer';\n this.dataChannel.onmessage = (ev) => {\n const { key, data } = ParseMessage(ev);\n this.bridge.emit(key, data);\n };\n };\n }\n // fetch additional candidates\n async fetchAdditionalCandidates(host, id) {\n var _a;\n if (((_a = this.dataChannel) === null || _a === void 0 ? void 0 : _a.readyState) === 'closed')\n return;\n const res = await fetch(`${host}/connections/${id}/additional-candidates`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n if (res.ok) {\n const candidates = await res.json();\n // eslint-disable-next-line no-undef\n candidates.forEach((c) => {\n // eslint-disable-line no-undef\n this.localPeerConnection.addIceCandidate(c);\n });\n }\n }\n async connect() {\n const host = `${this.url}/.wrtc/v2`;\n let headers = { 'Content-Type': 'application/json' };\n if (this.authorization)\n headers = { ...headers, ['Authorization']: this.authorization };\n let userData = {};\n try {\n const res = await fetch(`${host}/connections`, {\n method: 'POST',\n headers\n });\n if (res.status >= 300) {\n throw {\n name: 'Error',\n message: `Connection failed with status code ${res.status}.`,\n status: res.status,\n statusText: res.statusText\n };\n }\n const json = await res.json();\n userData = json.userData;\n this.remotePeerConnection = json;\n }\n catch (error) {\n console.error(error.message);\n return { error };\n }\n const { id, localDescription } = this.remotePeerConnection;\n /**\n * testing\n */\n // console.log(localDescription.sdp?.split('\\n'))\n // remove all host type candidates (for testing)\n // let removedHostCandidates: any[] = []\n // localDescription.sdp = localDescription.sdp\n // ?.split('\\n')\n // .filter(line => {\n // if (/typ host/.test(line)) {\n // console.log('removing', line)\n // removedHostCandidates.push(line.replace('a=', '').trim())\n // }\n // return !/typ host/.test(line)\n // })\n // .join('\\n')\n // console.log(localDescription.sdp)\n // add all (host) candidates manually\n // setTimeout(() => {\n // removedHostCandidates.forEach(candidate => {\n // console.log('try to add candidate: ', candidate)\n // this.localPeerConnection.addIceCandidate({ candidate, sdpMid: '0', sdpMLineIndex: 0 })\n // })\n // }, 2000)\n // eslint-disable-next-line no-undef\n const configuration = {\n // @ts-ignore\n sdpSemantics: 'unified-plan',\n ...this.rtcConfiguration\n };\n // @ts-ignore\n const RTCPc = RTCPeerConnection || webkitRTCPeerConnection; // eslint-disable-line no-undef\n // create rtc peer connection\n this.localPeerConnection = new RTCPc(configuration);\n // get additional ice candidates\n // we do still continue to gather candidates even if the connection is established,\n // maybe we get a better connection.\n // So the server is still gathering candidates and we ask for them frequently.\n const showBackOffIntervals = (attempts = 10, initial = 50, factor = 1.8, jitter = 20) => Array(attempts)\n .fill(0)\n .map((_, index) => parseInt((initial * factor ** index).toString()) + parseInt((Math.random() * jitter).toString()));\n showBackOffIntervals().forEach(ms => {\n setTimeout(() => {\n this.fetchAdditionalCandidates(host, id).catch(() => { });\n }, ms);\n });\n try {\n await this.localPeerConnection.setRemoteDescription(localDescription);\n this.localPeerConnection.addEventListener('datachannel', this.onDataChannel, { once: true });\n const originalAnswer = await this.localPeerConnection.createAnswer();\n const updatedAnswer = new RTCSessionDescription({\n type: 'answer',\n sdp: originalAnswer.sdp\n });\n await this.localPeerConnection.setLocalDescription(updatedAnswer);\n try {\n await fetch(`${host}/connections/${id}/remote-description`, {\n method: 'POST',\n body: JSON.stringify(this.localPeerConnection.localDescription),\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n }\n catch (error) {\n console.error(error.message);\n return { error };\n }\n const waitForDataChannel = () => {\n return new Promise(resolve => {\n this.localPeerConnection.addEventListener('datachannel', () => {\n resolve();\n }, { once: true });\n });\n };\n if (!this.dataChannel)\n await waitForDataChannel();\n return {\n userData,\n localPeerConnection: this.localPeerConnection,\n dataChannel: this.dataChannel,\n id: id\n };\n }\n catch (error) {\n console.error(error.message);\n this.localPeerConnection.close();\n return { error };\n }\n }\n}\n//# sourceMappingURL=connectionsManager.js.map","import { ERRORS } from '@geckos.io/common/lib/constants.js';\nexport default class PeerConnection {\n async connect(connectionsManager) {\n // @ts-ignore\n const webRTCPcSupported = RTCPeerConnection || webkitRTCPeerConnection; // eslint-disable-line no-undef\n if (webRTCPcSupported) {\n const { localPeerConnection, dataChannel, id, userData, error } = await connectionsManager.connect();\n if (error)\n return { error };\n if (!localPeerConnection || !dataChannel || !id || !userData)\n return { error: new Error('Something went wrong in \"await connectionsManager.connect()\"') };\n this.localPeerConnection = localPeerConnection;\n this.dataChannel = dataChannel;\n this.id = id;\n return { userData };\n }\n else {\n const error = new Error(ERRORS.BROWSER_NOT_SUPPORTED);\n console.error(error.message);\n return { error };\n }\n }\n}\n//# sourceMappingURL=peerConnection.js.map","const makeRandomId = (length = 24) => {\n const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < length; i++) {\n id += possible.charAt(Math.floor(Math.random() * possible.length));\n }\n return id;\n};\nexport { makeRandomId };\n//# sourceMappingURL=makeRandomId.js.map","const runInterval = (interval = 200, runs = 1, cb) => {\n let counter = 0;\n if (typeof cb !== 'function') {\n console.error('You have to define your callback function!');\n return;\n }\n const i = setInterval(() => {\n cb();\n counter++;\n if (counter === runs - 1) {\n clearInterval(i);\n }\n }, interval);\n cb();\n};\nexport { runInterval };\n//# sourceMappingURL=runInterval.js.map","import { makeRandomId } from './makeRandomId.js';\nimport { runInterval } from './runInterval.js';\nconst makeReliable = (options, cb) => {\n const { interval = 150, runs = 10 } = options;\n const id = makeRandomId(24);\n runInterval(interval, runs, () => {\n cb(id);\n });\n};\nexport { makeReliable };\n//# sourceMappingURL=reliableMessage.js.map","import ConnectionsManagerClient from '../wrtc/connectionsManager.js';\nimport { EVENTS } from '@geckos.io/common/lib/constants.js';\nimport PeerConnection from '../wrtc/peerConnection.js';\nimport { makeReliable } from '@geckos.io/common/lib/reliableMessage.js';\nexport class ClientChannel {\n constructor(url, authorization, port, label, rtcConfiguration // eslint-disable-line no-undef\n ) {\n this.userData = {};\n // stores all reliable messages for about 15 seconds\n this.receivedReliableMessages = [];\n this.url = port ? `${url}:${port}` : url;\n this.connectionsManager = new ConnectionsManagerClient(this.url, authorization, label, rtcConfiguration);\n this.bridge = this.connectionsManager.bridge;\n // remove all event listeners on disconnect\n this.bridge.on(EVENTS.DISCONNECTED, () => this.bridge.removeAllListeners());\n }\n onconnectionstatechange() {\n const lpc = this.peerConnection.localPeerConnection;\n lpc.onconnectionstatechange = () => {\n if (lpc.connectionState === 'disconnected' || lpc.connectionState === 'closed')\n this.bridge.emit(EVENTS.DISCONNECTED);\n };\n }\n /** Get the channel's id. */\n get id() {\n return this.peerConnection.id;\n }\n /** Close the WebRTC connection */\n close() {\n this.peerConnection.localPeerConnection.close();\n // fire the DISCONNECTED event manually\n this.bridge.emit(EVENTS.DISCONNECTED);\n try {\n const host = `${this.url}/.wrtc/v2`;\n fetch(`${host}/connections/${this.id}/close`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n }\n catch (error) {\n console.error(error.message);\n }\n }\n /** Emit a message to the server. */\n emit(eventName, data = null, options) {\n if (options && options.reliable) {\n makeReliable(options, (id) => this.connectionsManager.emit(eventName, {\n MESSAGE: data,\n RELIABLE: 1,\n ID: id\n }));\n }\n else {\n this.connectionsManager.emit(eventName, data);\n }\n }\n /** Emit a raw message to the server */\n get raw() {\n return {\n /**\n * Emit a raw message.\n * @param rawMessage The raw message. Can be of type 'USVString | ArrayBuffer | ArrayBufferView'\n */\n emit: (rawMessage) => this.emit(EVENTS.RAW_MESSAGE, rawMessage)\n };\n }\n /**\n * Listen for a raw message from the server.\n * @param callback The event callback.\n */\n onRaw(callback) {\n this.bridge.on(EVENTS.RAW_MESSAGE, (rawMessage) => {\n const cb = (rawMessage) => callback(rawMessage);\n cb(rawMessage);\n });\n }\n /**\n * Listen for the connect event.\n * @param callback The event callback.\n */\n async onConnect(callback) {\n var _a;\n this.peerConnection = new PeerConnection();\n const response = await this.peerConnection.connect(this.connectionsManager);\n if (response.error)\n callback(response.error);\n else {\n // set the userData\n if (response.userData)\n this.userData = response.userData;\n // keep track of the maxMessageSize\n this.maxMessageSize = this.connectionsManager.maxMessageSize = (_a = this.peerConnection.localPeerConnection\n .sctp) === null || _a === void 0 ? void 0 : _a.maxMessageSize;\n // init onConnectionStateChange event\n this.onconnectionstatechange();\n // we are now ready\n callback();\n }\n }\n /**\n * Listen for the disconnect event.\n * @param callback The event callback.\n */\n onDisconnect(callback) {\n this.bridge.on(EVENTS.DISCONNECTED, callback);\n }\n /**\n * Listen for a message from the server.\n * @param eventName The event name.\n * @param callback The event callback.\n */\n on(eventName, callback) {\n this.bridge.on(eventName, (data) => {\n // check if message is reliable\n // and reject it if it has already been submitted\n const isReliableMessage = data && data.RELIABLE === 1 && data.ID !== 'undefined';\n const expireTime = 15000; // 15 seconds\n const deleteExpiredReliableMessages = () => {\n const currentTime = new Date().getTime();\n this.receivedReliableMessages.forEach((msg, index, object) => {\n if (msg.expire <= currentTime) {\n object.splice(index, 1);\n }\n });\n };\n if (isReliableMessage) {\n deleteExpiredReliableMessages();\n if (this.receivedReliableMessages.filter(obj => obj.id === data.ID).length === 0) {\n this.receivedReliableMessages.push({\n id: data.ID,\n timestamp: new Date(),\n expire: new Date().getTime() + expireTime\n });\n callback(data.MESSAGE);\n }\n else {\n // reject message\n }\n }\n else {\n callback(data);\n }\n });\n }\n}\n/**\n * The geckos.io client library.\n * @param options.iceServers An array of RTCIceServers. See https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer.\n * @param options.iceTransportPolicy RTCIceTransportPolicy enum defines string constants which can be used to limit the transport policies of the ICE candidates to be considered during the connection process.\n * @param options.label The label of the DataChannel. Default: 'geckos.io'.\n * @param options.port The port of the server. Default: 9208.\n * @param options.url The url of the server. Default: \\`${location.protocol}//${location.hostname}\\`.\n */\nconst geckosClient = (options = {}) => {\n const { authorization = undefined, iceServers = [], iceTransportPolicy = 'all', label = 'geckos.io', port = 9208, url = `${location.protocol}//${location.hostname}` } = options;\n return new ClientChannel(url, authorization, port, label, { iceServers, iceTransportPolicy });\n};\nexport default geckosClient;\n//# sourceMappingURL=channel.js.map","import { defineQuery, defineSystem, hasComponent } from \"bitecs\";\nimport { World } from \"../factory/world\";\nimport {\n\tGltfComponent,\n\tLocalPlayerComponent,\n\tSpineComponent,\n} from \"../components\";\n\nimport * as THREE from \"three\";\nimport * as spine from \"@esotericsoftware/spine-threejs\";\nimport { ImGui } from \"imgui-js\";\nimport { NetworkEvent } from \"./network\";\n\nconst spineAvatarQuery = defineQuery([SpineComponent]);\nconst gltfAvatarQuery = defineQuery([GltfComponent]);\n\nexport function createAnimationSystem() {\n\treturn defineSystem((world: World) => {\n\t\tconst {\n\t\t\ttime: { delta },\n\t\t} = world;\n\n\t\t// handle spine avatar animations\n\t\tconst spineAvatars = spineAvatarQuery(world);\n\t\tfor (let x = 0; x < spineAvatars.length; x++) {\n\t\t\tconst eid = spineAvatars[x];\n\t\t\tconst player = world.players.get(eid)?.player;\n\n\t\t\tif (!player) continue;\n\n\t\t\t// always facing camera (billboard effect)\n\t\t\tplayer.quaternion.set(\n\t\t\t\tplayer.quaternion.x,\n\t\t\t\tworld.camera.quaternion.y,\n\t\t\t\tplayer.quaternion.z,\n\t\t\t\tworld.camera.quaternion.w,\n\t\t\t);\n\t\t\tfor (let y = 0; y < player.children.length; y++) {\n\t\t\t\tlet mesh = player.children[y];\n\t\t\t\tif (mesh instanceof spine.SkeletonMesh) {\n\t\t\t\t\tmesh.update(delta / SpineComponent.timeScale[eid]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// handle gltf avatar animations\n\t\tconst gltfAvatars = gltfAvatarQuery(world);\n\t\tfor (let x = 0; x < gltfAvatars.length; x++) {\n\t\t\tconst eid = gltfAvatars[x];\n\t\t\tconst player = world.players.get(eid)?.player;\n\n\t\t\tif (!player) continue;\n\n\t\t\tfor (let y = 0; y < player.children.length; y++) {\n\t\t\t\t//@ts-ignore: createPlayer() adds a mixer component to the model\n\t\t\t\tlet mixer = player.children[y].mixer;\n\t\t\t\tif (!(mixer instanceof THREE.AnimationMixer)) continue;\n\n\t\t\t\tmixer.update(delta / GltfComponent.timeScale[eid]);\n\n\t\t\t\tif (GltfComponent.animAction[eid] === -1) continue;\n\n\t\t\t\tlet animations = player.children[y].animations;\n\t\t\t\tlet clip = animations[GltfComponent.animAction[eid]];\n\n\t\t\t\tif (mixer.clipAction(clip).time !== clip.duration) continue;\n\n\t\t\t\t// return to playing previous animation state\n\t\t\t\tGltfComponent.animAction[eid] = -1;\n\t\t\t\tclip =\n\t\t\t\t\tanimations[GltfComponent.animState[eid]] ??\n\t\t\t\t\tanimations.find((animation) =>\n\t\t\t\t\t\t/idle_state$/i.test(animation.name),\n\t\t\t\t\t) ??\n\t\t\t\t\tanimations[0];\n\t\t\t\tmixer.stopAllAction();\n\t\t\t\tmixer.clipAction(clip).play();\n\t\t\t}\n\t\t}\n\n\t\treturn world;\n\t});\n}\n\nexport function getStateNames(\n\tanims: THREE.AnimationClip[] | undefined,\n): string[] {\n\tif (anims === undefined) return [];\n\n\tlet result: string[] = [];\n\n\tanims.forEach((anim) => {\n\t\t// if animation name has suffix \"_state\", it is a state\n\t\tif (/_state$/i.test(anim.name)) {\n\t\t\tresult.push(anim.name);\n\t\t}\n\t});\n\n\treturn result;\n}\n\nexport function getActionNames(\n\tanims: THREE.AnimationClip[] | undefined,\n): string[] {\n\tif (anims === undefined) return [];\n\n\tlet result: string[] = [];\n\n\tanims.forEach((anim) => {\n\t\t// if animation name has suffix \"_action\", it is an action\n\t\tif (/_action$/i.test(anim.name)) {\n\t\t\tresult.push(anim.name);\n\t\t}\n\t});\n\n\treturn result;\n}\n\nexport function playAnimation(\n\tworld: World,\n\teid: number,\n\tclip: string | number,\n\tanims: THREE.AnimationClip[],\n) {\n\tlet animName = \"\";\n\tlet animIndex = 0;\n\n\tif (typeof clip === \"string\") {\n\t\tanimName = clip;\n\t\tanimIndex = anims.findIndex((anim) => anim.name === animName);\n\t}\n\tif (typeof clip === \"number\") {\n\t\tanimIndex = clip;\n\t\tanimName = anims[animIndex].name;\n\t}\n\tif (animIndex === -1) return;\n\n\tconst player = world.players.get(eid)?.player;\n\tif (player === undefined) return;\n\n\t//@ts-ignore\n\tconst mixer: THREE.AnimationMixer = player.children[0].mixer;\n\n\tmixer.stopAllAction();\n\n\tif (/_action$/i.test(animName)) {\n\t\tGltfComponent.animAction[eid] = animIndex;\n\t\tconst clip =\n\t\t\tanims[GltfComponent.animAction[eid]] ??\n\t\t\tanims.find((animation) => /_action$/i.test(animation.name)) ??\n\t\t\tanims[0];\n\t\tconst animation = mixer.clipAction(clip);\n\n\t\tanimation.clampWhenFinished = true;\n\t\tanimation.loop = THREE.LoopOnce;\n\t\tanimation.play();\n\n\t\tif (hasComponent(world, LocalPlayerComponent, eid))\n\t\t\tworld.network.emit(NetworkEvent.PlayerAnim, { action: animIndex });\n\t} else {\n\t\tGltfComponent.animState[eid] = animIndex;\n\t\tconst clip =\n\t\t\tanims[GltfComponent.animState[eid]] ??\n\t\t\tanims.find((animation) => /idle_state$/i.test(animation.name)) ??\n\t\t\tanims[0];\n\t\tconst animation = mixer.clipAction(clip);\n\n\t\t// animation.clampWhenFinished = true;\n\t\t// animation.loop = THREE.LoopOnce;\n\t\tanimation.play();\n\n\t\tif (hasComponent(world, LocalPlayerComponent, eid))\n\t\t\tworld.network.emit(NetworkEvent.PlayerAnim, { state: animIndex });\n\t}\n\n\tconsole.log(\"Playing animation:\", eid, animName, anims[animIndex], anims);\n}\n","import { addComponent, addEntity } from \"bitecs\";\nimport {\n\tGltfComponent,\n\tLocalPlayerComponent,\n\tPlayerComponent,\n\tSpineComponent,\n\tTransformComponent,\n} from \"../components\";\nimport { World } from \"./world\";\n\nimport * as THREE from \"three\";\nimport * as spine from \"@esotericsoftware/spine-threejs\";\nimport { GLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\nimport { API_URL } from \"../constants\";\n\nexport type Player = THREE.Group & { eid: number };\nexport enum Avatar {\n\tGLTF,\n\tSpine,\n}\n\nexport const createPlayer = (\n\tworld: World,\n\tname: string = \"Unnamed\",\n\tlocal: boolean = false,\n\tavatar: Avatar = Avatar.GLTF,\n\tavatarFile: string = \"\",\n\tinitialScale: number = 1,\n): Player => {\n\tconst eid = addEntity(world);\n\tlet entity = Object.assign(new THREE.Group(), { eid });\n\tentity.name = `${name} (Player)`;\n\n\tif (local) {\n\t\taddComponent(world, LocalPlayerComponent, eid);\n\t}\n\taddComponent(world, PlayerComponent, eid);\n\taddComponent(world, TransformComponent, eid);\n\n\tTransformComponent.scale.x[eid] = 1;\n\tTransformComponent.scale.y[eid] = 1;\n\tTransformComponent.scale.z[eid] = 1;\n\n\tif (avatar === Avatar.Spine) {\n\t\tif (avatarFile === \"\") avatarFile = \"spineboy\";\n\n\t\tworld.spineAssetManager.loadText(`${avatarFile}.json`);\n\t\tworld.spineAssetManager.loadTextureAtlas(\n\t\t\t`${avatarFile}.atlas`,\n\t\t\t() => {\n\t\t\t\tif (entity !== undefined)\n\t\t\t\t\tentity.add(\n\t\t\t\t\t\tcreateSpineMesh(world.spineAssetManager, avatarFile),\n\t\t\t\t\t);\n\t\t\t\taddComponent(world, SpineComponent, eid);\n\t\t\t\tSpineComponent.timeScale[eid] = 1000;\n\t\t\t},\n\t\t\tfunction (e) {\n\t\t\t\tconsole.error(e);\n\t\t\t},\n\t\t);\n\t} else if (avatar === Avatar.GLTF) {\n\t\tif (avatarFile === \"\")\n\t\t\tavatarFile = \"/static/assets/avatars/RobotExpressive.glb\";\n\n\t\tconsole.log(`${API_URL}${avatarFile}`);\n\n\t\tconst loader = new GLTFLoader();\n\t\tloader.load(\n\t\t\t`${API_URL}${avatarFile}`,\n\t\t\tfunction (gltf) {\n\t\t\t\tlet model: THREE.Group | THREE.Object3D = gltf.scene;\n\t\t\t\tmodel.scale.set(\n\t\t\t\t\tinitialScale * model.scale.x,\n\t\t\t\t\tinitialScale * model.scale.y,\n\t\t\t\t\tinitialScale * model.scale.z,\n\t\t\t\t);\n\n\t\t\t\tentity.add(\n\t\t\t\t\tObject.assign(model, {\n\t\t\t\t\t\tmixer: new THREE.AnimationMixer(model),\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tmodel = entity.children[0];\n\t\t\t\t//@ts-ignore: this is probably a bad idea for the future...\n\t\t\t\tconst mixer: THREE.AnimationMixer = model.mixer;\n\t\t\t\tmodel.animations = gltf.animations;\n\t\t\t\tconst clip =\n\t\t\t\t\tmodel.animations.find((animation) =>\n\t\t\t\t\t\t/idle_state$/i.test(animation.name),\n\t\t\t\t\t) ?? model.animations[0];\n\t\t\t\tconst clipIndex = model.animations.indexOf(clip);\n\t\t\t\tconst action = mixer.clipAction(clip).play();\n\t\t\t\taction.time = Math.random() * clip.duration;\n\n\t\t\t\taddComponent(world, GltfComponent, eid);\n\t\t\t\tGltfComponent.timeScale[eid] = 1000;\n\t\t\t\tGltfComponent.animState[eid] = clipIndex;\n\t\t\t\tGltfComponent.animAction[eid] = -1;\n\n\t\t\t\tconsole.log(\"Created GLTF mesh\", model);\n\t\t\t},\n\t\t\tundefined,\n\t\t\tfunction (e) {\n\t\t\t\tconsole.error(e);\n\t\t\t},\n\t\t);\n\t}\n\n\t// position\n\tObject.defineProperty(entity.position, \"eid\", { get: () => eid });\n\tObject.defineProperty(entity.position, \"store\", {\n\t\tget: () => TransformComponent.position,\n\t});\n\n\tObject.defineProperty(entity.position, \"x\", {\n\t\tget() {\n\t\t\treturn this.store.x[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.x[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.position, \"y\", {\n\t\tget() {\n\t\t\treturn this.store.y[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.y[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.position, \"z\", {\n\t\tget() {\n\t\t\treturn this.store.z[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.z[this.eid] = n;\n\t\t},\n\t});\n\n\t// rotation\n\tObject.defineProperty(entity.rotation, \"eid\", { get: () => eid });\n\tObject.defineProperty(entity.rotation, \"store\", {\n\t\tget: () => TransformComponent.rotation,\n\t});\n\n\tObject.defineProperty(entity.rotation, \"_x\", {\n\t\tget() {\n\t\t\treturn this.store.x[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.x[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.rotation, \"_y\", {\n\t\tget() {\n\t\t\treturn this.store.y[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.y[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.rotation, \"_z\", {\n\t\tget() {\n\t\t\treturn this.store.z[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.z[this.eid] = n;\n\t\t},\n\t});\n\n\t// scale\n\tObject.defineProperty(entity.scale, \"eid\", { get: () => eid });\n\tObject.defineProperty(entity.scale, \"store\", {\n\t\tget: () => TransformComponent.scale,\n\t});\n\n\tObject.defineProperty(entity.scale, \"x\", {\n\t\tget() {\n\t\t\treturn this.store.x[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.x[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.scale, \"y\", {\n\t\tget() {\n\t\t\treturn this.store.y[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.y[this.eid] = n;\n\t\t},\n\t});\n\tObject.defineProperty(entity.scale, \"z\", {\n\t\tget() {\n\t\t\treturn this.store.z[this.eid];\n\t\t},\n\t\tset(n) {\n\t\t\tthis.store.z[this.eid] = n;\n\t\t},\n\t});\n\n\treturn entity;\n};\n\nconst createSpineMesh = (\n\tassetManager: spine.AssetManager,\n\tavatarFile: string,\n) => {\n\t// Load the texture atlas using name.atlas and name.png from the AssetManager.\n\t// The function passed to TextureAtlas is used to resolve relative paths.\n\tlet atlas = assetManager.require(`${avatarFile}.atlas`);\n\n\t// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments\n\tlet atlasLoader = new spine.AtlasAttachmentLoader(atlas);\n\n\t// Create a SkeletonJson instance for parsing the .json file.\n\tlet skeletonJson = new spine.SkeletonJson(atlasLoader);\n\n\t// Set the scale to apply during parsing, parse the file, and create a new skeleton.\n\tskeletonJson.scale = 0.3;\n\tlet skeletonData = skeletonJson.readSkeletonData(\n\t\tassetManager.require(`${avatarFile}.json`),\n\t);\n\n\t// Create a SkeletonMesh from the data and attach it to the scene\n\tlet skeletonMesh = new spine.SkeletonMesh(skeletonData, (parameters) => {\n\t\tparameters.depthTest = true;\n\t\tparameters.depthWrite = true;\n\t\tparameters.alphaTest = 0.001;\n\t});\n\tskeletonMesh.state.setAnimation(0, \"idle\", true);\n\tconsole.log(\"Created Spine skeleton mesh\", skeletonMesh);\n\t// console.log(skeletonMesh.state.data.skeletonData.animations);\n\treturn skeletonMesh;\n};\n","/* eslint-disable */\nconst keys = Object.keys\nfunction identity(value) {\n return value\n}\nfunction isBoolean(val) {\n return typeof val === \"boolean\"\n}\nfunction isElement(val) {\n return val && typeof val.nodeType === \"number\"\n}\nfunction isString(val) {\n return typeof val === \"string\"\n}\nfunction isNumber(val) {\n return typeof val === \"number\"\n}\nfunction isObject(val) {\n return typeof val === \"object\" ? val !== null : isFunction(val)\n}\nfunction isFunction(val) {\n return typeof val === \"function\"\n}\nfunction isComponentClass(Component) {\n const { prototype } = Component\n return !!(prototype && prototype.isReactComponent)\n}\nfunction isArrayLike(obj) {\n return isObject(obj) && typeof obj.length === \"number\" && typeof obj.nodeType !== \"number\"\n}\nfunction forEach(value, fn) {\n if (!value) return\n for (const key of keys(value)) {\n fn(value[key], key)\n }\n}\n\nfunction createRef() {\n return Object.seal({\n current: null,\n })\n}\nfunction isRef(maybeRef) {\n return isObject(maybeRef) && \"current\" in maybeRef\n}\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found on\n * https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/LICENSE\n */\n\n/**\n * CSS properties which accept numbers but are not in units of \"px\".\n */\nconst isUnitlessNumber = {\n animationIterationCount: 0,\n borderImageOutset: 0,\n borderImageSlice: 0,\n borderImageWidth: 0,\n boxFlex: 0,\n boxFlexGroup: 0,\n boxOrdinalGroup: 0,\n columnCount: 0,\n columns: 0,\n flex: 0,\n flexGrow: 0,\n flexPositive: 0,\n flexShrink: 0,\n flexNegative: 0,\n flexOrder: 0,\n gridArea: 0,\n gridRow: 0,\n gridRowEnd: 0,\n gridRowSpan: 0,\n gridRowStart: 0,\n gridColumn: 0,\n gridColumnEnd: 0,\n gridColumnSpan: 0,\n gridColumnStart: 0,\n fontWeight: 0,\n lineClamp: 0,\n lineHeight: 0,\n opacity: 0,\n order: 0,\n orphans: 0,\n tabSize: 0,\n widows: 0,\n zIndex: 0,\n zoom: 0,\n // SVG-related properties\n fillOpacity: 0,\n floodOpacity: 0,\n stopOpacity: 0,\n strokeDasharray: 0,\n strokeDashoffset: 0,\n strokeMiterlimit: 0,\n strokeOpacity: 0,\n strokeWidth: 0,\n}\n\n/**\n * @param prefix vendor-specific prefix, eg: Webkit\n * @param key style name, eg: transitionDuration\n * @return style name prefixed with `prefix`, properly camelCased, eg:\n * WebkitTransitionDuration\n */\nfunction prefixKey(prefix, key) {\n return prefix + key.charAt(0).toUpperCase() + key.substring(1)\n}\n\n/**\n * Support style names that may come passed in prefixed by adding permutations\n * of vendor prefixes.\n */\nconst prefixes = [\"Webkit\", \"ms\", \"Moz\", \"O\"]\n// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an\n// infinite loop, because it iterates over the newly added props too.\nkeys(isUnitlessNumber).forEach(prop => {\n prefixes.forEach(prefix => {\n isUnitlessNumber[prefixKey(prefix, prop)] = 0 // isUnitlessNumber[prop]\n })\n})\n\nconst jsxDomType = Symbol.for(\"jsx-dom:type\")\nvar JsxDomType = /*#__PURE__*/ (function (JsxDomType) {\n JsxDomType[\"ShadowRoot\"] = \"ShadowRoot\"\n return JsxDomType\n})(JsxDomType || {})\nfunction ShadowRoot(_ref) {\n let { children, ref, ...attr } = _ref\n return {\n [jsxDomType]: JsxDomType.ShadowRoot,\n ref,\n attr,\n children,\n }\n}\nfunction isShadowRoot(el) {\n return el != null && el[jsxDomType] === JsxDomType.ShadowRoot\n}\n\nconst SVGNamespace = \"http://www.w3.org/2000/svg\"\nconst XLinkNamespace = \"http://www.w3.org/1999/xlink\"\nconst XMLNamespace = \"http://www.w3.org/XML/1998/namespace\"\n\n// https://facebook.github.io/react/docs/jsx-in-depth.html#booleans-null-and-undefined-are-ignored\n// Emulate JSX Expression logic to ignore certain type of children or className.\nfunction isVisibleChild(value) {\n return !isBoolean(value) && value != null\n}\nconst DomTokenList = typeof DOMTokenList !== \"undefined\" ? DOMTokenList : function () {}\n\n/**\n * Convert a `value` to a className string.\n * `value` can be a string, an array or a `Dictionary`.\n */\nfunction className(value) {\n if (Array.isArray(value)) {\n return value.map(className).filter(Boolean).join(\" \")\n } else if (value instanceof DomTokenList) {\n return \"\" + value\n } else if (isObject(value)) {\n return keys(value)\n .filter(k => value[k])\n .join(\" \")\n } else if (isVisibleChild(value)) {\n return \"\" + value\n } else {\n return \"\"\n }\n}\nconst svg = {\n animate: 0,\n circle: 0,\n clipPath: 0,\n defs: 0,\n desc: 0,\n ellipse: 0,\n feBlend: 0,\n feColorMatrix: 0,\n feComponentTransfer: 0,\n feComposite: 0,\n feConvolveMatrix: 0,\n feDiffuseLighting: 0,\n feDisplacementMap: 0,\n feDistantLight: 0,\n feFlood: 0,\n feFuncA: 0,\n feFuncB: 0,\n feFuncG: 0,\n feFuncR: 0,\n feGaussianBlur: 0,\n feImage: 0,\n feMerge: 0,\n feMergeNode: 0,\n feMorphology: 0,\n feOffset: 0,\n fePointLight: 0,\n feSpecularLighting: 0,\n feSpotLight: 0,\n feTile: 0,\n feTurbulence: 0,\n filter: 0,\n foreignObject: 0,\n g: 0,\n image: 0,\n line: 0,\n linearGradient: 0,\n marker: 0,\n mask: 0,\n metadata: 0,\n path: 0,\n pattern: 0,\n polygon: 0,\n polyline: 0,\n radialGradient: 0,\n rect: 0,\n stop: 0,\n svg: 0,\n switch: 0,\n symbol: 0,\n text: 0,\n textPath: 0,\n tspan: 0,\n use: 0,\n view: 0,\n}\nconst nonPresentationSVGAttributes =\n /^(a(ll|t|u)|base[FP]|c(al|lipPathU|on)|di|ed|ex|filter[RU]|g(lyphR|r)|ke|l(en|im)|ma(rker[HUW]|s)|n|pat|pr|point[^e]|re[^n]|s[puy]|st[^or]|ta|textL|vi|xC|y|z)/\nfunction createFactory(tag) {\n return createElement.bind(null, tag)\n}\nfunction Fragment(attr) {\n const fragment = document.createDocumentFragment()\n appendChild(attr.children, fragment)\n return fragment\n}\nclass Component {\n constructor(props) {\n this.props = props\n }\n render() {\n return null\n }\n}\n\n/* @__PURE__ */\nObject.defineProperties(Component.prototype, {\n isReactComponent: {\n value: true,\n },\n})\nfunction initComponentClass(Class, attr, children) {\n attr = {\n ...attr,\n children,\n }\n const instance = new Class(attr)\n return instance.render()\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction jsx(tag, _ref) {\n let { children, ...attr } = _ref\n if (!attr.namespaceURI && svg[tag] === 0) {\n attr = {\n ...attr,\n namespaceURI: SVGNamespace,\n }\n }\n let node\n if (isString(tag)) {\n node = attr.namespaceURI\n ? document.createElementNS(attr.namespaceURI, tag)\n : document.createElement(tag)\n attributes(attr, node)\n appendChild(children, node)\n\n // Select `option` elements in `select`\n if (node instanceof window.HTMLSelectElement && attr.value != null) {\n if (attr.multiple === true && Array.isArray(attr.value)) {\n const values = attr.value.map(value => String(value))\n node\n .querySelectorAll(\"option\")\n .forEach(option => (option.selected = values.includes(option.value)))\n } else {\n node.value = attr.value\n }\n }\n attachRef(attr.ref, node)\n } else if (isFunction(tag)) {\n // Custom elements.\n if (isObject(tag.defaultProps)) {\n attr = {\n ...tag.defaultProps,\n ...attr,\n }\n }\n node = isComponentClass(tag)\n ? initComponentClass(tag, attr, children)\n : tag({\n ...attr,\n children,\n })\n } else {\n throw new TypeError(`Invalid JSX element type: ${tag}`)\n }\n return node\n}\nfunction createElement(tag, attr) {\n for (\n var _len = arguments.length, children = new Array(_len > 2 ? _len - 2 : 0), _key2 = 2;\n _key2 < _len;\n _key2++\n ) {\n children[_key2 - 2] = arguments[_key2]\n }\n if (isString(attr) || Array.isArray(attr)) {\n children.unshift(attr)\n attr = {}\n }\n attr = attr || {}\n if (attr.children != null && !children.length) {\n ;({ children, ...attr } = attr)\n }\n return jsx(\n tag,\n {\n ...attr,\n children,\n },\n attr.key\n )\n}\nfunction attachRef(ref, node) {\n if (isRef(ref)) {\n ref.current = node\n } else if (isFunction(ref)) {\n ref(node)\n }\n}\nfunction appendChild(child, node) {\n if (isArrayLike(child)) {\n appendChildren(child, node)\n } else if (isString(child) || isNumber(child)) {\n appendChildToNode(document.createTextNode(child), node)\n } else if (child === null) {\n appendChildToNode(document.createComment(\"\"), node)\n } else if (isElement(child)) {\n appendChildToNode(child, node)\n } else if (isShadowRoot(child)) {\n const shadowRoot = node.attachShadow(child.attr)\n appendChild(child.children, shadowRoot)\n attachRef(child.ref, shadowRoot)\n }\n}\nfunction appendChildren(children, node) {\n for (const child of [...children]) {\n appendChild(child, node)\n }\n return node\n}\nfunction appendChildToNode(child, node) {\n if (node instanceof window.HTMLTemplateElement) {\n node.content.appendChild(child)\n } else {\n node.appendChild(child)\n }\n}\nfunction normalizeAttribute(s, separator) {\n return s.replace(/[A-Z]/g, match => separator + match.toLowerCase())\n}\nfunction style(node, value) {\n if (value == null || value === false);\n else if (Array.isArray(value)) {\n value.forEach(v => style(node, v))\n } else if (isString(value)) {\n node.setAttribute(\"style\", value)\n } else if (isObject(value)) {\n forEach(value, (val, key) => {\n if (key.indexOf(\"-\") === 0) {\n // CSS custom properties (variables) start with `-` (e.g. `--my-variable`)\n // and must be assigned via `setProperty`.\n node.style.setProperty(key, val)\n } else if (isNumber(val) && isUnitlessNumber[key] !== 0) {\n node.style[key] = val + \"px\"\n } else {\n node.style[key] = val\n }\n })\n }\n}\nfunction attribute(key, value, node) {\n switch (key) {\n case \"xlinkActuate\":\n case \"xlinkArcrole\":\n case \"xlinkHref\":\n case \"xlinkRole\":\n case \"xlinkShow\":\n case \"xlinkTitle\":\n case \"xlinkType\":\n attrNS(node, XLinkNamespace, normalizeAttribute(key, \":\"), value)\n return\n case \"xmlnsXlink\":\n attr(node, normalizeAttribute(key, \":\"), value)\n return\n case \"xmlBase\":\n case \"xmlLang\":\n case \"xmlSpace\":\n attrNS(node, XMLNamespace, normalizeAttribute(key, \":\"), value)\n return\n }\n switch (key) {\n case \"htmlFor\":\n attr(node, \"for\", value)\n return\n case \"dataset\":\n forEach(value, (dataValue, dataKey) => {\n if (dataValue != null) {\n node.dataset[dataKey] = dataValue\n }\n })\n return\n case \"innerHTML\":\n case \"innerText\":\n case \"textContent\":\n if (isVisibleChild(value)) {\n node[key] = value\n }\n return\n case \"dangerouslySetInnerHTML\":\n if (isObject(value)) {\n node.innerHTML = value[\"__html\"]\n }\n return\n case \"value\":\n if (value == null || node instanceof window.HTMLSelectElement) {\n // skip nullish values\n // for `