@mml-io/3d-web-client-core 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.js +10 -9
- package/build/index.js.map +2 -2
- package/package.json +3 -3
package/build/index.js.map
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"version": 3,
|
3
3
|
"sources": ["../src/camera/CameraManager.ts", "../src/helpers/math-helpers.ts", "../src/input/EventHandlerCollection.ts", "../src/input/VirtualJoystick.ts", "../src/tweakpane/tweakPaneActivity.ts", "../src/character/Character.ts", "../src/character/CharacterModel.ts", "../src/character/CharacterMaterial.ts", "../src/rendering/shaders/bayer-dither.ts", "../src/rendering/shaders/shader-helpers.ts", "../src/tweakpane/blades/characterFolder.ts", "../src/character/CharacterState.ts", "../src/character/CharacterSpeakingIndicator.ts", "../src/character/CharacterTooltip.ts", "../src/character/CanvasText.ts", "../src/character/CharacterManager.ts", "../src/character/LocalController.ts", "../src/character/RemoteController.ts", "../src/character/url-position.ts", "../src/character/CharacterModelLoader.ts", "../src/input/KeyInputManager.ts", "../src/mml/MMLCompositionScene.ts", "../src/tweakpane/TweakPane.ts", "../src/tweakpane/blades/bcsFolder.ts", "../src/tweakpane/blades/environmentFolder.ts", "../src/tweakpane/blades/postExtrasFolder.ts", "../src/tweakpane/blades/rendererFolder.ts", "../src/tweakpane/blades/rendererStatsFolder.ts", "../src/tweakpane/blades/ssaoFolder.ts", "../src/tweakpane/blades/toneMappingFolder.ts", "../src/tweakpane/tweakPaneStyle.ts", "../src/rendering/composer.ts", "../src/sun/Sun.ts", "../src/rendering/post-effects/bright-contrast-sat.ts", "../src/rendering/shaders/vertex-shader.ts", "../src/rendering/post-effects/gauss-grain.ts", "../src/rendering/post-effects/n8-ssao/N8SSAOPass.ts", "../src/rendering/post-effects/n8-ssao/BlueNoise.ts", "../src/rendering/post-effects/n8-ssao/DepthDownSample.ts", "../src/rendering/post-effects/n8-ssao/EffectCompositer.ts", "../src/rendering/post-effects/n8-ssao/EffectShader.ts", "../src/rendering/post-effects/n8-ssao/FullScreenTriangle.ts", "../src/rendering/post-effects/n8-ssao/PoissionBlur.ts", "../src/time/TimeManager.ts", "../src/collisions/CollisionsManager.ts"],
|
4
|
-
"sourcesContent": ["import { PerspectiveCamera, Raycaster, Vector3 } from \"three\";\n\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { remap } from \"../helpers/math-helpers\";\nimport { EventHandlerCollection } from \"../input/EventHandlerCollection\";\nimport { VirtualJoystick } from \"../input/VirtualJoystick\";\nimport { getTweakpaneActive } from \"../tweakpane/tweakPaneActivity\";\n\nexport class CameraManager {\n public readonly camera: PerspectiveCamera;\n\n public initialDistance: number = 3.3;\n\n private minDistance: number = 0.1;\n private maxDistance: number = 8;\n\n private initialFOV: number = 60;\n private fov: number = this.initialFOV;\n private minFOV: number = 85;\n private maxFOV: number = 60;\n private targetFOV: number = this.initialFOV;\n\n public minPolarAngle: number = Math.PI * 0.25;\n private maxPolarAngle: number = Math.PI * 0.95;\n\n private dampingFactor: number = 0.091;\n\n public targetDistance: number = this.initialDistance;\n private distance: number = this.initialDistance;\n private desiredDistance: number = this.initialDistance;\n\n private targetPhi: number | null;\n private phi: number = Math.PI / 2;\n private targetTheta: number | null;\n private theta: number = Math.PI / 2;\n public dragging: boolean = false;\n\n private target: Vector3 = new Vector3(0, 1.55, 0);\n private hadTarget: boolean = false;\n\n private rayCaster: Raycaster;\n\n private eventHandlerCollection: EventHandlerCollection;\n\n private isLerping: boolean = false;\n private finalTarget: Vector3 = new Vector3();\n private lerpTarget: Vector3 = new Vector3();\n\n private lerpFactor: number = 0;\n private lerpDuration: number = 2.1;\n\n private hasTouchControl: boolean = false;\n private lastTouchX: number = 0;\n private lastTouchY: number = 0;\n\n constructor(\n targetElement: HTMLElement,\n private collisionsManager: CollisionsManager,\n initialPhi = Math.PI / 2,\n initialTheta = -Math.PI / 2,\n ) {\n this.phi = initialPhi;\n this.targetPhi = initialPhi;\n this.theta = initialTheta;\n this.targetTheta = initialTheta;\n this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1, 400);\n this.camera.position.set(0, 1.4, -this.initialDistance);\n this.rayCaster = new Raycaster();\n\n this.hasTouchControl = VirtualJoystick.checkForTouch();\n\n this.eventHandlerCollection = EventHandlerCollection.create([\n [targetElement, \"mousedown\", this.onMouseDown.bind(this)],\n [document, \"mouseup\", this.onMouseUp.bind(this)],\n [document, \"mousemove\", this.onMouseMove.bind(this)],\n [targetElement, \"wheel\", this.onMouseWheel.bind(this)],\n ]);\n\n if (this.hasTouchControl) {\n this.eventHandlerCollection.add(targetElement, \"touchstart\", this.onTouchStart.bind(this), {\n passive: false,\n });\n this.eventHandlerCollection.add(document, \"touchmove\", this.onTouchMove.bind(this), {\n passive: false,\n });\n this.eventHandlerCollection.add(document, \"touchend\", this.onTouchEnd.bind(this), {\n passive: false,\n });\n }\n }\n\n private onTouchStart(evt: TouchEvent): void {\n Array.from(evt.touches).forEach((touch) => {\n if (!VirtualJoystick.isTouchOnJoystick(touch)) {\n this.dragging = true;\n this.lastTouchX = touch.clientX;\n this.lastTouchY = touch.clientY;\n }\n });\n }\n\n private onTouchMove(evt: TouchEvent): void {\n if (!this.dragging || getTweakpaneActive()) {\n return;\n }\n evt.preventDefault();\n\n const touch = Array.from(evt.touches).find((t) => !VirtualJoystick.isTouchOnJoystick(t));\n if (touch) {\n const dx = touch.clientX - this.lastTouchX;\n const dy = touch.clientY - this.lastTouchY;\n this.lastTouchX = touch.clientX;\n this.lastTouchY = touch.clientY;\n\n if (this.targetTheta !== null && this.targetPhi !== null) {\n this.targetTheta += dx * 0.01;\n this.targetPhi -= dy * 0.01;\n this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));\n }\n }\n }\n\n private onTouchEnd(evt: TouchEvent): void {\n if (this.dragging) {\n const touchEnded = Array.from(evt.changedTouches).some(\n (t) => !VirtualJoystick.isTouchOnJoystick(t),\n );\n if (touchEnded) {\n this.dragging = false;\n }\n }\n }\n\n private onMouseDown(): void {\n this.dragging = true;\n }\n\n private onMouseUp(_event: MouseEvent): void {\n this.dragging = false;\n }\n\n private onMouseMove(event: MouseEvent): void {\n if (!this.dragging || getTweakpaneActive()) return;\n if (this.targetTheta === null || this.targetPhi === null) return;\n this.targetTheta += event.movementX * 0.01;\n this.targetPhi -= event.movementY * 0.01;\n this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));\n event.preventDefault();\n }\n\n private onMouseWheel(event: WheelEvent): void {\n const scrollAmount = event.deltaY * 0.001;\n this.targetDistance += scrollAmount;\n this.targetDistance = Math.max(\n this.minDistance,\n Math.min(this.maxDistance, this.targetDistance),\n );\n this.desiredDistance = this.targetDistance;\n event.preventDefault();\n }\n\n public setTarget(target: Vector3): void {\n if (!this.isLerping) {\n this.target.copy(target);\n } else {\n this.finalTarget.copy(target);\n this.lerpTarget.copy(this.target);\n this.lerpFactor = 0;\n }\n\n if (!this.hadTarget) {\n this.hadTarget = true;\n this.reverseUpdateFromPositions();\n }\n }\n\n public setLerpedTarget(target: Vector3, targetDistance: number): void {\n this.isLerping = true;\n this.targetDistance = targetDistance;\n this.desiredDistance = targetDistance;\n this.setTarget(target);\n }\n\n public reverseUpdateFromPositions(): void {\n const dx = this.camera.position.x - this.target.x;\n const dy = this.camera.position.y - this.target.y;\n const dz = this.camera.position.z - this.target.z;\n this.targetDistance = Math.sqrt(dx * dx + dy * dy + dz * dz);\n this.targetTheta = Math.atan2(dz, dx);\n this.targetPhi = Math.acos(dy / this.targetDistance);\n this.phi = this.targetPhi;\n this.theta = this.targetTheta;\n this.distance = this.targetDistance;\n this.desiredDistance = this.targetDistance;\n this.targetFOV = remap(\n this.targetDistance,\n this.minDistance,\n this.maxDistance,\n this.minFOV,\n this.maxFOV,\n );\n this.fov = this.targetFOV;\n }\n\n public adjustCameraPosition(): void {\n /*\n The purpose for the offsetDistance is to set the rayCaster further from the player\n than the camera is on the z relative axis, so we can avoid having a camera collider\n and expensive checks to prevent seeing clipped wals or floors or objects when we\n readjust the camera. 50cm (the current offset) should get a good balance for most\n indoor environments\n */\n const offsetDistance = 0.5;\n const offset = new Vector3(0, 0, offsetDistance);\n offset.applyEuler(this.camera.rotation);\n const rayOrigin = this.camera.position.clone().add(offset);\n const rayDirection = this.target.clone().sub(rayOrigin).normalize();\n\n this.rayCaster.set(rayOrigin, rayDirection);\n const firstRaycastHit = this.collisionsManager.raycastFirst(this.rayCaster.ray);\n const cameraToPlayerDistance = this.camera.position.distanceTo(this.target);\n\n if (firstRaycastHit !== null && firstRaycastHit[0] <= cameraToPlayerDistance) {\n this.targetDistance = cameraToPlayerDistance - firstRaycastHit[0];\n this.distance = this.targetDistance;\n } else {\n this.targetDistance += (this.desiredDistance - this.targetDistance) * this.dampingFactor * 4;\n }\n }\n\n public dispose() {\n this.eventHandlerCollection.clear();\n }\n\n private easeOutExpo(x: number): number {\n return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);\n }\n\n public updateAspect(aspect: number): void {\n this.camera.aspect = aspect;\n }\n\n public update(): void {\n if (this.isLerping && this.lerpFactor < 1) {\n this.lerpFactor += 0.01 / this.lerpDuration;\n this.lerpFactor = Math.min(1, this.lerpFactor);\n this.target.lerpVectors(this.lerpTarget, this.finalTarget, this.easeOutExpo(this.lerpFactor));\n } else {\n this.adjustCameraPosition();\n }\n\n if (\n this.phi !== null &&\n this.targetPhi !== null &&\n this.theta !== null &&\n this.targetTheta !== null\n ) {\n this.distance += (this.targetDistance - this.distance) * this.dampingFactor * 0.21;\n this.phi += (this.targetPhi - this.phi) * this.dampingFactor;\n this.theta += (this.targetTheta - this.theta) * this.dampingFactor;\n\n const x = this.target.x + this.distance * Math.sin(this.phi) * Math.cos(this.theta);\n const y = this.target.y + this.distance * Math.cos(this.phi);\n const z = this.target.z + this.distance * Math.sin(this.phi) * Math.sin(this.theta);\n\n this.targetFOV = remap(\n this.targetDistance,\n this.minDistance,\n this.maxDistance,\n this.minFOV,\n this.maxFOV,\n );\n this.fov += (this.targetFOV - this.fov) * this.dampingFactor;\n this.camera.fov = this.fov;\n this.camera.updateProjectionMatrix();\n\n this.camera.position.set(x, y, z);\n this.camera.lookAt(this.target);\n\n if (this.isLerping && this.lerpFactor >= 1) {\n this.isLerping = false;\n }\n }\n }\n}\n", "import { Quaternion, Vector3, Vector4 } from \"three\";\n\nexport const roundToDecimalPlaces = (value: number, decimalPlaces: number): number => {\n const mult = 10 ** decimalPlaces;\n return Math.round(value * mult) / mult;\n};\n\nexport const toArray = (\n origin: Vector3 | Vector4 | Quaternion,\n precision: number = 3,\n): number[] => {\n const array = [];\n array[0] = roundToDecimalPlaces(origin.x, precision);\n array[1] = roundToDecimalPlaces(origin.y, precision);\n array[2] = roundToDecimalPlaces(origin.z, precision);\n if (origin instanceof Vector4 || origin instanceof Quaternion) {\n array[3] = roundToDecimalPlaces(origin.w, precision);\n }\n return array;\n};\n\nexport const getSpawnPositionInsideCircle = (\n radius: number,\n positions: number,\n id: number,\n yPos: number = 0,\n): Vector3 => {\n if (id > 0) id += 3;\n const goldenAngle = Math.PI * (3 - Math.sqrt(5));\n const theta = id * goldenAngle;\n const scale = id / positions;\n const scaledRadius = scale * radius;\n const x = Math.cos(theta) * scaledRadius;\n const z = Math.sin(theta) * scaledRadius;\n return new Vector3(x, yPos, z);\n};\n\nexport const round = (n: number, digits: number): number => {\n return Number(n.toFixed(digits));\n};\n\nexport const ease = (target: number, n: number, factor: number): number => {\n return round((target - n) * factor, 5);\n};\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport const remap = (\n value: number,\n minValue: number,\n maxValue: number,\n minScaledValue: number,\n maxScaledValue: number,\n): number => {\n return (\n minScaledValue +\n ((maxScaledValue - minScaledValue) * (value - minValue)) / (maxValue - minValue)\n );\n};\n", "type ListenerFunc = (...args: any[]) => void;\n\ntype EventSpecificationTuple = [EventTarget, string, ListenerFunc, AddEventListenerOptions?];\n\nexport class EventHandlerCollection {\n private eventsByTarget: Map<EventTarget, Map<string, Set<ListenerFunc>>> = new Map();\n\n public add(\n target: EventTarget,\n key: string,\n listener: ListenerFunc,\n options?: AddEventListenerOptions,\n ): this {\n target.addEventListener(key, listener, options);\n\n let existingTarget = this.eventsByTarget.get(target);\n if (existingTarget === undefined) {\n existingTarget = new Map();\n this.eventsByTarget.set(target, existingTarget);\n }\n let existingKey = existingTarget.get(key);\n if (existingKey === undefined) {\n existingKey = new Set();\n existingTarget.set(key, existingKey);\n }\n existingKey.add(listener);\n\n return this;\n }\n\n public clear() {\n this.eventsByTarget.forEach((keyMap, target) => {\n keyMap.forEach((listenerSet, key) => {\n listenerSet.forEach((listenerFunc) => {\n target.removeEventListener(key, listenerFunc);\n });\n });\n });\n this.eventsByTarget.clear();\n }\n\n static create(initial?: Array<EventSpecificationTuple>): EventHandlerCollection {\n const instance = new EventHandlerCollection();\n if (initial !== undefined) {\n initial.forEach(([target, key, listenerFunc, options]) => {\n instance.add(target, key, listenerFunc, options);\n });\n }\n return instance;\n }\n}\n", "interface JoyStickAttributes {\n radius?: number;\n inner_radius?: number;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n mouse_support?: boolean;\n visible?: boolean;\n anchor?: \"left\" | \"right\";\n}\n\nexport class VirtualJoystick {\n public static JOYSTICK_DIV: HTMLDivElement | null = null;\n\n private radius: number;\n private inner_radius: number;\n private anchor: \"left\" | \"right\";\n private x: number;\n private y: number;\n private width: number;\n private height: number;\n private mouse_support: boolean;\n\n private div: HTMLDivElement;\n private base: HTMLSpanElement;\n private control: HTMLSpanElement;\n\n public left: boolean = false;\n public right: boolean = false;\n public up: boolean = false;\n public down: boolean = false;\n public hasDirection: boolean = false;\n\n constructor(attrs: JoyStickAttributes) {\n this.radius = attrs.radius || 50;\n this.inner_radius = attrs.inner_radius || this.radius / 2;\n this.anchor = attrs.anchor || \"left\";\n this.x = attrs.x || 0;\n this.y = attrs.y || 0;\n this.width = attrs.width || this.radius * 2 + this.inner_radius * 2;\n this.height = attrs.height || this.radius * 2 + this.inner_radius * 2;\n this.mouse_support = this.checkTouch() || attrs.mouse_support === true;\n\n this.initializeJoystick();\n }\n\n public static checkForTouch(): boolean {\n try {\n document.createEvent(\"TouchEvent\");\n return true;\n } catch (e) {\n return false;\n }\n }\n\n public static isTouchOnJoystick(touch: Touch): boolean {\n if (!VirtualJoystick.JOYSTICK_DIV) {\n return false;\n }\n const divRect = VirtualJoystick.JOYSTICK_DIV.getBoundingClientRect();\n return (\n touch.clientX >= divRect.left &&\n touch.clientX <= divRect.right &&\n touch.clientY >= divRect.top &&\n touch.clientY <= divRect.bottom\n );\n }\n\n private checkTouch() {\n return VirtualJoystick.checkForTouch();\n }\n\n private initializeJoystick(): void {\n if (!VirtualJoystick.JOYSTICK_DIV) {\n this.div = document.createElement(\"div\");\n const divStyle = this.div.style;\n divStyle.display = this.checkTouch() || this.mouse_support ? \"visible\" : \"none\";\n divStyle.position = \"fixed\";\n if (this.anchor === \"left\") {\n divStyle.left = `${this.x}px`;\n } else {\n divStyle.right = `${this.x}px`;\n }\n divStyle.bottom = `${this.y}px`;\n divStyle.width = `${this.width}px`;\n divStyle.height = `${this.height}px`;\n divStyle.zIndex = \"10000\";\n divStyle.overflow = \"hidden\";\n document.body.appendChild(this.div);\n VirtualJoystick.JOYSTICK_DIV = this.div;\n }\n\n this.setupBaseAndControl();\n this.bindEvents();\n }\n\n private setupBaseAndControl(): void {\n this.base = document.createElement(\"span\");\n let divStyle = this.base.style;\n divStyle.width = `${this.radius * 2}px`;\n divStyle.height = `${this.radius * 2}px`;\n divStyle.position = \"absolute\";\n divStyle.left = `${this.width / 2 - this.radius}px`;\n divStyle.bottom = `${this.height / 2 - this.radius}px`;\n divStyle.borderRadius = \"50%\";\n divStyle.borderColor = \"rgba(200,200,200,0.5)\";\n divStyle.borderWidth = \"2px\";\n divStyle.borderStyle = \"solid\";\n this.div.appendChild(this.base);\n\n this.control = document.createElement(\"span\");\n divStyle = this.control.style;\n divStyle.width = `${this.inner_radius * 2}px`;\n divStyle.height = `${this.inner_radius * 2}px`;\n divStyle.position = \"absolute\";\n divStyle.left = `${this.width / 2 - this.inner_radius}px`;\n divStyle.bottom = `${this.height / 2 - this.inner_radius}px`;\n divStyle.borderRadius = \"50%\";\n divStyle.backgroundColor = \"rgba(200,200,200,0.3)\";\n divStyle.borderWidth = \"1px\";\n divStyle.borderColor = \"rgba(200,200,200,0.8)\";\n divStyle.borderStyle = \"solid\";\n this.div.appendChild(this.control);\n }\n\n private bindEvents(): void {\n this.div.addEventListener(\"touchstart\", this.handleTouchStart.bind(this), false);\n this.div.addEventListener(\"touchmove\", this.handleTouchMove.bind(this), false);\n this.div.addEventListener(\"touchend\", this.clearFlags.bind(this), false);\n\n if (this.mouse_support) {\n this.div.addEventListener(\"mousedown\", this.handleMouseDown.bind(this));\n this.div.addEventListener(\"mousemove\", this.handleMouseMove.bind(this));\n this.div.addEventListener(\"mouseup\", this.handleMouseUp.bind(this));\n }\n }\n\n private handleTouchStart(evt: TouchEvent): void {\n evt.preventDefault();\n if (evt.touches) {\n const touch = evt.touches[0];\n this.updateControlAndDirection(touch);\n }\n }\n\n private handleTouchMove(evt: TouchEvent): void {\n evt.preventDefault();\n if (evt.touches.length > 0) {\n const touch = evt.touches[0];\n this.updateControlAndDirection(touch);\n }\n }\n\n private handleMouseDown(evt: MouseEvent): void {\n evt.preventDefault();\n this.updateControlAndDirection(evt);\n }\n\n private handleMouseMove(evt: MouseEvent): void {\n if (evt.buttons === 1) {\n evt.preventDefault();\n this.updateControlAndDirection(evt);\n }\n }\n\n private handleMouseUp(evt: MouseEvent): void {\n this.clearFlags();\n }\n\n private clearFlags = (): void => {\n this.left = false;\n this.right = false;\n this.up = false;\n this.down = false;\n this.hasDirection = false;\n this.control.style.left = `${this.width / 2 - this.inner_radius}px`;\n this.control.style.top = `${this.height / 2 - this.inner_radius}px`;\n };\n\n private updateControlAndDirection(input: Touch | MouseEvent): void {\n const rect = this.div.getBoundingClientRect();\n const dx = input.clientX - (rect.left + this.div.offsetWidth / 2);\n const dy = input.clientY - (rect.top + this.div.offsetHeight / 2);\n\n const distance = Math.min(Math.sqrt(dx * dx + dy * dy), this.radius);\n const angle = Math.atan2(dy, dx);\n const constrainedX = distance * Math.cos(angle);\n const constrainedY = distance * Math.sin(angle);\n\n this.control.style.left = `${constrainedX + this.width / 2 - this.inner_radius}px`;\n this.control.style.top = `${constrainedY + this.height / 2 - this.inner_radius}px`;\n\n this.up = this.isUp(dx, dy);\n this.down = this.isDown(dx, dy);\n this.left = this.isLeft(dx, dy);\n this.right = this.isRight(dx, dy);\n this.hasDirection = this.up || this.down || this.left || this.right;\n }\n\n private isUp(dx: number, dy: number): boolean {\n return dy < 0 && Math.abs(dx) <= 2 * Math.abs(dy);\n }\n\n private isDown(dx: number, dy: number): boolean {\n return dy > 0 && Math.abs(dx) <= 2 * Math.abs(dy);\n }\n\n private isLeft(dx: number, dy: number): boolean {\n return dx < 0 && Math.abs(dy) <= 2 * Math.abs(dx);\n }\n\n private isRight(dx: number, dy: number): boolean {\n return dx > 0 && Math.abs(dy) <= 2 * Math.abs(dx);\n }\n}\n", "let isTweakpaneActive = false;\n\nexport function setTweakpaneActive(status: boolean) {\n isTweakpaneActive = status;\n}\n\nexport function getTweakpaneActive() {\n return isTweakpaneActive;\n}\n", "import { Color, Group, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { Composer } from \"../rendering/composer\";\n\nimport { CharacterModel } from \"./CharacterModel\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { CharacterSpeakingIndicator } from \"./CharacterSpeakingIndicator\";\nimport { AnimationState } from \"./CharacterState\";\nimport { CharacterTooltip } from \"./CharacterTooltip\";\n\nexport type AnimationConfig = {\n idleAnimationFileUrl: string;\n jogAnimationFileUrl: string;\n sprintAnimationFileUrl: string;\n airAnimationFileUrl: string;\n};\n\nexport type CharacterDescription = {\n meshFileUrl?: string;\n mmlCharacterUrl?: string;\n mmlCharacterString?: string;\n};\n\nexport class Character extends Group {\n private model: CharacterModel | null = null;\n public color: Color = new Color();\n public tooltip: CharacterTooltip | null = null;\n public speakingIndicator: CharacterSpeakingIndicator | null = null;\n\n constructor(\n private readonly characterDescription: CharacterDescription,\n private readonly animationConfig: AnimationConfig,\n private readonly characterModelLoader: CharacterModelLoader,\n private readonly characterId: number,\n private readonly modelLoadedCallback: () => void,\n private readonly cameraManager: CameraManager,\n private readonly composer: Composer,\n private readonly isLocal: boolean,\n ) {\n super();\n this.tooltip = new CharacterTooltip();\n this.add(this.tooltip);\n this.load();\n }\n\n private async load(): Promise<void> {\n this.model = new CharacterModel(\n this.characterDescription,\n this.animationConfig,\n this.characterModelLoader,\n this.cameraManager,\n this.characterId,\n this.isLocal,\n );\n await this.model.init();\n this.add(this.model.mesh!);\n if (this.speakingIndicator === null) {\n this.speakingIndicator = new CharacterSpeakingIndicator(this.composer.postPostScene);\n }\n this.modelLoadedCallback();\n }\n\n public updateAnimation(targetAnimation: AnimationState) {\n this.model?.updateAnimation(targetAnimation);\n }\n\n public update(time: number, deltaTime: number) {\n if (!this.model) return;\n if (this.tooltip) {\n this.tooltip.update(this.cameraManager.camera);\n }\n if (this.speakingIndicator) {\n this.speakingIndicator.setTime(time);\n if (this.model.mesh && this.model.headBone) {\n this.speakingIndicator.setBillboarding(\n this.model.headBone?.getWorldPosition(new Vector3()),\n this.cameraManager.camera,\n );\n }\n }\n this.model.update(deltaTime);\n }\n\n getCurrentAnimation(): AnimationState {\n return this.model?.currentAnimation || AnimationState.idle;\n }\n}\n", "import {\n MMLCharacter,\n type MMLCharacterDescription,\n ModelLoader,\n parseMMLDescription,\n} from \"@mml-io/3d-web-avatar\";\nimport {\n AnimationAction,\n AnimationClip,\n AnimationMixer,\n Bone,\n LoopRepeat,\n Mesh,\n MeshStandardMaterial,\n Object3D,\n SkinnedMesh,\n} from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\n\nimport { AnimationConfig, CharacterDescription } from \"./Character\";\nimport { CharacterMaterial } from \"./CharacterMaterial\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { AnimationState } from \"./CharacterState\";\n\nexport class CharacterModel {\n public mesh: Object3D | null = null;\n public headBone: Bone | null = null;\n\n private materials: Map<string, CharacterMaterial> = new Map();\n\n public animations: Record<string, AnimationAction> = {};\n public animationMixer: AnimationMixer | null = null;\n public currentAnimation: AnimationState = AnimationState.idle;\n\n public mmlCharacterDescription: MMLCharacterDescription;\n\n constructor(\n private readonly characterDescription: CharacterDescription,\n private readonly animationConfig: AnimationConfig,\n private characterModelLoader: CharacterModelLoader,\n private readonly cameraManager: CameraManager,\n private readonly characterId: number,\n private readonly isLocal: boolean,\n ) {}\n\n public async init(): Promise<void> {\n await this.loadMainMesh();\n await this.setAnimationFromFile(this.animationConfig.idleAnimationFileUrl, AnimationState.idle);\n await this.setAnimationFromFile(\n this.animationConfig.jogAnimationFileUrl,\n AnimationState.walking,\n );\n await this.setAnimationFromFile(\n this.animationConfig.sprintAnimationFileUrl,\n AnimationState.running,\n );\n await this.setAnimationFromFile(this.animationConfig.airAnimationFileUrl, AnimationState.air);\n this.applyCustomMaterials();\n }\n\n private applyCustomMaterials(): void {\n if (!this.mesh) return;\n this.mesh.traverse((child: Object3D) => {\n if ((child as Mesh).isMesh || (child as SkinnedMesh).isSkinnedMesh) {\n const asMesh = child as Mesh;\n const originalMaterial = asMesh.material as MeshStandardMaterial;\n if (this.materials.has(originalMaterial.name)) {\n asMesh.material = this.materials.get(originalMaterial.name)!;\n } else {\n const material =\n originalMaterial.name === \"body_replaceable_color\"\n ? new CharacterMaterial(\n this.isLocal,\n this.cameraManager,\n this.characterId,\n originalMaterial,\n )\n : new CharacterMaterial(\n this.isLocal,\n this.cameraManager,\n this.characterId,\n originalMaterial,\n originalMaterial.color,\n );\n this.materials.set(originalMaterial.name, material);\n asMesh.material = material;\n }\n }\n });\n }\n\n public updateAnimation(targetAnimation: AnimationState) {\n if (this.currentAnimation !== targetAnimation) {\n this.transitionToAnimation(targetAnimation);\n }\n }\n\n private setMainMesh(mainMesh: Object3D): void {\n this.mesh = mainMesh;\n this.mesh.position.set(0, -0.4, 0);\n this.mesh.traverse((child: Object3D) => {\n if (child.type === \"SkinnedMesh\") {\n child.castShadow = true;\n child.receiveShadow = true;\n }\n });\n this.animationMixer = new AnimationMixer(this.mesh);\n }\n\n private async composeMMLCharacter(\n mmlCharacterDescription: MMLCharacterDescription,\n ): Promise<Object3D | undefined> {\n if (mmlCharacterDescription.base?.url.length === 0) {\n throw new Error(\n \"ERROR: An MML Character Description was provided but it's not a valid <m-character> string, or a valid URL\",\n );\n }\n\n let mergedCharacter: Object3D | null = null;\n if (mmlCharacterDescription) {\n const characterBase = mmlCharacterDescription.base?.url || null;\n if (characterBase) {\n this.mmlCharacterDescription = mmlCharacterDescription;\n const mmlCharacter = new MMLCharacter(new ModelLoader());\n mergedCharacter = await mmlCharacter.mergeBodyParts(\n characterBase,\n mmlCharacterDescription.parts,\n );\n if (mergedCharacter) {\n return mergedCharacter.children[0].children[0];\n }\n }\n }\n }\n\n private async loadCharacterFromDescription(): Promise<Object3D | null> {\n if (this.characterDescription.meshFileUrl) {\n return (\n (await this.characterModelLoader.load(this.characterDescription.meshFileUrl, \"model\")) ||\n null\n );\n }\n\n let mmlCharacterSource: string;\n if (this.characterDescription.mmlCharacterUrl) {\n const res = await fetch(this.characterDescription.mmlCharacterUrl);\n mmlCharacterSource = await res.text();\n } else if (this.characterDescription.mmlCharacterString) {\n mmlCharacterSource = this.characterDescription.mmlCharacterString;\n } else {\n throw new Error(\n \"ERROR: No Character Description was provided. Specify one of meshFileUrl, mmlCharacterUrl or mmlCharacterString\",\n );\n }\n\n const parsedMMLDescription = parseMMLDescription(mmlCharacterSource);\n const mmlCharacterDescription = parsedMMLDescription[0];\n if (parsedMMLDescription[1].length > 0) {\n console.warn(\"Errors parsing MML Character Description: \", parsedMMLDescription[1]);\n }\n const mmlCharacterBody = await this.composeMMLCharacter(mmlCharacterDescription);\n if (mmlCharacterBody) {\n return mmlCharacterBody;\n }\n return null;\n }\n\n private async loadMainMesh(): Promise<void> {\n const mainMesh = await this.loadCharacterFromDescription();\n if (typeof mainMesh !== \"undefined\") {\n this.setMainMesh(mainMesh as Object3D);\n } else {\n throw new Error(\"ERROR: No Character Model was loaded\");\n }\n }\n\n private cleanAnimationClips(skeletalMesh: Object3D, animationClip: AnimationClip): AnimationClip {\n const availableBones = new Set<string>();\n skeletalMesh.traverse((child) => {\n const asBone = child as Bone;\n if (asBone.isBone) {\n availableBones.add(child.name);\n }\n });\n animationClip.tracks = animationClip.tracks.filter((track) => {\n const trackName = track.name.split(\".\")[0];\n return availableBones.has(trackName);\n });\n return animationClip;\n }\n\n private async setAnimationFromFile(\n animationFileUrl: string,\n animationType: AnimationState,\n ): Promise<void> {\n return new Promise(async (resolve, reject) => {\n const animation = await this.characterModelLoader.load(animationFileUrl, \"animation\");\n const cleanAnimation = this.cleanAnimationClips(this.mesh!, animation as AnimationClip);\n if (typeof animation !== \"undefined\" && cleanAnimation instanceof AnimationClip) {\n this.animations[animationType] = this.animationMixer!.clipAction(cleanAnimation);\n this.animations[animationType].stop();\n if (animationType === AnimationState.idle) {\n this.animations[animationType].play();\n }\n resolve();\n } else {\n reject(`failed to load ${animationType} from ${animationFileUrl}`);\n }\n });\n }\n\n private transitionToAnimation(\n targetAnimation: AnimationState,\n transitionDuration: number = 0.15,\n ): void {\n if (!this.mesh) return;\n\n const currentAction = this.animations[this.currentAnimation];\n this.currentAnimation = targetAnimation;\n const targetAction = this.animations[targetAnimation];\n\n if (!targetAction) return;\n\n if (currentAction) {\n currentAction.enabled = true;\n currentAction.fadeOut(transitionDuration);\n }\n\n if (!targetAction.isRunning()) targetAction.play();\n\n targetAction.setLoop(LoopRepeat, Infinity);\n targetAction.enabled = true;\n targetAction.fadeIn(transitionDuration);\n }\n\n update(time: number) {\n if (this.animationMixer) {\n this.animationMixer.update(time);\n this.materials.forEach((material) => material.update());\n }\n }\n}\n", "import { Color, MeshPhysicalMaterial, MeshStandardMaterial, Texture, UniformsUtils } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { ease } from \"../helpers/math-helpers\";\nimport { bayerDither } from \"../rendering/shaders/bayer-dither\";\nimport {\n injectBefore,\n injectBeforeMain,\n injectInsideMain,\n} from \"../rendering/shaders/shader-helpers\";\nimport { characterValues } from \"../tweakpane/blades/characterFolder\";\n\ntype TUniform<TValue = any> = { value: TValue };\n\nexport class CharacterMaterial extends MeshStandardMaterial {\n private uniforms: Record<string, TUniform> = {\n discardAll: { value: 1 },\n diffuseColor: { value: new Color() },\n map: { value: null },\n };\n private colorsCube216: Color[] = [];\n private targetAlpha: number = 1;\n private currentAlpha: number = 1;\n\n constructor(\n private isLocal: boolean,\n private cameraManager: CameraManager,\n private characterId: number,\n private originalMaterial: MeshStandardMaterial,\n private colorOverride?: Color,\n ) {\n super();\n this.copy(this.originalMaterial);\n this.generateColorCube();\n\n this.color = this.colorOverride || this.colorsCube216[this.characterId];\n this.envMapIntensity = characterValues.envMapIntensity;\n this.transparent = true;\n this.side = this.originalMaterial.side;\n\n this.onBeforeCompile = (shader) => {\n this.uniforms = UniformsUtils.clone(shader.uniforms);\n this.uniforms.nearClip = { value: 0.01 };\n this.uniforms.farClip = { value: 1000.0 };\n this.uniforms.ditheringNear = { value: 0.3 };\n this.uniforms.ditheringRange = { value: 0.5 };\n this.uniforms.time = { value: 0.0 };\n this.uniforms.diffuseRandomColor = { value: new Color() };\n this.uniforms.discardAll = { value: 0 };\n shader.uniforms = this.uniforms;\n\n shader.vertexShader = \"varying vec3 vWorldPosition;\\n\" + shader.vertexShader;\n shader.vertexShader = shader.vertexShader.replace(\n \"#include <worldpos_vertex>\",\n \"vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\nvWorldPosition = worldPosition.xyz;\",\n );\n shader.vertexShader = injectBeforeMain(shader.vertexShader, \"varying vec2 vUv;\");\n shader.vertexShader = injectInsideMain(shader.vertexShader, \"vUv = uv;\");\n\n shader.fragmentShader = injectBeforeMain(\n shader.fragmentShader,\n /* glsl */ `\n varying vec2 vUv;\n varying vec3 vWorldPosition;\n uniform float nearClip;\n uniform float farClip;\n uniform float ditheringNear;\n uniform float ditheringRange;\n uniform float time;\n uniform vec3 diffuseRandomColor;\n uniform int discardAll;\n ${bayerDither}\n `,\n );\n\n shader.fragmentShader = injectBefore(\n shader.fragmentShader,\n \"#include <output_fragment>\",\n /* glsl */ `\n if (discardAll == 1) {\n discard;\n } else {\n float distance = length(vWorldPosition - cameraPosition);\n float normalizedDistance = (distance - nearClip) / (farClip - nearClip);\n ivec2 p = ivec2(mod(gl_FragCoord.xy, 8.0));\n float d = 0.0;\n if (p.x <= 3 && p.y <= 3) {\n d = bayerDither(bayertl, p);\n } else if (p.x > 3 && p.y <= 3) {\n d = bayerDither(bayertr, p - ivec2(4, 0));\n } else if (p.x <= 3 && p.y > 3) {\n d = bayerDither(bayerbl, p - ivec2(0, 4));\n } else if (p.x > 3 && p.y > 3) {\n d = bayerDither(bayerbr, p - ivec2(4, 4));\n }\n if (distance <= ditheringNear + d * ditheringRange) discard; \n outgoingLight *= diffuseRandomColor; \n }\n `,\n );\n };\n this.needsUpdate = true;\n }\n\n private generateColorCube() {\n const saturation = 1.0;\n const lightness = 0.9;\n const goldenRatioConjugate = 0.618033988749895;\n let hue = 0;\n\n for (let i = 0; i < 216; i++) {\n const color = new Color();\n color.setHSL(hue, saturation, lightness);\n this.colorsCube216.push(color);\n hue = (hue + goldenRatioConjugate) % 1;\n }\n }\n\n public update() {\n if (this.isLocal) {\n this.targetAlpha = this.cameraManager.targetDistance < 0.4 ? 0.0 : 1.0;\n this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.07);\n if (this.currentAlpha > 0.999) {\n this.currentAlpha = 1;\n this.cameraManager.minPolarAngle = Math.PI * 0.25;\n }\n if (this.currentAlpha < 0.001) {\n this.currentAlpha = 0;\n this.cameraManager.minPolarAngle = Math.PI * 0.35;\n }\n this.uniforms.discardAll.value = this.currentAlpha === 0 ? 1 : 0;\n if (this.currentAlpha !== this.opacity) {\n this.opacity = this.currentAlpha;\n }\n }\n this.metalness = characterValues.metalness;\n this.roughness = characterValues.roughness;\n this.emissive = new Color().setRGB(\n characterValues.emissive.r,\n characterValues.emissive.g,\n characterValues.emissive.b,\n );\n this.emissiveIntensity = characterValues.emissiveIntensity;\n this.envMapIntensity = characterValues.envMapIntensity;\n }\n}\n", "export const bayerDither: string = /* glsl */ `\nconst mat4 bayertl = mat4( \n 0.0 / 64.0, 32.0 / 64.0, 8.0 / 64.0, 40.0 / 64.0,\n 48.0 / 64.0, 16.0 / 64.0, 56.0 / 64.0, 24.0 / 64.0,\n 12.0 / 64.0, 44.0 / 64.0, 4.0 / 64.0, 36.0 / 64.0,\n 60.0 / 64.0, 28.0 / 64.0, 52.0 / 64.0, 20.0 / 64.0\n);\n\nconst mat4 bayertr = mat4( \n 2.0 / 64.0, 34.0 / 64.0, 10.0 / 64.0, 42.0 / 64.0,\n 50.0 / 64.0, 18.0 / 64.0, 58.0 / 64.0, 26.0 / 64.0,\n 14.0 / 64.0, 46.0 / 64.0, 6.0 / 64.0, 38.0 / 64.0,\n 62.0 / 64.0, 30.0 / 64.0, 54.0 / 64.0, 22.0 / 64.0\n);\n\nconst mat4 bayerbl = mat4( \n 3.0 / 64.0, 35.0 / 64.0, 11.0 / 64.0, 43.0 / 64.0,\n 51.0 / 64.0, 19.0 / 64.0, 59.0 / 64.0, 27.0 / 64.0,\n 15.0 / 64.0, 47.0 / 64.0, 7.0 / 64.0, 39.0 / 64.0,\n 63.0 / 64.0, 31.0 / 64.0, 55.0 / 64.0, 23.0 / 64.0\n);\n\nconst mat4 bayerbr = mat4( \n 1.0 / 64.0, 33.0 / 64.0, 9.0 / 64.0, 41.0 / 64.0,\n 49.0 / 64.0, 17.0 / 64.0, 57.0 / 64.0, 25.0 / 64.0,\n 13.0 / 64.0, 45.0 / 64.0, 5.0 / 64.0, 37.0 / 64.0,\n 61.0 / 64.0, 29.0 / 64.0, 53.0 / 64.0, 21.0 / 64.0\n);\n\nfloat bayerDither(mat4 m, ivec2 p) {\n if (p.y == 0) {\n if (p.x == 0) { return m[0][0]; }\n else if (p.x == 1) { return m[1][0]; }\n else if (p.x == 2) { return m[2][0]; }\n else { return m[3][0]; }\n } else if (p.y == 1) {\n if (p.x == 0) { return m[0][1]; }\n else if (p.x == 1) { return m[1][1]; }\n else if (p.x == 2) { return m[2][1]; }\n else { return m[3][1]; }\n } else if (p.y == 2) {\n if (p.x == 0) { return m[0][1]; }\n else if (p.x == 1) { return m[1][2]; }\n else if (p.x == 2) { return m[2][2]; }\n else { return m[3][2]; }\n } else {\n if (p.x == 0) { return m[0][3]; }\n else if (p.x == 1) { return m[1][3]; }\n else if (p.x == 2) { return m[2][3]; }\n else { return m[3][3]; }\n }\n}\n`;\n", "export function injectBeforeMain(shaderSource: string, codeToInject: string): string {\n return shaderSource.replace(\n \"void main() {\",\n `\n\n${codeToInject}\n\nvoid main() {`,\n );\n}\n\nexport function injectInsideMain(shaderSource: string, codeToInject: string): string {\n return shaderSource.replace(\n \"void main() {\",\n `void main() {\n\n${codeToInject}\n\n `,\n );\n}\n\nexport function injectBefore(shaderSource: string, before: string, codeToInject: string): string {\n return shaderSource.replace(\n before,\n `\n${codeToInject}\n\n${before}\n `,\n );\n}\n\nexport function injectAfter(shaderSource: string, after: string, codeToInject: string): string {\n return shaderSource.replace(\n after,\n `\n${after}\n\n${codeToInject}\n\n `,\n );\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nexport const characterValues = {\n metalness: 0.2,\n roughness: 0.8,\n emissive: { r: 1.0, g: 1.0, b: 1.0 },\n emissiveIntensity: 0.01,\n envMapIntensity: 0.12,\n};\n\nconst characterOptions = {\n metalness: { min: 0, max: 1, step: 0.01 },\n roughness: { min: 0, max: 1, step: 0.01 },\n emissiveIntensity: { min: 0, max: 1, step: 0.01 },\n envMapIntensity: { min: 0, max: 1, step: 0.01 },\n};\n\nexport class CharacterFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"characterMaterial\", expanded: expand });\n this.folder.addBinding(characterValues, \"metalness\", characterOptions.metalness);\n this.folder.addBinding(characterValues, \"roughness\", characterOptions.roughness);\n this.folder.addBinding(characterValues, \"emissive\", {\n color: { type: \"float\" },\n });\n this.folder.addBinding(\n characterValues,\n \"emissiveIntensity\",\n characterOptions.emissiveIntensity,\n );\n this.folder.addBinding(characterValues, \"envMapIntensity\", characterOptions.envMapIntensity);\n }\n\n public setupChangeEvent(): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"emissive\": {\n const value = e.value as { r: number; g: number; b: number };\n characterValues.emissive = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n break;\n }\n default: {\n break;\n }\n }\n });\n }\n}\n", "export enum AnimationState {\n \"idle\" = 0,\n \"walking\" = 1,\n \"running\" = 2,\n \"jumpToAir\" = 3,\n \"air\" = 4,\n \"airToGround\" = 5,\n}\n\nexport type CharacterState = {\n id: number;\n position: {\n x: number;\n y: number;\n z: number;\n };\n rotation: {\n quaternionY: number;\n quaternionW: number;\n };\n state: AnimationState;\n};\n", "import {\n Camera,\n CircleGeometry,\n GLSL3,\n Mesh,\n Object3D,\n RawShaderMaterial,\n Scene,\n Vector3,\n} from \"three\";\n\nimport { ease } from \"../helpers/math-helpers\";\n\nexport class CharacterSpeakingIndicator {\n private vertexShader = /* glsl */ `\n in vec3 position;\n in vec2 uv;\n uniform mat4 modelViewMatrix;\n uniform mat4 projectionMatrix;\n out vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }`;\n\n private fragmentShader = /* glsl */ `\n precision highp float;\n\n uniform float time;\n uniform float alpha;\n in vec2 vUv;\n out vec4 fragColor;\n\n const float size = 1.7;\n const float distribution = 0.03;\n const float speed = 0.2;\n const float overdraw = 3.5;\n const float shapeK = 0.25;\n\n float sdHyperbola(vec2 p, float k, float wi) {\n p = abs(p);\n float k2 = k * k;\n float a = p.x + p.y;\n float i = 0.5 * (a - k2 / a) > wi ? -1.0 : 1.0;\n float x = clamp(0.5 * (a - k2 / a), 0.0, wi);\n vec2 q = vec2(x, sqrt(x * x + k2));\n float s = sign(p.x * p.x - p.y * p.y + k2);\n return s * length(p - q);\n }\n\n void main(void) {\n vec2 uv = (vUv * 2.0 - 1.0);\n float r = -(uv.x * uv.x + uv.y * uv.y);\n float z = 0.5 + 0.5 * sin((r + time * speed) / distribution);\n float a = clamp(smoothstep(-0.1, 0.2, size - length(uv * 2.0)), 0.0, 0.5);\n float h = clamp(sdHyperbola(uv, shapeK, 1.0), 0.0, 1.0) * overdraw;\n float fragAlpha = clamp(a * h, 0.0, 0.7);\n fragColor = vec4(z * fragAlpha) * alpha;\n }`;\n\n private uniforms = {\n time: { value: 0.0 },\n alpha: { value: 0.0 },\n };\n\n private geometry: CircleGeometry = new CircleGeometry(0.35, 21);\n private material: RawShaderMaterial = new RawShaderMaterial({\n vertexShader: this.vertexShader,\n fragmentShader: this.fragmentShader,\n uniforms: this.uniforms,\n transparent: true,\n glslVersion: GLSL3,\n });\n private mesh = new Mesh(this.geometry, this.material);\n\n private currentAlpha = 0.0;\n private targetAlpha = 0.0;\n\n constructor(private scene: Scene | Object3D) {\n this.scene.add(this.mesh);\n }\n\n public setBillboarding(position: Vector3, camera: Camera) {\n this.mesh.position.set(position.x, position.y - 0.15, position.z);\n this.mesh.lookAt(camera.position);\n }\n\n public setTime(value: number) {\n this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.06);\n this.uniforms.time.value = value;\n this.uniforms.alpha.value = this.currentAlpha;\n }\n\n public setSpeaking(value: boolean) {\n this.targetAlpha = value === true ? 1.0 : 0.0;\n }\n\n public dispose() {\n this.scene.remove(this.mesh);\n this.mesh.material.dispose();\n this.mesh.geometry.dispose();\n }\n}\n", "import {\n Camera,\n Color,\n FrontSide,\n LinearFilter,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n PlaneGeometry,\n} from \"three\";\n\nimport { THREECanvasTextTexture } from \"./CanvasText\";\n\nenum LabelAlignment {\n left = \"left\",\n center = \"center\",\n right = \"right\",\n}\n\nconst fontScale = 5;\nconst defaultLabelColor = new Color(0x000000);\nconst defaultFontColor = new Color(0xffffff);\nconst defaultLabelAlignment = LabelAlignment.center;\nconst defaultLabelFontSize = 9;\nconst defaultLabelPadding = 0;\nconst defaultLabelWidth = 0.25;\nconst defaultLabelHeight = 0.125;\nconst defaultLabelCastShadows = true;\n\nconst tooltipGeometry = new PlaneGeometry(1, 1, 1, 1);\n\nexport class CharacterTooltip extends Mesh {\n private tooltipMaterial: MeshBasicMaterial;\n private visibleOpacity: number = 0.85;\n private targetOpacity: number = 0;\n private fadingSpeed: number = 0.02;\n private secondsToFadeOut: number = 15;\n\n private props = {\n content: \"\",\n alignment: defaultLabelAlignment,\n width: defaultLabelWidth,\n height: defaultLabelHeight,\n fontSize: defaultLabelFontSize,\n padding: defaultLabelPadding,\n color: defaultLabelColor,\n fontColor: defaultFontColor,\n castShadows: defaultLabelCastShadows,\n };\n\n constructor() {\n super(tooltipGeometry);\n this.tooltipMaterial = new MeshBasicMaterial({\n map: null,\n transparent: true,\n opacity: 0,\n side: FrontSide,\n });\n this.material = this.tooltipMaterial;\n this.position.set(0, 1.6, 0);\n this.visible = false;\n }\n\n private redrawText(content: string) {\n if (!this.tooltipMaterial) {\n return;\n }\n if (this.tooltipMaterial.map) {\n this.tooltipMaterial.map.dispose();\n }\n const { texture, width, height } = THREECanvasTextTexture(content, {\n bold: true,\n fontSize: this.props.fontSize * fontScale,\n paddingPx: this.props.padding,\n textColorRGB255A1: {\n r: this.props.fontColor.r * 255,\n g: this.props.fontColor.g * 255,\n b: this.props.fontColor.b * 255,\n a: 1.0,\n },\n backgroundColorRGB255A1: {\n r: this.props.color.r * 255,\n g: this.props.color.g * 255,\n b: this.props.color.b * 255,\n a: 1.0,\n },\n dimensions: {\n width: this.props.width * (100 * fontScale),\n height: this.props.height * (100 * fontScale),\n },\n alignment: this.props.alignment,\n });\n\n this.tooltipMaterial.map = texture;\n this.tooltipMaterial.map.magFilter = LinearFilter;\n this.tooltipMaterial.map.minFilter = LinearFilter;\n this.tooltipMaterial.needsUpdate = true;\n\n this.scale.x = width / (100 * fontScale);\n this.scale.y = height / (100 * fontScale);\n this.position.y = 1.6;\n }\n\n setText(text: string, temporary: boolean = false) {\n this.redrawText(text);\n this.visible = true;\n this.targetOpacity = this.visibleOpacity;\n if (temporary) {\n setTimeout(() => {\n this.hide();\n }, this.secondsToFadeOut * 1000);\n }\n }\n\n hide() {\n this.targetOpacity = 0;\n }\n\n update(camera: Camera) {\n this.lookAt(camera.position);\n const opacity = this.tooltipMaterial.opacity;\n if (opacity < this.targetOpacity) {\n this.tooltipMaterial.opacity = Math.min(\n this.tooltipMaterial.opacity + this.fadingSpeed,\n this.targetOpacity,\n );\n } else if (opacity > this.targetOpacity) {\n this.tooltipMaterial.opacity = Math.max(\n this.tooltipMaterial.opacity - this.fadingSpeed,\n this.targetOpacity,\n );\n if (opacity >= 1 && this.tooltipMaterial.transparent) {\n this.tooltipMaterial.transparent = false;\n this.tooltipMaterial.needsUpdate = true;\n } else if (opacity > 0 && opacity < 1 && !this.tooltipMaterial.transparent) {\n this.tooltipMaterial.transparent = true;\n this.tooltipMaterial.needsUpdate = true;\n }\n if (this.tooltipMaterial.opacity <= 0) {\n this.visible = false;\n }\n }\n }\n}\n", "import { Texture, LinearFilter, RGBAFormat, MeshBasicMaterial } from \"three\";\n\ntype RGBA = {\n r: number;\n g: number;\n b: number;\n a: number;\n};\n\ntype CanvasTextOptions = {\n fontSize: number;\n textColorRGB255A1: RGBA;\n backgroundColorRGB255A1?: RGBA;\n font?: string;\n bold?: boolean;\n paddingPx?: number;\n alignment?: string;\n dimensions?: {\n width: number;\n height: number;\n };\n};\n\nfunction getTextAlignOffset(textAlign: CanvasTextAlign, width: number) {\n switch (textAlign) {\n case \"center\":\n return width / 2;\n case \"right\":\n return width;\n default:\n return 0;\n }\n}\n\nfunction printAtWordWrap(\n context: CanvasRenderingContext2D,\n fullText: string,\n x: number,\n y: number,\n lineHeight: number,\n fitWidth: number,\n padding: number,\n alignment: string,\n) {\n const lines = fullText.split(\"\\n\");\n let currentLine = 0;\n for (const text of lines) {\n fitWidth = fitWidth || 0;\n\n if (fitWidth <= 0) {\n context.fillText(text, x, y + lineHeight * currentLine);\n currentLine++;\n continue;\n }\n let words = text.split(\" \");\n let lastWordIndex = 1;\n while (words.length > 0 && lastWordIndex <= words.length) {\n const str = words.slice(0, lastWordIndex).join(\" \");\n const textWidth = context.measureText(str).width;\n if (textWidth + padding * 2 > fitWidth) {\n if (lastWordIndex === 1) {\n lastWordIndex = 2;\n }\n context.fillText(\n words.slice(0, lastWordIndex - 1).join(\" \"),\n x + padding,\n y + lineHeight * currentLine + padding,\n );\n currentLine++;\n words = words.splice(lastWordIndex - 1);\n lastWordIndex = 1;\n } else {\n lastWordIndex++;\n }\n }\n if (lastWordIndex > 0 && words.length > 0) {\n const xOffset = alignment === \"center\" ? 0 : padding;\n context.fillText(words.join(\" \"), x + xOffset, y + lineHeight * currentLine + padding);\n currentLine++;\n }\n }\n}\n\nexport function CanvasText(message: string, options: CanvasTextOptions): HTMLCanvasElement {\n const fontsize = options.fontSize;\n const textColor = options.textColorRGB255A1;\n const backgroundColor = options.backgroundColorRGB255A1 || { r: 255, g: 255, b: 255, a: 1 };\n const padding = options.paddingPx || 0;\n const font = options.font || \"Arial\";\n const fontString = (options.bold ? \"bold \" : \"\") + fontsize + \"px \" + font;\n\n const canvas = document.createElement(\"canvas\");\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const ct = canvas.getContext(\"2d\")!;\n\n // calculate text alignment offset\n const textAlign = (options.alignment as CanvasTextAlign) ?? \"left\";\n\n if (options.dimensions) {\n // NOTE: setting the canvas dimensions resets the context properties, so\n // we always do it first\n canvas.width = options.dimensions.width;\n canvas.height = options.dimensions.height;\n ct.clearRect(0, 0, canvas.width, canvas.height);\n ct.font = fontString;\n ct.textAlign = textAlign;\n ct.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n ct.lineWidth = 0;\n ct.fillRect(0, 0, canvas.width, canvas.height);\n ct.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n ct.font = fontString;\n printAtWordWrap(\n ct,\n message,\n getTextAlignOffset(textAlign, canvas.width),\n fontsize,\n fontsize,\n canvas.width,\n padding,\n textAlign,\n );\n } else {\n // NOTE: setting the canvas dimensions resets the context properties, so\n // we always do it first. However, we also need to take into account the\n // font size to measure the text in the first place.\n ct.font = fontString;\n const metrics = ct.measureText(message);\n const textWidth = metrics.width;\n const textHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;\n canvas.width = textWidth + padding * 2;\n canvas.height = textHeight + padding;\n ct.clearRect(0, 0, canvas.width, canvas.height);\n ct.font = fontString;\n ct.textAlign = textAlign;\n ct.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n ct.lineWidth = 0;\n ct.fillRect(0, 0, canvas.width, canvas.height);\n ct.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n ct.font = fontString;\n ct.fillText(message, padding + getTextAlignOffset(textAlign, textWidth), textHeight);\n }\n\n return canvas;\n}\n\nexport function THREECanvasTextTexture(\n text: string,\n options: CanvasTextOptions,\n): { texture: Texture; width: number; height: number } {\n const canvas = CanvasText(text, options);\n\n const texture = new Texture(canvas);\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n texture.format = RGBAFormat;\n texture.needsUpdate = true;\n\n return { texture, width: canvas.width, height: canvas.height };\n}\n\nexport function THREECanvasTextMaterial(\n text: string,\n options: CanvasTextOptions,\n): { material: MeshBasicMaterial; width: number; height: number } {\n const { texture, width, height } = THREECanvasTextTexture(text, options);\n\n const material = new MeshBasicMaterial();\n material.map = texture;\n material.transparent = true;\n material.depthWrite = false;\n material.needsUpdate = true;\n\n return { material, width, height };\n}\n", "import { PositionAndRotation } from \"mml-web\";\nimport { Euler, Group, Quaternion, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { ease } from \"../helpers/math-helpers\";\nimport { KeyInputManager } from \"../input/KeyInputManager\";\nimport { Composer } from \"../rendering/composer\";\nimport { TimeManager } from \"../time/TimeManager\";\n\nimport { AnimationConfig, Character, CharacterDescription } from \"./Character\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\nimport { LocalController } from \"./LocalController\";\nimport { RemoteController } from \"./RemoteController\";\nimport { encodeCharacterAndCamera } from \"./url-position\";\n\nexport class CharacterManager {\n private updateLocationHash = true;\n\n public readonly headTargetOffset = new Vector3(0, 1.3, 0);\n\n private id: number = 0;\n\n public remoteCharacters: Map<number, Character> = new Map();\n public remoteCharacterControllers: Map<number, RemoteController> = new Map();\n\n private localCharacterSpawned: boolean = false;\n private localController: LocalController;\n public localCharacter: Character | null = null;\n\n private speakingCharacters: Map<number, boolean> = new Map();\n\n public readonly group: Group;\n\n constructor(\n private readonly composer: Composer,\n private readonly characterModelLoader: CharacterModelLoader,\n private readonly collisionsManager: CollisionsManager,\n private readonly cameraManager: CameraManager,\n private readonly timeManager: TimeManager,\n private readonly keyInputManager: KeyInputManager,\n private readonly clientStates: Map<number, CharacterState>,\n private readonly sendUpdate: (update: CharacterState) => void,\n private readonly animationConfig: AnimationConfig,\n private readonly characterDescription: CharacterDescription,\n ) {\n this.group = new Group();\n }\n\n public spawnLocalCharacter(\n characterDescription: CharacterDescription,\n id: number,\n spawnPosition: Vector3 = new Vector3(),\n spawnRotation: Euler = new Euler(),\n ) {\n const character = new Character(\n characterDescription,\n this.animationConfig,\n this.characterModelLoader,\n id,\n () => {\n // character loaded callback\n },\n this.cameraManager,\n this.composer,\n true,\n );\n const quaternion = new Quaternion().setFromEuler(character.rotation);\n this.sendUpdate({\n id: id,\n position: {\n x: spawnPosition.x,\n y: spawnPosition.y,\n z: spawnPosition.z,\n },\n rotation: { quaternionY: quaternion.y, quaternionW: quaternion.w },\n state: AnimationState.idle,\n });\n this.id = id;\n this.localCharacter = character;\n this.localController = new LocalController(\n this.localCharacter,\n this.id,\n this.collisionsManager,\n this.keyInputManager,\n this.cameraManager,\n this.timeManager,\n );\n this.localCharacter.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n this.localCharacter.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);\n character.tooltip?.setText(`${id}`);\n this.group.add(character);\n this.localCharacterSpawned = true;\n }\n\n public spawnRemoteCharacter(\n characterDescription: CharacterDescription,\n id: number,\n spawnPosition: Vector3 = new Vector3(),\n spawnRotation: Euler = new Euler(),\n ) {\n const character = new Character(\n characterDescription,\n this.animationConfig,\n this.characterModelLoader,\n id,\n () => {\n // character loaded callback\n },\n this.cameraManager,\n this.composer,\n false,\n );\n\n this.remoteCharacters.set(id, character);\n const remoteController = new RemoteController(character, id);\n remoteController.character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n remoteController.character.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);\n this.remoteCharacterControllers.set(id, remoteController);\n character.tooltip?.setText(`${id}`);\n this.group.add(character);\n }\n\n public getLocalCharacterPositionAndRotation(): PositionAndRotation {\n if (this.localCharacter && this.localCharacter && this.localCharacter) {\n return {\n position: this.localCharacter.position,\n rotation: this.localCharacter.rotation,\n };\n }\n return {\n position: { x: 0, y: 0, z: 0 },\n rotation: { x: 0, y: 0, z: 0 },\n };\n }\n\n public clear() {\n for (const [id, character] of this.remoteCharacters) {\n this.group.remove(character);\n this.remoteCharacters.delete(id);\n this.remoteCharacterControllers.delete(id);\n }\n if (this.localCharacter) {\n this.group.remove(this.localCharacter);\n this.localCharacter = null;\n }\n }\n\n public setSpeakingCharacter(id: number, value: boolean) {\n this.speakingCharacters.set(id, value);\n }\n\n public update() {\n if (this.localCharacter) {\n this.localCharacter.update(this.timeManager.time, this.timeManager.deltaTime);\n if (this.speakingCharacters.has(this.id)) {\n this.localCharacter.speakingIndicator?.setSpeaking(this.speakingCharacters.get(this.id)!);\n }\n\n this.localController.update();\n if (this.timeManager.frame % 2 === 0) {\n this.sendUpdate(this.localController.networkState);\n }\n\n const targetOffset = new Vector3();\n targetOffset\n .add(this.headTargetOffset)\n .applyQuaternion(this.localCharacter.quaternion)\n .add(this.localCharacter.position);\n this.cameraManager.setTarget(targetOffset);\n\n for (const [id, update] of this.clientStates) {\n if (this.remoteCharacters.has(id) && this.speakingCharacters.has(id)) {\n const character = this.remoteCharacters.get(id);\n character?.speakingIndicator?.setSpeaking(this.speakingCharacters.get(id)!);\n }\n const { position } = update;\n if (!this.remoteCharacters.has(id) && this.localCharacterSpawned === true) {\n this.spawnRemoteCharacter(\n this.characterDescription!,\n id,\n new Vector3(position.x, position.y, position.z),\n );\n }\n\n const characterController = this.remoteCharacterControllers.get(id);\n if (characterController) {\n characterController.update(update, this.timeManager.time, this.timeManager.deltaTime);\n }\n }\n\n for (const [id, character] of this.remoteCharacters) {\n if (!this.clientStates.has(id)) {\n character.speakingIndicator?.dispose();\n this.group.remove(character);\n this.remoteCharacters.delete(id);\n this.remoteCharacterControllers.delete(id);\n }\n }\n\n if (this.updateLocationHash && this.timeManager.frame % 60 === 0) {\n window.location.hash = encodeCharacterAndCamera(\n this.localCharacter,\n this.cameraManager.camera,\n );\n }\n }\n }\n}\n", "import { Euler, Line3, Matrix4, Quaternion, Ray, Raycaster, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { CollisionMeshState, CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { KeyInputManager } from \"../input/KeyInputManager\";\nimport { TimeManager } from \"../time/TimeManager\";\n\nimport { Character } from \"./Character\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\n\nconst downVector = new Vector3(0, -1, 0);\n\nconst airResistance = 0.5;\nconst groundResistance = 0.99999999;\nconst airControlModifier = 0.05;\nconst groundWalkControl = 0.75;\nconst groundRunControl = 1.0;\nconst baseControl = 200;\nconst collisionDetectionSteps = 15;\nconst minimumSurfaceAngle = 0.9;\n\nexport class LocalController {\n public capsuleInfo = {\n radius: 0.4,\n segment: new Line3(new Vector3(), new Vector3(0, 1.05, 0)),\n };\n\n private gravity: number = -42;\n private jumpForce: number = 20;\n private coyoteTimeThreshold: number = 70;\n\n private coyoteTime: boolean = false;\n private canJump: boolean = true;\n private characterOnGround: boolean = false;\n private characterWasOnGround: boolean = false;\n private characterAirborneSince: number = 0;\n private currentHeight: number = 0;\n private currentSurfaceAngle = new Vector3();\n\n private characterVelocity: Vector3 = new Vector3();\n private vectorUp: Vector3 = new Vector3(0, 1, 0);\n private vectorDown: Vector3 = new Vector3(0, -1, 0);\n\n private rotationOffset: number = 0;\n private azimuthalAngle: number = 0;\n\n private tempMatrix: Matrix4 = new Matrix4();\n private tempSegment: Line3 = new Line3();\n private tempQuaternion: Quaternion = new Quaternion();\n private tempEuler: Euler = new Euler();\n private tempVector: Vector3 = new Vector3();\n private tempVector2: Vector3 = new Vector3();\n private tempVector3: Vector3 = new Vector3();\n private rayCaster: Raycaster = new Raycaster();\n\n private surfaceTempQuaternion = new Quaternion();\n private surfaceTempQuaternion2 = new Quaternion();\n private surfaceTempVector1 = new Vector3();\n private surfaceTempVector2 = new Vector3();\n private surfaceTempVector3 = new Vector3();\n private surfaceTempVector4 = new Vector3();\n private surfaceTempVector5 = new Vector3();\n private surfaceTempRay = new Ray();\n private lastFrameSurfaceState:\n | [\n CollisionMeshState,\n {\n lastMatrix: Matrix4;\n },\n ]\n | null = null;\n\n private forward: boolean;\n private backward: boolean;\n private left: boolean;\n private right: boolean;\n private run: boolean;\n private jump: boolean;\n private anyDirection: boolean;\n private conflictingDirections: boolean;\n\n public networkState: CharacterState;\n\n constructor(\n private readonly character: Character,\n private readonly id: number,\n private readonly collisionsManager: CollisionsManager,\n private readonly keyInputManager: KeyInputManager,\n private readonly cameraManager: CameraManager,\n private readonly timeManager: TimeManager,\n ) {\n this.networkState = {\n id: this.id,\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: AnimationState.idle,\n };\n }\n\n private updateControllerState(): void {\n this.forward = this.keyInputManager.forward;\n this.backward = this.keyInputManager.backward;\n this.left = this.keyInputManager.left;\n this.right = this.keyInputManager.right;\n this.run = this.keyInputManager.run;\n this.jump = this.keyInputManager.jump;\n this.anyDirection = this.keyInputManager.anyDirection;\n this.conflictingDirections = this.keyInputManager.conflictingDirection;\n }\n\n public update(): void {\n this.updateControllerState();\n\n this.rayCaster.set(this.character.position, this.vectorDown);\n const firstRaycastHit = this.collisionsManager.raycastFirst(this.rayCaster.ray);\n if (firstRaycastHit !== null) {\n this.currentHeight = firstRaycastHit[0];\n this.currentSurfaceAngle.copy(firstRaycastHit[1]);\n }\n\n if (this.anyDirection || !this.characterOnGround) {\n const targetAnimation = this.getTargetAnimation();\n this.character.updateAnimation(targetAnimation);\n } else {\n this.character.updateAnimation(AnimationState.idle);\n }\n\n if (this.anyDirection) {\n this.updateRotation();\n }\n\n for (let i = 0; i < collisionDetectionSteps; i++) {\n this.updatePosition(\n this.timeManager.deltaTime,\n this.timeManager.deltaTime / collisionDetectionSteps,\n i,\n );\n }\n\n if (this.character.position.y < 0) {\n this.resetPosition();\n }\n this.updateNetworkState();\n }\n\n private getTargetAnimation(): AnimationState {\n if (!this.character) return AnimationState.idle;\n\n const jumpHeight = this.characterVelocity.y > 0 ? 0.2 : 1.8;\n if (this.currentHeight > jumpHeight && !this.characterOnGround) {\n return AnimationState.air;\n }\n if (this.conflictingDirections) {\n return AnimationState.idle;\n }\n return this.run && this.anyDirection\n ? AnimationState.running\n : this.anyDirection\n ? AnimationState.walking\n : AnimationState.idle;\n }\n\n private updateRotationOffset(): void {\n if (this.conflictingDirections) return;\n if (this.forward) {\n this.rotationOffset = Math.PI;\n if (this.left) this.rotationOffset = Math.PI + Math.PI / 4;\n if (this.right) this.rotationOffset = Math.PI - Math.PI / 4;\n } else if (this.backward) {\n this.rotationOffset = Math.PI * 2;\n if (this.left) this.rotationOffset = -Math.PI * 2 - Math.PI / 4;\n if (this.right) this.rotationOffset = Math.PI * 2 + Math.PI / 4;\n } else if (this.left) {\n this.rotationOffset = Math.PI * -0.5;\n } else if (this.right) {\n this.rotationOffset = Math.PI * 0.5;\n }\n }\n\n private updateAzimuthalAngle(): void {\n const camToModelDistance = this.cameraManager.camera.position.distanceTo(\n this.character.position,\n );\n const isCameraFirstPerson = camToModelDistance < 2;\n if (isCameraFirstPerson) {\n const cameraForward = this.tempVector\n .set(0, 0, 1)\n .applyQuaternion(this.cameraManager.camera.quaternion);\n this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);\n } else {\n this.azimuthalAngle = Math.atan2(\n this.cameraManager.camera.position.x - this.character.position.x,\n this.cameraManager.camera.position.z - this.character.position.z,\n );\n }\n }\n\n private computeAngularDifference(rotationQuaternion: Quaternion): number {\n return 2 * Math.acos(Math.abs(this.character.quaternion.dot(rotationQuaternion)));\n }\n\n private updateRotation(): void {\n this.updateRotationOffset();\n this.updateAzimuthalAngle();\n const rotationQuaternion = this.tempQuaternion.setFromAxisAngle(\n this.vectorUp,\n this.azimuthalAngle + this.rotationOffset,\n );\n const angularDifference = this.computeAngularDifference(rotationQuaternion);\n const desiredTime = 0.07;\n const angularSpeed = angularDifference / desiredTime;\n const frameRotation = angularSpeed * this.timeManager.deltaTime;\n this.character.quaternion.rotateTowards(rotationQuaternion, frameRotation);\n }\n\n private applyControls(deltaTime: number) {\n const resistance = this.characterOnGround ? groundResistance : airResistance;\n\n // Dampen the velocity based on the resistance\n const speedFactor = Math.pow(1 - resistance, deltaTime);\n this.characterVelocity.multiplyScalar(speedFactor);\n\n const acceleration = this.tempVector.set(0, 0, 0);\n\n if (this.characterOnGround) {\n if (!this.jump) {\n this.canJump = true;\n }\n\n if (this.jump && this.canJump) {\n acceleration.y += this.jumpForce / deltaTime;\n this.canJump = false;\n } else {\n if (this.currentSurfaceAngle.y < minimumSurfaceAngle) {\n acceleration.y += this.gravity;\n }\n }\n } else if (this.jump && this.coyoteTime) {\n acceleration.y += this.jumpForce / deltaTime;\n this.canJump = false;\n } else {\n acceleration.y += this.gravity;\n this.canJump = false;\n }\n\n const control =\n (this.characterOnGround\n ? this.run\n ? groundRunControl\n : groundWalkControl\n : airControlModifier) * baseControl;\n\n const controlAcceleration = this.tempVector2.set(0, 0, 0);\n\n if (!this.conflictingDirections) {\n if (this.forward) {\n const forward = this.tempVector3\n .set(0, 0, -1)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle);\n controlAcceleration.add(forward);\n }\n\n if (this.backward) {\n const backward = this.tempVector3\n .set(0, 0, 1)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle);\n controlAcceleration.add(backward);\n }\n\n if (this.left) {\n const left = this.tempVector3\n .set(-1, 0, 0)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle);\n controlAcceleration.add(left);\n }\n\n if (this.right) {\n const right = this.tempVector3\n .set(1, 0, 0)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle);\n controlAcceleration.add(right);\n }\n }\n if (controlAcceleration.length() > 0) {\n controlAcceleration.normalize();\n controlAcceleration.multiplyScalar(control);\n }\n acceleration.add(controlAcceleration);\n this.characterVelocity.addScaledVector(acceleration, deltaTime);\n\n this.character.position.addScaledVector(this.characterVelocity, deltaTime);\n }\n\n private updatePosition(deltaTime: number, stepDeltaTime: number, iter: number): void {\n this.applyControls(stepDeltaTime);\n\n if (iter === 0) {\n const lastMovement = this.getMovementFromSurfaces(this.character.position, deltaTime);\n if (lastMovement) {\n this.character.position.add(lastMovement.position);\n const asQuaternion = this.tempQuaternion.setFromEuler(this.character.rotation);\n const lastMovementEuler = this.tempEuler.setFromQuaternion(lastMovement.rotation);\n lastMovementEuler.x = 0;\n lastMovementEuler.z = 0;\n lastMovement.rotation.setFromEuler(lastMovementEuler);\n asQuaternion.multiply(lastMovement.rotation);\n this.character.rotation.setFromQuaternion(asQuaternion);\n }\n }\n this.character.updateMatrixWorld();\n\n const avatarSegment = this.tempSegment;\n avatarSegment.copy(this.capsuleInfo.segment!);\n avatarSegment.start.applyMatrix4(this.character.matrixWorld).applyMatrix4(this.tempMatrix);\n avatarSegment.end.applyMatrix4(this.character.matrixWorld).applyMatrix4(this.tempMatrix);\n\n const positionBeforeCollisions = this.tempVector.copy(avatarSegment.start);\n this.collisionsManager.applyColliders(avatarSegment, this.capsuleInfo.radius!);\n this.character.position.copy(avatarSegment.start);\n const deltaCollisionPosition = avatarSegment.start.sub(positionBeforeCollisions);\n\n this.characterOnGround = deltaCollisionPosition.y > 0;\n\n if (this.characterWasOnGround && !this.characterOnGround) {\n this.characterAirborneSince = Date.now();\n }\n\n this.coyoteTime =\n this.characterVelocity.y < 0 &&\n !this.characterOnGround &&\n Date.now() - this.characterAirborneSince < this.coyoteTimeThreshold;\n\n this.characterWasOnGround = this.characterOnGround;\n }\n\n public getMovementFromSurfaces(userPosition: Vector3, deltaTime: number) {\n let lastMovement: { rotation: Quaternion; position: Vector3 } | null = null;\n\n // If we have a last frame state, we can calculate the movement of the mesh to apply it to the user\n if (this.lastFrameSurfaceState !== null) {\n const meshState = this.lastFrameSurfaceState[0];\n\n // Extract the matrix from the current frame and the last frame\n const currentFrameMatrix = meshState.matrix;\n const lastFrameMatrix = this.lastFrameSurfaceState[1].lastMatrix;\n\n if (lastFrameMatrix.equals(currentFrameMatrix)) {\n // No movement from this mesh - do nothing\n } else {\n // The mesh has moved since the last frame - calculate the movement\n\n // Get the position of the mesh in the last frame\n const lastMeshPosition = this.surfaceTempVector1;\n const lastMeshRotation = this.surfaceTempQuaternion;\n lastFrameMatrix.decompose(lastMeshPosition, lastMeshRotation, this.surfaceTempVector3);\n\n // Get the position of the mesh in the current frame\n const currentMeshPosition = this.surfaceTempVector2;\n const currentMeshRotation = this.surfaceTempQuaternion2;\n currentFrameMatrix.decompose(\n currentMeshPosition,\n currentMeshRotation,\n this.surfaceTempVector3,\n );\n\n // Calculate the difference between the new position and the old position to determine the movement due to translation of position\n const meshTranslationDelta = this.surfaceTempVector5\n .copy(currentMeshPosition)\n .sub(lastMeshPosition);\n\n // Calculate the relative position of the user to the mesh in the last frame\n const lastFrameRelativeUserPosition = this.surfaceTempVector3\n .copy(userPosition)\n .sub(lastMeshPosition);\n\n // Calculate the relative quaternion of the mesh in the last frame to the mesh in the current frame\n const meshRotationDelta = lastMeshRotation.invert().multiply(currentMeshRotation);\n\n // Apply the relative quaternion to the relative user position to determine the new position of the user given just the rotation\n const translationDueToRotation = this.surfaceTempVector4\n .copy(lastFrameRelativeUserPosition)\n .applyQuaternion(meshRotationDelta)\n .sub(lastFrameRelativeUserPosition);\n\n // Combine the mesh translation delta and the rotation translation delta to determine the total movement of the user\n const translationAndRotationPositionDelta = this.surfaceTempVector1\n .copy(meshTranslationDelta)\n .add(translationDueToRotation);\n\n lastMovement = {\n position: translationAndRotationPositionDelta,\n rotation: meshRotationDelta,\n };\n lastFrameMatrix.copy(currentFrameMatrix);\n }\n }\n\n const newPosition = this.surfaceTempVector3.copy(userPosition);\n if (lastMovement) {\n newPosition.add(lastMovement.position);\n }\n newPosition.setY(newPosition.y + 0.05);\n\n // Raycast down from the new position to see if there is a surface below the user which will be tracked in the next frame\n const ray = this.surfaceTempRay.set(newPosition, downVector);\n const hit = this.collisionsManager.raycastFirst(ray);\n if (hit && hit[0] < 0.8) {\n // There is a surface below the user\n const currentCollisionMeshState = hit[2];\n this.lastFrameSurfaceState = [\n currentCollisionMeshState,\n { lastMatrix: currentCollisionMeshState.matrix.clone() },\n ];\n } else {\n if (this.lastFrameSurfaceState !== null && lastMovement) {\n // Apply the last movement to the user's velocity\n this.characterVelocity.add(\n lastMovement.position.clone().divideScalar(deltaTime), // The position delta is the result of one tick which is deltaTime seconds, so we need to divide by deltaTime to get the velocity per second\n );\n }\n this.lastFrameSurfaceState = null;\n }\n return lastMovement;\n }\n\n private updateNetworkState(): void {\n const characterQuaternion = this.character.getWorldQuaternion(this.tempQuaternion);\n this.networkState = {\n id: this.id,\n position: {\n x: this.character.position.x,\n y: this.character.position.y,\n z: this.character.position.z,\n },\n rotation: { quaternionY: characterQuaternion.y, quaternionW: characterQuaternion.w },\n state: this.character.getCurrentAnimation(),\n };\n }\n\n private resetPosition(): void {\n this.characterVelocity.y = 0;\n this.character.position.y = 3;\n this.characterOnGround = false;\n }\n}\n", "import { Quaternion, Vector3 } from \"three\";\n\nimport { Character } from \"./Character\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\n\nexport class RemoteController {\n public currentAnimation: AnimationState = AnimationState.idle;\n\n public networkState: CharacterState;\n\n constructor(\n public readonly character: Character,\n public readonly id: number,\n ) {\n this.networkState = {\n id: this.id,\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: this.currentAnimation as AnimationState,\n };\n }\n\n public update(clientUpdate: CharacterState, time: number, deltaTime: number): void {\n if (!this.character) return;\n this.updateFromNetwork(clientUpdate);\n this.character.update(time, deltaTime);\n }\n\n private updateFromNetwork(clientUpdate: CharacterState): void {\n const { position, rotation, state } = clientUpdate;\n this.character.position.lerp(new Vector3(position.x, position.y, position.z), 0.15);\n const rotationQuaternion = new Quaternion(0, rotation.quaternionY, 0, rotation.quaternionW);\n this.character.quaternion.slerp(rotationQuaternion, 0.6);\n if (state !== this.currentAnimation) {\n this.currentAnimation = state;\n this.character.updateAnimation(state);\n }\n }\n}\n", "import { Object3D, Quaternion, Vector3 } from \"three\";\n\nimport { toArray } from \"../helpers/math-helpers\";\n\nexport function encodeCharacterAndCamera(character: Object3D, camera: Object3D): string {\n return [\n ...toArray(character.position),\n ...toArray(character.quaternion),\n ...toArray(camera.position),\n ...toArray(camera.quaternion),\n ].join(\",\");\n}\n\nexport function decodeCharacterAndCamera(hash: string): {\n character: { position: Vector3; quaternion: Quaternion };\n camera: { position: Vector3; quaternion: Quaternion };\n} {\n const values = hash.split(\",\").map(Number);\n return {\n character: {\n position: new Vector3(values[0], values[1], values[2]),\n quaternion: new Quaternion(values[3], values[4], values[5], values[6]),\n },\n camera: {\n position: new Vector3(values[7], values[8], values[9]),\n quaternion: new Quaternion(values[10], values[11], values[12], values[13]),\n },\n };\n}\n", "import { AnimationClip, LoadingManager, Object3D } from \"three\";\nimport { GLTF, GLTFLoader as ThreeGLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\n\nclass CachedGLTFLoader extends ThreeGLTFLoader {\n private blobCache: Map<string, string>;\n\n constructor(\n manager?: LoadingManager,\n private debug: boolean = false,\n ) {\n super(manager);\n this.blobCache = new Map();\n }\n\n setBlobUrl(originalUrl: string, blobUrl: string) {\n this.blobCache.set(originalUrl, blobUrl);\n }\n\n getBlobUrl(originalUrl: string): string | undefined {\n return this.blobCache.get(originalUrl);\n }\n\n load(\n url: string,\n onLoad: (gltf: GLTF) => void,\n onProgress?: ((event: ProgressEvent<EventTarget>) => void) | undefined,\n onError?: ((event: ErrorEvent) => void) | undefined,\n ): void {\n const blobUrl = this.getBlobUrl(url);\n if (blobUrl) {\n if (this.debug === true) {\n console.log(`Loading cached ${url.split(\"/\").pop()}`);\n }\n super.load(blobUrl, onLoad, onProgress, onError);\n } else {\n super.load(url, onLoad, onProgress, onError);\n }\n }\n}\n\nclass LRUCache<K, V> {\n private maxSize: number;\n private cache: Map<K, V>;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n this.cache = new Map();\n }\n\n get(key: K): V | undefined {\n const item = this.cache.get(key);\n if (item) {\n this.cache.delete(key);\n this.cache.set(key, item);\n }\n return item;\n }\n\n set(key: K, value: V): void {\n if (this.cache.size >= this.maxSize) {\n const oldestKey = this.cache.keys().next().value;\n this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n}\n\ninterface CachedModel {\n blob: Blob;\n originalExtension: string;\n}\n\nexport class CharacterModelLoader {\n private readonly loadingManager: LoadingManager;\n private readonly gltfLoader: CachedGLTFLoader;\n private modelCache: LRUCache<string, CachedModel>;\n private ongoingLoads: Map<string, Promise<CachedModel>> = new Map();\n\n constructor(\n maxCacheSize: number = 100,\n private debug: boolean = false,\n ) {\n this.loadingManager = new LoadingManager();\n this.gltfLoader = new CachedGLTFLoader(this.loadingManager, this.debug);\n this.modelCache = new LRUCache(maxCacheSize);\n }\n\n async load(fileUrl: string, fileType: \"model\"): Promise<Object3D | undefined>;\n async load(fileUrl: string, fileType: \"animation\"): Promise<AnimationClip | undefined>;\n async load(\n fileUrl: string,\n fileType: \"model\" | \"animation\",\n ): Promise<Object3D | AnimationClip | undefined> {\n const cachedModel = this.modelCache.get(fileUrl);\n\n if (cachedModel) {\n const blobURL = URL.createObjectURL(cachedModel.blob);\n this.gltfLoader.setBlobUrl(fileUrl, blobURL);\n return this.loadFromUrl(fileUrl, fileType, cachedModel.originalExtension);\n } else {\n if (this.debug === true) {\n console.log(`Loading ${fileUrl} from server`);\n }\n const ongoingLoad = this.ongoingLoads.get(fileUrl);\n if (ongoingLoad)\n return ongoingLoad.then((loadedModel) => {\n const blobURL = URL.createObjectURL(loadedModel.blob);\n return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);\n });\n\n const loadPromise: Promise<CachedModel> = fetch(fileUrl)\n .then((response) => response.blob())\n .then((blob) => {\n const originalExtension = fileUrl.split(\".\").pop() || \"\";\n const cached = { blob, originalExtension };\n this.modelCache.set(fileUrl, cached);\n this.ongoingLoads.delete(fileUrl);\n return cached;\n });\n\n this.ongoingLoads.set(fileUrl, loadPromise);\n return loadPromise.then((loadedModel) => {\n const blobURL = URL.createObjectURL(loadedModel.blob);\n return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);\n });\n }\n }\n\n private async loadFromUrl(\n url: string,\n fileType: \"model\" | \"animation\",\n extension: string,\n ): Promise<Object3D | AnimationClip | undefined> {\n if ([\"gltf\", \"glb\"].includes(extension)) {\n return new Promise((resolve, reject) => {\n this.gltfLoader.load(\n url,\n (object: GLTF) => {\n if (fileType === \"model\") {\n resolve(object.scene as Object3D);\n } else if (fileType === \"animation\") {\n resolve(object.animations[0] as AnimationClip);\n } else {\n const error = `Trying to load unknown ${fileType} type of element from file ${url}`;\n console.error(error);\n reject(error);\n }\n },\n undefined,\n (error) => {\n console.error(`Error loading GL(B|TF) from ${url}: ${error}`);\n reject(error);\n },\n );\n });\n } else {\n console.error(`Error: can't recognize ${url} extension: ${extension}`);\n }\n }\n}\n", "import { EventHandlerCollection } from \"./EventHandlerCollection\";\nimport { VirtualJoystick } from \"./VirtualJoystick\";\n\nenum Key {\n W = \"w\",\n A = \"a\",\n S = \"s\",\n D = \"d\",\n SHIFT = \"shift\",\n SPACE = \" \",\n}\n\nexport class KeyInputManager {\n private keys = new Map<string, boolean>();\n private eventHandlerCollection = new EventHandlerCollection();\n private directionJoystick: VirtualJoystick | null = null;\n\n constructor(private shouldCaptureKeyPress: () => boolean = () => true) {\n this.eventHandlerCollection.add(document, \"keydown\", this.onKeyDown.bind(this));\n this.eventHandlerCollection.add(document, \"keyup\", this.onKeyUp.bind(this));\n this.eventHandlerCollection.add(window, \"blur\", this.handleUnfocus.bind(this));\n this.directionJoystick = new VirtualJoystick({\n radius: 70,\n inner_radius: 20,\n x: 70,\n y: 0,\n mouse_support: false,\n });\n }\n\n private handleUnfocus(_event: FocusEvent): void {\n this.keys.clear();\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n if (this.shouldCaptureKeyPress()) {\n if (event.key.length === 2 && event.key[0] === \"F\") {\n // Ignore all Function keys\n return;\n }\n if (event.metaKey) {\n // Ignore all meta keys (e.g. Alt, Cmd)\n return;\n }\n this.keys.set(event.key.toLowerCase(), true);\n event.preventDefault();\n }\n }\n\n private onKeyUp(event: KeyboardEvent): void {\n this.keys.set(event.key.toLowerCase(), false);\n }\n\n public isKeyPressed(key: string): boolean {\n return this.keys.get(key) || false;\n }\n\n public isMovementKeyPressed(): boolean {\n return (\n [Key.W, Key.A, Key.S, Key.D].some((key) => this.isKeyPressed(key)) ||\n this.directionJoystick!.hasDirection\n );\n }\n\n get forward(): boolean {\n return this.isKeyPressed(Key.W) || this.directionJoystick!.up;\n }\n\n get backward(): boolean {\n return this.isKeyPressed(Key.S) || this.directionJoystick!.down;\n }\n\n get left(): boolean {\n return this.isKeyPressed(Key.A) || this.directionJoystick!.left;\n }\n\n get right(): boolean {\n return this.isKeyPressed(Key.D) || this.directionJoystick!.right;\n }\n\n get run(): boolean {\n return this.isKeyPressed(Key.SHIFT);\n }\n\n get jump(): boolean {\n return this.isKeyPressed(Key.SPACE);\n }\n\n get anyDirection(): boolean {\n return this.isMovementKeyPressed();\n }\n\n get conflictingDirection(): boolean {\n return (\n (this.isKeyPressed(Key.W) && this.isKeyPressed(Key.S)) ||\n (this.isKeyPressed(Key.A) && this.isKeyPressed(Key.D))\n );\n }\n\n public dispose() {\n this.eventHandlerCollection.clear();\n }\n}\n", "import {\n IMMLScene,\n Interaction,\n InteractionListener,\n InteractionManager,\n MElement,\n MMLClickTrigger,\n PositionAndRotation,\n PromptManager,\n PromptProps,\n ChatProbe,\n LoadingProgressManager,\n} from \"mml-web\";\nimport { AudioListener, Group, Object3D, PerspectiveCamera, Scene, WebGLRenderer } from \"three\";\n\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\n\nexport class MMLCompositionScene {\n public group: Group;\n\n public readonly mmlScene: IMMLScene;\n private readonly promptManager: PromptManager;\n private readonly interactionManager: InteractionManager;\n private readonly interactionListener: InteractionListener;\n private readonly chatProbes = new Set<ChatProbe>();\n private readonly clickTrigger: MMLClickTrigger;\n private readonly loadingProgressManager: LoadingProgressManager;\n\n constructor(\n targetElement: HTMLElement,\n private renderer: WebGLRenderer,\n private scene: Scene,\n private camera: PerspectiveCamera,\n private audioListener: AudioListener,\n private collisionsManager: CollisionsManager,\n private getUserPositionAndRotation: () => PositionAndRotation,\n ) {\n this.group = new Group();\n this.promptManager = PromptManager.init(targetElement);\n\n const { interactionListener, interactionManager } = InteractionManager.init(\n targetElement,\n this.camera,\n this.scene,\n );\n this.interactionManager = interactionManager;\n this.interactionListener = interactionListener;\n this.loadingProgressManager = new LoadingProgressManager();\n\n this.mmlScene = {\n getAudioListener: () => this.audioListener,\n getRenderer: () => this.renderer,\n getThreeScene: () => this.scene,\n getRootContainer: () => this.group,\n getCamera: () => this.camera,\n addCollider: (object: Object3D, mElement: MElement) => {\n this.collisionsManager.addMeshesGroup(object as Group, mElement);\n },\n updateCollider: (object: Object3D) => {\n this.collisionsManager.updateMeshesGroup(object as Group);\n },\n removeCollider: (object: Object3D) => {\n this.collisionsManager.removeMeshesGroup(object as Group);\n },\n getUserPositionAndRotation: this.getUserPositionAndRotation,\n addInteraction: (interaction: Interaction) => {\n this.interactionListener.addInteraction(interaction);\n },\n updateInteraction: (interaction: Interaction) => {\n this.interactionListener.updateInteraction(interaction);\n },\n removeInteraction: (interaction: Interaction) => {\n this.interactionListener.removeInteraction(interaction);\n },\n addChatProbe: (chatProbe: ChatProbe) => {\n this.chatProbes.add(chatProbe);\n },\n updateChatProbe: () => {\n // no-op\n },\n removeChatProbe: (chatProbe: ChatProbe) => {\n this.chatProbes.delete(chatProbe);\n },\n prompt: (promptProps: PromptProps, callback: (message: string | null) => void) => {\n this.promptManager.prompt(promptProps, callback);\n },\n getLoadingProgressManager: () => {\n return this.loadingProgressManager;\n },\n };\n\n this.clickTrigger = MMLClickTrigger.init(targetElement, this.mmlScene as IMMLScene);\n }\n\n onChatMessage(message: string) {\n for (const chatProbe of this.chatProbes) {\n chatProbe.trigger(message);\n }\n }\n\n dispose() {\n this.promptManager.dispose();\n this.clickTrigger.dispose();\n this.interactionManager.dispose();\n }\n}\n", "import * as EssentialsPlugin from \"@tweakpane/plugin-essentials\";\nimport {\n BloomEffect,\n EffectComposer,\n EffectPass,\n NormalPass,\n SSAOEffect,\n ToneMappingEffect,\n} from \"postprocessing\";\nimport { Scene, WebGLRenderer } from \"three\";\nimport { FolderApi, Pane } from \"tweakpane\";\n\nimport { BrightnessContrastSaturation } from \"../rendering/post-effects/bright-contrast-sat\";\nimport { GaussGrainEffect } from \"../rendering/post-effects/gauss-grain\";\nimport { Sun } from \"../sun/Sun\";\nimport { TimeManager } from \"../time/TimeManager\";\n\nimport { BrightnessContrastSaturationFolder } from \"./blades/bcsFolder\";\nimport { CharacterFolder } from \"./blades/characterFolder\";\nimport { EnvironmentFolder } from \"./blades/environmentFolder\";\nimport { PostExtrasFolder } from \"./blades/postExtrasFolder\";\nimport { RendererFolder, rendererValues } from \"./blades/rendererFolder\";\nimport { RendererStatsFolder } from \"./blades/rendererStatsFolder\";\nimport { SSAOFolder } from \"./blades/ssaoFolder\";\nimport { ToneMappingFolder } from \"./blades/toneMappingFolder\";\nimport { setTweakpaneActive } from \"./tweakPaneActivity\";\nimport { tweakPaneStyle } from \"./tweakPaneStyle\";\n\nexport class TweakPane {\n private gui: Pane;\n\n private renderStatsFolder: RendererStatsFolder;\n private rendererFolder: RendererFolder;\n private toneMappingFolder: ToneMappingFolder;\n private ssaoFolder: SSAOFolder;\n private bcsFolder: BrightnessContrastSaturationFolder;\n private postExtrasFolder: PostExtrasFolder;\n // @ts-ignore\n private character: CharacterFolder;\n private environment: EnvironmentFolder;\n\n private export: FolderApi;\n\n private saveVisibilityInLocalStorage: boolean = true;\n public guiVisible: boolean = false;\n\n constructor(\n private renderer: WebGLRenderer,\n private scene: Scene,\n private composer: EffectComposer,\n ) {\n const appWrapper = document.getElementById(\"app\")!;\n const tweakPaneWrapper = document.createElement(\"div\");\n tweakPaneWrapper.id = \"tweakpane-panel\";\n appWrapper.appendChild(tweakPaneWrapper);\n\n this.gui = new Pane({ container: tweakPaneWrapper! });\n this.gui.registerPlugin(EssentialsPlugin);\n\n if (this.saveVisibilityInLocalStorage) {\n const localStorageGuiVisible = localStorage.getItem(\"guiVisible\");\n if (localStorageGuiVisible !== null) {\n if (localStorageGuiVisible === \"true\") {\n this.guiVisible = true;\n } else if (localStorageGuiVisible === \"false\") {\n this.guiVisible = false;\n }\n }\n }\n\n const styleElement = document.createElement(\"style\");\n styleElement.type = \"text/css\";\n styleElement.appendChild(document.createTextNode(tweakPaneStyle));\n document.head.appendChild(styleElement);\n\n this.renderStatsFolder = new RendererStatsFolder(this.gui, true);\n this.rendererFolder = new RendererFolder(this.gui, false);\n this.toneMappingFolder = new ToneMappingFolder(this.gui, false);\n this.ssaoFolder = new SSAOFolder(this.gui, false);\n this.bcsFolder = new BrightnessContrastSaturationFolder(this.gui, false);\n this.postExtrasFolder = new PostExtrasFolder(this.gui, false);\n this.character = new CharacterFolder(this.gui, false);\n this.environment = new EnvironmentFolder(this.gui, false);\n\n this.toneMappingFolder.folder.hidden = rendererValues.toneMapping === 5 ? false : true;\n\n this.export = this.gui.addFolder({ title: \"import / export\", expanded: false });\n\n window.addEventListener(\"keydown\", this.processKey.bind(this));\n this.setupRenderPane = this.setupRenderPane.bind(this);\n this.setupGUIListeners.bind(this)();\n }\n\n private setupGUIListeners(): void {\n const gui = this.gui as any;\n const paneElement: HTMLElement = gui.containerElem_;\n paneElement.style.right = this.guiVisible ? \"0px\" : \"-450px\";\n this.gui.element.addEventListener(\"mouseenter\", () => setTweakpaneActive(true));\n this.gui.element.addEventListener(\"mousedown\", () => setTweakpaneActive(true));\n this.gui.element.addEventListener(\"mouseup\", () => setTweakpaneActive(false));\n this.gui.element.addEventListener(\"mouseleave\", () => setTweakpaneActive(false));\n }\n\n private processKey(e: KeyboardEvent): void {\n if (e.key === \"p\") this.toggleGUI();\n }\n\n public setupRenderPane(\n composer: EffectComposer,\n normalPass: NormalPass,\n ppssaoEffect: SSAOEffect,\n ppssaoPass: EffectPass,\n n8aopass: any,\n toneMappingEffect: ToneMappingEffect,\n toneMappingPass: EffectPass,\n brightnessContrastSaturation: typeof BrightnessContrastSaturation,\n bloomEffect: BloomEffect,\n gaussGrainEffect: typeof GaussGrainEffect,\n hasLighting: boolean,\n sun: Sun | null,\n setHDR: () => void,\n setAmbientLight: () => void,\n setFog: () => void,\n ): void {\n // RenderOptions\n this.rendererFolder.setupChangeEvent(\n this.scene,\n this.renderer,\n this.toneMappingFolder.folder,\n toneMappingPass,\n );\n\n this.toneMappingFolder.setupChangeEvent(toneMappingEffect);\n this.ssaoFolder.setupChangeEvent(composer, normalPass, ppssaoEffect, ppssaoPass, n8aopass);\n this.bcsFolder.setupChangeEvent(brightnessContrastSaturation);\n this.postExtrasFolder.setupChangeEvent(bloomEffect, gaussGrainEffect);\n this.environment.setupChangeEvent(setHDR, setAmbientLight, setFog, sun);\n this.environment.folder.hidden = hasLighting === false || sun === null;\n\n const exportButton = this.export.addButton({ title: \"export\" });\n exportButton.on(\"click\", () => {\n this.downloadSettingsAsJSON(this.gui.exportState());\n });\n const importButton = this.export.addButton({ title: \"import\" });\n importButton.on(\"click\", () => {\n this.importSettingsFromJSON((settings) => {\n this.gui.importState(settings);\n });\n });\n }\n\n public updateStats(timeManager: TimeManager): void {\n this.renderStatsFolder.update(this.renderer, this.composer, timeManager);\n }\n\n private formatDateForFilename(): string {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\"); // Months are 0-11\n const day = String(date.getDate()).padStart(2, \"0\");\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${year}-${month}-${day} ${hours}-${minutes}-${seconds}`;\n }\n\n private downloadSettingsAsJSON(settings: any): void {\n const jsonString = JSON.stringify(settings, null, 2);\n const blob = new Blob([jsonString], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.download = `settings ${this.formatDateForFilename()}.json`;\n a.href = url;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n private importSettingsFromJSON(callback: (settings: any) => void): void {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \".json\";\n input.addEventListener(\"change\", (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = (loadEvent) => {\n try {\n const settings = JSON.parse(loadEvent.target?.result as string);\n callback(settings);\n } catch (err) {\n console.error(\"Error parsing JSON:\", err);\n }\n };\n reader.readAsText(file);\n }\n });\n input.click();\n }\n\n private toggleGUI(): void {\n this.guiVisible = !this.guiVisible;\n const gui = this.gui as any;\n const paneElement: HTMLElement = gui.containerElem_;\n paneElement.style.right = this.guiVisible ? \"0px\" : \"-450px\";\n if (this.saveVisibilityInLocalStorage) {\n localStorage.setItem(\"guiVisible\", this.guiVisible === true ? \"true\" : \"false\");\n }\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { BrightnessContrastSaturation } from \"../../rendering/post-effects/bright-contrast-sat\";\n\nexport const bcsValues = {\n brightness: 0,\n contrast: 1,\n saturation: 1,\n};\n\nconst bcsOptions = {\n brightness: {\n amount: { min: -1.0, max: 1.0, step: 0.01 },\n },\n contrast: {\n amount: { min: 0.0, max: 2.0, step: 0.01 },\n },\n saturation: {\n amount: { min: 0.0, max: 2.0, step: 0.01 },\n },\n};\n\nexport class BrightnessContrastSaturationFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"brightness / contrast / sat\",\n expanded: expand,\n });\n this.folder.addBinding(bcsValues, \"brightness\", bcsOptions.brightness.amount);\n this.folder.addBinding(bcsValues, \"contrast\", bcsOptions.contrast.amount);\n this.folder.addBinding(bcsValues, \"saturation\", bcsOptions.saturation.amount);\n }\n\n public setupChangeEvent(brightnessContrastSaturation: typeof BrightnessContrastSaturation): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"brightness\":\n brightnessContrastSaturation.uniforms.brightness.value = e.value;\n break;\n case \"contrast\":\n brightnessContrastSaturation.uniforms.contrast.value = e.value;\n break;\n case \"saturation\":\n brightnessContrastSaturation.uniforms.saturation.value = e.value;\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, ButtonApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { Sun } from \"../../sun/Sun\";\n\nexport const sunValues = {\n sunPosition: {\n sunAzimuthalAngle: 214.5,\n sunPolarAngle: -41.5,\n },\n sunIntensity: 1,\n sunColor: { r: 1.0, g: 1.0, b: 1.0 },\n};\n\nconst sunOptions = {\n sunPosition: {\n sunAzimuthalAngle: { min: 0, max: 360, step: 1 },\n sunPolarAngle: { min: -90, max: 90, step: 1 },\n },\n sunIntensity: { min: 0, max: 3, step: 0.05 },\n};\n\nexport const envValues = {\n ambientLight: {\n ambientLightIntensity: 0.05,\n ambientLightColor: { r: 1, g: 1, b: 1 },\n },\n fog: {\n fogNear: 30,\n fogFar: 210,\n fogColor: { r: 0.42, g: 0.48, b: 0.59 },\n },\n};\n\nconst envOptions = {\n ambientLight: {\n ambientLightIntensity: { min: 0, max: 1, step: 0.01 },\n },\n fog: {\n fogNear: { min: 0, max: 80, step: 1 },\n fogFar: { min: 81, max: 300, step: 1 },\n },\n};\n\nexport class EnvironmentFolder {\n public folder: FolderApi;\n private sun: FolderApi;\n private sunButton: ButtonApi;\n private ambient: FolderApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"environment\", expanded: expand });\n\n this.sun = this.folder.addFolder({ title: \"sun\", expanded: true });\n\n this.ambient = this.folder.addFolder({ title: \"ambient\", expanded: true });\n\n this.sun.addBinding(\n sunValues.sunPosition,\n \"sunAzimuthalAngle\",\n sunOptions.sunPosition.sunAzimuthalAngle,\n );\n this.sun.addBinding(\n sunValues.sunPosition,\n \"sunPolarAngle\",\n sunOptions.sunPosition.sunPolarAngle,\n );\n this.sun.addBinding(sunValues, \"sunIntensity\", sunOptions.sunIntensity);\n this.sun.addBinding(sunValues, \"sunColor\", {\n color: { type: \"float\" },\n });\n this.sunButton = this.sun.addButton({ title: \"Set HDRI\" });\n\n this.ambient.addBinding(\n envValues.ambientLight,\n \"ambientLightIntensity\",\n envOptions.ambientLight.ambientLightIntensity,\n );\n this.ambient.addBinding(envValues.ambientLight, \"ambientLightColor\", {\n color: { type: \"float\" },\n });\n this.ambient.addBinding(envValues.fog, \"fogNear\", envOptions.fog.fogNear);\n this.ambient.addBinding(envValues.fog, \"fogFar\", envOptions.fog.fogFar);\n this.ambient.addBinding(envValues.fog, \"fogColor\", {\n color: { type: \"float\" },\n });\n }\n\n public setupChangeEvent(\n setHDR: () => void,\n setAmbientLight: () => void,\n setFog: () => void,\n sun: Sun | null,\n ): void {\n this.sun.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"sunAzimuthalAngle\": {\n const value = e.value as number;\n sun?.setAzimuthalAngle(value * (Math.PI / 180));\n break;\n }\n case \"sunPolarAngle\": {\n const value = e.value as number;\n sun?.setPolarAngle(value * (Math.PI / 180));\n break;\n }\n case \"sunIntensity\": {\n const value = e.value as number;\n sun?.setIntensity(value);\n break;\n }\n case \"sunColor\": {\n const value = e.value as { r: number; g: number; b: number };\n sunValues.sunColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n sun?.setColor();\n break;\n }\n default:\n break;\n }\n });\n this.sunButton.on(\"click\", () => {\n setHDR();\n });\n this.ambient.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"ambientLightIntensity\": {\n envValues.ambientLight.ambientLightIntensity = e.value as number;\n setAmbientLight();\n break;\n }\n case \"ambientLightColor\": {\n const value = e.value as { r: number; g: number; b: number };\n envValues.ambientLight.ambientLightColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n setAmbientLight();\n break;\n }\n case \"fogNear\": {\n envValues.fog.fogNear = e.value as number;\n setFog();\n break;\n }\n case \"fogFar\": {\n envValues.fog.fogFar = e.value as number;\n setFog();\n break;\n }\n case \"fogColor\": {\n const value = e.value as { r: number; g: number; b: number };\n envValues.fog.fogColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n setFog();\n break;\n }\n default:\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BloomEffect } from \"postprocessing\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { GaussGrainEffect } from \"../../rendering/post-effects/gauss-grain\";\n\nexport const extrasValues = {\n grain: 0.055,\n bloom: 3,\n};\n\nconst extrasOptions = {\n grain: {\n amount: { min: 0, max: 0.2, step: 0.002 },\n },\n bloom: {\n amount: { min: 0, max: 5, step: 0.05 },\n },\n};\n\nexport class PostExtrasFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"bloom / grain\", expanded: expand });\n this.folder.addBinding(extrasValues, \"bloom\", extrasOptions.bloom.amount);\n this.folder.addBinding(extrasValues, \"grain\", extrasOptions.grain.amount);\n }\n\n public setupChangeEvent(\n bloomEffect: BloomEffect,\n gaussGrainEffect: typeof GaussGrainEffect,\n ): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"bloom\":\n bloomEffect.intensity = e.value as number;\n break;\n case \"grain\":\n gaussGrainEffect.uniforms.amount.value = e.value as number;\n break;\n default:\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { EffectPass } from \"postprocessing\";\nimport { Scene, ShadowMapType, ToneMapping, WebGLRenderer } from \"three\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nexport const rendererValues = {\n shadowMap: 2,\n toneMapping: 5,\n exposure: 1,\n bgIntensity: 1,\n bgBlurriness: 0.0,\n};\n\nconst rendererOptions = {\n shadowMap: { min: 0, max: 2, step: 1 },\n toneMapping: { min: 0, max: 5, step: 1 },\n exposure: { min: 0, max: 3, step: 0.01 },\n bgIntensity: { min: 0, max: 1.3, step: 0.01 },\n bgBlurriness: { min: 0, max: 0.1, step: 0.001 },\n};\n\nconst shadowMapTypes: Record<number, string> = {\n 0: \"BasicShadowMap\",\n 1: \"PCFShadowMap\",\n 2: \"PCFSoftShadowMap\",\n};\n\nconst toneMappingTypes: Record<number, string> = {\n 0: \"NoToneMapping\",\n 1: \"LinearToneMapping\",\n 2: \"ReinhardToneMapping\",\n 3: \"CineonToneMapping\",\n 4: \"ACESFilmicToneMapping\",\n 5: \"CustomToneMapping\",\n};\n\nconst monitoredValues = {\n shadowMapType: shadowMapTypes[rendererValues.shadowMap],\n toneMappingType: toneMappingTypes[rendererValues.toneMapping],\n};\n\nconst setShadowMapType = (value: number): void => {\n monitoredValues.shadowMapType = shadowMapTypes[value];\n};\n\nconst setToneMappingType = (value: number): void => {\n monitoredValues.toneMappingType = toneMappingTypes[value];\n};\n\nexport class RendererFolder {\n private folder: FolderApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"rendererOptions\",\n expanded: expand,\n });\n\n this.folder.addBinding(rendererValues, \"shadowMap\", rendererOptions.shadowMap);\n this.folder.addBinding(monitoredValues, \"shadowMapType\", { readonly: true });\n this.folder.addBinding(rendererValues, \"toneMapping\", rendererOptions.toneMapping);\n this.folder.addBinding(monitoredValues, \"toneMappingType\", { readonly: true });\n this.folder.addBinding(rendererValues, \"exposure\", rendererOptions.exposure);\n this.folder.addBinding(rendererValues, \"bgIntensity\", rendererOptions.bgIntensity);\n this.folder.addBinding(rendererValues, \"bgBlurriness\", rendererOptions.bgBlurriness);\n }\n\n public setupChangeEvent(\n scene: Scene,\n renderer: WebGLRenderer,\n toneMappingFolder: FolderApi,\n toneMappingPass: EffectPass,\n ): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"shadowMap\": {\n const value = e.value as ShadowMapType;\n renderer.shadowMap.type = value;\n setShadowMapType(value);\n break;\n }\n case \"toneMapping\":\n renderer.toneMapping = e.value as ToneMapping;\n toneMappingFolder.hidden = e.value !== 5;\n toneMappingPass.enabled = e.value === 5 ? true : false;\n setToneMappingType(e.value as ToneMapping);\n break;\n case \"exposure\":\n renderer.toneMappingExposure = e.value as number;\n break;\n case \"bgIntensity\":\n scene.backgroundIntensity = e.value as number;\n break;\n case \"bgBlurriness\":\n scene.backgroundBlurriness = e.value as number;\n break;\n default:\n break;\n }\n });\n }\n}\n", "import { EffectComposer } from \"postprocessing\";\nimport { WebGLRenderer } from \"three\";\nimport { FolderApi } from \"tweakpane\";\n\nimport { TimeManager } from \"../../time/TimeManager\";\n\ntype StatsData = {\n triangles: string;\n geometries: string;\n textures: string;\n shaders: string;\n postPasses: string;\n drawCalls: string;\n rawDeltaTime: string;\n deltaTime: string;\n FPS: string;\n};\n\nexport class RendererStatsFolder {\n private folder: FolderApi;\n private performance: FolderApi;\n private defails: FolderApi;\n\n private statsData: StatsData = {\n triangles: \"0\",\n geometries: \"0\",\n textures: \"0\",\n shaders: \"0\",\n postPasses: \"0\",\n drawCalls: \"0\",\n rawDeltaTime: \"0\",\n deltaTime: \"0\",\n FPS: \"0\",\n };\n\n constructor(parentFolder: FolderApi, expanded: boolean = true) {\n this.folder = parentFolder.addFolder({ title: \"renderStats\", expanded: expanded });\n this.folder.addBinding(this.statsData, \"FPS\", { readonly: true });\n this.folder.addBinding(this.statsData, \"deltaTime\", { readonly: true });\n this.folder.addBinding(this.statsData, \"rawDeltaTime\", { readonly: true });\n this.folder.addBinding(this.statsData, \"triangles\", { readonly: true });\n this.folder.addBinding(this.statsData, \"geometries\", { readonly: true });\n this.folder.addBinding(this.statsData, \"textures\", { readonly: true });\n this.folder.addBinding(this.statsData, \"shaders\", { readonly: true });\n this.folder.addBinding(this.statsData, \"postPasses\", { readonly: true });\n this.folder.addBinding(this.statsData, \"drawCalls\", { readonly: true });\n }\n\n public update(renderer: WebGLRenderer, composer: EffectComposer, timeManager: TimeManager): void {\n const { geometries, textures } = renderer.info.memory;\n const { triangles, calls } = renderer.info.render;\n this.statsData.triangles = triangles.toString();\n this.statsData.geometries = geometries.toString();\n this.statsData.textures = textures.toString();\n this.statsData.shaders = renderer.info.programs!.length.toString();\n this.statsData.postPasses = composer.passes.length.toString();\n this.statsData.drawCalls = calls.toString();\n this.statsData.rawDeltaTime = (\n Math.round(timeManager.rawDeltaTime * 100000) / 100000\n ).toString();\n this.statsData.deltaTime = (Math.round(timeManager.deltaTime * 100000) / 100000).toString();\n this.statsData.FPS = timeManager.fps.toString();\n }\n}\n", "import { BindingApi, BladeApi, BladeController, TpChangeEvent, View } from \"@tweakpane/core\";\nimport { BlendFunction, EffectComposer, EffectPass, NormalPass, SSAOEffect } from \"postprocessing\";\nimport { Color } from \"three\";\nimport { FolderApi } from \"tweakpane\";\n\nexport const ppssaoValues = {\n enabled: false,\n blendFunction: BlendFunction.MULTIPLY,\n distanceScaling: true,\n depthAwareUpsampling: true,\n samples: 30,\n rings: 11,\n luminanceInfluence: 0.7,\n radius: 0.03,\n intensity: 2.5,\n bias: 0.05,\n fade: 0.03,\n resolutionScale: 0.5,\n color: { r: 0, g: 0, b: 0 },\n worldDistanceThreshold: 30,\n worldDistanceFalloff: 7,\n worldProximityThreshold: 0.5,\n worldProximityFalloff: 0.3,\n};\n\nconst ppssaoOptions = {\n samples: { min: 1, max: 50, step: 1 },\n rings: { min: 1, max: 50, step: 1 },\n luminanceInfluence: { min: 0, max: 1, step: 0.01 },\n radius: { min: 0, max: 0.1, step: 0.001 },\n intensity: { min: 0, max: 5, step: 0.1 },\n bias: { min: 0, max: 0.1, step: 0.001 },\n fade: { min: 0, max: 0.1, step: 0.001 },\n resolutionScale: { min: 0.25, max: 2, step: 0.25 },\n worldDistanceThreshold: { min: 0, max: 200, step: 1 },\n worldDistanceFalloff: { min: 0, max: 200, step: 1 },\n worldProximityThreshold: { min: 0, max: 2, step: 0.01 },\n worldProximityFalloff: { min: 0, max: 2, step: 0.01 },\n};\n\nexport const n8ssaoValues = {\n enabled: true,\n halfRes: false,\n aoRadius: 5,\n distanceFalloff: 3.0,\n intensity: 1.0,\n color: { r: 0, g: 0, b: 0 },\n aoSamples: 16,\n denoiseSamples: 4,\n denoiseRadius: 12,\n viewMode: \"Combined\",\n};\n\nexport const n8ssaoOptions = {\n radius: { min: 0.1, max: 6, step: 0.1 },\n distanceFalloff: { min: 1, max: 6, step: 0.1 },\n intensity: { min: 0.1, max: 5, step: 0.1 },\n aoSamples: [2, 4, 8, 16, 32, 64],\n denoiseSamples: [2, 4, 8, 16, 32, 64],\n denoiseRadius: [3, 6, 12],\n viewMode: [\"Combined\", \"AO\", \"No AO\", \"Split\", \"Split AO\", \"No AO\"],\n};\n\nconst ssaoMaterialParams = [\n \"fade\",\n \"bias\",\n \"minRadiusScale\",\n \"worldDistanceThreshold\",\n \"worldDistanceFalloff\",\n \"worldProximityThreshold\",\n \"worldProximityFalloff\",\n];\n\nexport class SSAOFolder {\n private folder: FolderApi;\n\n private ppssao: FolderApi;\n private n8ssao: FolderApi;\n\n private aoSamples: BindingApi;\n private denoiseSamples: BindingApi;\n private denoiseRadius: BindingApi;\n private aoDisplay: BindingApi;\n\n private postProcessingSSAOIndex: number = 1;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"ambientOcclusion\", expanded: expand });\n this.n8ssao = this.folder.addFolder({\n title: \"N8 ambientOcclusion\",\n expanded: n8ssaoValues.enabled,\n });\n this.ppssao = this.folder.addFolder({\n title: \"PP ambientOcclusion\",\n expanded: ppssaoValues.enabled,\n });\n\n // Post-processing SSAO\n {\n this.ppssao.addBinding({ enabled: ppssaoValues.enabled }, \"enabled\");\n this.ppssao.addBinding({ showEffectOnly: false }, \"showEffectOnly\");\n this.ppssao.addBinding(ppssaoValues, \"samples\", ppssaoOptions.samples);\n this.ppssao.addBinding(ppssaoValues, \"rings\", ppssaoOptions.rings);\n this.ppssao.addBinding(ppssaoValues, \"luminanceInfluence\", ppssaoOptions.luminanceInfluence);\n this.ppssao.addBinding(ppssaoValues, \"radius\", ppssaoOptions.radius);\n this.ppssao.addBinding(ppssaoValues, \"intensity\", ppssaoOptions.intensity);\n this.ppssao.addBinding(ppssaoValues, \"bias\", ppssaoOptions.bias);\n this.ppssao.addBinding(ppssaoValues, \"fade\", ppssaoOptions.fade);\n this.ppssao.addBinding(ppssaoValues, \"resolutionScale\", ppssaoOptions.resolutionScale);\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldDistanceThreshold\",\n ppssaoOptions.worldDistanceThreshold,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldDistanceFalloff\",\n ppssaoOptions.worldDistanceFalloff,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldProximityThreshold\",\n ppssaoOptions.worldProximityThreshold,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldProximityFalloff\",\n ppssaoOptions.worldProximityFalloff,\n );\n this.ppssao.addBinding(ppssaoValues, \"color\", { color: { alpha: false, type: \"float\" } });\n }\n\n // N8 SSAO\n {\n this.n8ssao.addBinding({ enabled: n8ssaoValues.enabled }, \"enabled\");\n this.n8ssao.addBinding({ halfRes: n8ssaoValues.halfRes }, \"halfRes\");\n this.n8ssao.addBinding(n8ssaoValues, \"aoRadius\", n8ssaoOptions.radius);\n this.n8ssao.addBinding(n8ssaoValues, \"distanceFalloff\", n8ssaoOptions.distanceFalloff);\n this.n8ssao.addBinding(n8ssaoValues, \"intensity\", n8ssaoOptions.intensity);\n this.n8ssao.addBinding(n8ssaoValues, \"color\", { color: { alpha: false, type: \"float\" } });\n\n this.aoSamples = this.n8ssao.addBinding(n8ssaoValues, \"aoSamples\", {\n view: \"radiogrid\",\n groupName: \"aoSamples\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.aoSamples[y * 3 + x]}`,\n value: n8ssaoOptions.aoSamples[y * 3 + x],\n }),\n label: \"aoSamples\",\n });\n\n this.denoiseSamples = this.n8ssao.addBinding(n8ssaoValues, \"denoiseSamples\", {\n view: \"radiogrid\",\n groupName: \"denoiseSamples\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.denoiseSamples[y * 3 + x]}`,\n value: n8ssaoOptions.denoiseSamples[y * 3 + x],\n }),\n label: \"denoiseSamples\",\n });\n\n this.denoiseRadius = this.n8ssao.addBinding(n8ssaoValues, \"denoiseRadius\", {\n view: \"radiogrid\",\n groupName: \"denoiseRadius\",\n size: [3, 1],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.denoiseRadius[y * 3 + x]}`,\n value: n8ssaoOptions.denoiseRadius[y * 3 + x],\n }),\n label: \"denoiseRadius\",\n });\n\n this.aoDisplay = this.n8ssao.addBinding(n8ssaoValues, \"viewMode\", {\n view: \"radiogrid\",\n groupName: \"viewMode\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.viewMode[y * 3 + x]}`,\n value: `${n8ssaoOptions.viewMode[y * 3 + x]}`,\n }),\n label: \"viewMode\",\n });\n }\n\n this.folder.addBlade({ view: \"separator\" });\n }\n\n public setupChangeEvent(\n composer: EffectComposer,\n normalPass: NormalPass,\n ppssaoEffect: SSAOEffect,\n ppssaoPass: EffectPass,\n n8aopass: any,\n ): void {\n this.ppssao.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"enabled\": {\n const value = e.value as boolean;\n if (e.value === true) {\n composer.addPass(normalPass, this.postProcessingSSAOIndex);\n composer.addPass(ppssaoPass, this.postProcessingSSAOIndex + 1);\n } else {\n composer.removePass(ppssaoPass);\n composer.removePass(normalPass);\n }\n ppssaoValues.enabled = value;\n normalPass.enabled = value;\n ppssaoPass.enabled = value;\n break;\n }\n case \"showEffectOnly\": {\n const value = e.value as boolean;\n const blend = value === true ? BlendFunction.NORMAL : BlendFunction.MULTIPLY;\n ppssaoEffect.blendMode.blendFunction = blend;\n break;\n }\n case \"resolutionScale\": {\n const value = e.value as number;\n ppssaoEffect.resolution.scale = value;\n break;\n }\n case \"color\": {\n const value = e.value as { r: number; g: number; b: number };\n ppssaoEffect.color = new Color().setRGB(value.r, value.g, value.b);\n break;\n }\n default: {\n break;\n }\n }\n\n if (ssaoMaterialParams.includes(target)) {\n (ppssaoEffect.ssaoMaterial as any)[target] = e.value;\n return;\n }\n (ppssaoEffect as any)[target] = e.value;\n });\n\n this.n8ssao.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"enabled\":\n if (e.value === true) {\n composer.addPass(n8aopass, this.postProcessingSSAOIndex + 2);\n } else {\n composer.removePass(n8aopass);\n }\n n8aopass.enabled = e.value;\n break;\n case \"halfRes\":\n n8aopass.configuration.halfRes = e.value;\n break;\n case \"aoRadius\":\n n8aopass.configuration.aoRadius = e.value;\n break;\n case \"distanceFalloff\":\n n8aopass.configuration.distanceFalloff = e.value;\n break;\n case \"intensity\":\n n8aopass.configuration.intensity = e.value;\n break;\n case \"color\":\n const value = (e as any).value;\n n8aopass.configuration.color = new Color().setRGB(value.r, value.g, value.b);\n break;\n default:\n break;\n }\n });\n\n this.aoSamples.on(\"change\", (e: any) => {\n n8aopass.configuration.aoSamples = e.value;\n });\n\n this.denoiseSamples.on(\"change\", (e: any) => {\n n8aopass.configuration.denoiseSamples = e.value;\n });\n\n this.denoiseRadius.on(\"change\", (e: any) => {\n n8aopass.configuration.denoiseRadius = e.value;\n });\n\n this.aoDisplay.on(\"change\", (e: any) => {\n n8aopass.setDisplayMode(e.value);\n });\n }\n}\n", "import { BindingApi, BladeApi, BladeController, TpChangeEvent, View } from \"@tweakpane/core\";\nimport { ToneMappingEffect, ToneMappingMode } from \"postprocessing\";\nimport { FolderApi } from \"tweakpane\";\n\nexport const toneMappingValues = {\n mode: 2 as ToneMappingMode,\n resolution: 512,\n whitePoint: 32.0,\n middleGrey: 21.0,\n minLuminance: 0.01,\n averageLuminance: 0.01,\n adaptationRate: 2.0,\n};\n\nconst toneMappingOptions = {\n mode: { min: 0, max: 4, step: 1 },\n resolution: { min: 64, max: 512, step: 64 },\n whitePoint: { min: 0, max: 32, step: 0.01 },\n middleGrey: { min: 0, max: 32, step: 0.01 },\n minLuminance: { min: 0, max: 32, step: 0.001 },\n averageLuminance: { min: 0.001, max: 0.2, step: 0.001 },\n adaptationRate: { min: 0.1, max: 2.0, step: 0.1 },\n};\n\nconst customToneMappingTypes: Record<number, string> = {\n 0: \"REINHARD\",\n 1: \"REINHARD2\",\n 2: \"REINHARD2_ADAPTIVE\",\n 3: \"OPTIMIZED_CINEON\",\n 4: \"ACES_FILMIC\",\n};\n\nconst customToneMappingBlade = {\n customToneMappingType: customToneMappingTypes[toneMappingValues.mode],\n};\n\nconst setCustomToneMappingType = (value: number): void => {\n customToneMappingBlade.customToneMappingType = customToneMappingTypes[value];\n};\n\nexport class ToneMappingFolder {\n public folder: FolderApi;\n private minLuminance: BindingApi;\n private avgLuminance: BindingApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"customToneMapping\",\n expanded: expand,\n });\n this.folder.addBinding(toneMappingValues, \"mode\", toneMappingOptions.mode);\n this.folder.addBinding(customToneMappingBlade, \"customToneMappingType\", { readonly: true });\n this.folder.addBinding(toneMappingValues, \"whitePoint\", toneMappingOptions.whitePoint);\n this.folder.addBinding(toneMappingValues, \"middleGrey\", toneMappingOptions.middleGrey);\n this.minLuminance = this.folder.addBinding(\n toneMappingValues,\n \"minLuminance\",\n toneMappingOptions.minLuminance,\n );\n this.minLuminance.hidden = toneMappingValues.mode === 2 ? true : false;\n this.avgLuminance = this.folder.addBinding(\n toneMappingValues,\n \"averageLuminance\",\n toneMappingOptions.averageLuminance,\n );\n this.avgLuminance.hidden = toneMappingValues.mode === 2 ? true : false;\n this.folder.addBinding(toneMappingValues, \"adaptationRate\", toneMappingOptions.adaptationRate);\n }\n\n public setupChangeEvent(toneMappingEffect: ToneMappingEffect): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n if (target === \"mode\") {\n this.minLuminance.hidden = toneMappingValues.mode === 2 ? true : false;\n this.avgLuminance.hidden = toneMappingValues.mode === 2 ? true : false;\n setCustomToneMappingType(e.value as number);\n }\n (toneMappingEffect as any)[target] = e.value;\n return;\n });\n }\n}\n", "export const tweakPaneStyle = `\n:root {\n --tp-base-background-color: rgba(12, 12, 12, 0.6);\n --tp-base-shadow-color: hsla(0, 0%, 0%, 0.2);\n --tp-button-background-color: hsla(0, 0%, 80%, 1);\n --tp-button-background-color-active: hsla(0, 0%, 100%, 1);\n --tp-button-background-color-focus: hsla(0, 0%, 95%, 1);\n --tp-button-background-color-hover: hsla(0, 0%, 85%, 1);\n --tp-button-foreground-color: hsla(0, 0%, 0%, 0.7);\n --tp-container-background-color: hsla(0, 0%, 0%, 0.3);\n --tp-container-background-color-active: hsla(0, 0%, 0%, 0.6);\n --tp-container-background-color-focus: hsla(0, 0%, 0%, 0.5);\n --tp-container-background-color-hover: hsla(0, 0%, 0%, 0.4);\n --tp-container-foreground-color: hsla(0, 0%, 90%, 0.6);\n --tp-groove-foreground-color: hsla(0, 0%, 0%, 0.2);\n --tp-input-background-color: hsla(0, 0%, 30%, 0.3);\n --tp-input-background-color-active: hsla(0, 0%, 0%, 0.6);\n --tp-input-background-color-focus: hsla(0, 0%, 0%, 0.5);\n --tp-input-background-color-hover: hsla(0, 0%, 0%, 0.4);\n --tp-input-foreground-color: hsla(0, 0%, 100%, 0.6);\n --tp-label-foreground-color: hsla(0, 0%, 100%, 0.6);\n --tp-monitor-background-color: hsla(0, 0%, 0%, 0.3);\n --tp-monitor-foreground-color: hsla(0, 0%, 100%, 0.3);\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-brkv {\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-dfwv {\n z-index: 100;\n color: white;\n width: 600px !important;\n display: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-fldv {\n margin: 1px 0px 0px 0px !important;\n}\n\n.tp-fldv_b {\n overflow: visible !important;\n}\n\n.tp-fldv_t {\n font-size: 13px;\n font-weight: 900;\n color: #ffffff;\n background-color: rgba(70, 70, 70, 0.3);\n border-top: 1px solid rgba(210, 210, 210, 0.1);\n border-radius: 3px;\n}\n\n.tp-lblv_l {\n font-size: 12px;\n padding-left: 0px !important;\n padding-right: 0px !important;\n}\n\n.tp-lblv_v {\n width: 150px;\n}\n\n.tp-sldtxtv_t {\n max-width: 50px;\n}\n\n.tp-sglv_i {\n font-size: 12px;\n color: rgba(255, 255, 255, 0.7);\n}\n\n.tp-ckbv_w {\n border: 1px solid rgba(200, 200, 250, 0.2);\n}\n`;\n", "import {\n EffectComposer,\n RenderPass,\n EffectPass,\n FXAAEffect,\n ShaderPass,\n BloomEffect,\n SSAOEffect,\n BlendFunction,\n TextureEffect,\n ToneMappingEffect,\n SMAAEffect,\n SMAAPreset,\n EdgeDetectionMode,\n PredicationMode,\n NormalPass,\n} from \"postprocessing\";\nimport {\n AmbientLight,\n Color,\n Fog,\n HalfFloatType,\n LinearSRGBColorSpace,\n LoadingManager,\n PMREMGenerator,\n PerspectiveCamera,\n SRGBColorSpace,\n Scene,\n ShadowMapType,\n ToneMapping,\n Vector2,\n WebGLRenderer,\n} from \"three\";\nimport { RGBELoader } from \"three/examples/jsm/loaders/RGBELoader.js\";\n\nimport { Sun } from \"../sun/Sun\";\nimport { TimeManager } from \"../time/TimeManager\";\nimport { bcsValues } from \"../tweakpane/blades/bcsFolder\";\nimport { envValues } from \"../tweakpane/blades/environmentFolder\";\nimport { extrasValues } from \"../tweakpane/blades/postExtrasFolder\";\nimport { rendererValues } from \"../tweakpane/blades/rendererFolder\";\nimport { n8ssaoValues, ppssaoValues } from \"../tweakpane/blades/ssaoFolder\";\nimport { toneMappingValues } from \"../tweakpane/blades/toneMappingFolder\";\nimport { TweakPane } from \"../tweakpane/TweakPane\";\n\nimport { BrightnessContrastSaturation } from \"./post-effects/bright-contrast-sat\";\nimport { GaussGrainEffect } from \"./post-effects/gauss-grain\";\nimport { N8SSAOPass } from \"./post-effects/n8-ssao/N8SSAOPass\";\n\nexport class Composer {\n private width: number = 1;\n private height: number = 1;\n private resizeListener: () => void;\n\n public resolution: Vector2 = new Vector2(this.width, this.height);\n\n private isEnvHDRI: boolean = false;\n\n private readonly scene: Scene;\n public postPostScene: Scene;\n private readonly camera: PerspectiveCamera;\n public readonly renderer: WebGLRenderer;\n\n public readonly effectComposer: EffectComposer;\n private readonly renderPass: RenderPass;\n\n private readonly normalPass: NormalPass;\n private readonly normalTextureEffect: TextureEffect;\n private readonly ppssaoEffect: SSAOEffect;\n private readonly ppssaoPass: EffectPass;\n private readonly n8aopass: N8SSAOPass;\n\n private readonly fxaaEffect: FXAAEffect;\n private readonly fxaaPass: EffectPass;\n private readonly bloomEffect: BloomEffect;\n private readonly bloomPass: EffectPass;\n private readonly toneMappingEffect: ToneMappingEffect;\n private readonly smaaEffect: SMAAEffect;\n\n private readonly toneMappingPass: EffectPass;\n private readonly smaaPass: EffectPass;\n\n private readonly bcs = BrightnessContrastSaturation;\n private readonly bcsPass: ShaderPass;\n\n private readonly gaussGrainEffect = GaussGrainEffect;\n private readonly gaussGrainPass: ShaderPass;\n\n private ambientLight: AmbientLight | null = null;\n\n public sun: Sun | null = null;\n public spawnSun: boolean;\n\n constructor(scene: Scene, camera: PerspectiveCamera, spawnSun: boolean = false) {\n this.scene = scene;\n this.postPostScene = new Scene();\n this.camera = camera;\n this.spawnSun = spawnSun;\n this.renderer = new WebGLRenderer({\n powerPreference: \"high-performance\",\n antialias: false,\n stencil: false,\n depth: false,\n });\n this.renderer.outputColorSpace = SRGBColorSpace;\n this.renderer.info.autoReset = false;\n this.renderer.setSize(this.width, this.height);\n this.renderer.shadowMap.enabled = true;\n this.renderer.shadowMap.type = rendererValues.shadowMap as ShadowMapType;\n this.renderer.toneMapping = rendererValues.toneMapping as ToneMapping;\n this.renderer.toneMappingExposure = rendererValues.exposure;\n\n this.setAmbientLight();\n this.setFog();\n\n this.effectComposer = new EffectComposer(this.renderer, {\n frameBufferType: HalfFloatType,\n });\n\n this.renderPass = new RenderPass(this.scene, this.camera);\n\n this.normalPass = new NormalPass(this.scene, this.camera);\n this.normalPass.enabled = ppssaoValues.enabled;\n this.normalTextureEffect = new TextureEffect({\n blendFunction: BlendFunction.SKIP,\n texture: this.normalPass.texture,\n });\n this.ppssaoEffect = new SSAOEffect(this.camera, this.normalPass.texture, {\n blendFunction: ppssaoValues.blendFunction,\n distanceScaling: ppssaoValues.distanceScaling,\n depthAwareUpsampling: ppssaoValues.depthAwareUpsampling,\n samples: ppssaoValues.samples,\n rings: ppssaoValues.rings,\n luminanceInfluence: ppssaoValues.luminanceInfluence,\n radius: ppssaoValues.radius,\n intensity: ppssaoValues.intensity,\n bias: ppssaoValues.bias,\n fade: ppssaoValues.fade,\n resolutionScale: ppssaoValues.resolutionScale,\n color: new Color().setRGB(ppssaoValues.color.r, ppssaoValues.color.g, ppssaoValues.color.b),\n worldDistanceThreshold: ppssaoValues.worldDistanceThreshold,\n worldDistanceFalloff: ppssaoValues.worldDistanceFalloff,\n worldProximityThreshold: ppssaoValues.worldProximityThreshold,\n worldProximityFalloff: ppssaoValues.worldProximityFalloff,\n });\n this.ppssaoPass = new EffectPass(this.camera, this.ppssaoEffect, this.normalTextureEffect);\n this.ppssaoPass.enabled = ppssaoValues.enabled;\n\n this.fxaaEffect = new FXAAEffect();\n this.bloomEffect = new BloomEffect({\n intensity: extrasValues.bloom,\n });\n\n this.n8aopass = new N8SSAOPass(this.scene, this.camera, this.width, this.height);\n this.n8aopass.configuration.aoRadius = n8ssaoValues.aoRadius;\n this.n8aopass.configuration.distanceFalloff = n8ssaoValues.distanceFalloff;\n this.n8aopass.configuration.intensity = n8ssaoValues.intensity;\n this.n8aopass.configuration.color = new Color().setRGB(\n n8ssaoValues.color.r,\n n8ssaoValues.color.g,\n n8ssaoValues.color.b,\n );\n this.n8aopass.configuration.aoSamples = n8ssaoValues.aoSamples;\n this.n8aopass.configuration.denoiseSamples = n8ssaoValues.denoiseSamples;\n this.n8aopass.configuration.denoiseRadius = n8ssaoValues.denoiseRadius;\n this.n8aopass.enabled = n8ssaoValues.enabled;\n\n this.fxaaPass = new EffectPass(this.camera, this.fxaaEffect);\n this.bloomPass = new EffectPass(this.camera, this.bloomEffect);\n\n this.toneMappingEffect = new ToneMappingEffect({\n mode: toneMappingValues.mode,\n resolution: toneMappingValues.resolution,\n whitePoint: toneMappingValues.whitePoint,\n middleGrey: toneMappingValues.middleGrey,\n minLuminance: toneMappingValues.minLuminance,\n averageLuminance: toneMappingValues.averageLuminance,\n adaptationRate: toneMappingValues.adaptationRate,\n });\n this.smaaEffect = new SMAAEffect({\n preset: SMAAPreset.ULTRA,\n edgeDetectionMode: EdgeDetectionMode.COLOR,\n predicationMode: PredicationMode.DEPTH,\n });\n\n this.toneMappingPass = new EffectPass(this.camera, this.toneMappingEffect);\n this.toneMappingPass.enabled =\n rendererValues.toneMapping === 5 || rendererValues.toneMapping === 0 ? true : false;\n\n this.bcsPass = new ShaderPass(this.bcs, \"tDiffuse\");\n this.bcs.uniforms.brightness.value = bcsValues.brightness;\n this.bcs.uniforms.contrast.value = bcsValues.contrast;\n this.bcs.uniforms.saturation.value = bcsValues.saturation;\n\n this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, \"tDiffuse\");\n this.smaaPass = new EffectPass(this.camera, this.smaaEffect);\n\n this.effectComposer.addPass(this.renderPass);\n if (ppssaoValues.enabled) {\n this.effectComposer.addPass(this.normalPass);\n this.effectComposer.addPass(this.ppssaoPass);\n }\n if (n8ssaoValues.enabled) {\n this.effectComposer.addPass(this.n8aopass);\n }\n this.effectComposer.addPass(this.fxaaPass);\n this.effectComposer.addPass(this.smaaPass);\n this.effectComposer.addPass(this.bloomPass);\n this.effectComposer.addPass(this.toneMappingPass);\n this.effectComposer.addPass(this.bcsPass);\n this.effectComposer.addPass(this.gaussGrainPass);\n\n if (this.spawnSun === true) {\n this.sun = new Sun();\n this.scene.add(this.sun);\n }\n\n this.resizeListener = () => {\n this.fitContainer();\n };\n window.addEventListener(\"resize\", this.resizeListener, false);\n this.fitContainer();\n }\n\n public setupTweakPane(tweakPane: TweakPane) {\n tweakPane.setupRenderPane(\n this.effectComposer,\n this.normalPass,\n this.ppssaoEffect,\n this.ppssaoPass,\n this.n8aopass,\n this.toneMappingEffect,\n this.toneMappingPass,\n this.bcs,\n this.bloomEffect,\n this.gaussGrainEffect,\n this.spawnSun,\n this.sun,\n this.setHDRIFromFile.bind(this),\n this.setAmbientLight.bind(this),\n this.setFog.bind(this),\n );\n }\n\n public dispose() {\n window.removeEventListener(\"resize\", this.resizeListener);\n }\n\n public fitContainer() {\n if (!this) {\n console.error(\"Composer not initialized\");\n return;\n }\n const parentElement = this.renderer.domElement.parentNode as HTMLElement;\n if (!parentElement) {\n return;\n }\n this.width = parentElement.clientWidth;\n this.height = parentElement.clientHeight;\n this.camera.aspect = this.width / this.height;\n this.camera.updateProjectionMatrix();\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.resolution.set(\n this.width * window.devicePixelRatio,\n this.height * window.devicePixelRatio,\n );\n this.effectComposer.setSize(\n this.width / window.devicePixelRatio,\n this.height / window.devicePixelRatio,\n );\n this.renderPass.setSize(this.width, this.height);\n if (ppssaoValues.enabled) {\n this.normalPass.setSize(this.width, this.height);\n this.normalTextureEffect.setSize(this.width, this.height);\n this.ppssaoPass.setSize(this.width, this.height);\n }\n if (n8ssaoValues.enabled) {\n this.n8aopass.setSize(this.width, this.height);\n }\n this.fxaaPass.setSize(this.width, this.height);\n this.smaaPass.setSize(this.width, this.height);\n this.bloomPass.setSize(this.width, this.height);\n this.toneMappingPass.setSize(this.width, this.height);\n this.gaussGrainPass.setSize(this.width, this.height);\n this.renderer.setSize(this.width, this.height);\n }\n\n public render(timeManager: TimeManager): void {\n this.renderer.info.reset();\n this.normalPass.texture.needsUpdate = true;\n this.gaussGrainEffect.uniforms.resolution.value = this.resolution;\n this.gaussGrainEffect.uniforms.time.value = timeManager.time;\n this.gaussGrainEffect.uniforms.alpha.value = 1.0;\n this.effectComposer.render();\n this.renderer.render(this.postPostScene, this.camera);\n }\n\n public useHDRI(url: string, fromFile: boolean = false): void {\n if ((this.isEnvHDRI && fromFile === false) || !this.renderer) return;\n const pmremGenerator = new PMREMGenerator(this.renderer);\n new RGBELoader(new LoadingManager()).load(\n url,\n (texture) => {\n const envMap = pmremGenerator!.fromEquirectangular(texture).texture;\n if (envMap) {\n envMap.colorSpace = LinearSRGBColorSpace;\n envMap.needsUpdate = true;\n this.scene.background = envMap;\n this.scene.backgroundIntensity = rendererValues.bgIntensity;\n this.isEnvHDRI = true;\n texture.dispose();\n pmremGenerator!.dispose();\n }\n },\n () => {},\n (error: ErrorEvent) => {\n console.error(`Can't load ${url}: ${JSON.stringify(error)}`);\n },\n );\n }\n\n public setHDRIFromFile(): void {\n if (!this.renderer) return;\n const fileInput = document.createElement(\"input\");\n fileInput.type = \"file\";\n fileInput.accept = \".hdr\";\n fileInput.addEventListener(\"change\", () => {\n const file = fileInput.files?.[0];\n if (!file) {\n console.log(\"no file\");\n return;\n }\n const fileURL = URL.createObjectURL(file);\n if (fileURL) {\n this.useHDRI(fileURL, true);\n URL.revokeObjectURL(fileURL);\n document.body.removeChild(fileInput);\n }\n });\n document.body.appendChild(fileInput);\n fileInput.click();\n }\n\n public setFog(): void {\n const fogColor = new Color().setRGB(\n envValues.fog.fogColor.r,\n envValues.fog.fogColor.g,\n envValues.fog.fogColor.b,\n );\n this.scene.fog = new Fog(fogColor, envValues.fog.fogNear, envValues.fog.fogFar);\n }\n\n public setAmbientLight(): void {\n if (this.ambientLight) {\n this.scene.remove(this.ambientLight);\n this.ambientLight.dispose();\n }\n const ambientLightColor = new Color().setRGB(\n envValues.ambientLight.ambientLightColor.r,\n envValues.ambientLight.ambientLightColor.g,\n envValues.ambientLight.ambientLightColor.b,\n );\n this.ambientLight = new AmbientLight(\n ambientLightColor,\n envValues.ambientLight.ambientLightIntensity,\n );\n this.scene.add(this.ambientLight);\n }\n}\n", "import { CameraHelper, Color, DirectionalLight, Group, OrthographicCamera, Vector3 } from \"three\";\n\nimport { sunValues } from \"../tweakpane/blades/environmentFolder\";\n\nexport class Sun extends Group {\n private readonly debug: boolean = false;\n private readonly sunOffset: Vector3 = new Vector3(\n sunValues.sunPosition.sunAzimuthalAngle * (Math.PI / 180),\n sunValues.sunPosition.sunPolarAngle * (Math.PI / 180),\n 100,\n );\n private readonly shadowResolution: number = 8192;\n private readonly shadowCamFrustum: number = 50;\n private readonly camHelper: CameraHelper | null = null;\n\n private readonly shadowCamera: OrthographicCamera;\n private readonly directionalLight: DirectionalLight;\n\n public target: Vector3 | null = null;\n\n constructor() {\n super();\n this.shadowCamera = new OrthographicCamera(\n -this.shadowCamFrustum,\n this.shadowCamFrustum,\n this.shadowCamFrustum,\n -this.shadowCamFrustum,\n 0.1,\n 200,\n );\n if (this.debug === true) {\n this.camHelper = new CameraHelper(this.shadowCamera);\n }\n this.directionalLight = new DirectionalLight(0xffffff, 0.5);\n this.directionalLight.intensity = sunValues.sunIntensity;\n this.directionalLight.shadow.normalBias = 0.01;\n this.directionalLight.shadow.radius = 0.02;\n this.directionalLight.shadow.camera = this.shadowCamera;\n this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);\n this.directionalLight.castShadow = true;\n this.setColor();\n\n this.updateCharacterPosition(new Vector3(0, 0, 0));\n\n this.add(this.directionalLight);\n if (this.debug === true && this.camHelper instanceof CameraHelper) {\n this.add(this.camHelper);\n }\n }\n\n public updateCharacterPosition(position: Vector3 | undefined) {\n if (!position) return;\n this.target = position;\n this.setSunPosition(this.sunOffset.x, this.sunOffset.y);\n }\n\n public setAzimuthalAngle(angle: number) {\n if (this.sunOffset) this.sunOffset.x = angle;\n if (this.target) this.updateCharacterPosition(this.target);\n }\n\n public setPolarAngle(angle: number) {\n if (this.sunOffset) this.sunOffset.y = angle;\n if (this.target) this.updateCharacterPosition(this.target);\n }\n\n public setIntensity(intensity: number) {\n this.directionalLight.intensity = intensity;\n }\n\n public setColor() {\n this.directionalLight.color = new Color().setRGB(\n sunValues.sunColor.r,\n sunValues.sunColor.g,\n sunValues.sunColor.b,\n );\n }\n\n private setSunPosition(azimuthalAngle: number, polarAngle: number) {\n if (!this.target) return;\n const distance = this.sunOffset.z;\n const sphericalPosition = new Vector3(\n distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),\n distance * Math.cos(polarAngle),\n distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle),\n );\n const newSunPosition = this.target.clone().add(sphericalPosition);\n this.directionalLight.position.set(newSunPosition.x, newSunPosition.y, newSunPosition.z);\n this.directionalLight.target.position.copy(this.target.clone());\n this.directionalLight.target.updateMatrixWorld();\n }\n}\n", "import { ShaderMaterial, Uniform } from \"three\";\n\nimport { vertexShader } from \"../shaders/vertex-shader\";\n\nexport const BrightnessContrastSaturation = new ShaderMaterial({\n uniforms: {\n tDiffuse: new Uniform(null),\n brightness: new Uniform(0.0),\n contrast: new Uniform(1.0),\n saturation: new Uniform(1.0),\n },\n vertexShader: vertexShader,\n fragmentShader: /* glsl */ `\n precision highp float;\n in vec2 vUv;\n\n uniform sampler2D tDiffuse;\n uniform float brightness;\n uniform float contrast;\n uniform float saturation;\n\n mat4 brightnessMatrix(float brightness) {\n return mat4(\n 1, 0, 0, 0,\n 0, 1, 0, 0,\n 0, 0, 1, 0,\n brightness, brightness, brightness, 1\n );\n }\n\n mat4 contrastMatrix(float contrast) {\n float t = (1.0 - contrast) / 2.0;\n\n return mat4(\n contrast, 0, 0, 0,\n 0, contrast, 0, 0,\n 0, 0, contrast, 0,\n t, t, t, 1\n );\n }\n\n mat4 saturationMatrix(float saturation) {\n vec3 luminance = vec3(0.3086, 0.6094, 0.0820);\n float oneMinusSat = 1.0 - saturation;\n vec3 red = vec3(luminance.x * oneMinusSat);\n red += vec3(saturation, 0, 0);\n vec3 green = vec3(luminance.y * oneMinusSat);\n green += vec3(0, saturation, 0);\n vec3 blue = vec3(luminance.z * oneMinusSat);\n blue += vec3(0, 0, saturation);\n return mat4(\n red, 0,\n green, 0,\n blue, 0,\n 0, 0, 0, 1\n );\n }\n\n void main(void) {\n vec4 color = texture(tDiffuse, vUv);\n gl_FragColor = (\n brightnessMatrix(brightness) *\n contrastMatrix(contrast) *\n saturationMatrix(saturation) *\n color\n );\n }\n `,\n dithering: true,\n});\n", "export const vertexShader = /* glsl */ `\n precision highp float;\n\n out vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `;\n", "import { ShaderMaterial, Uniform, Vector2 } from \"three\";\n\nimport { vertexShader } from \"../shaders/vertex-shader\";\n\nexport const GaussGrainEffect = new ShaderMaterial({\n uniforms: {\n tDiffuse: new Uniform(null),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n amount: new Uniform(0.0),\n alpha: new Uniform(0.0),\n },\n vertexShader: vertexShader,\n fragmentShader: /* glsl */ `\n precision highp float;\n in vec2 vUv;\n\n uniform sampler2D tDiffuse;\n uniform vec2 resolution;\n uniform float time;\n uniform float amount;\n uniform float alpha;\n\n const float PI = acos(-1.0);\n const float TAU = PI * 2.0;\n const float SQRTAU = sqrt(TAU);\n\n float gaussian(float z, float u, float o) {\n return (\n (1.0 / (o * SQRTAU)) *\n (exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))\n );\n }\n\n vec3 gaussgrain() {\n vec2 ps = vec2(1.0) / resolution.xy;\n vec2 uv = gl_FragCoord.xy * ps;\n float t = time;\n float seed = dot(uv, vec2(12.9898, 78.233));\n float noise = fract(sin(seed) * 43758.5453123 + t);\n noise = gaussian(noise, 0.0, 0.5);\n return vec3(noise);\n }\n\n void main(void) {\n vec2 uv = vUv;\n vec4 originalColor = texture(tDiffuse, uv);\n vec3 grain = gaussgrain();\n vec3 col = originalColor.rgb + (grain * amount);\n gl_FragColor = vec4(clamp(col, 0.0, 1.0), alpha);\n }\n `,\n dithering: true,\n});\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Pass } from \"postprocessing\";\nimport {\n Color,\n DataTexture,\n FloatType,\n Fog,\n FogExp2,\n HalfFloatType,\n LinearFilter,\n NearestFilter,\n NoColorSpace,\n OrthographicCamera,\n PerspectiveCamera,\n RGBAFormat,\n RedFormat,\n RepeatWrapping,\n Scene,\n ShaderMaterial,\n Texture,\n Uniform,\n Vector2,\n Vector3,\n WebGLMultipleRenderTargets,\n WebGLRenderTarget,\n WebGLRenderer,\n} from \"three\";\n\nimport { BlueNoise } from \"./BlueNoise\";\nimport { DepthDownSample } from \"./DepthDownSample\";\nimport { EffectCompositer } from \"./EffectCompositer\";\nimport { EffectShader } from \"./EffectShader\";\nimport { FullScreenTriangle } from \"./FullScreenTriangle\";\nimport { PoissionBlur } from \"./PoissionBlur\";\n\nconst bluenoiseBits: Uint8Array = Uint8Array.from(atob(BlueNoise), (c) => c.charCodeAt(0));\n\nexport type RenderModeType = \"Combined\" | \"AO\" | \"No AO\" | \"Split\" | \"Split AO\";\n\ntype PresetsType = \"Performance\" | \"Low\" | \"Medium\" | \"High\" | \"Ultra\";\n\ninterface IConfiguration {\n aoSamples: number;\n aoRadius: number;\n denoiseSamples: number;\n denoiseRadius: number;\n distanceFalloff: number;\n intensity: number;\n denoiseIterations: number;\n renderMode: number;\n color: Color;\n gammaCorrection: boolean;\n logarithmicDepthBuffer: boolean;\n screenSpaceRadius: boolean;\n halfRes: boolean;\n depthAwareUpsampling: boolean;\n colorMultiply: boolean;\n}\n\nfunction checkTimerQuery(\n timerQuery: WebGLQuery,\n gl: WebGL2RenderingContext,\n pass: N8SSAOPass,\n): void {\n const available = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT_AVAILABLE);\n if (available) {\n const elapsedTimeInNs = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT);\n const elapsedTimeInMs = elapsedTimeInNs / 1000000;\n pass.lastTime = elapsedTimeInMs;\n } else {\n setTimeout(() => checkTimerQuery(timerQuery, gl, pass), 1);\n }\n}\n\nclass N8SSAOPass extends Pass {\n private debugMode: boolean;\n\n public scene: Scene;\n public camera: PerspectiveCamera | OrthographicCamera;\n public lastTime: number = 0;\n\n private width: number;\n private height: number;\n\n public configuration: IConfiguration & ProxyHandler<IConfiguration>;\n\n private autosetGamma: boolean = true;\n private samples: Vector3[] = [];\n private samplesR: number[] = [];\n private samplesDenoise: Vector2[] = [];\n\n private copyQuadMaterial: ShaderMaterial = new ShaderMaterial({\n uniforms: { tDiffuse: new Uniform(null) },\n\n depthWrite: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }\n `,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D tDiffuse;\n varying vec2 vUv;\n void main(void) {\n gl_FragColor = texture2D(tDiffuse, vUv);\n }\n `,\n });\n\n private copyQuad: FullScreenTriangle = new FullScreenTriangle(this.copyQuadMaterial);\n\n private writeTargetInternal: WebGLRenderTarget;\n private readTargetInternal: WebGLRenderTarget;\n private outputTargetInternal: WebGLRenderTarget;\n private depthDownsampleTarget: WebGLMultipleRenderTargets | null;\n\n private depthDownsampleQuad: FullScreenTriangle | null;\n private effectShaderQuad: FullScreenTriangle | null;\n private effectCompositerQuad: FullScreenTriangle | null;\n private poissonBlurQuad: FullScreenTriangle | null;\n\n private depthTexture: Texture;\n private bluenoise: DataTexture;\n\n private r: Vector2;\n private c: Color;\n\n constructor(\n scene: Scene,\n camera: PerspectiveCamera | OrthographicCamera,\n width = 512,\n height = 512,\n ) {\n super();\n this.width = width;\n this.height = height;\n\n this.camera = camera;\n this.scene = scene;\n\n this.configuration = new Proxy(\n {\n aoSamples: 16,\n aoRadius: 5.0,\n denoiseSamples: 8,\n denoiseRadius: 12,\n distanceFalloff: 1.0,\n intensity: 5,\n denoiseIterations: 2.0,\n renderMode: 0,\n color: new Color(0, 0, 0),\n gammaCorrection: true,\n logarithmicDepthBuffer: false,\n screenSpaceRadius: false,\n halfRes: false,\n depthAwareUpsampling: true,\n colorMultiply: true,\n },\n {\n set: (target: any, propName: string, value: any) => {\n const oldProp = target[propName];\n target[propName] = value;\n if (propName === \"aoSamples\" && oldProp !== value) {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"denoiseSamples\" && oldProp !== value) {\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"halfRes\" && oldProp !== value) {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureHalfResTargets();\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n this.setSize(this.width, this.height);\n }\n if (propName === \"depthAwareUpsampling\" && oldProp !== value) {\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"gammaCorrection\") {\n this.autosetGamma = false;\n }\n return true;\n },\n },\n );\n\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n this.configureSampleDependentPasses();\n this.configureHalfResTargets();\n\n this.writeTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.readTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.outputTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.bluenoise = new DataTexture(bluenoiseBits, 128, 128);\n this.bluenoise.colorSpace = NoColorSpace;\n this.bluenoise.wrapS = RepeatWrapping;\n this.bluenoise.wrapT = RepeatWrapping;\n this.bluenoise.minFilter = NearestFilter;\n this.bluenoise.magFilter = NearestFilter;\n this.bluenoise.needsUpdate = true;\n this.lastTime = 0;\n this.needsDepthTexture = true;\n this.needsSwap = true;\n this.r = new Vector2();\n this.c = new Color();\n }\n\n private configureHalfResTargets(): void {\n if (this.configuration.halfRes) {\n this.depthDownsampleTarget = new WebGLMultipleRenderTargets(\n this.width / 2,\n this.height / 2,\n 2,\n {\n depthBuffer: false,\n },\n );\n this.depthDownsampleTarget.texture[0].format = RedFormat;\n this.depthDownsampleTarget.texture[0].type = FloatType;\n this.depthDownsampleTarget.texture[0].minFilter = NearestFilter;\n this.depthDownsampleTarget.texture[0].magFilter = NearestFilter;\n this.depthDownsampleTarget.texture[1].format = RGBAFormat;\n this.depthDownsampleTarget.texture[1].type = HalfFloatType;\n this.depthDownsampleTarget.texture[1].minFilter = NearestFilter;\n this.depthDownsampleTarget.texture[1].magFilter = NearestFilter;\n this.depthDownsampleQuad = new FullScreenTriangle(new ShaderMaterial(DepthDownSample));\n } else {\n if (this.depthDownsampleTarget) {\n this.depthDownsampleTarget.dispose();\n this.depthDownsampleTarget = null;\n }\n if (this.depthDownsampleQuad) {\n this.depthDownsampleQuad.dispose();\n this.depthDownsampleQuad = null;\n }\n }\n }\n\n private configureSampleDependentPasses(): void {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n }\n\n private configureAOPass(logarithmicDepthBuffer = false): void {\n this.samples = this.generateHemisphereSamples(this.configuration.aoSamples);\n this.samplesR = this.generateHemisphereSamplesR(this.configuration.aoSamples);\n const e = { ...EffectShader };\n e.fragmentShader = e.fragmentShader\n .replace(\"16\", this.configuration.aoSamples.toString())\n .replace(\"16.0\", this.configuration.aoSamples.toString() + \".0\");\n if (logarithmicDepthBuffer) {\n e.fragmentShader = \"#define LOGDEPTH\\n\" + e.fragmentShader;\n }\n if (this.configuration.halfRes) {\n e.fragmentShader = \"#define HALFRES\\n\" + e.fragmentShader;\n }\n if (this.effectShaderQuad) {\n this.effectShaderQuad.material.dispose();\n this.effectShaderQuad.material = new ShaderMaterial(e);\n } else {\n this.effectShaderQuad = new FullScreenTriangle(new ShaderMaterial(e));\n }\n }\n\n private configureDenoisePass(logarithmicDepthBuffer: boolean = false): void {\n this.samplesDenoise = this.generateDenoiseSamples(this.configuration.denoiseSamples, 11);\n const p = { ...PoissionBlur };\n p.fragmentShader = p.fragmentShader.replace(\"16\", this.configuration.denoiseSamples.toString());\n if (logarithmicDepthBuffer) {\n p.fragmentShader = \"#define LOGDEPTH\\n\" + p.fragmentShader;\n }\n if (this.poissonBlurQuad) {\n this.poissonBlurQuad.material.dispose();\n this.poissonBlurQuad.material = new ShaderMaterial(p);\n } else {\n this.poissonBlurQuad = new FullScreenTriangle(new ShaderMaterial(p));\n }\n }\n\n private configureEffectCompositer(logarithmicDepthBuffer: boolean = false): void {\n const e = { ...EffectCompositer };\n\n if (logarithmicDepthBuffer) {\n e.fragmentShader = \"#define LOGDEPTH\\n\" + e.fragmentShader;\n }\n\n if (this.configuration.halfRes && this.configuration.depthAwareUpsampling) {\n e.fragmentShader = \"#define HALFRES\\n\" + e.fragmentShader;\n }\n\n if (this.effectCompositerQuad) {\n this.effectCompositerQuad.material.dispose();\n this.effectCompositerQuad.material = new ShaderMaterial(e);\n } else {\n this.effectCompositerQuad = new FullScreenTriangle(new ShaderMaterial(e));\n }\n }\n\n private generateHemisphereSamples(n: number): Vector3[] {\n const points = [];\n for (let k = 0; k < n; k++) {\n const theta = 2.399963 * k;\n const r = Math.sqrt(k + 0.5) / Math.sqrt(n);\n const x = r * Math.cos(theta);\n const y = r * Math.sin(theta);\n\n const z = Math.sqrt(1 - (x * x + y * y));\n points.push(new Vector3(x, y, z));\n }\n return points;\n }\n\n private generateHemisphereSamplesR(n: number): number[] {\n const samplesR = [];\n for (let i = 0; i < n; i++) {\n samplesR.push((i + 1) / n);\n }\n return samplesR;\n }\n\n private generateDenoiseSamples(numSamples: number, numRings: number): Vector2[] {\n const angleStep = (2 * Math.PI * numRings) / numSamples;\n const invNumSamples = 1.0 / numSamples;\n const radiusStep = invNumSamples;\n const samples = [];\n let radius = invNumSamples;\n let angle = 0;\n for (let i = 0; i < numSamples; i++) {\n samples.push(\n new Vector2(Math.cos(angle), Math.sin(angle)).multiplyScalar(Math.pow(radius, 0.75)),\n );\n radius += radiusStep;\n angle += angleStep;\n }\n return samples;\n }\n\n public setSize(width: number, height: number): void {\n this.width = width;\n this.height = height;\n const c = this.configuration.halfRes ? 0.5 : 1;\n this.writeTargetInternal.setSize(width * c, height * c);\n this.readTargetInternal.setSize(width * c, height * c);\n if (this.configuration.halfRes && this.depthDownsampleTarget) {\n this.depthDownsampleTarget.setSize(width * c, height * c);\n }\n this.outputTargetInternal.setSize(width, height);\n }\n\n public setDepthTexture(depthTexture: DataTexture): void {\n this.depthTexture = depthTexture;\n }\n\n public render(\n renderer: WebGLRenderer,\n inputBuffer: WebGLRenderTarget,\n outputBuffer: WebGLRenderTarget,\n ): void {\n const xrEnabled = renderer.xr.enabled;\n renderer.xr.enabled = false;\n\n let ext: any;\n let timerQuery: WebGLQuery | null = null;\n let gl: WebGL2RenderingContext | WebGLRenderingContext | null = null;\n gl = renderer.getContext();\n\n if (this.debugMode) {\n ext = gl.getExtension(\"EXT_disjoint_timer_query_webgl2\");\n if (ext === null) {\n console.error(\"EXT_disjoint_timer_query_webgl2 not available, disabling debug mode.\");\n this.debugMode = false;\n gl = null;\n }\n }\n\n if (this.debugMode && gl) {\n timerQuery = (gl as WebGL2RenderingContext).createQuery()!;\n (gl as WebGL2RenderingContext).beginQuery(ext.TIME_ELAPSED_EXT, timerQuery);\n }\n\n if (\n renderer.capabilities.logarithmicDepthBuffer !== this.configuration.logarithmicDepthBuffer\n ) {\n this.configuration.logarithmicDepthBuffer = renderer.capabilities.logarithmicDepthBuffer;\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n }\n\n if (inputBuffer.texture.type !== this.outputTargetInternal.texture.type) {\n this.outputTargetInternal.texture.type = inputBuffer.texture.type;\n this.outputTargetInternal.texture.needsUpdate = true;\n }\n\n this.camera.updateMatrixWorld();\n this.r.set(this.width, this.height);\n let trueRadius = this.configuration.aoRadius;\n\n if (this.configuration.halfRes && this.configuration.screenSpaceRadius) {\n trueRadius *= 0.5;\n }\n\n if (this.configuration.halfRes && this.depthDownsampleQuad) {\n const depthDownsampleUniforms = this.depthDownsampleQuad.material.uniforms;\n renderer.setRenderTarget(this.depthDownsampleTarget);\n depthDownsampleUniforms.sceneDepth.value = this.depthTexture;\n depthDownsampleUniforms.resolution.value = this.r;\n depthDownsampleUniforms.near.value = this.camera.near;\n depthDownsampleUniforms.far.value = this.camera.far;\n depthDownsampleUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n depthDownsampleUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n depthDownsampleUniforms.logDepth.value = this.configuration.logarithmicDepthBuffer;\n this.depthDownsampleQuad.render(renderer);\n }\n\n if (!this.effectShaderQuad) return;\n\n const effectShaderUniforms = this.effectShaderQuad.material.uniforms;\n\n effectShaderUniforms.sceneDiffuse.value = inputBuffer.texture;\n effectShaderUniforms.sceneDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.texture[0]\n : this.depthTexture;\n effectShaderUniforms.sceneNormal.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.texture[1]\n : null;\n effectShaderUniforms.projMat.value = this.camera.projectionMatrix;\n effectShaderUniforms.viewMat.value = this.camera.matrixWorldInverse;\n effectShaderUniforms.projViewMat.value = this.camera.projectionMatrix\n .clone()\n .multiply(this.camera.matrixWorldInverse.clone());\n effectShaderUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n effectShaderUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n effectShaderUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n effectShaderUniforms.resolution.value = this.configuration.halfRes\n ? this.r\n .clone()\n .multiplyScalar(1 / 2)\n .floor()\n : this.r;\n effectShaderUniforms.time.value = performance.now() / 1000;\n effectShaderUniforms.samples.value = this.samples;\n effectShaderUniforms.samplesR.value = this.samplesR;\n effectShaderUniforms.bluenoise.value = this.bluenoise;\n effectShaderUniforms.radius.value = trueRadius;\n effectShaderUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n effectShaderUniforms.near.value = this.camera.near;\n effectShaderUniforms.far.value = this.camera.far;\n effectShaderUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n effectShaderUniforms.ortho.value = this.camera instanceof OrthographicCamera;\n effectShaderUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n\n // Start the AO\n renderer.setRenderTarget(this.writeTargetInternal);\n this.effectShaderQuad.render(renderer);\n // End the AO\n\n const poissonBlurUniforms = this.poissonBlurQuad!.material.uniforms;\n\n // Start the blur\n for (let i = 0; i < this.configuration.denoiseIterations; i++) {\n if (!poissonBlurUniforms || !this.poissonBlurQuad) return;\n [this.writeTargetInternal, this.readTargetInternal] = [\n this.readTargetInternal,\n this.writeTargetInternal,\n ];\n poissonBlurUniforms.tDiffuse.value = this.readTargetInternal.texture;\n poissonBlurUniforms.sceneDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.texture[0]\n : this.depthTexture;\n poissonBlurUniforms.projMat.value = this.camera.projectionMatrix;\n poissonBlurUniforms.viewMat.value = this.camera.matrixWorldInverse;\n poissonBlurUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n poissonBlurUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n poissonBlurUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n poissonBlurUniforms.resolution.value = this.configuration.halfRes\n ? this.r\n .clone()\n .multiplyScalar(1 / 2)\n .floor()\n : this.r;\n poissonBlurUniforms.time.value = performance.now() / 1000;\n poissonBlurUniforms.blueNoise.value = this.bluenoise;\n poissonBlurUniforms.radius.value =\n this.configuration.denoiseRadius * (this.configuration.halfRes ? 1 / 2 : 1);\n poissonBlurUniforms.worldRadius.value = trueRadius;\n poissonBlurUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n poissonBlurUniforms.index.value = i;\n poissonBlurUniforms.poissonDisk.value = this.samplesDenoise;\n poissonBlurUniforms.near.value = this.camera.near;\n poissonBlurUniforms.far.value = this.camera.far;\n poissonBlurUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n poissonBlurUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n renderer.setRenderTarget(this.writeTargetInternal);\n this.poissonBlurQuad.render(renderer);\n }\n // End the blur\n\n const effectCompositerUniforms = this.effectCompositerQuad!.material.uniforms;\n\n // Start the composition\n if (!effectCompositerUniforms || !this.effectCompositerQuad) return;\n effectCompositerUniforms.sceneDiffuse.value = inputBuffer.texture;\n effectCompositerUniforms.sceneDepth.value = this.depthTexture;\n effectCompositerUniforms.near.value = this.camera.near;\n effectCompositerUniforms.far.value = this.camera.far;\n effectCompositerUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n effectCompositerUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n effectCompositerUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n effectCompositerUniforms.ortho.value = this.camera instanceof OrthographicCamera;\n effectCompositerUniforms.downsampledDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.texture[0]\n : this.depthTexture;\n effectCompositerUniforms.resolution.value = this.r;\n effectCompositerUniforms.blueNoise.value = this.bluenoise;\n effectCompositerUniforms.intensity.value = this.configuration.intensity;\n effectCompositerUniforms.renderMode.value = this.configuration.renderMode;\n effectCompositerUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n effectCompositerUniforms.radius.value = trueRadius;\n effectCompositerUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n effectCompositerUniforms.gammaCorrection.value = this.autosetGamma\n ? this.renderToScreen\n : this.configuration.gammaCorrection;\n effectCompositerUniforms.tDiffuse.value = this.writeTargetInternal.texture;\n effectCompositerUniforms.color.value = this.c\n .copy(this.configuration.color)\n .convertSRGBToLinear();\n effectCompositerUniforms.colorMultiply.value = this.configuration.colorMultiply;\n effectCompositerUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n effectCompositerUniforms.fog.value = !!this.scene.fog;\n\n if (this.scene.fog) {\n if (this.scene.fog instanceof Fog && this.scene.fog.isFog === true) {\n effectCompositerUniforms.fogExp.value = false;\n effectCompositerUniforms.fogNear.value = this.scene.fog.near;\n effectCompositerUniforms.fogFar.value = this.scene.fog.far;\n } else if (this.scene.fog instanceof FogExp2) {\n effectCompositerUniforms.fogExp.value = true;\n effectCompositerUniforms.fogDensity.value = this.scene.fog.density;\n } else {\n console.error(`Unsupported fog type ${this.scene.fog.constructor.name} in SSAOPass.`);\n }\n }\n\n renderer.setRenderTarget(this.outputTargetInternal);\n this.effectCompositerQuad.render(renderer);\n renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);\n this.copyQuad.material.uniforms.tDiffuse.value = this.outputTargetInternal.texture;\n this.copyQuad.render(renderer);\n\n if (this.debugMode && gl && timerQuery) {\n (gl as WebGL2RenderingContext).endQuery(ext.TIME_ELAPSED_EXT);\n checkTimerQuery(timerQuery as WebGLQuery, gl as WebGL2RenderingContext, this);\n }\n\n renderer.xr.enabled = xrEnabled;\n }\n\n public enableDebugMode(): void {\n this.debugMode = true;\n }\n\n public disableDebugMode(): void {\n this.debugMode = false;\n }\n\n public setDisplayMode(mode: \"Combined\" | \"AO\" | \"No AO\" | \"Split\" | \"Split AO\"): void {\n this.configuration.renderMode = [\"Combined\", \"AO\", \"No AO\", \"Split\", \"Split AO\"].indexOf(\n mode,\n ) as number;\n }\n\n public setQualityMode(mode: PresetsType): void {\n if (mode === \"Performance\") {\n this.configuration.aoSamples = 8;\n this.configuration.denoiseSamples = 4;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"Low\") {\n this.configuration.aoSamples = 16;\n this.configuration.denoiseSamples = 4;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"Medium\") {\n this.configuration.aoSamples = 16;\n this.configuration.denoiseSamples = 8;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"High\") {\n this.configuration.aoSamples = 64;\n this.configuration.denoiseSamples = 8;\n this.configuration.denoiseRadius = 6;\n } else if (mode === \"Ultra\") {\n this.configuration.aoSamples = 64;\n this.configuration.denoiseSamples = 16;\n this.configuration.denoiseRadius = 6;\n }\n }\n}\n\nexport { N8SSAOPass };\n", "// Original code from: https://github.com/N8python/n8ao\n\n/* eslint-disable max-len */\nexport const BlueNoise: string =\n \"5L7pP4UXrOIr/VZ1G3f6p89FIWU7lqc7J3DPxKjJUXODJoHQzf/aNVM+ABlvhXeBGN7iC0WkmTjEaAqOItBfBdaK5KSGV1ET5SOKl3x9JOX5w2sAl6+6KjDhVUHgbqq7DZ5EeYzbdSNxtrQLW/KkPJoOTG4u5CBUZkCKHniY9l7DUgjuz708zG1HIC8qfohi1vPjPH9Lq47ksjRrjwXD4MlVCjdAqYFGodQ8tRmHkOfq4wVRIAHvoavPHvN1lpk3X4Y1yzAPGe8S9KBs3crc4GwlU1dEOXiWol/mgQqxkNqB1xd04+0Bmpwj0GcCc4NUi+c731FUxjvaexCkCJ0qhrJJ++htWqetNC4NewClu8aFRSwrqiJEGe+qtTg4CYCHaF1wJI0sy/ZBQAI0qAMyBvVjWZlv2pdkCaro9eWDLK5I4mbb8E4d7hZr9dDJiTJm6Bmb5S+2F7yal/JPdeLUfwq7jmVLaQfhv4tWMJAt7V4sG9LuAv2oPJgSj1nnlBvPibfHM2TrlWHwGCLGxW/5Jm2TotaDL+pHDM5pn1r0UuTZ24N8S5k68bLHW9tfD+2k4zGev23ExJb4YTRKWrj82N5LjJ26lj1BkGZ0CsXLGGELoPaYQomjTqPxYqhfwOwDliNGVqux9ffuybqOKgsbB51B1GbZfG8vHDBE2JQGib1mnCmWOWAMJcHN0cKeDHYTflbDTVXajtr68mwfRje6WueQ/6yWqmZMLWNH7P27zGFhMFqaqfg11Q88g/9UA/FROe9yfq0yOO0pnNAxvepFy2BpEbcgG+mCyjCC01JWlOZlIPdf1TtlyOt7L94ToYGCukoFt4OqwOrofamjECpSgKLLmrRM+sNRAw12eaqk8KtdFk7pn2IcDQiPXCh16t1a+psi+w9towHTKPyQM0StKr61b2BnN1HU+aezFNBLfHTiXwhGTbdxLLmrsAGIVSiNAeCGE8GlB0iOv2v78kP0CTmAPUEqnHYRSDlP+L6m/rYjEK6Q85GRDJi2W20/7NLPpSOaMR++IFvpkcwRuc59j8hh9tYlc1xjdt2jmp9KJczB7U9P43inuxLOv11P5/HYH5d6gLB0CsbGC8APjh+EcCP0zFWqlaACZweLhVfv3yiyd8R3bdVg8sRKsxPvhDaPpiFp9+MN+0Ua0bsPr+lhxfZhMhlevkLbR4ZvcSRP6ApQLy3+eMh9ehCB3z5DVAaN3P6J8pi5Qa88ZQsOuCTWyH6q8yMfBw8y8nm6jaOxJhPH6Hf0I4jmALUBsWKH4gWBnyijHh7z3/1HhQzFLRDRrIQwUtu11yk7U0gDw/FatOIZOJaBx3UqbUxSZ6dboFPm5pAyyXC2wYdSWlpZx/D2C6hDO2sJM4HT9IKWWmDkZIO2si/6BKHruXIEDpfAtz3xDlIdKnnlqnkfCyy6vNOPyuoWsSWBeiN0mcfIrnOtp2j7bxjOkr25skfS/lwOC692cEp7TKSlymbsyzoWg/0AN66SvQYo6BqpNwPpTaUu25zMWlwVUdfu1EEdc0O06TI0JmHk4f6GZQbfOs//OdgtGPO6uLoadJycR8Z80rkd88QoNmimZd8vcpQKScCFkxH1RMTkPlN3K7CL/NSMOiXEvxrn9VyUPFee63uRflgaPMSsafvqMgzTt3T1RaHNLLFatQbD0Vha4YXZ/6Ake7onM65nC9cyLkteYkDfHoJtef7wCrWXTK0+vH38VUBcFJP0+uUXpkiK0gDXNA39HL/qdVcaOA16kd2gzq8aHpNSaKtgMLJC6fdLLS/I/4lUWV2+djY9Rc3QuJOUrlHFQERtXN4xJaAHZERCUQZ9ND2pEtZg8dsnilcnqmqYn3c1sRyK0ziKpHNytEyi2gmzxEFchvT1uBWxZUikkAlWuyqvvhteSG9kFhTLNM97s3X1iS2UbE6cvApgbmeJ/KqtP0NNT3bZiG9TURInCZtVsNZzYus6On0wcdMlVfqo8XLhT5ojaOk4DtCyeoQkBt1mf5luFNaLFjI/1cnPefyCQwcq5ia/4pN4NB+xE/3SEPsliJypS964SI6o5fDVa0IERR8DoeQ+1iyRLU1qGYexB61ph4pkG1rf3c2YD6By1pFCmww9B0r2VjFeaubkIdgWx4RKLQRPLENdGo8ezI5mkNtdCws19aP1uHhenD+HKa8GDeLulb2fiMRhU2xJzzz9e4yOMPvEnGEfbCiQ17nUDpcFDWthr68mhZ4WiHUkRpaVWJNExuULcGkuyVLsQj59pf6OHFR7tofhy9FMrWPCEvX1d5sCVJt8yBFiB6NoOuwMy4wlso9I2G4E5/5B2c6vIZUUY9fFujT3hpkdTuVhbhBwLCtnlIjBpN4cq+waZ0wXSrmebcl+dcrb7sPh9jKxFINkScDTBgjSUfLkC3huJJs/M4M8AOFxbbSIVpBUarYFmLpGsv+V6TJnWNTwI41tubwo7QSI1VOdRKT/Pp8U3oK2ciDbeuWnAGAANvQjGfcewdAdo6H83XzqlK/4yudtFHJSv9Y+qJskwnVToH1I0+tJ3vsLBXtlvMzLIxUj/8LcqZnrNHfVRgabFNXW0qpUvDgxnP3f54KooR3NI+2Q/VHAYFigMkQE5dLH6C6fGs/TKeE6E2jOhZQcP9/rrJjJKcLYdn5cw6XLCUe9F7quk5Yhac+nYL5HOXvp6Q/5qbiQHkuebanX77YSNx34YaWYpcEHuY1u/lEVTCQ7taPaw3oNcn/qJhMzGPZUs3XAq48wj/hCIO2d5aFdfXnS0yg57/jxzDJBwkdOgeVnyyh19Iz1UqiysT4J1eeKwUuWEYln23ydtP7g3R1BnvnxqFPAnOMgOIop2dkXPfUh/9ZKV3ZQbZNactPD4ql5Qg9CxSBnIwzlj/tseQKWRstwNbf17neGwDFFWdm/8f+nDWt/WlKV3MUiAm3ci6xXMDSL5ubPXBg/gKEE7TsZVGUcrIbdXILcMngvGs7unvlPJh6oadeBDqiAviIZ/iyiUMdQZAuf/YBAY0VP1hcgInuWoKbx31AOjyTN2OOHrlthB3ny9JKHOAc8BMvqopikPldcwIQoFxTccKKIeI815GcwaKDLsMbCsxegrzXl8E0bpic/xffU9y1DCgeKZoF2PIY77RIn6kSRdBiGd8NtNwT74dyeFBMkYraPkudN26x9NPuBt4iCOAnBFaNSKVgKiZQruw22kM1fgBKG7cPYAxdHJ8M4V/jzBn2jEJg+jk/jjV4oMmMNOpKB5oVpVh7tK529Z+5vKZ0NSY2A4YdcT0x4BdkoNEDrpsTmekSTjvx9ZBiTHrm9M/n/hGmgpjz4WEjttRfAEy5DYH5vCK/9GuVPa4hoApFaNlrFD/n2PpKOw24iKujKhVIz41p1E0HwsCd/c17OA0H0RjZi1V/rjJLexUzpmXTMIMuzaOBbU4dxvQMgyvxJvR6DyF3BaHkaqT4P3FRYlm+zh8EEGgmkNqD1WRUubDW62VqLoH8UEelIpL7C8CguWWGGCAIDPma9bnh+7IJSt0Cn6ACER2mYk8dLsrN70RUVLiE0ig+08yPY9IOtuqHf/KYsT84BwhMcVq7t8q1WVjpJGNyXdtIPIjhAzabtrX03Itn29QO3TCixE9WpkHIOdAoGvqCrw1D3x9g9Px8u0yZZuulZuGy0veSY34KDSlhsO1zx2ZMrpDBzCHPB4niwApk6NevIvmBxU3+4yaewDvgEQDJ6Of5iRxjAIpp9UO8EzNY4blj4qh8SCSZTqbe/lShE6tNU9Y5IoWHeJxPcHF9KwYQD7lFcIpcscHrcfkHJfL2lL1zczKywEF7BwkjXEirgBcvNWayatqdTVT5oLbzTmED3EOYBSXFyb2VIYk3t0dOZWJdG1nP+W7Qfyeb8MSIyUGKEA57ptPxrPHKYGZPHsuBqQuVSrn0i8KJX+rlzAqo8AawchsJ26FckxTf5+joTcw+2y8c8bushpRYEbgrdr64ltEYPV2AbVgKXV3XACoD1gbs01CExbJALkuItjfYN3+6I8kbiTYmdzBLaNC+xu9z/eXcRQV1Lo8cJoSsKyWJPuTncu5vcmfMUAWmuwhjymK1rhYR8pQMXNQg9X+5ha5fEnap+LhUL1d5SURZz9rGdOWLhrMcMKSaU3LhOQ/6a6qSCwgzQxCW2gFs53fpvfWxhH+xDHdKRV6w29nQ6rNqd9by+zm1OpzYyJwvFyOkrVXQUwt4HaapnweCa7Tj2Mp/tT4YcY3Q/tk1czgkzlV5mpDrdp1spOYB8ionAwxujjdhj5y9qEHu0uc36PAKAYsKLaEoiwPnob0pdluPWdv4sNSlG8GWViI+x/Z4DkW/kSs2iE3ADFjg4TCvgCbX3v0Hz0KZkerrpzEIukAusidDs2g/w0zgmLnZXvVr5kkpwQTLZ0L6uaTHl0LVikIuNIVPmL3fOQJqIdfzymUN0zucIrDintBn6ICl/inj5zteISv5hEMGMqtHc2ghcFJvmH3ZhIZi34vqqTFCb9pltTYz582Y3dwYaHb9khdfve1YryzEwEKbI8qm62qv+NyllC+WxLLAJjz0ZaEF2aTn35qeFmkbP6LDYcbwqWxA0WKsteB7vy8bRHE4r8LhubWDc0pbe90XckSDDAkRej0TQlmWsWwaz18Tx2phykVvwuIRzf4kt9srT8N7gsMjMs0NLAAldabFf2tiMoaaxHcZSX51WPc1BrwApMxih227qTZkcgtkdK1h314XvZKUKh/XysWYnk1ST4kiBI1B9OlfTjB3WHzTAReFLofsGtikwpIXzQBc/gOjz2Thlj36WN0sxyf4RmAFtrYt64fwm+ThjbhlmUTZzebLl4yAkAqzJSfjPBZS2H/IvkkTUdVh0qdB6EuiHEjEil5lk9BTPzxmoW4Jx543hiyy4ASdYA2DNoprsR9iwGFwFG3F2vIROy4L5CZrl230+k733JwboSNBKngsaFPtqo+q3mFFSjC1k0kIAFmKihaYSwaSF7konmYHZWmchuaq15TpneA2ADSRvA07I7US0lTOOfKrgxhzRl0uJihcEZhhYWxObjvNTJ/5sR4Aa5wOQhGClGLb746cJhQ2E6Jie1hbGgWxUH7YSKETptrTeR/xfcMNk2WM12S0XElC9klR8O7jLYekEOZdscP0ypSdoCVZAoK+2ju2PHE869Q9rxCs9DVQco4BriiPbCjN/8tBjsah4IuboR5QbmbyDpcdXVxGMxvWKIjocBuKbjb+B4HvkunbG0wX0IFCjQKoNMFIKcJSJXtkP3EO+J16uh4img0LQlBAOYwBLupu5r1NALMo0g3xkd9b4f7KoCBWHeyk24FmYUCy/PGLv0xErOTyORp8TJ5nnc2k1dOVBTJok7iHye9dwxwRVP3c7eAS8pMmJYHGpzIHz6ii2WJm8HMTPAZdA4q+ugj3PNCL/N45kyglqvQV4f/+ryDDG5RPy5HVoV9FVuJcq2dxF9Y0heVoipV6q1LyfAeuMzbsUV+rsSBmCSV+1CdKlxy0T0Y6Om0X6701URm2Ml6DIQgJ/3KO6kwcMYRrmKsY7TfxWhSXZll+1PfyRXe9HS0t1IKTQMZL7ZqQ8D/o+en57Y9XAQ9C+kZYykNr0xOMxEwu2+Cppm69mQyTm3H7QX6kHvXF201r+KVAf354qypJC5OHSeBU47bM1bTaVmdVEWQ+9CcvvHdu8Ue5UndHM+EeukmR82voQpetZ7WJjyXs+tPS60nk09gymuORoHNtbm0VuvyigiEvOsyHiRBW7V6FyTCppLPEHvesan91SlEh1/QEunq+qgREFXByDwNKcAH5s8/RFg8hP4wcPmFqX0xXGSKY087bqRLsBZe52jThx0XLkhKQUWPvI18WQQS3g2Ra1pzQ1oNFKdfJJjyaH5tJH6w0/upJobwB8KZ5cIs9LnVGxfBaHXBfvLkNpab7dpU6TdcbBIc+A4bqXE/Xt8/xsGQOdoXra4Us5nDAM6v2BNBQaGMmgMfQQV+ikTteSHvyl8wUxULiYRIEKaiDxpBJnyf9OoqQdZVJ8ahqOvuwqq5mnDUAUzUr/Lvs1wLu2F+r4eZMfJPL4gV5mKLkITmozRnTvA7VABaxZmFRtkhvU5iH9RQ1z26ku7aABokvptx7RKZBVL6dveLKOzg0NC7HAxcg5kE1wuyJiEQLOpO0ma3AtWD2Q2Wmn2oPZeDYAwVyEpxuwDy7ivmdUDSL95ol3h2JByTMovOCgxZ1q4E5nwwa7+4WtDAse6bDdr27XgAi5Px3IWbyZ/vRiECKwOMeJSuIl8A4Ds0emI3SgKVVWVO5uyiEUET+ucEq0casA+DQyhzRc8j+Plo0pxKynB/t0uXod1FVV4fX1sC4kDfwFaUDGQ4p9HYgaMqIWX3OF/S8+vcR0JS0bDapWKJwAIIQiRUzvh5YwtzkjccbbrT9Ky/qt5X7MAGA0lzh43mDF9EB6lCGuO/aFCMhdOqNryvd73KdJNy3mxtT8AqgmG4xq7eE1jKu6rV0g8UGyMatzyIMjiOCf4lIJFzAfwDbIfC72TJ/TK+cGsLR8blpjlEILjD8Mxr7IffhbFhgo12CzXRQ2O8JqBJ70+t12385tSmFC8Or+U8svOaoGoojT1/EmjRMT7x2iTUZ7Ny02VGeMZTtGy029tGN1/9k7x3mFu63lYnaWjfJT1m1zpWO3HSXpGkFqVd/m3kDMv4X9rmLOpwEeu8r6TI6C2zUG+MT6v90OU3y5hKqLhpyFLGtkZhDmUg/W1JGSmA8N1TapR4Kny+P6+DuMadZ9+xBbv06nfOjMwkoTsjG0zFmNbvlxEjw+Pl5QYK+V8Qyb+nknZ0Nb/Ofi9+V0eoNtTrtD1/0wzUGGG5u2D/J1ouO/PjXFJVx6LurVnPOyFVbZx7s3ZSjSq+7YN3wzTbFbUvP8GBh7cKieJt56SIowQ2I577+UEXrxUKMFO+XaLLCALuiJWB2vUdpsT+kQ+adoeTfwOulXhd/KZ7ygjj6PhvGT1xzfT7hTwd6dzSB4xV70CesHC0dsg2VyujlMGBKjg5snbrHHX/LNj3SsoLGSX+bZNTDDCNTXh+dCVPlj4K8+hJ/kVddrbtZw26Hx5qYiv3oNNg5blHRSPtmojhZmBQAz8sLC9nAuWNSz1dIofFtlryEKklbdkhBCcx5dhj7pinXDNlCeatCeTCEjYCpZ3HRf5QzUcRR1Tdb3gwtYtpPdgMxmWfJGoZSu1EsCJbIhS16Ed97+8br4Ar1mB1GcnZVx/HPtJl4CgbHXrrDPwlE4od8deRQYLt9IlsvCqgesMmLAVxB+igH7WGTcY/e3lLHJ4rkBgh2p1QpUBRb/cSQsJCbosFDkalbJigimldVK7TIHKSq2w8mezku9hgw8fXJxGdXoL1ggma52kXzjP78l0d0zMwtTVlt0FqnRyGLPGEjmICzgSp7XPFlUr7AeMclQ4opqwBFInziM5F8oJJ8qeuckGOnAcZZOLl1+ZhGF17pfIuujipwFJL7ChIIB2vlo0IQZGTJPNa2YjNcGUw+a/gWYLkCp+bOGIYhWr08UIE709ZEHlUoEbumzgpJv1D0+hWYNEpj+laoZIK5weO2DFwLL6UBYNrXTm9YvvxeN9U9oKsB3zKBwzFFwDgid5ESMhy68xBnVa55sCZd+l5AnzT8etYjIwF/BGwEx1jjzFv32bk6EeJulESARh8RZ48o7rKw67UZpudPa15SDnL8AL8xMV2SC0D1P53p190zhCFkMmEiir2olwxcJppl/kLm6/0QSUQLNaxi1AC3Pg1CTosX2YQr73PjEIxIlg4mJ62vP7ZyoHE55B0SX9YrrrCPtNsrJEwtn6KOSt7nLT3n3DLJTPbLulcqQ1kETP6Huts29oP+JLEqRGWgnrqMD+mhCl1XCZifjgQ39AeudE8pyu2DqnYU3PyPbJhStq1HbP+VxgseWL+hQ+4w1okADlA9WqoaRuoS7IY77Cm40cJiE6FLomUMltT+xO3Upcv5dzSh9F57hodSBnMHukcH1kd9tqlpprBQ/Ij9E+wMQXrZG5PlzwYJ6jmRdnQtRj64wC/7vsDaaMFteBOUDR4ebRrNZJHhwlNEK9Bz3k7jqOV5KJpL74p2sQnd7vLE374Jz+G7H3RUbX17SobYOe9wKkL/Ja/zeiKExOBmPo0X29bURQMxJkN4ddbrHnOkn6+M1zTZHo0efsB23WSSsByfmye2ZuTEZ12J3Y8ffT6Fcv8XVfA/k+p+xJGreKHJRVUIBqfEIlRt987/QXkssXuvLkECSpVEBs+gE1meB6Xn1RWISG6sV3+KOVjiE9wGdRHS8rmTERRnk0mDNU/+kOQYN/6jdeq0IHeh9c6xlSNICo9OcX1MmAiEuvGay43xCZgxHeZqD7etZMigoJI5V2q7xDcXcPort7AEjLwWlEf4ouzy2iPa3lxpcJWdIcHjhLZf1zg/Kv3/yN1voOmCLrI1Fe0MuFbB0TFSUt+t4Wqe2Mj1o2KS0TFQPGRlFm26IvVP9OXKIQkjfueRtMPoqLfVgDhplKvWWJA673+52FgEEgm+HwEgzOjaTuBz639XtCTwaQL/DrCeRdXun0VU3HDmNmTkc6YrNR6tTVWnbqHwykSBswchFLnvouR0KRhDhZiTYYYNWdvXzY+61Jz5IBcTJavGXr9BcHdk/3tqaLbwCbfpwjxCFSUs1xfFcRzRfMAl+QYuCpsYGz9H01poc1LyzhXwmODmUSg/xFq/RosgYikz4Om/ni9QCcr28ZPISaKrY7O+CspM/s+sHtnA9o9WgFWhcBX2LDN2/AL5uB6UxL/RaBp7EI+JHGz6MeLfvSNJnBgI9THFdUwmg1AXb9pvd7ccLqRdmcHLRT1I2VuEAghBduBm7pHNrZIjb2UVrijpZPlGL68hr+SDlC31mdis0BjP4aZFEOcw+uB17y5u7WOnho60Vcy7gRr7BZ9z5zY1uIwo+tW1YKpuQpdR0Vi7AxKmaIa4jXTjUh7MRlNM0W/Ut/CSD7atFd4soMsX7QbcrUZZaWuN0KOVCL9E09UcJlX+esWK56mre/s6UO9ks0owQ+foaVopkuKG+HZYbE1L1e0VwY2J53aCpwC77HqtpyNtoIlBVzOPtFvzBpDV9TjiP3CcTTGqLKh+m7urHvtHSB/+cGuRk4SsTma9sPCVJ19UPvaAv5WB8u57lNeUewwKpXmmKm5XZV91+FqCCT6nVrrrOgXfYmGFlVjqsSn3/yufkGIdtmdD0yVBcYFR3hDx43e3E4iuiEtP3Me9gcsBqveQdKojKR//qD2nEDY0IktMgFvH+SqVWi9mAorym92NEGbY8MeDjp553MiTXCRSASPt+Ga5q7pB9vwFQCTpaoevx0yEfrq9rMs3eU6wclBMJ9Ve8m6QuLYZ58J41YG3jW/khW92h6M/vbFIUPuopZ6VVtpciesU74Ef7ic8iSymDohGeUn4ubT0vRsXmbsjaJaYhL8f+8I5EiD5l680MJbxX/4GYrOg4iPQqpKp0qddSu/HKtznHeVyxgTwhfEORMCwnaqetVSzvidaWN9P+fXtGXfEP9cTdwx2gKVfDdICq7hecgRhIs0qlCt6+5pGlCc6kWoplHa/KjP+FJdXBU/IDoKMxRjFhSYkggIkhvRKiN/b2ud8URPF+lB87AGAwyMjr/Wju2Uj5IrppXZWjI3d14BdKE2fhALyQPmHqqA+AXd2LwvRHcBq4mhOQ4oNRWH7wpzc6Pggfcbv9kqhLxrJKEaJqA6Rxi+TDNOJstd5DoRVCDjmVspCVyHJsFEWPg9+NA8l1e4X2PDvOd5MPZAGw6LRhWqeZoSQcPf9/dGJYAyzCmttlRnx0BfrKQ/G9i5DVJft9fuJwMi3OD/0Dv1bRoxcXAyZ0wMJ6rwk9RjRTF4ZK8JviCCNuVt/BqQYiphOzWCpnbwOZt6qXuiAabQWrS4mNXQ7cEErXR/yJcbdFp5nWE1bPBjD0fmG3ovMxmOq5blpcOs0DtNQpci1t+9DKERWAO53IVV/S4yhMklvIp0j0FIQgwjdUptqmoMYGVWSI5YkTKLHZdXRDv9zs+HdFZt1QVcdlGOgATro3fg6ticCrDQKUJC7bYX50wdvetilEwVenHhlr85HMLRLTD6nDXWId4ORLwwe5IXiOhpuZTVTv+xdkTxJofqeCRM/jcZqQlU0gFVTlYlfwMi6HKR2YG4fQ8TOtgR+yV+BMZb6L5OwDc/28/xdfD7GXFaVA2ZSObiIxBwT2Zev637EuvpM6rxcogdM4FJFa0ZhF7nrqtNsqWg5M7hZMORpjd4szf/wS+Ahs1shY54Ct5J1dOBO4sdEtSnRc0P9PhgyOCt6aQW98R22DpAcNTDe72AHK40vutKTPfpokghRPuGvz0dulBPKfC3O4KVDCyWrJGO7Ikdu06A0keKlVfi0tGcpO0NhzXEh75NHyMysAMV19fq7//sPC0For1k2uFEvq8lwrMAfmP7afR69U2RqaILHe7glpc8HmVf87Qb2ohsw+Di9U+ePdHLecS66MhB/0OwdcXR5WBcWTZLGq/kiAaT+bzkjR8GIpWdv6pfIgQ+Q0xdiKvo+gNB7/Nf9knNJGxnh7LeZEFtMn517tNc74PPS0M4K3I6HHZqNPA+VZcBc/g5a2ARyqKrJ4Z3krsuA+VOJJz2KJpBMgCCWFln3u7k6/q3DETAubKG/pt3ObaNT0NI0Qug90L2ip5dHnZJUjPTvK5E96aX/4mRU2u8n8kh6MKbY7ANBro3huF06U+JvfyELQP25oIaj+n0ITQ4KT9rXZD4EtBIOj95fYNldDN3io/VMIvWNj9P/b95WEMq8UAVfG2XG0N6fSYdnBEC7sUEbatbDICH9qA8TTuW9kEt9DlFOZFP7bdfYLa/khSY8W5K/AkIIAPXtMvyVKyESjKx9nfragssxC0jFMVY94d8lOAwRocdS/l/P43cBGa3IqDa0ihGPcmwS8O8Vj16Uy55rOrnN0shhRJZdW8I7F0Q0KeHc35GFo4aJOFc25gNafBu1V/VO0qS4Qkb6wjRrnlepUWjtYyaDABZceValuOMtoDdeIITWKOJiwGPpB12lQgwkmXh9M86podb0D117mNQ8ElluFvbaS8RTKQ6lyj88dUwoJU/ofOeubhoXWBF8eNumkVJu+As3ED/AvLlrV91UowIWI2m8HBG+a3k247ZKAGYsOcWe7fTWqL8eqwM5ZFuoXbeugPKuMOAtOsN+4dSwkhrSAlfGNTzFwEmCNWtzpa9CgPbYNcmoHtO8pj8qMvlGET6nrkJoQ2lp5MEUV1E2A4ZH70JUlCLXvqTIpZlzyxdr5p/GZiD1/BuFOGbyfFzhuxaC/l3lC2jjt6GNRBa06AqqPlYtdA7kiidYa5Qi0/XpXiMDyMXNOj3kmJEaXufW0GO8+DF8OoMULX1vvjCePKNis4AmxQKLCF+cjf/wyilCJvuiyLVPSdsuRTPZ0AhpdDF/1uFmDwG7iP3qYwNsKzqd3sYdnMolCOuQOIHWy1eQpWhuV+jmSeAC5zCc0/KsOIXkZPdiw8vtB33jEBpezpGDBP4JLY2wH1J7Fzp8y8RICqVd25mDT2tDb/L1mh4fv9TOfDH5dTeATqu+diOZi+/sIt18hiTovPsVQVaqXLPRx/4R/uH/86tBMcF+WBkThKLfblcVCIECc8DgNRVX97KdrsCeIK+CvJZMfwrftcDZDZyp7G8HeKl7bPYnTKX88dXAwAyz66O2chkPDHy/2K2XcT/61XnlAKgPwtI8yP9Vu45yh55KHhJu93mL4nfo8szp/IyDjmFHtSMqqoWsj8WaVhbjXgzZxcqZcyOe7pUK6aXF/Y32LnBOt0WN28UmHRiOpL525C63I2JQPX8vvOU0fz2ij74OeJ1Apgu3JRObfdo9xGDpp7cv3TdULEfNS6Gu3EJu7drBsBsogUqUc6wAUW3ux0/1hLVI/JEKJrAGm8g72C2aJSsGAsKFW4CBvBXVlNIKa5r7HvT1BeGYBfxTR1vhNlFFNN8WQYwr39yT/13XzRGiF2IsfE8HcN0+lN1zN/OnzekVBKkFY11GgrK5CLxrE/2HCEMwQb9yOuP2rTXiZzTEETp/ismFGcTWmbM9G1Sn2D/x3G74uWYZY4rgKB2Zo2bTKS6QnM5x1Yee66Y1L7K44AyiY5K2MH5wrTwxMFh+S8LzNQ25z6sunWZyiRwFIIvSnioltUXNiOr+XMZ6O9h9HcHxZJkfF0tUm6QkU7iJ2ozXARitiL86aqVsMOpmvdIBROhUoanPtCjgft8up3hAaKpw9Qs9MzYtBA2ijHXotzarkV3zKEK0dFFQUwT74NgCmGGuSCEDmFCezXPC9BhyGhmzNa6rQeQQz+r9CmGUZjIQEPsHwe86oCOQhWaHERsv5ia9rZvJ//7UXO7B329YUkLLAiqpLRsVV5XpcfdawlJqi/BVcCqO6dr9YJTFFRMVGhfUbB9YWNvYPY6RyaydAFYq1YIBQxuNAGfYWLMAHtt2XRHoOKCLz+qf5HCVBDOPOktQ3SdJBfxUkaiD585bmTzMwU3oeXUHZ55EC99Kz9kk4ZXMIENwVVpqW2JmGIcUiutIMj2KkpjE2QD+dIZUCxcX57kH7hiuUPnKCTdaw4KN95XPeFRvMcvo5L8LexWqvaJPECzwXCs/4XPAlSMpWUzBBjK3pEnkbueMkMJQrYcnXf7PjbAoJra1VLX4YuscQLpaeYWbT+h24hCFrfcHjxxx6WTSe4AGY/KHRZCQKqTuFWt0D8RmGWmvXSdg1ptIefYPshuIVZT7CV4Ny67fvjJugy0TNYHqoCO45CB88kxrvIsih19DqjD0UqiJsTFPcGW3P/ULOG3nb8CjpgVTIoa5nO9ZYEX4uEHu8hLXrJPjV1lTQ5xTdZVagg+Wj8V0EE4yPsTc345KM6lVXqLiHtm+G6edC4GVEiPgd98g+twSYm18gCsPnjqlLcFm9e72CLJbYD+ocIZOxuVjrX6IKh9fh7WqdIZ66x9PWkDGOVVGkx7jM76Ywe16DX9ng205kg5eq+R2q2MguTJxYv/wWHliD9mOYpzZKNXYC3Wr4iBGkm54hBwkPzFhiX/VBHdVH/KJ1ZIMOHxIN6arKdxrm6EBsgwDt0mPe0MX1HRUMq8ctcmysU6xX0bzM1J07kAvq33jw1q0Pq2cyMWme8F7aVkfhzZEFdyi8fVBQav0YZqvAjZ83WKH726rBx5Bn7GHFthR6H4lFsltu+jWmsAibJ3kpWMG/QbncU7n9skIBL0MuXXtj9sJg+4Dl0XhKJ1LcrMydaIgyrgZgScP4k8YQvcsBmD26X1iYXKLzMYfZn2IfRjznsrJ1e5cnl/3a5xiNoI6n1x1U36FWckJbyx+hiSZg0QqAqeeSvzFYMlZ2REnO/a6yoQhu7PdHMYEPFIvfyGeyCU8e7rpju4DrlOhszj9rOIpNsvCkuD+TLyf5J7D/wsPkBpscFVI1q7oUSU9bN30vH5AqnO7bsf+9rGhtVjOJQ32H9hHSAzR2ape4L0Cz4WxaySm4jvuGXwkFp5NMMLrgZ8LdA+5uLuyxO5SMOmJNDBcbbLefv7z6LyxBwltnfQLd7qqpG1MmNcoLUcx73BkNF/xpdS0cKd6G646ntChXSeTZJJTFYGw39T7fqXDPKoG2cF7/ZcTvME42gXLVjTqzAER1Rt5m7GYsh0X0+XgOeW9MJqE5j/rpGzY6vUu6ACcCTzDMdZHiWELpDnvgE1hmztLcSYz0MtNyUBLqvylUJJnJu79Sku9NMHCTkgqozTnhMFfduV2NLCSYvAI5HUvQp1h/M02vKFD6eosIkGTg6mujUo1W8hy5Knf/erkBQC9LzNqPAYCgR+hczgevta88NNqSlBZryq9QNeUK7RpbvHjoNhUKAAeNYH55LeTW36KyFaXdAkBvyNP9xmRuBokPi2OhqDby6IZ61mwfzG+GmACkS+G80A4WGON5izgJWeeDK91jzusfOi0RmEsVJXwbVUr8u/J2LCQaMnHhi+wJTEPN9tS2b6W4GRGCNmtjAMgPsP357nOeD3H2tcDAPu5xQBKMHf/j4ZhXlkvvy3YmBJsjsd4pSOlfPZCnw5JvzxEXM5JIc+E2mU4CgB0mdJnH4NEsCHYNeVRDXFNuyZUE4nuvaJf1h+11AWLdAZ72D9XNRcxfb2+XHZN/SN48U7yl+sNZhg5gn/PD8wkBtnRj1zBUPIWnoMP6yGUEEzuT+VaX3x2jEIZAZsr3rs9wCfY1Ss0EdIFFzBbyruUup4EPanbSYew5tf16/ZWVup5iykttuqL4xoC/jdZWsAZeSfDSd3fP9kbyAFYXkf0Q2lmxaTkKRZrCo9XCoiUG4yP1URJ5G7+HSOhhJp0Anz0N07QZtyFUye6rcgiOFbtyoO1lkuV0iQ602MTyFK9xLqNHtNy4cJaTO6hjtiwNynVc34ZA6H7k8ai6S6eF6jIG0xJx+JfP97lzuCZr8vU5SIzImaNpiQhyvDbz23//PJcOk7hD4iIvJzfIgOGIR6ZPEJpWHZQoacbF+omeHw8aWHaNOfaIyGeG4lEryMfhtNmWh4RAIpn8dLs7ZE2eTVDwK++xDoSUgh47WDmKlZ/k6OosEUoQjk7Q+Kp7OxwgMFShAv6z4pTW8loVj2+qXLQ0T3hmIue8qHy1o/HXjm089m71t6mrrUyDftqMYtmfvQXKDlZ+K1HR/FkqPSqcjGlcPPIwbMw3wIFKBdVMJ4pFLt+oOIkWZMw8pkoYZ3byw4LmAF+7BdicGXFcb5PWtDw5XNNVc6eB9dv0rAEpgr5J+bLr010bpfGw+IkRoxDbkDFmQdEQUSElP5bViLo1ur/23KN0jEwl+rGC6AUMKxHcv+T9F1Ktpn8jSSrKxJnVkK8UD/tH5DN6nXB8mjUdFU539e9ywLtLYCwmHYVEVqnFmdubduaSd1ivIo4pTsX+mJcOAkrR1D60RIoocCBIdwJhCBM1rOE2XSlPo0U+khALvw+zfxYzwzd4roWlLJkZheFRR8QB8v4USwmAcDswUZ2P/7v7Xa51Fs7orYebYyww4YW5869Y/c6Kq2eTR9HLSjYuChTkXaDygoo8nz/yJ0KzfX8oowaNAwz8HvQdlLU9V9hjqYMURyYvPzZ60G0itmUdZwB+sY6rUkMAZZtWStbDFmnk/dQorhwr3121XQWffrK3as0g29ASwxbsZ3dZAq/96b7/XWckbjmo8+jwdE680DzoEUUivnBgowMuBQxHXoGyp+w/cSGY88rWtmwoyNNIvChs/QsZRnbdV7y8x7t2RkliJV/j8e6qfctrTsMV22zoqgQuTSNFh7U7p/Q49L0kygXNnEYXCBDgi5BeNWxu7VjULcUHI+lGj+OTCEATzWrDmaynq3wT9IAejtvh3esCu6sEu9JOsXxMDpqxm4Tzl+pt2Wa5Bq3TM5TKH4N7KLir8FGIPA569+uJ1VEL3fW8Jyigz/nEUjAVYrdCWq2MnS4hQVgcvXq9aF7Xke/k++rAtIQqckPNwjKrV2t7HCOrA1ps88Y5Rw1Zp+9itnB71j8tNiQc7mV1kUCQXkoi5fOsq1uC6hUPUL7Z69NAM6lg0c/aeiifHoi35v+pVBh7CDM1XfvYpiK5JIbIQFHafmnhHfRTnMagKcjdE7zzgtxkTPKVrObTySTT51g9bB5ro/dzn/sB24fNM2LGJuRQsmC49PLi1jTRfZaLpo8Txxxczij5Pl2vur+S1wQW3W5qyVcIUySZHtFDQHv+EYDoZG1T1J7D91vEIV8dHzUBzW1UyuxRbP+M/CM/vsas6RzmS5traXnQ0Jzv9hYXxKHcs15TQCP744XsLjzFjILYURXFnhM+nnV0iO6nwls9TR4tlz1J9/NvE8FGg5mgpZA4htS05AK0NnU2gxuqf2vjCyWlm3ypKvaX4vxh8Um1MHGB2NTeAFhbDyGm+5w2zqJAWxVlj6dVePb5yR+aMhuz05YubCQJ0BOtoYQ6PoDoW5fCwCtXj5SHvCgL/3B5z2mcXWaRTf8/GsFAfX/ntdWZWFc2xg8MJeenwZ4dZUToce43If4zVb1ex3BMAWGhgkPwR5EgktZhW3Yi+nsnZTUr9FYI160YhAraB0zMV+ouHz6hYm25/ETDM0MTmcypoGgZISSkfwYAQaHGY45yZ91K4A4Mm4fnbMk8GTc4orypT3NLBqAxYdcY/qCH82PpIkmVOEHi1NoYaUymuImLLcib5pmd2MHTB3JR+4rLdRc3gtQ9zeFdciciRiWviu3HkqaLSxJeI2rgc7OKQslItumACQow89elXmi4P3gTZeCauvMH5nF4VrBcLjjwGD+KlKqe/RWIEgT2wGqAgSuL6b+RTTPnQZzxZ5y5HQJkEEKJp5NfoB8hJBM8qn6xbOFtyzBjVBrwSS1zCJR3lEc9ODQ5Wu/xct9/2Q6qLHnmNx6XwZus/i8rEd6UsVxGtoDrm+Br0L5oUojlwdcqyVV4PIMsR60JhZwJtgX7izQWj+GOeF9DA8Wexdmv6DWjgR8LEBp9YuPAM8tJDu3uCumNqHnF2ATYX/tuVO55OgQuiUhmDmJbF9jJyifBRtxOVI9DCNLUY71IXZYTuiYcnILQ/XHuVJ8aHDStL0N+3eYNvXwHi2vEiTPnBqzsC4TsPnFVnYY042j5i7C11AVdBZ1pGSa52jM9dIL119rry0mgGxFzI8xPs+7bmMfYKh37A4HtA081olG1m9S4Zch2hoNCGVvVhd6UL7C2d5hKIBHoB+Uxarq/4aQXhh7IWjSj+ca7Vhqb4+ZwY3nHXh2S9JH4XZxQojbe/eINxYlozTYtT2rpU/xbj+W2hXjFQ+z+dQ8wh9751MP0UpjutQdxz3/FJYAEG5BF400JXWCBs7KrCRf/l+F+d9EuwVk6thOPDB+HNS9iWlLmDgXvY6K0vgiyoeA3An+jWufdAG1suUMBuJT+/w0FNJZbObUT8c5q5WtQxASQF6E+/u8UwVBs1eo8jTamCrcdhZJlADJbqn3crcDHQlBQNGq7btcGKiJXW6q0cn3F0xzf+k1JJS2testB3rx15ZPTDXm8QV5XE2qxBOdM2n6t5YbxyNOmEdsHx+hMp+y9pWkcgw1NikeXuafJvzcjaNwE1Ad6gG79S68aO7jWpKgBETYLmV4ONHhBk7Be8tjf2WVvWMDQvQdOnk448yeMv1tQKU1xev0L171e/qxkMZbmkfKnd29XRCK2hgNNJhwt1qiYWZGKz7Di6K3fGDT7DO2YQ7WU33svE/WKGbWQEvzUV2w+VNYDocI4yxQ6i3i4zU2TjmjCwu5Pk+Ja9HSwLpEoUswq3tFJ1jimthgMXd7KjSl6Qd0K+vxWT8G4/+xITHsWDGSfQTSdFQth5uVVfa8wrkDZHTGVgpJys2ik+3I0dSf6TNo6A/sVptyY/kx1hdAWKPI6t/xj6s+fPMU3hg1vkEB0RRHq/tCy3KUUhzU/d0JKxTyjvUms5iy1GbOFco0NA4t83SK9sBmtLWm4kOLLflyxqgQYP08iyXwYXzKnlQ6VTipuaspSJ9g5H5Lu3eLMnPKbhcwuEg0VZ80ppJWjUnhS3rL35erzysp+fJhxsUs86m28/UwW+IgrS5Y0zWaxlFJ8xML5wk8sg1ragF+eNajyI0Y4mwStxt1RZH2BjaAhvu+SnNNIK88thEgZEsoHv+ii+OMmXJL7dnAiINVDz3tCnqDgpQX9OguNGgZj3axcjq1UgxDw785yNIpqNiLgv57399jVmJ0/RStNswaFIs6FtnkilFZldxj6m562jL4p5g3Y9XCiXRJX6nq2PGJFifFR7EyPG4jDMnBM4t+O8ZpEp3th7TCxEw+ZG4afHl4sNFaqxyLh6+979tt0Aq9BrqI+CS2U7HJoKiGmyVU1lFa3/0O5mNC1bzRgNMy+GXyifLwJP7FwUSUmxmVRpn+gnXWoIuswPutsiciurvN6lsMG7yqEc2Y5ZI3jrPgPq0xEKPZpF7teJa0TQn8BQL4Th+hjv2ByfwKookyXEmj0d1KMcsmfKaeKK3cZZubiYqmSCrnGpYTwgPk5itKucVtjViuswQsDR6TuyGSIHYvlz7wkLg1Rr0K9kV1o8RgABlhbLrN74cVWJW6TnfXN0q12JFMpUbEa8t1+j440FA+17o8qa8PQ9igkctVROVIfB3jU5vtGm5pYYHYSDvU2TEc15pIz19ka1q6c/7WXfF8+POkApdOw7nn7Kqz6V4tru7NXgnA/u0g6+fPRT3hp/QrDQwMsjwNCZxdWrR6pgCBDJNc7/KAlwC0UZ4yWQs0KsuwbbOgcTxQPK54wiXr7s+221hzZ8RVxfoRUKM3e4lpxHC83JllxlrV760tl06f7/65qhE1jhMfivAUXIXfRMe3uY/G2TpWYzDrw5Cm5cS062Bx9lhHq9gtJp8xZwAtSdSuW/Kd7+orEAiswA76N8ezmVGYgNaYlQ/xk930LAWAtKVBC4U6R08L45IohB1kFia7XJs0TcaT2zBZoLFuOGu4iJaoAnfjL3uS6gnRH7G7A+aT6ETlmkYUfgrBuaSLLDJfhPJe01PfN0oqBTeQURasl3N8BZiQSgdr0aDv3hPTiog4NSyfAUyy98WP7dnTDWQTY+Qwzgk1uxwRqHl5MpC/84Cuw1TXfRlgJrwPop10kCHjmffnFdxCe2J3R3J5j+3H/sZn3IUu3Suy+I+dAOMWvzwExNR3RRPVelZAhtarKlXPWNjPRIVP4JsAFSRXs3o/fSYAPaV/zP8q6DltH47/rYhCLdy/LrpOsbaLf09eACcClJosNefetNElkSFSuCgeY7oTAAl+8Y2zOXJb/bgEDpoDXfQqc6lnlBr/WsmVznkBS1M7ufiqpxvKXjwvR4WxLbh5NbMNy8LsnX4UiuAi8XonbSUcVZKQOWBYUecSOMj6jMG8gHu7WNreBHY90lV7FocDprSrSbexkAtMW9KlXcnrOyLnZdodGYdxz8aw71HztIqLhRdCOB6NyzHPoS2hDy6wLk0I5Jr2t+U0A+A7EsgSn/Ih03A5CspHnVF4MOic+Lck3m61Um+GHDEe4DrHBhmgtDlRQl1XJ/V/VumCHtUDDcZCkgjVMBOmVOGYW0Rcdi1ahdjhBcFlfjA+5cRjBop1aNDvdrf7CxkLVgxiCxhRctW8wczM8+kVmIrGtkaHGlr8y2D098HXE23r7fnJFUU68zyeyM265igNOGPzFG0dIgUDWN6S3ZcfMERJdWVvpGhVEHXNLeWqHiTcF3wOt0FbJY4XHEpmkoG9MQPJJ4ueQ01+MB+SR0rCSGzlE8zod19q75LlLWgzogpnJoD4gPxUYcX+Gpc5Ly4nk+Zm8LDXcNR7SNVxLh6NAcx8ekjb/AC7ADlRnfuHaHJaBodZr7RBX9FLTvocY6kY8bavdAkQicE9bbwGLkZu6whTCJ56lOvM39ijehpTOFqR3V53nQx4hfOvwRPU2y2w7UU8yiRbcyaX6jGJ9CRvl9ybV1tebTp5MMuMnwLcx/lven0w9T0atJuiUE2WtYGiVMaP3EchABl5AsyaCpu/BKAWDFvU2vaCL2/fJBKCKLjxG6xzT4Mh4wHhH3/EqsGSoQAHu2wbHmXHj2LvoW19GXDa2oyeKRwGG1PU+S7mE/S+UmjHiDF1oqJ0R5QsdjAZYN1MzpNX5YDqWYfhfdjAXyFQaVyGKkp1oEGTR8MK6jaGfRDFd41u2Ex8ac8jKPYu3pXsk8gu+m9tr1RVzTTuDsACW4S1h32yFHX7qpXSmA0QVEcR8W9j2Juu0pcYqTmdis88VgT3gq7iYue5Hx/3K6hFQa9rZrNSDcjaSQlNn4LSqs20bypnKqpzvnnxjMdz5StbzvoAJKgVZa4DLCVoJW765/KyTF4s4YztmAT1c0pTmKJHTpa106FegDo8p2zD6uOnwpYi0vJlRMDe9wPT6964UfAf6lq3qWypUOx9q6BbKEYt7K3gWMXDNN6wAm1fNnSOnZ4JkbPq7jLQrl0wL1V7QwO/sXneKGfTgUL28I5iPVG9dA2gS7Ki005JUR7Vmw4gX4TJvy1WS74cIXD08LCF5obqcZwamuoZ+FPMJEck0TLHjyH1baPr55/Cy0ptDfRJ7d89pbP48tLMHG5dO11Z8xSSpPGQSgXDWmpsNsmm+MvxJjMCi7OFDHxxpmTtjgnOCq+c7Fi1DybfhAntviKccz+sj+OPKPYOKeYYPLvq6MpUx/chSvBccg9dfbeqetQNCs3eiCFZTU1mrDido/mib64STMgsa+IKLk9PyxGGbVSQB9GsHto6f5prAFIbRDSItDedz3t5+Nn69FFS0nEfmkF7hKBmNVce5xv65USKGBoHYxJyutSGnRIq7vMDsAMvirOEJOzNi5Kt7fypuSU2c2Npo6UH5jMOkePH0TwgpammO3Fb2FX6f11309z/mqRmQ949HHRj/wMzKNx95M9pwKf+UQkMEwisL3YVotvHhCv4y00Ui0Ql8dR7tGqFcSdYtmoAOuAodkBNs4PZSjAAF7S/szwLddFMdCyB/dWPgFUiUE+WmUUCjYrKfJLQfNNpQ4NKaF57w7Kp/isZVwQPUJyjJavN3fQNKU+F74jVBJYQEcEdw0Niinyea0l9PJ1/AcTm/LI91RZjDvLI81pnat7RKU2P4/TnIAa3hIEfeg4iGQ+wTDlURK6YjNpN5s5VkQW9w7sDYKU4XmjyZsCQLxztqd4SDQvLyuPDhURAJXKfR1c7tq3mRu4usFHPqz7HgS0X7kNxiWWR3fb3uVwbgKpmgLYkwKrXKt09COw4MjhxeZlDXKy7nNLHXAIKPtferWQnZLboonQXK81x+BB3oUidBehK1swSXxVbscj/LsfONu/xYEXYPM3aMqIYd+2hAnFvDHbdrJLhGEd3sG5PyxqhzejhQJo9wauFK3xmPYqxB99J8zYU9/yzrEZNzzbvPoR9vUlE3Ha4zspVDzHHffPZMJ1VLZkKqGCf8ZqupqMt6T+NRPfmPm2xeDgvzMrRJEL4/zzlu7Z35smvzbgeC25VP2CUrZkRxEi15A0769ojdO1d7C9OG+swj1ROMM3NgKdeBADoRMeJkRZcZ1FbQu6C0BS9NNSaoxtFzYT4lX7+PQ7BKa84yrN+ujVVef+SgnEie1G0N+eOtbZF/UU+wkeerWjloYqFiqo0vBnmxh+TwNMo9I/8lfU2XTCT0K4OoWE08ipyNHjxHvfhY6qa3x4HzdQ8+jkiO5+j91YkihS5memfpFREHP/2veN5XcRue2zCVuAub8V6vDlOvyP+PBm+owyRhMmng5wwGGIXsOkQekXrXpE/6dFjkHwwoFoj5bIFiqp+4wHpSWRbv2xGrRpd2c87FzMP6Hfj/3LWIBqFiNOAxBw+AAP1XqUBszdZhzOSQrQS4Ein4fyV7MaGsB0VsMF4bPb4lx/foTGQRJv45LpoxDd84xCawHaX7jpXUrOdkFxx2oUvY2xqpgIvcVufwd+zAnaaVTnEyDXD7S/o/xrrk4mgTjXhcjj5Rzrbr23NmuZQvpdNzny5MCR9bwvIRIqzOZZLsstZSCDYa56JTvzxgBs20dYTtTUbe21uljlWqGfSh2bYAzOpf6UguK30ZxNXgLHs6Y6urtxFA5iLYvlue5mDONW0MOtQjhqr8fRbCkYneiDkvzHkQVT4F9v9vxh2SIGPBH8bZb8ugo/BSgXojeSdNXbBAIDsB6DUNSXnwlu/bFLaCqSbvu4+YLplwO1JbtrMf9ZUfsxerAZjB7E/zl3qwgK27FswemUmSM4i37YAVhQSocuV8AcDI/CSeCDNPavESshDQ8A/lVIrAJAMdP/rHXouiNU8RL/TIvfQiuZEb6dkIKMGGOW5kT8vO8pivWnT4v7qmwuJo52AS1r/RyQ2g/7c9ZJgmMIzf0GvJJRfMNu1utRNuLWHOm9JIMcJK3qiDtVpGCDP45W1oTTMUnMC91kYhP0GHjhCW8V38xhjHgFFBfuWMsmSQ9MvNqKXiqtUhDAkIy0PW7YSKaKUv6zctAiIk+Jt17kG6LpNVOeMvJnlVBaJSkKe0HTJJUMvf8R2zna35/yh2wNlWLzIP3BJR5aRNxkV94ICOlycI1/JYRZtzvWMNoIpQrdNvyBuBydhSwhRwPo079Xk/XQZpbhzN/KK4NbdJQV0JIMP+Y5UBIM3TTYlFGYVjcvA5yVozkimco91Fx/eo+ydgAx1gMezTh+bYxCtXPYkMoPdtaElRusxlmdSV9zgF4Np+iylun3LVxCycAFxGCFsmARf6y4I6zXY0tx81aQyalr3/ih+ZjxGNWdhItgNLdEZ/BOIJpPoAveh2bKbEFxU/M0+4xqDo3Ox8MnNn8Lmv15NJigSvJV+y2W/ZogEXNiv0/nuFzZGr0pKujOShzcdkEVlMw8mNZXZCbtM9V+mfawtLxCTvo+enFWhJcFv8LVTFycDjPGBXRQKNN+z68HJtYdpH++g5WdhQpCO+DE7Qdu6TmZgtetrpU2ZlgpslOx+4hb3aXaqbdc92LCh51er8vm1GQ9uWD9+fAPRV50ixhgc5zi2Jsg1xQVxzlaELRWJ5biyF+eCwNV0oFnTbBHr3Glm9qlGVOpoOsQC8hlNG88fxeAekkCGnHFn6i5WzyO7ShDYbZ2KM4eqndyy01v+6TFhmkxgc0dndt7EzRCcEfBxSaWZwcev6MDZcuvSZQ9CNSd4Tx25TY6UAbrhikuP1vNFfPdZhCG1pe6vx4D6Ez3zIb0zDa42FPpxWvIpEeXb7YTcfZOahSpSYaWLH/vq0F3U1KO7ZxliZpoMBBYJs91IE0bOkrPNQ/USYY0qKCO3CU+AFbOYxzKWBkIglrX34377BZ18MKQCv1KWfIHEeguSpvrNH5RQOD4LeiH2gdx1MOAKphlL41F4RpxaU4dy8xERFgqoyICQq9XmQ8WJSokwqvhQM0fLtsvyCO2PAkJ3BZg5IqoR5q/GdTLgOWPFR53Nqw9Ma5vBzZcQ4+iZgetmKg5ZIn+/7Jbi+VlViXuD9CaAUtdEmnwWTS7wZWuskVvc/SDaaKV+Jz6HrZTHo3UrAu0IZDBkXWmL+mTTjdTb1A+MdhKkY/hvFNwXj1FzUngsN58u/kTdJ3Xi0hy7efR6faAOi4SKGaiOty8lxDFkiD9wq2GW1EZEsoWGw/WzxXhWDzYY8CC7WuLFHc+x19jhH+FiLXwDIARRtnkJPF2BUPZ9+grZ3tjqAWhhN3h74w5pooRQUNATy05A9HDLnILGSCtfESoSilqtqAIQ/TV2t3KhOc+teDf5t+DqZDdB8Ob9YXyklrSO73pR0QAxPvQj57c6FIR5dOciqeHZ2LRABMROo8Jk8V6JFewCL8TCd/A5MSbXLky1cW7mXobqgeEXdFDoEydKo5oCuyn+2JYI/7pIGFAzErlHZ5hOaiT17HC3zp2HpJwsIAb4/oIoZ8x8ak43Yp83Ermq55Dg8HxKGHXbXs47sh0PzQELTGFsf5eO3lYAuJjMneoYWk8W/3tW2WLntEKBZEW4hOFgo8K58Rj0vk5KLyezu1d8SO/JcuxpOJqFUM2sxBmbQ/9qqwb90R0WulpR/Ju84bQ5/fTh7po/pbBb7AQaYNdK3fatD3K4TLHAaa66MQzp/+ZGyCjzo5OXRzJ8UHyg/YpNHvvlOpwQIOjakpLHwGV4WsLDPjEIqG23ily3LL0dlkYQxj3Xx0ApCo35zYGoGOtIclYS83MnI5TwVdQ+Hg453WFQN694DaqhGaL/dm0KncXYqXLi5polgT4DOrzD4oSVhrkh8GW2PaXjOFDCLPcn4RQj8dRGIJuV81LxMPZ0UL6zpkaebhbFBxcRJe38UiTbUPDjFWk2jBqzrBvXcKmgdDcmRyJhIpuq+3DQY464AlY42z2EM0yIK0I6b+VgpanMfpdWo7OxKY8RM5tSJv340/qD8SxrYsybMuUkF8fHj7HcvxEPC5YYrH4LW1YKg6QaeFZLvPbrHZHvi4OXLKkN8cGQO8019OKqcv6QnBlj01e7qS5evoGm53rv+VmDxxCXDiOrDg+IaPeMPrn8TJ1oReXYI3yb+4HQbikxP5TQXHk4YXPUv95+KmkxGsRgTwP71YiMpqNXp0loHZeXRp9i3euKrVtxMM0e6XAoACwNtcc6sOuhZVb1htBLudzahrDFt5GkdlwHjZl5y0LbvSHwII+qYeDwRKTTzyXaInHIM+8rc5TrjUlPRVwB5LKFpQnV8e7vLv7T7V/iJTW9h9TnRtNCSGcofBWYm5P7wZcAq3AFamEW/GMbo27ldz0plt5HI53ddWkn9IuCZY+Iy0MATUh3YenRTbVgdLYtu893SuN6EL4e9V4NhlzUjI8nOS6B99ecyC1Ot8sDahQpWHbmt2YvWGyL3S9tEVLKYs+LnghBmmSl2uPWfqPobPwBHNLW21LUjfZb7jfLMTsMp3icGO1npK/rCsUgdBVKVg0Ys+/WKuTmVJoC8Oe5h3PK1TQhbpZ2ytP9nlutQPtLAEt+CVT90DfVkn7lHLOX8AfS6HLzfHeAhu1alnl19RHKV1LI0G7RPzYgVaSpX7th9f06uo2WpxjL86i/2uzK2qj/ClHbGDyQr3F9/axmq4kJ7zZFVXVVwfiFr5bhUGVZeQJHKFAcsnqPKsb8vHyB9SpFpT9U1U7D4aS9vYgqajxhC+hOkolJV2dKAxysCkWBo3SPiPUrSQYZxOWwWCoQzbV0oeaDEcgUtqI3nq9TSmpQ688/+wb26P2CHLY1H7q5lypXSrnwnnztq/jN1o9lyvLmLyGguV0VJnDCREkiUNrZqGG06MsyA+Phd9CuFoM5M1Pyk7S6TJaHdTw0ni3n5ysAup0kyxr65lFc81NcH8xSmpp+iOEtQZrH/y01k1rGMRJAGFhi+nDecpUlnrh+qBOCMZCcSCovOPJrxjZnZJDMLdpMVu+tBSVS1nKxsYjY9Dtq1/++riVfLUVhzofIcIgQQPOqHioELxU3EpCcZMoL9laa5YlOZAMEp5apx7CphrkL+fyKbBAf8ctwVd93FTo7F5Oc/alNsCgK6lHruPROtN2RybiLqx8P5LTUZXU+Aoyz08zYHasR3U8hPDKj+6arWXR9yWdJoMn45prCSURKKy3+JHgvs2Ot6v6GbEtdCumgCttv2VNoU3KOqUwqNIWHqYm4eMijTM9VWB7umEyp7UPOI8fduHJY0W9xSCZdvc2xMjo3Zdu2o/WZKDMOSh9UmLvo45IBppD2dG++HJu8kbfFdlwuIxk2KHhgHQeNKcHhFkYGRzL2VJVMOAb0Co64wvds5CaYl9ZmBm4zuGDeaO2eI1XM4+rD/HmZyRF62SabgAe8TF43VuMutigJJMfbW2UK0azGLFbOfujnHD+GGBYmSmOQbUCOY99HYvswBQA6r9hrc2jtsUUxLVjxnZ4JnIrTwIVdWCTPtpJpvlA7m01/4tbUMyz9mv1jdN1jkiHQCJXXKg8bJ+aqW6rbwbn5yDSHBTcFXIegrhHGAjJOZI1pyP83Z3vMYTAJoo8V9IwyS+U6OVg78+IhSYHDYjRs8FrF8smHQ9h4qAYxp49rRP2d5uxLAuP72GvZaYvfeLOkMrcg0PkPuq7NsXhMFmiZa6PKBH1l+oKHI5DBLdZCvCwTPdXqmnz8gLzVRb/ixLTSdit2nrzt0x+5rDeZT+ac31NKNskQs6noKlQccyD3UxzfVZFmcbpmrfPsZD0Ve34xpKWk/E9Khn4A5yVPVq+dwnv0EyYecPqXGU7R8suTW0A6NJWweLI3iSGDlQXzMYsSWkSMhFTfyA2vTDt/3wXk+mVU6bRNkZvNnyVHYiA4tmnNwdh/RVsk/EgSerfTIf5VBmuAc2IKSeL5Nbrg3acgFj80mI8SWsc3dNAGCBLLMP89gH5UnLTKq78d9SxQH/g7DVnBh/qnBdw5CDrw/uMzcdXSxWqGIFcnQZt/1aOHxUg88MN2w+FPx/V75gy2wzEVe6G51PQIR2tZsxbv62HhgjwtlzrVREw/yzlaAiuXC26cnpvQzWXp2mOgihyPCWqq38nEadX2T7f1Y5zGxEGBaT//IcL/BsquAJX5EDbX8X1p8nLWR2yyjFRvqC/jssoCJBCDJOsZvoBfXqQSEKhNARH1YfueeKBslAwLi24/wAO1BHptlf1kQFNsOPlDvlYednrEp3a4SAz/G7LIVEsZBu0EKWZu/euB/XKdkGonP6t6lgEcCOw8mceuzvEVzyoPnMyzrqoNQXJb9C8ZCXSiedKiCgNwfNkpVlHbUgE2Rb9WFScOeEad+T+jT8XlSc8rcvkIuhAv/gxRu2eb2GonLTyokjcGF1EBpCJbhy2H3lhL0rdZIw1okA5pBg2oRfQceXTPzhuNKorTEF7t1UIgDqIo7/loxyTgbtKu29o9K9KujvCqUGyPY7upcfiZLNBVKh5uXAAZjQjhlhBp0ukmO4Avxu4xAVhCtnsOIA/tAm94U3HEuSr3wq+ZLo8pyoC9EB/q3pOzQRyCTkozmJwo1Ln/2xEbtNnS2S0NUIS3yz3/mBIdxONHxqP9FW+uoGI1F415lI1nZwK0SoPA0+flaokBGEoXgZnO4GOExU7VOjdPns59ekmDxqNhEHeAF5i5N/3W2NC1XGFjTpqLrnCECiwVkOTrLtp2ehUIaejOG6+1336YQSKMSsL4zhUjw6SQKryVRz5Ldn3R5/r8AOi02RJkQXPdvPsl/FMg96E/cJmIFLmEDzr1Gkh9G3zisG4pqM/MV6XIz+CtDUh6hmJB97VzN8jaPSS90vgDjvnaNlKky2/zIhE9ObugwrftI+Oi2a4VVaB/Mwn3VmaWjsU9NOf2usbcN/GLQMjvfeU/YvyEERPKw1leXZWWk1HXzY3P9MUq6MZq1hkEgFzds51mv8mnp1i4pQprPwY0TId1szXwe5TG+R5mMD76nGPQr7/EhQWksjsgGs7Zy5QYvMcGV5tcXJR+6hlHFIAc/M6XjkKYtwm673Bi+K1tNO9i1YBePTur4I+gMsOK7f7980mcJXhgdWdhNzUN2JvFsvXq3zZRG2V30sJtJYxj0aUv1u4/ppVHi1iHnTY3gDHsrQS8YwMX5XwZ2gcFYYe2wd7ZO9swr0gb8zf/fXx8QWKPXcK1UdJk3760B/TMlpWLCbhkqVoSTsOqzgkmFmFteCCTGhNyvFhw1RrTIWzRxq8Tj5FirvKvtkp2GAVhnZ7vnr71pyI0rKwQbVxKZuqM7GAvn2mRBj5p8djlHUsh/r/eBECptpbbjP5nFyuN4mvQLZCaxeTkDUzd/kNGLIzBFv1CElQO+xmf7Dzt1f7GM1Bh+wLDCJZlhcVDXbtPuGssdEie3lZNiWcXMTjZtWAT5MCmpq6JCRuFSHZYGKcSFZ9kOYJfEqLIcWdzpTA+Hmu+ktgSUwXVSwkaa/aHdZXh7IOyrudCBalCZpgXGRNbhN2XpEY60DXXO1Ci5ayZSoxtG0WRCC50+XtgWz7qgX5MRA5S+jzXCYy7O7Nn0ljVxiBxQNCZKZMTqi6mPfy2LZx76uyRUXHjnpJJEimflHDUxyX7fFg7iJvSrsZMH6Uv2xbfQNx5eCbx3oKycUrBY22KPmgfg/w07CDVsw6tb5VxPg5/X38cQtXI47U7MAGGjO28II12T+PjaXHlstPtkUQNn0DKkCYis+kVAkA1wyAJgYKLGnKD3nlVCarYqCkNIZbiVwO2Ydjl7N6iOtvvbAfuq7VKZLo0jEdw1YdsRaHcuJQulgb51JyELzYBkP1hd03IDcZfPg5XmNvYQSOINsCSn3BuLtkCPZRalK7+S97zxvJHiJCZJM9XP785NZ8B8fqDe/Ot0BS3PH1ptErwxBtpgfOj4d/41nrSjJQf9bV1kfdBHJxYbHILxOsWkZvoP/Z4Sl0Yx3bDjTF96xf96+6uIoQ351Ce6DeTwTnkPr20YwATlnhskWIddUohklNITCq/07zkiEc3B58uiBG6d9YAc4h/7s44FN2RG1UuZWeojrOZIhElvDP4KqHcOYbqqS95o7ilQH5ONJfy+aYiB+sPpn35HfHG3duLpNvBjXc+Klf4IKrFHjeVty02xPTNnbdL4gtkqPqMLhSgR/fDXzxJbSScqewiF1wdVoJ/fGL/nGWZfVlDHOQKD+/i/mqwXqvNqxtZeRHwoe/bodk66B9soOnZp36gdzVMRRQsQiBFf+HXjRcrRf9FsGghw3+qoN0JeeMvDJrkSBPsESDai/uVOzn2Ohge+UVdi050fdWpsjP0D/QuTdYs6QyI9xnhU8WT2+KBKzoZ7Bq8fOdKPeLulUhJjT34/EOnUloqus8+pzqNh/UdUOhgTlrbkuTfsaIYDm87u/GNIl3N53uaU8bgaBjpz0jdu1f59K4KFDtwUUeEUoeYx6DEkWKHdi7dtHhQF44lbysk7PqERrsuAQu2D5tDMl7kFoGdI8r/s8rMytJzYBU40wqeFvTl0ZVLdOB6Ya9E/f8VPbGx5MdpYqYMLMyB0QxVdnoJ+tgAQVWfH+jtOHD3PsjuT8dOTSrupuvHWRHQoGI1Qj1Hc6k+Mg84FAZ/gzl3SEzuGWZKFwuo2D3EiG95D2Z1szTqAuFRmT1nEh20tkC4ysmXx6JtN0taK1iRR62s2uNW5rSAvMEJ8yotr3UhJe22brlQn8Gvcq1I0aODaHJucQKVe6SXyfcDWODMw8xf+2C7Zx5a4Qlh7pJs550DictL4OxcDXKvVmLgVWRwb3moxv4kcxzm89EERJXCl7X/BziBkGQWOHPGF+6K5NFJYOFVv4+NyFq+OPMaSWZKoydplufY+CYyL63T8MCMmwqLTmAE8h0prhi174wnx7DHZWYuRJSYZ63uz97AGOzyI3aebclnud77znbZetbWUripe+AadLQeZPtWsF+FNiaXCy/98km137lWewyc7Gamai1Hd3Ls+KMMVh0R3NKTQ08TIClDfMKwUGKy/7YZlJHU3uW60X0r74Afh02v5MJgVOYkjmors6GAaDU7yKHydfkXYd6nEjYc76xws1LDLWCNNKBtUHNyLseOyNDgmHiJ41lXvq638RzDGis8WIniOb/pbTs+HsQVGPi6mxG+CU+oflMR6/qx3pVP+GPgqa0U0lo8MVmI1cBgSnPGgrh+J+m9TVg8nivua0EQP7xai44ruC5gsAVOp9bLsDXfHQujo6IpBmpfbbU8PDavZpTuJtmflVQuOImnRQ5kKoQz2NBFjdiHH3cF9QLgDP5vz/W5trCy22Uk+TCjXjdbCCHB3rJhKYTwiyQUf8xu6yTKtIwrbw4tzFgXDODmWYEnnpDupk3b4AP3qz4AZ2En5wi6aZV287AgCF4vH8TlWLni1E5Hd93vLxSYLBWSuj3eXGFtWyWpBkIeKu+YsBh19VeakA8OePM0ILu6dYYl9DNIK3kU1ybH+A5xYhFI/EqSX3vtNs6V5eQgxYLvu0hYFjiG+n8JzqLQVROiVa8XNQDYJtDAetPFSuEtGI3B8rnbbrNo9TJn/z3lRYq0ecBIe7a03vLESwhKOm1bGTk2kPMv/Sh9wyCOmIore7JhSFT9HIjonBfi+gcdDLfFt7dpShJmW1gkcXmitWwm1cC480CraHm/or2MHphB9Q1bmt/SBXFqXJdcv5GTt3IS2fRgqThhInCjRkh7Dk1iS2vMBLSGtRPppb4FEu762JehUMQxxLQre365CKoJGvJwVde91XQ+bDp5ZsMu/QHmLgITmwGXSpQFQlQBajqquxlwIOe2cyfezaSHIoRNLcwjW+epnmAtmmWA9KU29v/cA2iuWbj9ZV7HR4anhHkjbxnzKPHnIZ7Mm5wAf2o/3xUhnfH++quS20TdhalHgNhusidPKWyKWV8ZjFLgb1fX2r7ifLyUtxuKHHIfCWXQJ/DKeU61vxmPT34MTi2Q9r7/sK1CYuHVqMBsgtfenn31bUzCoyPN89KiO5wHveqnk3uyHnJSUBVTQQ3NyRPmeRKTQvWEBZ4QWcSgMyZF0RQgvUXRcp6KflF056fwahSioP622TdcTVYi4cAwSZLWDvfjoKFLMowPQpzn6ogXHc93fFA5NZmnwslSuesOyNI1EE3RM8kzat6thkmpOiGmm69Yn8yNuxz1YuuPWekoybkee106T9WTPXo44ea9E5QH2Ig6FZn716DBa2FyXHG1B+YfnmhbEpANlOi61BoGO4+G3WMJDokJXj9GhNsFqdaLjA1pkhLP+/mGCZoYsxNI+A+sMvWyoj+PMWeR8koRz+r9pNVEWT70WhiAkNTrojdr0sBLwxIM7D4zT+cVy96ZE+ABi9CqkM9VK7iOfkJVp7AqCqQ9EZ9emn8rB8zfoQZUBrVd6YS2AqiTFt0nJ8HfPGmnBWf3Xi5CgyWoLAmHJp/AfTdHB0+Ns5DlhL6UJ+O/6xys+CWVKtL9S8fVHkpwZZMJn6jVtiUTtXjywmiVXw9a6f/G7Qd4tZtcoS3aytxXYA9aGGmEeBobjiammhUaMDicH3nlOkDvvz19NqWOvHC2SMv7OQHtDIykYerPuoLz6SQNOBtw6oX2Sj3ZLITBDcWNx9CuZYYVaE+vleXnATrwn+PnuQ34jL52tp85aIOk684SUlQ8uyO2t+eIOHndZ3oxD+BcMAba/JVxRYUAUZoEw3D80WWOz0/ul+fYbhFnffx3PgOy2LLiu82D5FMSpi+Pd4EkIFTgfv7p/0vnX1wp0VpNzyXs/5S/4z0RFS21vIF67k1ERTfFuhLM/8fdbKognohMqTNF/+oqvXXLuJB7IHeDdn1X2eParLBEpz8y9CAN2g5VdE7EimekAOhkw+tTzqeEsgyQL4iVDnWrP/RcBd6CDm16/5t+I1SAxCn9wo8knzmpg8DYP8V/vHw8Stu7cliAt+G/VR4XPNZXWF2rZBeQO75os2jFJrbtkfhN9BzHT4HGgXTjyTy8NGsiQdeOw12GjYKCyxP+34kRHZqYsn0pFvVubB0+/emKRgiGXNRWQwMSvAB1xvTprD0Zyt08BjP/4W9HGNfNBcA0Qb9qF5hdQ4dDqpKAFLoIW2gFEVKOganw3M9/4WP9ckP0/g6kaJDRurtxNgT+PjvWYEWlFa80wKYCkd/0ZChV94njjGyg0t98Pz3AL2AFAhvRRiJwdfRcQqqhWkv/o6X45d5w1YLJOye3v7rgta7Ya0jAl/an42ng5Wz4S5we7n2+1W94JnpoGyV8WW2HYjKLkKmp4hBKlNtb5y4W1MrsG/wfq2N5Xrz2kqhdPQL/YoxgCQd6Y2KNkADVu7TxugQRWVuNL0BUj3JRFyWNeCmB74Wsz54OPnbq0GFFxzSkoiJ3Rtq8yEJMKvOMMalFKH7YFHKjb2nwrKVfuUUuRtTfJDiBuaEHHoX+MUrM2bBaAsSdnY5PjqcMBn/wwojQxzt2MoOCC3OEArr09ghhsj2M0mue5ntQcmcC1R/sK3zfShGJuazS+mJUeKxk5u36CYj8+SJCq8ZEv7bNf1+BywGeDQoTDGq6Yh1xW3Suwo2O/ykazTPK/TdVOICyiwK8MuQpK+FX3mqSPzxfLwFJ/iYDjs0WgW2kqXYgm+gkNToB5+jYH83Xlt0cbtEmkkBaVGlHz61rVuWzrK1yjn5nYHKvKCrBPPRth3AKDQQB83fdrbgIeIfB3iHya5NPpEyxbzmtN5Dnk7GqrQ4uu4h3QSoHU+74zs31cWqIx4SZ2bwWLvIxUtR6gufZhNZoMcmSB5z1O9TKvHMORD+VmuiqzsyJKA1OaApB+b9x6u9FTvUkalgl0r7raV+wRqimc2D7B1z/OiSagdd5UME2igLGUcgPlMSX1VsKQp/9yDiYei87KTBA2NPCUmgaLwVdvQFFFxWp2vGCY/KCUvxt3FOu6xIgwS4Vybvbj6feUCkrQPpO/wPHJPhAobSj/aa5YrUvjHMcQkDZwfc9mvghrk/PIPvcJa5InhVBfjh3Xr9vIvA4ac+m+pywS/EqkSX55xgiyj0TB1EE0NT3W2CPFdVD88P72SpdFzHS/6XsmbGtM8JE/m8eojzd4PM1bNADliZ+XG/9hbcKg6PftVKyKKt/8Bz4lGsHyT0VKj2vDGp/qDGBajSHrqzmpEjW5LXsb5kTV6HgbMcnPW2dzQju9N1sI/gPVlgGmk0bHKOX2Ws1q4aPizhcM/XiJ5EZNUK6bZNUeFaUJVTvGxglRUY7vdnoVOe0Raho3huh1XDeTlHpk/2gBjjhUQXe8FN5A4zcRqkNtKpSVq0xyw9j3yQlQxq/Lnqklpz8lXmzHkz8sX9HJjHwyn8UAjblvN0ZFIk4liejx0lVACoKvpsT9+pQoLY4weMHRzcuVC60DUFkaqLfclS4UJti5WK4FE3dYcc0OilX50uscLJomlR6pXriD6ELNNBWOSMt50CJjPkyt3Zn/xj1dlPVP1t6XExK+b3jMoULLPOrEGvjELfAMM1qcuBb0AijkIuFca8f8xapUlkvLjmmJW7RK94r8HaPzvmHHSqX9MXdivNI4A+JHy0VCe79UZZJvzMGzpnsj+Q6k3EItDBiA12fTMlSbEOMAWCdQq9TtyUiAaAqJozMzryEg0k+yVHqCc/DyJcCE2V4WXIhEnsOc5c8f4ChWfUaONhPPWogpDs/lyVCvp3m0NSfrAJKNiVy5aNC9gZ6c9BqwYgj/cDO3kdam6gCjhR+akALFYmt4ixHkWxKhDTGs5K+CwRiKJnvxP9dbxRPCBHbiVa8gsd2GuiNHZD98MNwXMdMC0MubVodd7dnyk3UQFfCIIL1osPxY0ZJ6DvZXwtZ2I0th6aqlTMULVo+lhSIU/5qO63lTSa3MgPRJEOi0AJ8/UlZuvgqLw9dyEDQoHTKWOsq+6fzoAyvIpv14fLaY+braPd6NkSaq0RClMenK1QLH87NZriUaeuCo6SZ7/CfUt2K6VOt0AjIK2jR0vorf6R8+TVzxZb+QdLimH9pU5tQc73xW93QRPMGy/gCK+R+YzmV4fHK52GWBEBL05EEoTY6OYG1WWji66dWnVTg0uPNw839p/yjLxkCfdTaH+v6hVUCd6HlROj6W8Mil6AYGC7NI2+qkZvJh/dAw/iQspXQNwwWHr6slLIp0hBHYTDh/J7Ba7ZR6cp3iU4bSXdmzhTahYDev4yKiIHyN64EANhI5OHYv1G4KXfIOvQizYWchPhzQg5eVGNMxsqrvWVxjtIbkKuHzE+IcA2NZ83GKz0D8z5zmgRnoJGKigseP9TmMS7BgAqtqyixA/SLc1KEUWrhXOQ6kA5ZQRazp3wwSa404cppBnfsS8EsEpbr/gXyW36cZ9pt1RhzyxGxDUmnZeBz/Uf1AP+gyLIg9x04u1fThm2w/H1ZXGvVqsO1VqutV5gUhFkdkwoCjzz3F3FUr1v0njGYT2mSZYvoF/fSd1W11c5VIhkEO06US5wYRmHVPYXmZnbK5YHQ8pkIDJ0yqssqFK34CuHE8RWb+Dr4omk779QOOcYomAMYQ9ILt2KUk2uNlahW/IjGtenuGLxb/t3aFoVz4oNwMZ7iyp4td8mdzgJAfnCcYtklubGAUB9k6bGC5DSkf5VFarnGEBWz600VGR8QywZ+jIYFZbtKT2QdDOYP6k7D8qVgEZByGmRedZRWaQDTggLyNgDD6pQwEeSs82+hTxWypqwU3zuAWqfwil+mytzVnKztyvMFJyJwPFaPr4Z3mTjyxCR2Jv674JVGGMUSWb0l+GtcYtd+NBGChwr8mB2hlyccget9liJhQEb0XgXfgVRlHlbO+jlZ9CcAew0Nw+tRcWgNnz/GL9Kur7RohRhaYZBBmQA6JhvzkazHRcdZDn0zDkfBmYP1PfQjP3d6qqx6gE7vrb3lBKEfK3Y/nCe4COdpr23oZCoIpssGXmqE8CGpO2bEwkSN6uqeqR4UtWR+xsgOzNeR49PTLJpFEAkXha5YaecJ8t/KR+eG7/HKV23zPZAMvHDC1rdxQ0l+6wlIgZbUybjBe6yusL7isRuuYYwg4+8+4lia2ox8RCdvmXlt00ZshBnAIfLkSwIqUzCcsD/d1ZG6Az728L4FCIqBKpbA6bzkJ87lYQpbaHpwPpqu3S0UqNDCwgg3q9MEn02X16E4xibz/rLx7NMDtHcwMOt9r1dVU6Hws9TvJVH7THrnSFESgN5eBy53Nq2Fdb8mySTxz5CitvVE+ZjHaYS3hq9Bax+uS7TxMIT4qJE7HGdsHM1/9uPNBylhP04Lck39JMe8v2dPOSJzyQoy8m/8Fc6h+X+5/mBVA9jAsG4vmx/KdUW+NXxgRt//SS2Ib7aGILsjOz+ZZQu/NMeuAsP1pFRTN90rqIVULbJ20ZJlrjoZD1VxHEoDFFGVWCVOT3jGK+vFD06gc3yDUSnZ7ZHjGmw4ZiAglY2nm78aUpXxI4BfUHqL6YQKFDCazUIryLi53RczlaTh0ry7WN4WpWK9sPJ0J49fu6RGUMYZd3+NrRvEdOrS5n+EJOTkr4lNzo8vawcYnR/n1Dq0rCHu5o2BGBEHABJbsFLi/mlWFO1MjpvUu6UPJjXlXse6MtBROT/mQfyegWGmFRQ7Q/O+rJp471+tQF10+bvkExfBoTQrewd5UwhAUODpyeW+aK6vx2AroUo2bGBZ/ZjcsJFfMYEMsm47LdQSq7T7peI2Ex+4/9oIAJGfhidbXA9UYPNhxigFTg83CETNYfYVkoambj3vv4MZNtE/wrIfTguBNqkQk9ebLPTmY2U4UCzbYqPKO5vjaZXeVksobDAJzhVjoU7p9TdFmNMyLyCQJryBSOcm0hFk/pcwcV15KZ/+IIqeQGPkTbiY1haWSnuQYBeyW5uSPHGtYw28cQS/v3rToNAUGVBSQ6zpBt4CHvaOfEJhuDJYZCcxvPeOStdCzaoSQn9nDe8wDc1MXrJ0+9N9TAKcS6u8ANLCLY4UfHLGf884/LFIn4OLOlRcNl7FS1IJgu1/vLm4INkgHt5ISp2vC3MFJHz1zJnopnKS1AgJtCmhJRZDaW6wis8CJ0KAJW0Yy0+kWI3lJ9N8yqJht68FMNVgkgaAGi5LuKmkZWm+ztKvf9gT8hJrXZkM/QdHI6wy9BqVeWa7g7ZM1YLbUv37YSnLmGsCrl/UVi/tG+fZbzY4bGye0zH08VQpGmyd/v++fS9EtasmbkQEIYnmLZLxO+tNHp3myIGwYBZVXjlWvrCiQcsP/Fu9l0HWmLBu3gvuJ4phtJsXXllJdM8iZIQR8Z6zEMs+cqVL7+TYhxDd0c0l4sbyIEw6N+V0v3ZbUlidyekdcz/aIomGdZtmdI+1QUrrHw7eDXT+G3zbTZMXxpEgJc4zY5bH5az8eHzwoo8QUleUKpVRrsErGmSF6GPJ2OltKYL6/C4zx4rHdcfsrQTcWBmrBWMMiFiU4NGtpYeACqYafRyu8j8x7ltp3nxVbsPO0MSoaR8tv61/q+YCqHX3h4vy4HzjCYEl+4ZDtj2+mawuj4J0rBpcDw+spzuCQ2khFbks09lPGxK8HYJl0Y/lNLUxGLZ+2h6+EFSaD22bYzF7dk/EhCWh6u/v1HUVKC/r/Wl6JHtd1V68J9zdOTgbvJuQug4r4vUV3JJolQQ5tecHKqcNoYjOIs6BZTlfB+yHGfGdxTKsGxbU/4taKuH8Qpd/M7fIG5zebrpiDHV97T4jiUNt7K64/u1e/+erXV34aOjfddcKNO76EzIf1pfD+KivBsRlzlsjj17aDPq/lnKHQCLsD+3TK021HNzhZyuwpLRKS3KE0XH/0TqUOr3VqLMcsSZM6349QJDznPG+sUqeS6wwMWp28TAoDKdmjzW6f+2au71HsOzLIeWencRa5JapKkVTYpvwMIC8u2L+/hYGJmk0588rq6Nnqe041NMzU6lj1K5KmSj0ZRiVpzu2FSTl4PBYHAuhe5dtwnRQwvvNqIELVxKMFWedxxB7UO4zpYRe2x0zH4X6pI2m4g6YdCs08vR9B7omy/goQUYbUZA+wJamq7/c0FhkNm74Mp05NSCK1Dcy1+9qp82p8XVkUB4+SsVRJ/Tqtn8v2esmemr7zjCfjLicMb05JqNoL6zzz0KaYkXeStBrF9+T7EbZTo2Fa/wS5NhJvRoZc8QUfS46HX8HIZ8A6LK8zKtROnakAnEEFoonVlvYR71xYuBAXbjtxfu/bteN8WkArB3//qp+3btpi2SIMyK6rX03iCLnzOd2OrPnD6xqgVT35e6NUMpN7EJSz0DRRzyze1J+Dx3cfx0M577W84qifD51mZG8VNbBf+5PxmGGrGOmkO+Q41YnCkx51D+X3CXsNAjaz/XfcPJUXJ00vaQyfYDtmFq4kU1ZHdnep48T4IskzPsYT9or3rd/ubiYLqeBqjnGbuNWb9ZdPDxkeBmJwYTjsTU+VugQmtz5+C3QBX0piVh3d7BK+Hk4mO3q8qJVQXeIqs4hKuRvBfIwwUyKg9W1x8dv+EwESuk2Bgs1+Zc3wzx4eGasynWs3V360wH3fKXZFTckeHZdgtzTqcQPC2hCHhSXyFMyljvrneLE+c+b/YQ0XcDBam1oAPzvKmmcgER6AqnyC32Ic4HMP4FQN2rh4Y2ntrawByV+9oq/Z8hdwQEPYRYiELBCnuGGXDQbl3ZLuUo0vfKU/AuMwYfNXmNM2vkn/GRrpc5WDP+MEL80tbJDZfDNBRfpfcvVpf75u0LrkIIjnU4adaolZWzB2yjIVwNrF7zF//n4N5xHeaGc7Vh1EYRdc0h2l23qFvLBNQ5kHbmX8Yta2Vj4DU6eBN3XyJBvJf9iL4x+hw1hx/7Ej5U8EZr/Qhgoni5r9PxBfU3fdvXICGW9DzST7GV141bvyMDXblFG5PizNjJUVAWNSxIAStz6+eDAbkYeAKTj6DIR6ysFvZAloBLCgSdMFd3ol/WXDQh3BbBtLqO9hp08BfumZjLpTJGRAIHzDizXZfhbgqejNSS27BIXQLV0muwzgXGqYt9McSvtLWo1Fos3k6Nu2qGyFftqQyDz0/bmgvtZyiFce/SLYnjt2Q9BnlmUVBWOtbDPvUgOSizvJDhdiSkbLLP96MJ7dKO3eUK2nZnpb4s4b2XGF4T6gC4qo9TDv9z2SY4Rffb/RjPs76P0YiWADpPB/nQjC2tDRlxt4sdNCIjmMsLgU+cr8cpyaMSYI9maP4HHww2jTPkGKvF6H6+DFAF+jAZKT9oi23gpZ2zavE0xXPkF7a2FTNJ3bwxvsJV+o0fXZAkmouYq6B2+6ccHhnUIeL10QtZaPoZPJB7/Xry/2Nv+JJFmQ/p2NSiO5bYGA8ej1vh5QlWhaX3JMs5gMBnyyIfXIMf4im0WEUnCPAJzq9q04Tmxzy7nGKKEf31kAp6IFk95aj0AogL7iljLVJlOXNvV7BwZn4dKfuZweSEZBqy+Mvual0TVDHiwHuIuXbvaw+OkU7aeAfck0Hc6H0jgt9g6Rxb6dAuaiKEN1cUYtD88y0b9Arq1q6ML9B20/FunTnZNF+IHgsg641FfllDFpQ+dqrIPKQ8IkLx/2ppx0ivQSrehNaf5dwtBjnPHroRGzG/RWOdiW0COPzepxIqcsWjhfmBXSUD7YCvPm/qTGcSnhcriFKew6a5s0AgK03I1gEifX6y90cJBY9REbQ7yW/XB+zAXN1XZQVEs7r+0ajtx8KvVBKJksKj5YFGdhEennMbwgCJJIMdt/pJD6FIcNVegt2LiQS70DAJeiNNG86dQVNYNZmYEfo8oa002xKLh1+rHlBX40iY8Wlv7FqswQFktpyLn5oSdo1jBRz8V3aRIOmhSnrs2wxGwGBEVEXvRm8RZVvSQ0xlKMVWs9Y7nnmJ9jEVuDL08D2ES3plzvCNP3FpKQeSknFeVBXv5T1Yk0/X5vdj1J1LYa6Ffxxrv90ObLHARkCI+tz6+0i5cZTinvgIYLMVnV/OL+m4RCsTy/+9VQPsYv6X2qSSlVdQ3KM1SOntMNUBpb4C0MsDh10xHQ0cbJK0gsR6X93ru63BDYbRZmPISt1casVwVVE7+u3l55XJGJ0Ev6S+2zpNqOAH66RuzpVskXE6X8x6wHOfp5PAI/7YG3Zozh1U27IXGEEKIm13Rt/nTE3pKWA7i1NFdVQKQ0CNdqEsBkjiuM41dd5rIbR4DMnoDva07v1esxYBGU4JWJUJQyejYbI9p7pqjrpHZUNlz2exX1lTAks+WxY6CExoPlSlNNv6AIsE0VdPmHOj4m0a8bigDelTpIL1WoePLhblmhRlkPDKiZvkzz6eG8vLeJjCGJL1+VFa4QREBVyuhcpZm1ygJm9kuQ+8v4yEMw0VO+TKee6sMFRVc/kS4IirJupnw48LoR2aRk+GuDBZ25xnKFxdSYqZqvWlEcemsbzl7wvQg5z2xKxEUsquyGziyzd/X+XFl/ct9KRLzyyb6ComIL8Wam9x6LPNZXvhO0QQZmQ8T2MFjmRJ42WyRzfyLGkJKft94uO0Yy6Fflo3AoIEon3XBygpi3Je932ToU5EKoikvqkeLFACpsBN5dseemiMdHxOJKrVJDdTS0qCcTzPCyz506oyENFdelskwdghmUnWyXK2WeJX2CBXudNUBON/i8kMdtJm52REvmGqVmxe5aricuTCGLbgZtYvigT++E7xltEh/ZgUoMP+d8vaPU/HdhZaUjsgQ8OoqZeezvNR2JFm2on+IliVyYQ/58LmZ2stgKoBbs4SllwiTpNRw7ecL2WR8bbg05aTN00C8aGWtReWSsYsirJ0K0I97flI2gJRRN717wESryWahXUAFZAdyD08j9SIZQm+wq5GkoUkK5cQ3wk1x01x4fKLPgPIj6D6lZiylqvWGtl6KxCfoSQXlNZIHeDsrIRqhINxdrCinM0iMMkveNxhqrEzhnBn8F6nXVY5zUDLzOXpp338I2HycFa2pueObEof3HQgFEMnHS3/CDKwJAyYl3HyA4X5vXUE8MMa79gYELseTf0IEUJRsfSa873vl6n29lFq+GCqF1I+mB5PSyLFvgHv6hG5Hd14PAHTKhY+xzCgOwwRZxygPwNET0UiO9ynH0p3j7GAFEs+VSjl4ArhHJbySohRLfm6B7FxxYJLJxJlQr5UdD+5Vs0nM6CehSZZNYw4FzcpYoL6nS+wGGSNKLVLXgbgvzAbT4B1J4GMS16IKMlo5S/dzM/NM4NI+a1Fuk4qwaewoHqGp78vgp+SkuhLyAVhI2Or50Id4LlHwRon9o7JT3D2pibchFvFi2VTEx6cLX/qorW2YGSSmnu9+M8teW9DIRH1TfabuDIuLk16NFz3kNr5QLPGAd0JzN2IYFA140yqfi9LfBcZI3aUK/Gt2bfMMk8eqttN8c92OmUYKUaHbB9C9cpEwaOYs49MztuGtI0VMqDDHN8HiRP55BpRIJtIWbSyi0/LOC94XhzqGVyuzaVaBfg0f++sV8wy7ytxlQYA9w1ejE0XaCkpM9zbOrymf4OrEaIyQX84Z9e6wQ1czIvOihnSaq/fcFdkxJcMzE2kWcARwWT1U80dW6B+v6HdclWMyMWLYr49iKWrhm7o1yumJKxVGiv1Rx3Tw61jrh+vuNjikpFRxa0F9G7ZWs57nuhaIeT8ZRjYzuyq4WZBEXs4CyfvmZxGcS4/G2aWon2O/UkjqrfdbBUF0yavSPdNJacaaZxFQNejGDPK7SCF82XxiahbNpwFs/t07gbCJkDUvvKjqaYv1SNJBa21RKsOuGJNKO/F6HTjc1Q5t8lqLL4e83gWTT4aubYGtE+D4e9zdPPo2R3dvG7bDrCQosp62YhTaV3B/kEQGqtzvu59fbgA6lFyGe7urhYr3TWCBFYBmrEpB78fWnXUEd1z0LSzMcWL6vuh4CJYR0tg1jX4H0wkw9mkbM07MXopLJ2Rt7/aL3Hl3MjO8h/1lqNlK74QTbgkurmgd23XflEcMhjO52Y/Wsz+CqwkBCDN8SUcd0hvJ6srikURdDKw75ZZMyms8NdzvzfsXreeCzpVaPKbkgWo0BlD+qWqaXziVa7YTSezNkCD1UBphMwE3IFwG3+Oja0AILbwR+VMjirrIkRPt+DMtp+OKLpkiE15AVv3jn19brZGZkhhAsuT2sTiWSjLvxJkMICAGdQY6CcJ1bmQsycrXCCxoxrME8B5k7aYQkl31h4kmnvmUA1Uo5bGEJkzebQNuMeVIRwKr7shM3Y3iowzuO8Jm833ALhjeDbR9i+ajGdiv5nuQcBDW0PZ0CB/GHvnmE702e3iEmWKin/StmkbfvsVh9mXnjLzZCRfht3g5Fu6OpDSsq1DSVUie4hNThGTSTWkOhTKbARv54Bxp1m/BqW0CfvfUJMQYci+HzQBrAw7lHJI8klNzq1wbwtxf0zzTFIpYQcsU3ddDWDMuciKmN+BHJ47B6FkgX4uR5QSWzLqgN2wQK1aLp2hgMJGqMII4rLK56VcDk89QQhw6cy8PCM19olNpuDwdrQFvP+77wiyyKx8Z4MVJNxV5vJWOwvF+aDouZMW5HNno5d960qcPPO89qYm6Zh6UO7MyFx272aWYtu/0+UZ6eThOP3s/uMGRarrYNGVN2bkl0VbM7ZArP2AnCQLuPoIbkry4nTS/RsIdFmPg98zeYI4R0RY41FQsBym1OXnJcHtmKPjfEXuujVQGfCPrCZsaT+vFbMFWIvUy7OxquIvdi2DVp3+q3E3NGG06d/cz77wgHGWrfcy5LJIzCMZHkk6m2QnZCXYVXwMsVhJI9nJcgG/CrU5lgDb/DlVEsXG06BHIuqVfnTyLdAQZYmJlEEk43pdgF69V12XC+sB9W5Tfm3jPwiHn/VmGszkYx+Er49CLbyk3hDBSKuzDj+nzCo77ZO40EIP4ZROdSwWlf5S8wfYcAzjNdj/aZ8uknw3tur126RfCzMA+cUo5mPaZL9cVp33X0mRTUIS2vgtwDRgsSSX5xcJUWR8gZbdeqyqQEEAeDu3+BMlrgYP2SH/le2u1yfVFn5JX9VQ04X9mmABR/KOd3rAYqR+OQwLWao9MXVS1y+0OKo0FlXuirKuPaY1BQbY3Vo05Gf/+N+u4rDcFBQqiCrYhgRAEjvVW9eNCaOsukcJWEaDuo/pWCYGJLadm4ssTCPvVVEJNBfVXAcTIxH4EFtWFMJUy5of50QNXNZBl+oRuFIkdbt04DeU6j2A3vzzP+IkMahLD6zBVJv+xRBIc5fODvnJMmJRMI8kcyMFqxpeWZAHxC68tGFNyl6yyGN95SwNYXwDSIQCPlL9bzjZaWNWvs5puiP2lbEBlDw5vCHtVmb/sD8QBgOhRassChwM5o5g4lhlD4u86wmdmVmhmEXnCyLeQJ0rRtqYIWRhg72ieDnqmPvOkDTWtKR38TeJwrK/7IRYfbNspygrU6yV9YtJyw3I3uEkDgbPrpcNUpISYvzv3beFg3ZN+swedqf3IVKkcdiAezu/KpHGHPyvX9oT6qzTS342/DenW9ctM197UfFl4rk21KxSma1KnLIWlGGasMF4+G3dxTnqBscul4CqNda6Qy8ita7HCzKlYa86yljm+HQA2B5ArJoZy4LNxeT9izFuQhEoEhUTNJQj2pCc/O44h8GpQX6XgpaAvAQJLVNq0yXGFbzb3O54XQ6sm557+lT3A+VWPyCJn1MLbsssHIdFhJcMtBFQYi0bS+exQ4Rq74xNE2CIRSzi3nj5TNy2AoO0gdyBC0/2iH67UB581jmM92OHqgD4EzAzyxDauPnlIdZu0nWwB4dtxWN+meq/faIuQpK2hoRP/ULwIJ9r3xyxtXxfFwJ3YquXldSEnxoPiYD85u0OAHvKOG6+3eBraUiOgvdfp1EjiroeSLLFutuPPV9XqhAReYPaRy87OAkV5tzSqvyfufCvOMTtkpxApWsJ9n+cNM2uBWu4lj1oDjGasCfCt6cfgCzh6UbZanbL/qCgf/iHjKYaavIiRLJrU2BuzdsP97XHkXLYbbfsHVTlXSohKOXOJ+3LiR6ix9UFLo9qieejYk+P4e5wC64jGQLSxJzYt3cErx1Rtc2+xlJaEBynLN4hLl/qOrgBM7a+yswC0Mh2OieA4SR6MfM9WK/FOWbVyoUBIUAKOhhIZp2LOgukk0/DInn7sF7dRP6Nw77MaAcYg6k0gdjQN9/1wtGVSBm+6LwkI+xfcK9l+JiWepXul+/EEdV7XXp/9lUsW4RQmIkda9H38FJj3EYJTrG4hEU9YWtNd2lKI1683cXFVzSMkh+2nuu9K0JUBoAnrYkKVZpAKF9G7y5n/KMZrP2xPuUFSOaruqriffSEX9Euj/k5dgewEyQCFTif83LhkIjt5qJ1LyI4ynIznWl1SoAdecEp+I5WmKBB2fr5yw33NX94q6HIP0jW3Np2E0r1f7fUjqdxV+iCRULU+yAwPXFvTL7HqfFLj+wCfIbOg+nsW03rGTf1haLvAZA/nC52pSDnC4f0qOiA6WtK20BldZUaA6GO3m5ZOCGyemGK4a12hM3BXnbladA/yTRV+pH7IiT/9WOijGGNXzV+K4wmdmRjU3It+QwUCRat2mGkEHhOcQY06pWeQqBGjHkWcceX8/drkk+tYysHMXVk8hLhLGjUVgivK1Ra4K+RtUcZO5fkVkWQ4W8fyo2tafhGEDSsflUH7yj8wsATBE9YpskR+r7Ac8xqdxtEAfRioGXSprjbLI2DAZZz9HAYR7rUHzvh/UPpFvrLbd/hFf7sF3RimWNpiGsQRZ11RqfZkck9IJu/FPU2DYr/HWUdskJHuLufXCvDbKn0F9sM31Hn3zIuAMTUc+tQsO9ll6jnNnW9Ulo7d32jEQMqJIrWQL5+Se0a8lKRp+XhYp4IfyUaTRC58vFEjKupeFEpU4EOp1AjeALc7vZV0ovza8QSl3ru6xFpY0/ckElMOChkhLWSDHLCKaFK/qC/SIfT50GJZnkCr5SgXZRddXq8Gc6XNjIzSdCF+9YlUFKMiri/sn1Gp/dEMhARah97GidLqitLNBlF+H8XoQmdrM3GXBSCN6izNn2ON0OzpCxOuM917OZCw2ZC0DSvNuTOFCGGYf1TYgUbgK2KKc4zm/25dz3GhVpFqs6x4yhZBbiy/6FD1vXW/aIcDiSUoIhwrUtxuGGZijb47Jz8JfUTblzx4eNPbXeYpygkQo1xXonjeouTuJvAH/zH+FK50zOLAtbN9AO6xjfX09CsjKitMVlHWmmQybLoBHBPkC5IbAZxvs3cH1VAcy2X90WL6y/0SXNsGeLBdr1OWVuYg+/wUNiR7QnP2ec7jNrZZOosT6Olwn02Dh6zSwKoDnMFLfk7lBO0p9mWjex7gEFXNfxFO19qmaoISUZEgdTuy7sHgrD/36o3XeFdzLFoFnOJa4yaENBXdTSmVZacz+5IGdVkEgjQt/TxuhNGHGtQuzNDfM4iNZ28Ly9S9WkUGMNAfDRLr4ipZkJxUA6HnlOi4Yb04/Ze8rB+HEXpDGC5Jpr4fN62LQh8o6kxknE1P5/rNmz43jehFlRUvCyNi3Y5St7lC7a2ogCt3Za6M7AshQdbVV2+R2DuuiLEJz0MLhnn/1/F2Z2U3h560PrnhR0Gc/5GW5DwO/DGrR/4PvL046BKjUp1lfrtKfE4osRTS9/oB0GrNW3cYgvhU8ld61sHhKOf4P94t4n7h9zdRXDaFv4ORPHokkY+NA9QA49RmsGMfJLu1/RXuluq0J4fsUUBoa9dL9T0yDJXvGtuoln8aYrNzoapa7E8cR73/wX6KwBPpwCUUlxsBtOj0rnca7zu5FqJC5W0U8Yt529SAI0S6nmWnS8zguQLRzf/gRLaqSQ6E9T6Q84u1cs56dzBMv2eBG+zAKw2V0x1NJX1gC8M2MYZpScdXEKPG1442UFWTEUlkM9OjbR4FurtJNV4IqEu1htlgltESO0SeZMHZ1JM7bNtYegevwPSCmW+S8uEGj7FTSSV0HbDg1rOnt4Ws8DxqN2T/HOXNd5NGboZ8VTSD6g6rLWcoWOwsyeG08GPG6KHPiLRunEdTPNmY74ObRGT1VCHP7nmBYmjnH+kqK6rDyrEoNjdqc8uG8yZrHWBXU9weqD5rpQ6S/annq7P/GiYepA2ZDdJA/GbdxpHYatPgkXt5sop564gVHZamW6cq/cdADaLCXWt1WgK7y11WaQR90YOen8BECQ56pmJbLvzzfWBhUUJP+dAEEK4o4wZv2+IBAFEdNkNF3mKntsLE5PDLA/IEiV0rziyORzLJsoxRMCQV/HlpCkXsaizcHT/vxU9iadf2hOkKehGum3973fFs7uRlqxz/oDerFL0617PqG+VYIxjeRb2IRLZJGH8vp8ITzF7U7HUg8Crs3WpVY5r8wxn8tzGvUUwY5csVu15Vmm1xcs0UL/lUCkrOXdLtlaa4pHLeQgpd/vu1ZzjMOcgzfQaIwiZK+fMZjRLAHUf83TSCOkovb3xPkD0jElmb4TBqFrwn8G4KWr+RM58qhCnlVimQ390m8YLz+fNHbBRDs7GJgHSK+v5Z9cwZq4glnR2eTjnqTy8Wo7BEg24CL/RT1AKzOIE7muo8oegzn8R6qab08LzTcbb0ippsScfjQoJhsr4jKG2pMVczpCYqptZcGD5rxTHFbL3+NDnEUptRMyARhF2FMiM7pgaB/IpAna1AHa5EPt7oBdzMGg7kOdSOpxrPXbdP3l/+QCfCLMpCsxFd3VAxA/IPVvK8JaenCYCadhyZ6rJeGxTUh11+OOAjrXIJxb/EbIy8rv6h7hywPp9ZhPCcgt9BN808JhGIaKwtL85jO5nipQyAF690xJ9A2DMuCx55TSG88fN6rqBMYDI+I+DtFmoAqJB27B/xxN9xMLnQwLcLCHOx4GIFCq3/6i7gwJePjoG/HKNb0XjhuEQmYFzTgtt/uIo1bBX4C+y1jrb+R0mRj+RyaDkRus8W4WW73qbcjpjIh2tGUY6KJyhEaKiK+LHG5euQeYZO4zXoKbZOWiJTvJNNVrWugpXkIIIE4zK/g4JKATQjtaC1qbJ6khaJHxOTS2goU5zGyjmaPKvVPrBh27E7E2iZ/6omwpBARV/9EKeU1m4Msz8Q7y3MzEF0C8VIIqAxB+Fk8qG970lhV/ZIX6CsxiHqybemqil3Qv/cWKm96fPoMJWSA1dcF03dSwSyNMdvKKBCYVYLuqr2pISKPaNRJJw2R43RNE6avh/TNA1tGJ/ilW/e4LbOvIh7cS2OsbjyXcD6WS0DYaDa+og0lSxehZQiDSt2fVdtF+DO7/cEUAM3uju47Fl17rUPkRPaheA+6/jpSYK5Nh6rSwO8Pbi1y4/L0L5SStva0NcscpH0pw/3Y9+Eqw1SDVvRn2r2d8vRC6YhQywdhKWraKGBMILqjiU2l5d3jb1tnQIwi95QiTJW7MAjJD4Plr9FGRGlM4NQyAiG8wSAKUbRCpmxE+zk9YhXjiC/Rbt983pV0VzovJW+90dH65IOb2VS+Wk+MpsRgZ86uEuxeGPyB++07HlAwqFjq0sm5Lvom/rcHSaLduJrDdabujYJRWbbY2QZptvGwTHAiaqsAafE9NQa2oq6hV8+E2YRbdEcrirxyx9JVWpti7CsFfA/egMevH0MR40/X1jQzMYbw6mr01MI833RiE3EuU79cpspC8tuN6QxFB7ExHF8yrFQ4vRniEkTgKc8kT2tC2HgNJJ+l/FwYXky6qbHj1cMtBGVOw3SFMHn5l5odYVrLqhL6R4DujKq/CEsEj742QjUogvrSb9DOh1Mm5Z7n6MI+YHii3bWp2abi25FJIiX3GM/137MQVr4wwQ5IQETnYx0CoXX1nLeqLjQ2VlOulhy58iVxN5d0Q2TEV6MPr+wA6lluGEC5890db42elDUvTbbMcjHGrT7WA4eEhNLqVT35NhLruSPkwg1UCAUz94Dj23i6dqS1MPh40Oyi0W+wfoWYXIw+siweU3qKdQM/IWLUwDjgMQuiK+CTyRgR/Cg+XmfazCLiF1JChK7C2x+ROCl4t2WjYngGRxBWRQqqrNqx1EesLx8Z8GOimBJK3Ip3O0TWp1z6fhibUBvCtBpCBH7Wz0MrsYEtW/6gd/rLbB2IcMxOrxgW5u+/ZBOjd+9Zg9SRf7ln5tqXgM7wZE2rj4u7BOezWvuyca2TpJkQOR8U/bR+LRjmN6RAS7MCfYSPtJWSbZYnQL8vGmJb39SyiYiER2Via1nlShjJEe3JgCwTOTiIQJ5h+NQeEs7qWkpIDJiQHb7VwcR7T1gLGhKAqUT5DPO5zvGPny/DOh+Lo+Xhxf5wTkF5p5yY0vM1gw2UZQ2nhCedQ+PBxACaAeuBYTyBs9aNWvYATPBLUtXJ3H/+rMIUQ3Xz5MJKdV6OhLEEK73rb9hfjPlA0gKO4j120U6VHh4AJvL3WqjaY/KCbwpCzUCADZmnJdpD4p4U5ry6/YuhcWXcVV4dFm5J8qADBWw9jPITjUtkf0lhIJkzhXLTcXQBZaaunvCCxyWh6ifYzNTTCGJcUD6DyfGam2zj4qdBy7DwBaL2S2IxicF7F2ubPDvx0+DEQVydAIF4Utn+/niyxDQpGlaaG5eRQcfYEHaZeHBOfZ8x6KnSsZnB8YZbLVBcEF3Mv/87cj4r/BYDYAaUWrrm/rWPImSVpvPlB3xQvVG305B+bCj4kIW4ZWzFnX7/nApDibPZxncAV04laDsD872g54z55DZylkUKHXF7Y5iFwsc0HDovYpJ1P+XIAb4pKZnw/e2BrTZn6jCeAAvAt6Z8EdXqS/KoRwK37xhZL7w17n2PYpqnoCtRAvnU/CocUq+el+PFEwM2GkhLBAJXvVbqxBMfPWlA8XMNY1+dfsV9Uy0C+WgSzcXw/ylN23DlELK9DPZ1nzFCvyDWygh1ABv0LXhuVuDEraYOrX0J/NpbYoxjl/mfncXN1DorfumMjOo/dWEk/OvdZ8w/66CtISpGM2htGRpT929qEz+kRM+2XpAqcSS9GOrLWVVUVIm3Ez/yIqAWm019Td/ytbE6eeYJaY+mJpelcp0h+4Y1hmcF9J6cZQEJi7foY8n1psVTCzE0QYMX+ScYxKxb/bU9eproUaSNTxHeNhomtba4y/CfLAZYXndn5ndeIjFIsRWRpwX3HwrIsKxRgd52tRs/iun5uy44w8u2wZgayiPbOTWGXUn/BDqak5EZebXbdQHyE0yEhUO5HcDnE6xlAuZFDSKLDTTZz9bWcfe1wy8KhSOwh15cBRibt+faUQgl7/5na6Nl5d1o7iUWTjOhjQa4z2Pha1PNGSn0hZFeICMKGtHJ6EGQbB+HF6+M2e8YSQjJ2cnG2SVpdzXlnkzxYqwXv0s0WM8nggSh7Viq5joXNiF3RJ0A9637p1HFJd2I7GrQ4ZTOWRi8jcZaL/25Pox9feMT7VDPV6TT++0Ri3a1aLS8IABZh2dWfxnBmXDWPdvrxmBiF3eePVqd2ZM5bI9YAN23/3qVLElDeD61xvgRdjkXkl2tqif3zsX1gGp9mzEm6suh1kWL75XC2kXlrCreiNi2pfI+iWVFJDXPd3MBNp7VSAZRp1jpt3ug1pQEM470lZXwotpDljklvGxuNeKwTuKNJw0EK74nc0d851QXL9P4pxZdM7pkmbA7IU2S2Xa/AJRP2VOz3Kyp9oW6FgoQi4noNkoHeNnprbQod8n+dQSSbMzNRZIuL/riHaxoOHkaGYwROCZwqcbK1tUnU2Qt1J+3UTvklj6wOD/d8lrZG7ucjZiCyHxK5XVtzq9lDJ4N1FvARCTUfnLeOLc5bmrtGvb8mmsr0lDDyR5607k41wzglZH1fExfmsXrEjiNLSzSKGb7FVusl07/BgeCclDsQkds2G654GVeUpX7UHaqQBEmJsIyvfxvz85+WyRaoYuQfSH9WpJLeUoXpUt7+Crnl1Jqz+eARyCmzL59OUUBwBuoQAl5VddIrfG6xvDA/RZBOV5AfwjOrJ2xRo4N42rCSFCcnOY7xfewl6tVLetiM2tGLqRLc9k/owyHriX1A9BnluzfDc5xdEUKyuwzWPG+tZGNDV0WLl1JyHPflzcBpj92G0AR0lGaMSZuKui5/LUMn69X9wPKc6FVkNEHEjHjQKPQjuFCokjN+N/6DlMscpE48IhHIa0Ghrc36GwGEiPRymXWKD/di92yfjZjDM3fdHBdwSxJRSBVKHSwh6Ey1/zWZRZ4kk+KMS8HuroIw1UPa+PDVpsSIKvmqZnZisbfHFWNW/dl9n5+wM4VIzhmrETz3k9WU3s+z84SHh2f7dGT/G5WvoisBYAgwm+pqFS0A8xyhy4PiKfgS+6TgnQD5hDEerpzgFSaMcw3yvDZ0+xfL0yznf0uY8N6APiqHdoJZOWqTPnTIbeBLc5dvFdh+mvD+sDtl8BAWzYR7QkSgnx30Ru7TH5a/g4byacurCNvG0lTgpkj9w42uqBp1zMsKr2riOCQwfCRKkuSX9CGADOYGqCHh1JUsk6RwvI9OvM9fCJoL7Sap8NUQ7mAvdB2ougA01NdqxVo8NeGta0R9C7QybiN4uAtDxw2zLTG9+0we68JkqZrj9tJilUV/f4wOLc83GfstXOVF2bAJ6zf56YworQQEDj6QnC+lqyMkGAr0QuAikm0jqS7fy9bYSBz5hekPILc94b8aUau3Kt69QI1kFEmcb19aFQA4bSegA9/hFi61RDIVQ7iOBqViYdGaK8d3zH5qWIjed0hR9e6o4zELdXWhOVOcPCmZIYYXvgUsAyGUoCszsCiTdwOaPEL2kRnYh0mNSZGb6/kr8XfbyUdbEZ7mDBYy0yTDxhkrpIoJmVutN6FHk/E4cTEolaGnv7x+QxQIKZus8IEygpdtBDxj+lC5M6HaJ313pLDYbjpCA+oYl11ISRJ/fB2oIdDBHFLefQmF1uHk7vtSmIyI7Q9HG0qxu8QRWecP8ipKR1o4bGrAhR2KcGEDE6k8r2F7N9lNUZCswXi/EXaOlPb9fdsaw1Sspku1xrmyADIImEs//XiPqI3Jl8BlrsHf1mAVCBmlqE7usMbDEpilt45ia5CXzVqlIZ95Fesu48LEATS3dyXVEjwQAqVbFBttbLfXvX4LhaGKv6P3XBsKWvqEFfq1rPYdohHtQH03ehlVMpZ/BRCBFV6dffGCrIa7OngRAbORd6wsIcR/gQSxhfrfHFmb9Ws3Pk/SikwIvAIYljNbXbvIpKTROSiPcmBDp4hxLkrjR+MfBFZLV5I4usLY6WYmjhT2kzW9XAxxLYCELLIf6lg6p/GFgpoRTm+yQ6PYtmKVvdTHyBxv28y3vTiy+reYBZqmC7x0TDasiMCcA+TxdKgDY4s61MpZyI1+RUzeMfx1qh9MBXg1tI/HSKpcUj7+qTrwp35J3ezefo6UZiEWMPBtx0/tJyaej7NUmUHVRBJfB1q0bsw4yHfui2ZOPNh/6R2/I0j09t9QGeRxpuJzB6DNbaPTOmER6WTXYEGXq7DhzkvCP247uSz6r7MfaasDs419fVF4RAt4XoxkFRmk3sjrhpNSeuDoG5RpjE4pI3rH/ESPaF6RIIJBiAbVU/ct/nKrDmBQPBYlNob0WmW07GhOvvz0m/BXTsPB8qA8Iesm6PsDuOLEEm5+jbniDFyXfndwIXHgWBB1GCyGV52MU+5iXguncQS8T+WyxaPDqCCXMjwPJxGObdF8mBkG2+SpqaBQkeN+1IL8Cbb72d3ySQUR/uO+N9v36KAiKVEPx8EERU0vfKi53JWN50+LSYqgHmF0UrnnHCNpcwfX8ezokGL4sK/rgFZlXnIqg6a8EJh7DfMOwMgTwRjjZ+TrXsj7SA6EaMRroFgxXRIOGDPYZgkadllrCosfuVZqNQwAY1cDJzuD4ocR7PgZYXbCA3g9Jd1PRx7PyRTNad56qFMVIv/9AYYd32opL/KQOuEa2LIoyMUHWsHVeJEgDnTAizkdfigKSmZVUDrztoGXA+B+9B+MYT2q5BETXJUKRLiEw3upTpXnlh7hkEk8/0D3rV1lUxxSlnDzLfFArxdnXRhBNu085RxiTwTISjItGPuj0MQknBfLTi9AeLTT9QUKRG7bxHm7P2Kei6fVAeNBP31q/OVsTuBJZfKaxLodsCxObxFdyJNLV2tAt+2SCAO5/VWcDOd7Or0wzbVGwbXJr73+/PYn3VfNQ4CSxdqgXNPWDqh9ZFVRQbSeb+bFmOpdkO7C70y6dTSHVuHlIY33/KV1QHDJ226atG4ltS4fk0ZNDrmPZ2Lps6qyMYO+Wkmsyw/ECuxfXcZ0zM7vmLjkk/LsX/XG0vaL3KZb2C51I5TVf8fBJmMxHHzKvaXDwSTGiya0f8ZZ3olqbqcd2cjXM0jicXlX0cJsaB81POyuItwEiYZwsHn4gymrnlD0mfAro2YoSC7KxDdL1DQVO+0a7fN1fLkv8ElaXx46Z8EGJ/W6akIr6uEuiFIQB9fHujgNzIzAgaDEYVITJJO5XQkyimdgaTBvra1hUbw4jb8imqVpd7G9dSoQVNPatqBlbm7NLsdI/einfpw6HdFlo9bpLb/wBxf2BGK/YWhn6LhzEvBuRuBZJTDv7HV9WfnA2SyT3HV/F6f+23aOYC8rxO7QQ1FI4/0m/OAHdCwYedzx6F6TIlSh668B+Id3ZxNP3V+Z82Tt/AHYSzDsxyYC8mxyk+Za4Q6u8y70AKpUm1NPP2WMeSHfqCc5mUcG67RR+sJWZg7P5iG4FPnFmWKv1nwwk+fM0IIA5p7xmHnj1zbj89sN0hc81tzI6enBjIyPd6P5GXzsmp9IRHKS506SAEK7IxfjQLxkNK1x+M8YAYLrD1qWXqo03kTvXgYllmtbguZX1FQGpXYjbZzgqSLxcXTKqQ/GhYqBJzZtvPaYGODBTozt0Rw6/vP+hTUJGOAYcEWWr5Mqy4792lLWmElkf2k2HiF5268DSkEL2oQl+VXl2NXgbfa8xxQoI7lpuNkURcA/pNz/go3LD+w41q4eQy20ecjCwekr0XfODump0XPUm2vvNfk4P/tAVA2PLhl21zoFOrSKjd6D1AiMtz/f41uWlBWCDDY4tDRMhyGsls4GW7P8b0/dGx6VTgC6oCCWxMyJyOgl5RPaFDE/EzGGGL9XUm5X9L3crn0DvEELm/Vx6HwlGWtnfZK7dA8/zJkr9b7PBgLeFlmXyfUBxZHF8kxgW5tcxvkEz0roS70jNLvk3QNCTUIwCHnqk5NRDEaewDCzjTR5lKzNzx1RHHJNiZZJ0lXrAsSM03iKPyYNdJfMwUAvRlKP49yIx7XS9cvseBWVvGNAc2I0PmR6Xc9KjqauqjgG/Q8i16OIPtQ2Ll3qDkunTNq2O65AEFG5qycHaB2/159N4n67iMEpyNowNdkq/ZlDxsX4dRKNvBUJaYqhID70qa2Rgq8+AzqTaJhuYrqrDDO1n/0rWggrBcFsYwo7ujJZblKGamFf+3B5MTAXNUOKn5PW91Gx56gtqTqz1dYMML1dFR/KZUZom7Wky7v9EfKnYbBseAvDuBFBFFCuXnhvWc/JS4ipUIe59Ls/kL+W5lteo1xt5bkJYfug17vGw6cqrOjTG4nQXZ+RbEDCMTf5JZ4DBcuVv+tGPyucc3B6R9NMF/lc4ubulrqcBPhRUjGBILbQ+4uBJ9eUHMAj2ijfMskRMLcV5FdgqIWhiEvxNVlZSRrzTzySfBUjZHCJQtbgDZ8nRWLwk6rQKWD5aSHuJh0vBgvlNTP+a4P7p59l0FYBPtoNpiFl/dOo05KHesQCueTxj7IB6io9sqTWxTu2PK2C3ACiXWNyxs52441hxg3eco87pSRV1NUvQeac35o3tgUpXtmtl2yHh3QO1mQ55wSqIri3PtVxJ57l0nOuyav/0ixzLEq3QlLZmLb8Y2JVlrdQMjhpcC1j0DS+VHrYIB4JgyXacVu9PCRoC5Y2+p8qfeJA3OFreaabxWxz5omyn/l55+ufQkO5e9iODCdLWl2crwLrUpaMCi8EUcVXGb3Z8oBCUdwuuohn1sivwQp1O+DaRFYXIbHQibdPfq4dU8WeiYJ4WKMlNEuQr/BRIGwOrAIM3Ppjmzvh27Lyx6xK14sUHgNy2ggNG57CBbXznFP/0NVrUQef5mMdso3AJ33SJxInqYebzcZ2pEVYHYczXE/+mcptBHb4ANtGohwQabL1xmFHav/wFH/al8TKjzGnYiFLEifJHL7OJD0x/rtzWuCrDToEWPBNtRKXFZqz/kBH6gsxzy/TUzP6R+C/A456FbGm8soK/uYyafgNmX0re6fgXeehUvtDCXdAUJElJt7AMv+VMdIrrOK7TAaHo6E8Khx1rq48yOqMqtC08so9cQh/AV760CiEtSm6PBL7JKCZBV4m7t8Gbbc4TQRawpuwTFyS/vt1JBnAQUBDPdEddlJlVAfbGy+OKkohOw9BB/JY9rDZQK1o/kpfl82umHijUnj0gVqhJCsrzUxYl+ygkRPDEPZqUIo/+AtsGplmBSxL8bUE1iBc8lCtShF2iqMC1DdHIH1DcucbSNtxOF9LY4IMng4T9eTYzDr+gnOPVxWBYMambJUexTzxyvFOneFg3r4FBEHqG3QZRgnKISYUQKv9B23A8vhFRe8uNZpBtiMtXqOQlVEbO/HzkRbqVaGj4s2XRVlhO+ewkvEaTp4pNLXG1OVF6ncxf3Fq94KmGuG29LLsFI1fuX35J0TsRNGo+TCioyTrXLVEjPztNVQL1/q5tGSrMPhfJEaQxHcrnqhVVqN1gfF+JK9Pgcud/lGa+Ig7eKQpJuUN+PYhBYQ/b6ahi4nLNe5+d8rQlfK/gl3OQ3WDGWuUMOt1YlBKoX+99JWlZr6tTAVgDF0NSHs5fqbU0euO7cXKnvVB3taBFHP6/KKZCBfGqzNo6DgZgiAELh1EYOni64dmOWUuwAQCKu+L8tnTFLlL6uKkaNtO8YGlOBVU9mQFYx4aGPgGEI/HTycxYXBClfKbmSErtcsuhalOh73FnzRz/thPjvRJcRwPtZmCHs1nYjivLMWWGprl4fRUOlrCDiwNU+9TZuaVsuCxj/4DzKfcla139igH7Z+0uskWkEq/c0mrsRLlVpl8ln0G77hwK9rLKc+RLeI6KLKy3Um5C6Of3qiKNoY/7ad3EFvdP4VICsuTMTii/bee9efmKAiym0A+l3hS7SofuEJ46In7BEO+Kf597wnd6s5mL1d5zNRBdOEmfNKyPdUuCW3u/SfFQes7nYlfV/B1DOE9p/pmgK+bx+eZdZUMu44uBGlaPvej5wxU9aumiyt/uCCZ4PyO0OYfFAMMqTaYcI8GxYeHO/3tDJsJisLleLpS/gvPLbEksIm3R4OCJ21S4P//uyzQ4EJZyYmWZjtknKJbz0vFEi0zDWnZHl4kvpMSPlVI8cEAG5r0JoNN59joEsMhUcPZ1YtIDYX9cnR711x6SQEnBGgTz6d3b1iebIdotlgqE03w87xlD0+qEykcVizaOB3Z+ocaMGWybZTIdpR4niV9mDm65EzKK8VQq59iMlABk54A7zAlMdkYNmaRuWJN+bLJ7RqEZf8vrpM0+3cwD0NctuwJJA13JIJVFlPStNIXzAW4pp1OnTx3rMZQfF+o4p92WDkF2tx1MUdC14Er9l1RlYsEYnOubj2IotL4tkgKwnE219ZsjXb8PJFkzakaWhRBJAkgbR6myiYFsJgC/lellsN9g1ML0j4HX4rwIzHbq20FDkBdfqN9SUnIbJf0QQr+QxHx4f0kRekXaqKZYUXYMbRKa6OObLPOaKGft7xFAgT2pHuSw7kdfloER91zsJPWQJbkAzyDFkkgUg80kW7n7n+WBN3CMXA3lU6QR23Ipx/98577h2OGkpcp5YiTX/TikBkcza+iwBGNBi/j+GwW8tGbKxpiSNEQqUDdqfscbVMQ+OSYGoeQKSLwREfUGDjR/emc+ZAJsy3sraTZkpHFZAI69dwO1dvsOw/Q+O/2lgghmEsk6NKzmfI+OYuOG2UoagP9Le/y9UABk4VHk54+6fW891qe1yVDT2KUc5hNeePBaQwVb5BQYPt/+2xEpqsHC4GY37hXyRSGvfwYa7DGUDbMKd8vud28h67mpOl7fe4uFRe/HOKf3TFs+9RX+QpL0+C2b4R/8VfkUQOABt4tcaDV34nU/UFXBUDvPYMYe0F24AZPIWphY9bLwt+tWvmuWwhvAgPN1rxvo3hpXvQNSPsVKgFUKENrmSCjWPYCUoQfJFpepI6oqpsVwJt6IlBFGO4soABNOS2KtnF9P7E9sSLK1WWOdGvYNhxKO5/D5ACMSM3oLy6XvjzPe57hP26DKKsIbhLZqcz8tJOcm1zlVKV87cVqDh5iOgGkNIKp7JU8eBp4VRPvv6peu3DR+ROhro3GOnpo6Cdltkq395hUi+pDXzwcONA2YjC4BKvX3JGZi77wJboSzwwPelRCe5297Gau3hHdjkNfDMaoCdfo4BX1IthlFNEHUm2nTsuiPe/rOux7FSlxIwT09NqnvyBmWQYcleqlPEreuoCZRFvXL07v84AxlxNdJM/atDmCjpmzumIoYOf4uVqV/8ZnSwV78WW0S0R7AwI0EDq4B6IaI6AUBwPrNLY0eeSw24zQ6qVAgBGW5aK79Mg+Skj4XxdPl8axMl4x6nwmnAfEBIju1ssp4yr/gdi9kl+ScGW3r5NVqJ1fXRkW9O0A6JBottvWGypQioSH2C46bepNpt5dXRK28XY0hseEnW9fDBaUMHziavWy8Q7jttulrsjOd5WunqGz20rPiwX/3fdKuQgv0g4CDqGBMamo9htCyKqN0qTOxWP5MmZG0lur+eIMwtcrfYqJujT19J3dps8mrCySt1MRdmlNIykG8cIMszw/nMlRV1DmpxNn2zf3gflXm1sXSH00EqrICj29dnyNSbIteQOqjPLqBf2QDDVVCAgcCz7vER9m5X4XkTIeB4ppqaFa2UHE05QSkAhs7FkyPf40UFGlKG8GnrdKq0ZLUk9m5jleTBwhdDsYP8HCDKRE6LS48qLHD4pvSl3XFvmH8KBEmyeyNwwJzAJQd8MqhmKsdandB6Ec1bHOw8agmVGP/vvY2C60X8AnR2r2HhdkUbclW9+ozjmxmipA1AJIZnqxg4aa1Le0RHfU2vkpf68y/rFMYgCXue7eNqxoS0NkOw9a9/WcDFJOh0Grb8zYjPgaSDENIFMCM0H5OlIqq2r2FKGkaQSMzVm87r9L7fysa4xxVMD0h7CIExLBVbCe1/r/WavK3yPhHVe3XBjyVTDOqI4/90N/Cm5KnqxFrVYOHbwMIXa3GwNwVME+38OpXvNwD6l+jN8BDCRDEjGDFC+WObTdm+5/tfm0QeEfVUYFtA7gTobiCnl8rywroMyBHNClofz+W7OhssrGuos+fRhh8kBA+Ni0fYdhKK+qCZaY0LUDpn17UUKCX6dOZccCYzSsD2iSQP74pFnhlkOzACsapdT20zbjF6ZqLgELUPT8IglaX38zP6zfdyBF+NjNf247XNtmIz4QCO5iRy/GcS8jjaWMfTxI3EbUvzrprtgRQDOz/eMnyVQVbbFiTMZfhfQLeu+j6iY0Qs/QYGFdHefwzAYuVpPhVZK/tXsy6DAioLlmNDzAu1eQ5ihCnobO+MOZtSD0+uTpiOAvPwGWf52xDUHj4zbdFtZULPV4c1TmWflDGMkg/Ia6kPHprHErwFTGoBg+1D6oX8lSPdz5srAF0RbktUTmq44+USAYYowZQOVbM3BWMc603Oy9SQD3buNTgzJ7yaMBbo/pjkzVrpW5xYH0Ra11ykiz32vo4nBg9Zvm92KHWhJm7uQJV5DMPA1JHBWBMcjz/uZupwXqjoTffeHZ17N3waXUaR7cZDs94ewlhsbQrmI7/A4zJDUZj0qKiVQhn3f3AneEhDwl6GUdCBdKY14q9n6ay58twW2PRXXPJ6UE6TUs6oqH/0xgDpP3bx/mfcCUy5oo91agCPtpTfowGZ0tyw5mIOsUqvdURDhjuWLX/WIqaPlYx3zmJ3ahTcxtC5xQgKWrQskF57LaOvwYN0lzIwz/joNYkiZwLyB7Joi0CsWWRC6SapEN5TClIisNQtNPmfwKaKYb+Hguo76RtcQMXdRZWjEJNHq8KZKeg/uWWDOW6aygLP9JDrNNW7JfWDyHPR8GL+29zBAD5FY1WZXsmYfdKU1VTLLzAHERJJGTpwKZH5k0uZrDYM8zG9WX+RVDM8bsmN8cI2wKz0Td8GEq9T4DvY6FuhMsqPGHC1tkLdxuwBYP0Lu2RvjXaxodrZhKfkkIwGcfm+lFS4WMFPCz3FwWwuvNLNqv7c85xnk3aXWl49yCW0YTzTqwyKuKWSIFJum5G8BBjvxx2yDOZMh18M2WhRGX5VA0p3eAilBsGa54P+iEat2c0lLnTrXg7fzDLJrjO/213hRmT/92zHwHShntUiR+9KUWKWRcx9OrMWfefEo/p2FR7dbNWoP/P/se7JJUfBzJixcPvTzMvSTQrccDAmpwoLnh6pnsAF37U9Cakvwb0EZzywhYhfUyAZ4oAu4R1X55yrbJifKRbLIC6NaYqZxbpzV9ec4/SFSjJKEvmVGa9tHfUJayAvrPPbVHNaxlbdJOOn7f43GTTdGGufXu/daAhuYtol2y5rFVUxlDpyKCfYRz3fOyJZEjhxizetlF5kpK8kUuEpKNWnSG9VEdmcn7Tu0/U9Pho+IZiTincXepD9zQXGusmr6j19TKRCe4dmbGmRl1cDDNABYeOKT51fHc6+d1Q9T2n1UMmkd+aiSUgNIrogqtnInezaEs7HmtmpjKttWg7ulLhPvEEnGE5TqPY3iCItPzYojGET4V755b+cNmqdG6OBTlbYjDs4AAp+ho1Iq8R/eWa0/FOyB4K5JLQ/WqwpaNPuaoufHcJMEld4peiw/7uIRZ9U4otV2lACBY2PfSUUu7vJ/iZUtvPoJmd8K/BmbnNo2iumTtQxEeARnjsHdzf1JrE1L6NGFsI7t81c5GCgmWILKM5pWDA5HO53I6aju6916JkUl1YcYyk9Hwwf/waKzGbNaeXD2d1jBd+rriDyPgR5p32kxAb41vjMM5QjUrVztISMmbVDBnx2qArnLJ6ECRGZcfK4U6LCAMxRtE+Y32MobWIYqbeJLCsaF4pCXyZjPABVmN36NRAavX8RXO80JuF2m/Snmg2NL0dSW67EVH9I4fcFSjpL73r6ohLh/V+uK3786Tpz4u9p1byZEEFVjn4eK4wBNeQ7DGhdbFbRTt6/9b55EBMfJGakrqZ4U+Fgnh2uIpidUcG+iBjHE5HMRX2ZKkKLyYQElkw/Kbj2w8OvDaxd8rzWoSUnwkiP9DB4L1FBdrrf9anTqNfPehHTBlyG9cgcQLrR8tQEZN9zuxs8BV1Zf+cIk9kSStcCODphQCbZP7NYhgTuqPh967gyo6DhJVEeM/gq2arEo3NkVtX7D7mzM4zzsjwEazeZbygY6xwP5F5NLqPJ0Hxncni2XMn/GdHQmTbQF1zee4LOhZaDlBzMZLsKXcJ3sJsBmPODcSW/FKYiVgzz7wLdz0C3bFpTwedWpIZzG+H0kpS6hOFF5yNj/xUGHEQK75qxYUFuXq2vFITPVf7aaAWUF+eBV5VbBqFcUccHNaTmGaDdRTdXTurKJ8ATxX0DHWz2qNhGP4nrYJRCKI12hvvahdfR6RlR+zca42mjybVuHEEGrU2KvnHy9+mmlQDH4jYHZKC6knkne5Q28ldgrISAF0p2u8YVTy2bGLZqUkIV6zWDXi0DuZMiQhOJwUgZQNnrjzpboxif7CaCAFdxHukA5fPTubF6aLOTWCnS/EP8ZSOIyNGpkn86BVLEgxNoCo5XDdJHdnSB0Zy+5O4NQSsoKdZzikwg0eSvXAE6j6WW27irlXjNHHxiuOY/LaFsSgXv62JfK2/O09r1DMjpxv32Y457Wd8wFBf9V6i6CdLP2Z9qNFsxcP88S7N6b5FAkZAkO78T3f4mpUVnXed/QQC1AAudBr+gg118i202+jHf4m1tBvD2iwt/8PqoAWQSajReU2kDJ91lZ9cqfgKVbzge5mUlKDSh7aeClFOoVz9UEdTQyNyjj+u7JaX9DWyqtt6955fcvBJF1aKEjjPQjYV4+FQr9Fnd8NqWavBRL91OUcILzXVselzvLQtPmmvtdhkUNi8G+O+b/qcVyHvls9lJjRGbe0YWtuq9zXA02yIjtBjoQd1vY0EmEFvb3u3xiPt9Wix6NZ7ljWQVbw229SAPrh/hsIECHTLmxKxWD3/K6TUieQeqJIfpcIoOQcgmvHDyyRUevzKImeikRzg+ly1+qSicz7hh/DCm/39Fyk6M86XNkhcEgJKANNt1matUHBPuMmqkqR0Irsee0uIofjg8efSzC4Ml6OzAV1PuydANODV+SaVqKrg8qTvT2ROpiQHqoOAq3EdFRo1QW+1ak/AYmGEVA4cF99A82GRm5mLHhLHqOSqBVNF5d+tjFko2morW+bAtWqE3Mhi2uYPJEeL+puWOoJaLV9uHtQIj2GvjqEnPiF3gSNk2kq1rb+v31DDwcalu1nsmfE1n7J39uQgliDyyoBoudkZrUtnIUrDsC6iGs/DA1YU+EpC8VYQ4iw91D0O8kJIRK0Zo3YzUzYnm6vxq+9EDAP5SWf+Eyupwlhcyq7rgfu0UcsS/cyy18bZBvpooyg1q0GNkTJ+MwtXBtDoaChHEqMdF/a7GjUgboSb8jHDJrfqRhQ/bbI62r8nHoOa6UgOaJLxxg1EhXpXmkd3Rch7uNxgpPzxP/mBdrGsygnoth1z7Q/YLYJb7LwpuGREdhP+ef4imi3CBmJrq9pWR8/s43S4uxqNYHUv9ha9RBACBhuz+S4xTQTZaCKSoDHnxC8CxGhiHczvJUTlt4rrWQpu9+AvsrR2wMvwqpTTd2ETTsO/P3JJiLBUvcs0TXCPCRY2h9Nx8ZqMz8XSEqa9ByDLoNM8PxxK/62v/Wkztb9dlxfHsl4u4UjIZo5lD7knNDevOZvFRYHhwFE22lXrX+Sffrt3y9R1DKaG/GlAPLQQX/Hetzpmce0TT69U3cFZSUWj1hcJa25OoCXx3O5jXSizjPu68eF6JRu4ly0GPmihJAcdY54LAu+PeTtHdGWaRfb6RVp9zxwP+2PoTSQm+qFhD5LkhsYuT1IwWLIAUjU9P0z7IOUj2QP4sYABt2vX5hJCVUnjOBPVGQTmwyR8LSRc2WvhlmD4DMitovW8AmruHvsuxxMnY/ybXB0f6jgvY+7tMu0sJN5r4DBEBXa37SH5PepbiAlY5L6+09qF9dbg57qZdXr+Lkj+9ODwIdoY9Ogs9QXAMPBK9sNLNDM1mFaODMVpqeBBx3+/X8BkyPofOmxl+kYJsG1PP50FDBXj0A4uVUwSXOnyDvjHd5pupMiy5DyOMVDjPDi22YVTeKKPxtGz5/wLm/x/DzHO4PBKlriUyR2fdazZ8MZwZO2yzm40RwLqezNhsNT7aqhOqWBMfTbYcyVtVzrROKLQ/cw8h9MBYgLQZ5m7RtajLhjAmwWRubbOysVY9+MbTxulvSqQymjxTj0/yGmowXOk8LorLHbyciHZbi5Wipq5e028xOnXPq0SO1Ei/BmXFCr+iw4toQwld1d5KXZJaq1eDPduqLEuVRpKA9CzB7KJsTTpdrYpMaOsIFM7Wgr9Oh/caoRAohQN6A6HSrmbUuxffYlS4ymc4W40QYfauuqpQ/JTXe2l3gW1vBU3Q0CQWi+YnGMAlM7QCe806vIrrgQmejgYb3z21bFn0KNZj8qMbtk0fubcrDYYwmBhjZezZtAK7N3MQKKCODWwtmN/WYEGctudKJzRB3xrBGIXPbh2oyOsQ4psvw2packPl36ulG2AlW5rvS3xsDrZG0jPgcLNOBZVquBKudvtx5EyYnivmLREWPn30cbkfL4RsfTwuJVSFZZJFh6UkofGq/bkz/WqbPwyDk8xppCVNz7JQstijvxEWrb40THMQJebLnzyY2q2jx2SLecaR7/0b676f5ddR3aDQqQxzS6YlPvFcYbw+8vic5SAk75H9CSsEorQCVlJSk7DU5HBRkzDnV2QtTJe9fsfqy1sQNBXqUXzv+3HDVDSjlHNPKEmNGm5+zlEP/Pa0mLR8hxOG5PeuHfsO4YAaC+btxGwKVWC9Se7tv8fBJBx1n+Kox6GyPB1SVukkNQkjh9dl8s6dR8uwRo6Ep3zrpyoDHwNvpGU0zV5/27gpveUjCyrt2ZF4TOPsS/WygLkfE2dbNXsNDXjU0kggbh+REnbrOGVNbeYAoc4ZX0aRdyTYOFzlRKaGo4MoHLkMH9FMwYlY+jItBYVbIzsByLIUmu7xM7N3q4VtOAzdBtYpwYx/5yTIIJ9yh2VZWg/uPZimDRgASUeaIeF/TU+n3NBLOkQvsf4CKuJi9s4FqpE2p0HLaw6yIcFU8mcl8Jx6XPWv+eL9Uv+Eyr1QVYQfaJcVwJ6kjFn9GSZ3uvbIxaZMwi7x+nNLp60sgdzogotqc5oVT+LDsygUDk+S361me7L2BWYFkcDER/Rx+J0tgDZ6wwKRu7kFtxCpqtt19WgsF6LzpqmDlLORvOsY68JnuZgBdo7ozFmFR6uGXxbySNeCvPKl92vkVsYEYjZ70nSsNQz9WiIy0pcd4Cjnd16gHVj3X+IIr+ZH/gTnYy0JQvVtpoQKA3yqTH8ZK5WAWFLSXjNeHCwtYmaan6uJoOWW3ktmR0n9j0uxSEniCHfobcaa4adhh6U65iKCHer9DsvpoFJxkj5jhGLhPSjJ+hLddzatV/1Ocn1CE5uZoZAMtgkhUYN5zk9+VUjJxOTjDsX8kQFan+fCSw0rK8IhXNp3dynfHXSYCNq076Pn60lpsgbLC41pl75UNjAtdkXJ0OFBP9SOFxYd/qxoACmCf2c4BNjgll3P8P77ikGQPLbKe6Bprf5RR7SLTcoLj+WEriYD+XvlnCQ6gwN09MIkc6PH+xS8JfJD7iyBoSsLx/L/1AzaxG7e0eIP2dxroERhpC6jg8arrg7XQBksDHIJZIPRhy16WjWaucMUOLtxrgBU9rezETjoCtMnBYdaOAagkVHdueRkp+p0+SRoZ4ejQaCwhOiYRYYJC7NsV73oO8dwYLioC3qILoo9B/eMud5uERJdTB+L3gaZcXObntZ43fegezhpmSwHyw4dM10xfsXF1MY5XAR1XmGR9Qz8Yrc2BSBiUUf1wSye1tGQLKtmsheBI0zWEKzJu8/tdWQ84lcWgnXo9INPwDU5XiJi0OyBQbwRH1ahR14L10g9kAYWlDK/0N3VzcgYYursjTtw/2wSHmfTGJsx5NOXmMmVliBLLHGu6G0jFBLZtUkH7EzFzorhlKhKRrLqXXlXpO8crQ3CHEcZLu9XzwCc9SvkPe94gxwonijdizLHtGfLLKLF1cdtXMFa7Mf4P/JQHiBZIRXBzCKoqPaIuvh7X4/SQdEJnxbsIECUF90ZnrLUpBjTXiX4XAc3Mse7eTXKyZp8Q3Sf1S3esZyDQl+BBER4PmbGOeQ+K1112FbEeyqQZg56WiQ0jRCUmP+Kew9A1ZxSjutLVOfkpuBwoSkP4RGNoe7WrmyTXKI6nk1Tnz0oe2Vm3PjBDf8Gwhe+fwAYSAjlPra1TtCj1uu1GcdIAm6ViQn9Srqf1ym9fPIxInLxt48mCIl6DSTi4ZJ+XkJrz2dXWQqhpSF4nNWapdIjJH+p1Opedufkw0xHlr4vORb9BCJ3W8vAPdZSqI7VxbNaaOfqhI/8w7L9horVKv7MLnEr2l2XgUM6+i5Ix58xgRlYVxa+ltEdaupD5yktPEOlldMIatEHTM9j7h7hxVvQPEbtQP6BmDdVaPz2u/o7+Aiy4lsXGE+Km2ss6828uqY4y28croxcwQBaemP2+4hEA88WmmXnQTmIMFje/i5qVzP/dynhApy5GEB55hU7+jPdveexxyrULupZB1hjyqISvKscuKXOXZUnp8dPLlTkOIlOhMu9t4Vx5PLPIDK0SdUiZ95AlS0+/1macnq6hXYYejgXigt9NePxN2PY9CC0HftH0q8httvBeLZ48ootbmSIZgK7/Wm1zqq/lUDZBL6CYC5KDyLg/WfRKIQMNyN2X432uLr/f/9AoV132hvDNWvIbdgJKmzFwnqjd8+MjwrCINW480Y/0ve7EpvtXHg4WzJv5MuILg89gjdMk86QRO9Q/YKdmb+HV6eMqRTq/oudO/E6zvH3NzGgHNz/zI4Clc1kXUMDTrnDpBI2KbWe//7iI6d1A8nhX4F+4tGki7hfsA4VOK83fdLmcdAGqQRjtItVXa3J7vhE+x0h3K+fVJpM2FZDdY7gVF9ME1rtQmyQOE+F7b6vQAUregqMnIegpxtIKRhyTvfx+DFWZLf+VUZHUO+CicH8sE+9LpldACFUpG+WMfE56X+8xIB5l+Eu4ij2kBUNYythq4o1kyIEuD1kt9XQ97gS9+waaIHokWae6jm/Y8Govgmk31Z2M0SBZAIeudbA/y6RkBys3zsWVHoPxD73jIs92cougppJ3Uxf/pQcoOw/qt20epdVJgHhT5/Rg5mNf+bvQ4LJnwSxs7VE9Qc/myZF4IFBUAom49bMTIghVW6RJ2gfXkP6ovc0THTEpxZWx4zTkARVTfH75vftaIkZptS+h3ERciwL+zFBfxojqrdRqqdkYWAVmXpf+ueckOfXPrN5b9eEwl8OJWgoXwyPM73RDn5ix09+qYTUbhIRquBAIHnO03H3q5TFdSXzP+sPDF+FV61ALiJwLttts7/NF2qhFJI57p4sixeZfoEtm0Dg5wGwPCH6tc6aqO8oe5R+IkDR8TuyFEN2w2kBdTxxvejaSoap3bQlCW4svakUIjVrpe7zCbbcGL0xSe/T3hysCfb20Xj0oFitmmY1Q+1QAbHJj3MfeeZfxuvYYoF7mLnb9sF2SPQEFrRwt08qapY0ODw4ReEM3TamVg4j3BvgKWWLIeWrMXPSM+I3hBzjUn6TbqMNWIPDWj5FBYrWBwXYB71BOpmX+5iYomjHoQ7LUcQ867QRS3qZXYnBbLy/FO2tEGfzE/rGyNxED2nvMySIIs4Fx3fZIsIZn/tCkocG9krZ5TWha4eDI3zmyCQeBMYsXlRDNsMfjEEBFh6/Qhq12c9IUp606kEY5bwbG/QnU+IAyJhlftn2f8iRL5A7v4R9oAJGU2GYjNHqZUGg2z6az4YMtQyXcV9X9WBRlaYnfVIRsmuVGDhDBIoG6C8AkCK6LdXd0NgeShgVCNpx7iacd6L5r4rVi1Gco6rCBwBfwyIJs4Fhnq8IZrURn9zhkJ2FenUPijnbIom4cDNJT3zqMfvySGt4ko2KqwoGDH25QLfuWMbcuRhuQwYKgCX9VgClxETR6DM5DNjTv7F3ysG0kI8NKZ5AZDzjJnJD4VVPwVR/fNKHpzgM8QQGSapVEbQCuiSw0xjHphp0eDxZeames1Mp9WwQ2puhmhj5ql1Lv0eYJEpN8RFa01yfNY0KZkTpYzcO/Ckhbb36k9esVXSMPl1G/K7/sR9Mcqvz7tEmdFwGaO02c6azfLxlRg6byx5y5aqHXBgH+N8X+0pGSjHsaENs0tEcJU4XtLrRLBJGIFVEe3TvIYkvc3siaU1d3xi9t7TPq1L/+hMRqojqmp8jBLyo7KEuYZeOKHFM3mUkV+XkyhiFhmwxtLgSsGMbh8fE6hCR2rTOIinlmsF74yj7IpViQkLbyCbrvDt5/yX6I7Y1abrFs7QBI3D9QnlxlwbgZHvFTKeaFKcI3NvUQFQURMimQ5M+eF6vwSlYff+7/cWpYmvPrIh9BVONzVYOe2tQdAWWT5fJSYL5Upt0L6Dl/pZObBEdo+FPC4b2+iU09eJ6vb/kc2/uq9CvCUV9KB+C/CPAJdOu7vq8wf/Yxy8081PEnm7VGsIzzoFYnDvfYTUyPhdXV2yICWljxWqkyEe4e1n+SZCRACDyiLTdzj5Dq5ThMdA+CNJhV09iM2iW1Pgf2XiLDkIpNo8ugDtNdVTMEBsO+uHzrqEI+EwMOFr2gevD8TkmyjvrYH9Bw6rkARUFwc7DRpOCIaACn2Edjv7bmiS3MFeVgdj1y0Rv+v1DYqY6EwHst3CNlpq6XBW7Q/fu+F1R20aHUR5Z1LIZ7wvY0E/w99bKzAyUjG7671ZUYF6F5+Ynv4Cm0twLZ+GTrBp8VL/LMeq8XYgzYldrklMglyWJS7iWBhdA5GraO3m3rO2AorN4N62bHcpIhG8kbvIkybnRVTEWt5a5f7iIYJN61OO1gLp+lMKa9CuaUR/y9eoF3/jHgqh6iPSadglFYQ/GTsLkzIXMTFtBelXwJHtvmQtoXItuOsLGvL2IK/M295YD8SaNfSND8zTfgUXGYQRyrzsPYC1cxWOto+YkW9R3EinZBFUy/5HWXF6WeqLcPADGeJH3U642mjV9hMqA/GY+7DcN2bpls25VizlGv+FyH0qhDmmd0gUS8y90rDX+Xk6y6McJ6S7gM/DYcoTHv/2NeKg4rjMw8TqrlL9LBcLKWQxtuJxVX7ObKDCs6fNlfUj6iRrGPFdJD+ziFknCJKgixZ5RJQEQZi2MefRmUYi5crYu3Oh50a5Jf+upvNzFAo7KhxO8WRvoqnLO0wvvdcPsaVUOIcvfZoUierdTyFyoxwnJI91KCBroEodybtBGshuLseewOL8RJP+H2Oqsca/SYdeeRtivXY+FFQeTQ33eeX3DdtS0+wgHXVCCQk/CkG/az4aY+ExO9eyJRmpeKAXose57USPZEoRKo6m3uIY0rsGhjw0xAS7X1DuBTFVuo29v3dChgu70cPjpl5/xQmrPdA36PXNZRWOszr9FtTYYxG7dHUooremnYo1QnUGWsN/xygLq9TDGLLhVH/pc4pD+15uGiALFzU4PINmfD25G8LAsJea1dQlpC1s7rkYJUQqIwFNDY4Eh0dawLn8fCol/rhUCEbEHM1dJlCBpXxKfm7zt/ZpsbXgy68nEkEoLjs9rk0E9GFFZoYLZv/4qZR7nl7qBbeALu0FWvdWoNb4hCvlkME+i5nbMafn9uVxxXlpXBlOxHA7IKvKJLMXQanWkuK9A+2VI1JSDoY06+R0/g5TPJIHfO3roljfhM9ncx6Qrk66xY1H0+2UgF+oQgm28A27u9+T4rGo0sT6suA8Jdwthg1T9gojZro33dFb5pubkZ5ZHchLzsKkibaR3DHxf769V4iImNuKKrpgMMK8vcvF4YgFx9Asca63MVyNPtp5+zXPASns3bwdmsxnn1S54GTdkB4DwX4L7JXMnQGqIaS+mPgWxbIZbFcDNIrMilEIEGFczfvcACtmReTyzqnpITyfsh5QK4RKX9ZWtvUy4bWXjsLYbNV7MrrZsT82c9cmf4f8I0sSYqVIlcUYgI782imxBuEKs3OWcogWDmwlr9TGLtVSSTlyzHUW4PU9f7Wv06gLioBSoAf5esTj3FD9kKtTKQZfTKEIOcCYWcfIk4IkcfoFGKSLqsHhBpBOTfEJ6dxkBJXCSlknDrb8XJYO4/96XFd4ThAg4/Heg3u5p1kP3QG2yMuUrty2cFQaT3cWMABIB2diEu/1KfFFSKbfjTp8aUhb99C/ZA5m7h8JWsGwT5Ml9Uhw6CmNHyRA15TyVwIsOH0I1tFeVqQaoqT7wGjyqrJ9bI+WtpjMv5CAGQfj+k2aPOJZ/zLvxAtkd/Bzh9BZPEwVE0I0DI82uWK72P5+mHKig5zbXYrQE5bSNA9/gHvSND2qLV3hLPnoJp5q/NeZX7mhb2aWf7qkF8iM4HEHQ6YiYA+E+kPmfMGabHq62QBi8sSJ3yb68iTcA4YT6f+gJb6G3adGkY9eeu7XQZiQEi2fXRSKUOj/zLkyh4R3hOAX6xhT1yCvCHT2Jb9tAzSMxe0RFbM3g6b/VHgP8nyZkt45j1ZYBTwOpQIaFU7nU5focNbiclNOds9b6I+FOnBXwyAf1ViJPMKBBofmR8wg+77g5o3CiYUzQ+KdNxUo14XQc58/GKrIq3XSIefM9azql5sX7KlTsU8DGT1HlHIYnd10cJYsAEHoN0mLKcHTySHsjTFesKWsmK+siZFXhlavE6F44mweXOrX6FBoELRrvIrsst4OH+O47VaML4CK/cNrjlTodfRr3u2XZsHCcw9kXLGX/15sm10DYmP3G3387x7LDyVoplrs0pzIvfcy41eb2Ob/wM6tQNLxQKnfSbL0eyYL+RWR09qeHT/lWpCFvcISYlmdF/jMaIWDyxE/LA1tguYOSiQtSqHfgqHr1n/k5nFhnUBnU1J1eys/8qySmWwIplgfD3uNcFHlg6trf2B11Om/f7E9onO53sWHhas4nNuhBJsUn2OjOnOAFZi2dcAvexHytVxIdybjHcEdXUcp0jkab19hwZ0RddTUGjtyulBmpbfGD+4d+oynTEjmMlYS/pfoCyhEk9XbgbBf7wtFs5qleFrCmB0NrUYZLxmw+2wFqYEUy2hYP3ZxY8uhRZeFXZfhOD58zGBx7lo4yMjiBc0zvOGqVQm8d4tk1CRpyGJOGJWVU4EpHPxqgMP6hV7f0IxJugziIEJHavrZauRXe0/THYEOKpl/a4jm/fah+oAzHRBqwetjJBSjNp5LaZ3ZUNQElZJBDOF1e4muumSHF6da394Cvppq45QN1B2wYBfbx4Y9fnq5b+heTNTCmP9XhMQGniDhmdhGzfPUY5YPvTUhEcaaA2ucNDUO/xvaUVhXDIodrM/05R31bnFkjUjn34N7Aiuagl9VB9SjYsu83Ws9eoevaZVwZMC4uiZko2GtNzZCyMHRq6GKhvEGBiM1gLyvMZk3eR2dGcn19YX72JnDBY6RWncG7lGAg0YZR9lyoCyQ13gtnyBi05gPlO9yOeIYGqQrhgRpR+pAvx4czdaBMpVI7SgZMAhMSsdPUEQ9stTtwSabBmrln0uHsOMhDvi0bNRUWUmqnu3eiLgzk2XKGyTaHCe59vZZcmDkk8aOO6pTw5H+DWALBPMcCOmfIz4cF9E5zesXbQkQNDFk7vlnAcetbpid+Ce9MnTb3Clhv0lL7lyusJYCpLpalVXmQ67YNR+IIDh9vW7XeWnU3FFfdnO0yqCON1josSLVMTTaH/T3Q7Y+gOUofDwwXaGyGRB+4GRC2kk7zANlgd7PmE5kXda4IpmTbP2OqUJ/O9EXW4aslQR5PtYy3tNMamtk4Lwzb6WIFll7MVBneG5vPfEGslblvK4unzLLIvceI6WxhiZNc/nr10k9nn8ikKPz5jmA9oC+lWIE8QR4XYTcO6WZ7VMORykmWLBbTE1NQc8/TBpYSaYjlsyOK50EEwZC6/hyMiltFDU/OcVfSs/4s0Rk68qJkU5mIFxzQcySQSzLKmqQzkbb2ZlC8MLMP8Tt/ui2UK3r3IoyOWjDNfAV+2/iYAbaU/gcEuC9PqZbBCpHpobrsMSJpIpAbdk+lZArMaQfdQP2kY9Krk6TsjNb/ad7Ghc/HTlJyxRISEoijGyuLhUJB5Ch35PrR1oibmRE3vvhC5cWj/AFFMlliT5ELHoj9ieMLEG0BOkVRUXKuv2bfaF8AdXORnzTtMfXYqB8UVY5TvybX4Mkg9YXaiDDrp7KV8wVHpmx3MIlmRkznG4Q7DbYNTZBEi2yxQfQW37NrAOyCP8AXP/EHi/BLLFg/ip1tleZLojlnpdzKgSmJyi4IRDWNifCtFxTRjzh2z9DNa3KUZLZnixrksQWHwp2gRkmuu7HYPHYIQrdjih0WnNb7CL7hFDLjbfGaVLQh5Fu7SHtZTqDYzgY4QnM/x2PC8v6+qmCAMbOvWxZOIxjgpUF1ud2/e41K1bJAXPTZ0ctJLsigJDqNH6fNsXGGXNx7cwJPgP6INK3Qxc3ylfv0L1e9m37k+CqkJJTN6MvvQuae8WjO1l0JvBh6yHIrZgf/Bt/DNS1QULgHfUCLdwH6GVXxn8JChzrTEJL4dTZGD6nCwPWD+eeU/jxNc/wph/HYngIZcSTOnA7ZoHemc7pUYXx0Nr45Sbce9CyAvFnCzoIYbXxoDXYVwt/7sf509VEfvoLzjbFrRKr4vntb5dgeDiwRX6neO0yQZsOSoVjVvOOSAuP4PT+ezKgOTL5CMeBFh5fTyCTneXHNexLrs1pBpLHH3kmt/Gi6938ByjJyGR1wM7/rvRQQoS1drQjQ0vefqIJKlavxUAyi0PuILAyGGfaeCzz00DKjY1cowpRuwwf7rYPEZOByjttnqj6EUZ84F5gZp+4HJmTpMjNq0q/lyKFhwHKG0wkVp5h+gESx82VKGR+mbao8YOh23JnEy+eNJ45yos7d1gFc6GC67dt+OzE5TpAYicEpe2YtuuIHNt0hQpdLBdS8eqx9D9RSrya3h16jYIp9Ogfv58USTrQa6bOJgC6Fuw3VSohoUOQpQ/XY+PVKw2eV8Q1N6yxzymT6QIiLizm3kcA+jtFVJVj/IlTTGr7Tj6P8fQmh0ag3AJfRbLs8nmEQ1QHGUtaUv9djTgKNG5hVLyiujHLL77tNlHcYLwqquU6Z2V+WMoDwfBiMDqK39/tNhs7dXQhQTHYkold5VgNmV+WJr8ETyoKTHTS8g1RZL+KCbZw1LZoGTgR6eNleq+XGRggG9pbw1+WcW0jzJpvQle+pDWTA3yPaJogeuohg7EijR/48Se6kjwNpGStelAHWNOtzrfgmNxtH9r1eSRWLz79nRNF5th43Vy+rZ9FcwK7PlfJojQmk6yDIgDVpS2IJtFflHkl2pdrA/ZK4Grks9dfURGUNk54HimplKaYEZX5dE2M9W/60vxTLBE6XeIZ01h4YiHBHGMX+eAHZAHpSk2dFZUbQL/ylbq8VdzyOCnwzB532xAsz2XqmJFNJCZ6YuvEpyZtLa07GuhPki8MeZUI63KN4jC30SSX7/bWpsMyfpqrzmMI+cCYlmRUB0Mu4kG/untuIlFzWG2JnuSThOvNB87WuxDF4K9MPLtApA2nPV+2yMqZtQu/5eBgMzg8/6FBhddJz3kV0onK4Jbo71w6dhI4czF3ksh7/wVe0vAH8B/pVGb1v7xscPIhg6KL+hvTtq6g1+kCPpBURUhkj6yrfPgZ3/Xtc22MaQJp0ouI8smF0IW7P8ZfkCNRlxyoz5rOlXJ2YoBYf+hZJACLpIW6Ecg7s2fptIWtvuAgGvGV7dSNLkYv17ghjkJQx6tLucnApd6V56PAKNj/7Yyi6MOC9uwvXC4HnQSolMT49c6/5ZRIfWauOyw+arQBxET3gqjgZPldHDuhPDdYxffuJ1ityuwa75OUwVzCfQ3DhhKAfuieBFYqqN1i5usxjNFwKad4V39gjt2wLjcS1yX59qz0LCyVW9KbSYU9A28hy5DC7hdtdQxRU9PX4vfg8R4KZzpT7OhJe4Rwnuob88KsYJT3Xdb5uQj/iI2b9k+IAL2RazReg2nxwi3ia771jH8mWcStAs1NJu+cMgx6oarFqLe8b1HSRxQ7za0WtQhVKdhOSo+l5MyUbO7l4rtMf8vOidRDYSBoESyiDirZR/lirb7mNwOHR9B00U3KDHjR+/6/p0FjHCVpWNOzJcWfIRQkZ6XmbdXoGNbYi+/6K31kVQSpEiFHlf0XTAzQKDh03BJv6aoldSXInQfAEINY34mN7TGvaILI1iq1F8qQD9LdUyM1y1GkmIcoViAyaqPmTF6srtanuyTM4L1D0wyuj0tEVAfuycGdwEON4fnsCqlt5T6S1obgnUutprS4s5WpzQgzd4U9TRXJErli2+o2bS7A/uISBZhgh/679K/zLda6gWtuZwAvTGNdCbAN9uwZti3Hk9kKWrIq/zDHz00+fSYLcc5sgjgY5sWd/F9nGirgGojICMTxUzGmVVyjsC+0iZ7i++UKuLA2KCekIgylXj+DAZVKUFgBgXYW5+1bwyASMUltB5MhCcaMuivyyhZw3MJ7OjjmJyH+sH7zwWOwFaztw+KQpl6ETunGZ4wgXDkkep9RDpXHKdERy5R1KfOfi61l4kXklOVi+UvIPbGuKxTqSuKxjgg5aUU0X3V/EKdOugbYyeYKlYTyfe6Py6u2Z+A0k4k2giHiUVqkoC8MKxTXxmChSs68WryAMhUxyo84ORdwTONcLdmrVJbnyH+ugmyyx9iKEPADsMijuo2U3uJDa7Wnfr9gcycQq006VxIwrhk0FV/BDjqzquNOsEJXdrimGw0G+JVU4/5BNk+lE5kSCYz9cOOfNBtbtPUoVHnu1jfPwwGlaTc7GUxPcDFnEgwaHh5znVnSwPAAdXz5o6vI34Epz0NKfx11wmUjfW8nTAn60/CwPV4XjHM2yzXbq/EA9hUimpPyH+gMWQc8fiEpaTtk7l1iADxvDO8EMdlaQ0nXdXnhCuCrsoC+Uvlb9IaXpTbhDyzTzYYUPRsJ1khYU6+UMPk1YHn7mE5V3/F28Yia/wrwDdF+R6TmVzsqudzix7NyUGk46wXs0WaHIURcZDicGiV7SEhoVNTU0zgBoaSd49LNnCcmSgWRMUa0JKdpcVnfovdDcIyEcqOXD4VeP1baW1O5XKi8DuZzNuEL/drafxlkHz2RIla0Jp8ILNn7S3fdeg9UhAx9q0+SKtkZq2KsJrdjjyAjr3GfTjVIDAz98414NxYOtS7EWs2ZaFK7+4WBYoC5Hkeq4b/TVXen2W5sxGUXGVbea0PfIOieEzqtacY9iZH8JBwrLvaO9mQx8S8Xs1qoQA5mRuhLUFIcDGMj1wJK/K+vclB5Bl071Plrpq5+L4WJ77f/haemR3QBDVN+DYo/NMMFkqokI7b1nRwuzDmI5dEx4XMlGANd6UtZZVQ12+CHjwiLfAM9yPWaei6wRjGbxBRZUWxyt/lA3BanlqVbrdSdMBG5p3j4Pa9sSfYjUr77zB9h2qpnC6V8u1+XFmGBTP3y97KCCHykGfB6mbCNng2OYcDfFxSp12MaqtqOwry+xB9gUkHlnfW9DENAGqcYOxFOWwZHAJEeIuPuyLr3pc8euQGkJA6K1rmHJDoeAl370hmHY+Wk02WBNr6bOj8owlbEPXZobBQ/xU4JVN9l2GH0nnIedokXyCvBiq+jOf90wECFhhyXgaKiOos+J5t5i72+cySCooSeyr88ULT2mwUuMCLDw9Pty72PByiEtatpiqNeZF8Kladg4jD+8iY+w8ru/PveAVmrABMft/YevFyzmyB1LNidUz8yrnolKmitwK2bPJrQzSfyMg7RCZtnj801QmxB2Hh1RdODJ04NYCR84mkyeVmLrySQsPfWBiZawIPusj3W803YTrCIFZh55a7RhYSAh5uolGsv0TMC+pfZ8CJFMfhrjIkPX4iPlpoVij0m+1EDPaObMhssohxiQLjAb8un88eH/6Z8SnJxoDDY9JjIkM28xe9G9BMqE8CdRizNqXF+yzFoq+i0JXmGCunk6mGwVz7dw0Aht2yZLXL1jgrrUpP84ikBVljLiJmABWcOUt5aq4e2FLPP4IYwNw6/6kBGhUw92jqGvzzSz2IXFoSGkFThCZ6Hdi95k3hbTR+UyOtNXxKf3qOHtoG1+tO5u2H6XvCe4OZ0IsSdV2C22f4X0XRjnoLI9dkAJcmaPzyLbgrWgj/dizWHsrNz5PzGCCZ7zywhZMyk6RrEJ5ucZ5k4Fosm8+U94ZyJFHYaHthMhJSLgoHd9plpggxNFeaBMx2BdSg8d0qM1P9s3xHTr7n+uvFsfU5qJafAkyfAi/gC+OLxCw0uMl/XJ+id3bpdG4VxQwyKvZaxCWrPaRHIy9KcdR43jv9jfykGUTzB9KjyF1G0SkyMHMeY5wgAmcEp9B8ffD92GR4FQExXAD/Rm70xyf9mrg0HowJ+Y5o1trz3gJx6Em+pGPt0PvCVSXsmyA7BLMqIiL8iKyvmFzR0O7FJPoUD5dZJ1eKn4tDUJJ4Umb72XTHqR1qs8KsHPpu1Bas2jM6FoTMyoX5aScTz2RVJH0xso6SkxxuMBg3uUblz4fj83SnK1GADX8ZJtrY6l5lrbF1/ZuSi1BShVAdFnfBB3Sh1SW4KQz2mL+Y4svWwspzeGp4W6pTFKdMDjOxHzkJHkAfLjLjqf+T1Axa9og+Cl7gRTi70bSWjsQM9F19HqH1IdJOoerLMQTLpuVpFU//G6/hsxG6sFsnzMJ7n73SbIizBrcriqJQot6sKe+uP1gONUVuBIPlDJA49atkvafSdkS4NR+zciAFrwoHjdIsVSJKqDxAVrM15uFJb4cUI1Z5j3Wgo4gLqLZDMdNtYKJ1P7oBTGSBKZGTqguAYXj9FtcQ4sSbuwAvEKj0iSHfGzNYpAzMhIVEl+O5tVLe4s/3uEd9Gsrl6bogS5HKQwX3XK8Vnj7lf+5qIQiTSzRnfkEpdxxgU0LAZG7OSxjiHkVD2gFaZ1GjKhIedce7dFUwac8qA8Ut250wwH7O4rKHFECWEhhPfyyNNFFWeFrcIjCB9QkpXuz0U80DXFirexggv6bCvxlzrpYL2A02HykHogeIIum14ATyzZnKSfKNZqYUHkFr6qN2/mPO1WK01C9CpwXcl3fLEficn+qMiFNH5a/JFJBAF2ZZWJ5EP8mGzPCF9CDlr0z0YHruP+6bAUG47CNw5yDdR0WDTjq/DqDE8W+/fc6iTB4r9945YbHjR76ZqoOFAkp3KnRniRLdWK5iKvLCCH/Jf9vzHnX4LfdHlAiEucOADd6aaTJnMDTB0DnLoW9pvA/TvJPoH2GYOwUyBgDkGv7VLqRPzjz9nIWylnnWqIlm7L9YRAuucHIleKaTQCeUrXP0Wnyp2nmBxzeDiVOPsap6l6MYLHO4xg8HBAK3J1dgvBpIjcYDKZexJV5mf8c0hpw5ODKTwdkKCeeTezcPXh/9nI/FlRcIYy8sH3nKCQ0EEucVi+uinLNXGTmZXSuB5jYC2k1R6X8FYDLSs7G3qg+Wa30/SZZVsN+vbIWPDRqs9HMz/V2eXRrxClGwzMRZTnpwuqrD1GTjLUluOf9uPygJGxe+/EB6Ak5UCCsCWe2GLD5iZX8ywqGyaP9CGKOOsQ504tSVjAMPPpKo7Ex8LT3xYdh4QReijfasLvMKd8/bu689y+WY+S8IO9LXV7KYzmOOycnb7imsjeiBPCZgNd2Hd2fLIQOaLorPkKjFZcGRaNO6lp+pBPTMvw9QIbYuQZBlhu48VmV3i/3Y0m71BChUWR3cdNSS4D96YC5J0Y7ZFqMHBW6G9p9pf1EMvsoq2dzX2wSvNYXqdP47zyePLrk+nreb97cBNao7U34lHDXeFQ+HqT8XvcE26g42SyQZmHFRlH2UZ0kohpcgm7Li2wAo0IHMre/0XfRV0HtarB6og11KC3Z7/RUcqKzEPA7ZEJQgZNgBZE02MFT702HN67p516Nvqkm0Gjx83wQdQMeqxlml8LDK0V5SdTdnatEK7C+bhiQ3CLRBupVuTeGYhJY/BbrqiE1SY1vdXZ2SFuvNbcrI6ErGJV8/qH1acDEtu58Cm9IYXlR4R//8FS+sjKjiIPcuzVQ+9bV25MODrRYTzxFJYbLhp2Um/HKOncgLdKHj7tOrMZfxR6CrV1qRAGh+vD5dMMDkqvh3RtFI8M/B+95gOm4879zLjARkfVycAOqjJdoBfgWjWNsJnafTkmc7B3nIQv/Doeol9zaGW/DlpeEHHLSCVAFpPcoRFbXqIB0NIfCnsKcK8GmaNVe1S1WmDjR9kV2WjYdDpu3d+gX3edjZ363f9jQEbUhFXtuRXOQv+gmYCubqBrqUoagUdP7xj0HIFEZg93/KZ2CrZfN9t0A6WcpUJBI5WLyoLnqf11jJxzi7XP7icTGifXh8HPdPwOvmb7A1BFcfY2H1yrgpQ9LL1WPc8f4dqfuE91BNq8DtcEql3/06rGk4gsNyWI77GnH9IKwUsAFlrpUmA3zzUPojorig8/2Cbd3TjsCKM9wxliCLyKPngKsM1KFkqM6bMFtyxYYrU2eewcxYM6RkLIzuCbt2tjjkrWkSVoIS5lGaeH9ACsgsCD8uBJTg2FG+jOXwTTSCvGIWOiSPmrIKKcqEISVvUcMWhHEeUKjXTMdtBmPl8s4WipwTYa2j7rmaa0RNf7IXAOT77NGep/q0h0KdWRo5UPERTufgAqHgtum1dZEPq6OH8ILA+nokd8MXPhCko+zgkNqNlrLQew5ugiVBI+TSaF0+Nh/0lIpsCoBQWlDacVD+Vx3x3aSXTbkp6URafBo7r4W0YMJYL0MnwFM5mzSBvH459mHAZ0yzT09dEXgjVW9/ggg2LxRO6yGo5FTpGQS5EwMSjG3crtd3U4X4CO+KX5W46TC5B/X/DpEipFhWLaE6rpYO0r44KwsS9Ge9H2dfFY3QNvXA1sWHN6WR25HgQ091u/FmxcmTXpvXerH0b5xRi1MwmGmrK4ZAT1TapoD8+smzXuW4xfFWkVDOL7zk9xNtB53A3+dJrIzc5OTB601UXSFtQkX3hWaSnhB0fIWaxp9w7vGQDYtDAeTTDigrLMhVNfLUpJcIxhrMjO0Amicb+Ubauev6gApJbByzVQRTWq047GGRSYgxukHnlk5+xWTYTi31cQQCJ9ILZRJ3tV05M1AIgNeeDW2H8IBJqkzSl9nnKSajGYOD7eMyjHHWbG4SEV8CvAH8Iew6SodPSlX4spOyb4O8XdYQ2bne98jMMolgBIbc8j1VfPhmdPcqVcmf5qMjZcC2VzGSMF9s4863hYPVGq86Huy5cmg6zBz+qDU3yje9vmEr3yJ6kZhF5z8UdlkJdjq/581O9VuCR2B3lyEAfQoUZot9HdVILawreyRxAy11JlpE3UoO/fi5/5omkUs0A7Gvb5+bsteFVIW+9l+qR2dINow47smAidv0bLLEr/yqKcUanjvixyzAQCM5CVzq0r7rDR9M7wjLxBq9eBWRVmyK9TfSJqXHjL8T3l8phqzWGZrkRC5oiPO6C5Wf59fFDP+ituUaiEqytebX0Feyu7U5Leql5gBMTdDPsmK7KUOyA5TuWxjGc7dN7kJKEYpro0VWRhjMArMIGbutu6vN2OSHb6nvd508S4Q34uCRKu96bSAD7YHASNVhzXv8N8jroYf5Y7E9s4wTpkvo3BZkkWqpF0M1vka3jjUC/JuZvw9V8avX+D9bciICl12vr/bQJxDe+TN9MQwDJwOe5HRWZKtCtH/1/2brHVDE381FF3JIILjZf20UTFL4MLwmZtFv3M88Bv1x6hEyoaAlZ5p5QEWzlw8bJBt8orARhiododtduYtJBSF7octT9JzbeKdozaif0LBWL/u9RjbeVNLZ8UV44Ye6Sz56Vn8QlwftWL01WoPryii3ZZ930Zx6Ins/HGvGQmHAD+2qvuKQAs8Y6ublb+Dvhp3Y2NNMjsuzOvb6m4YtkPzbhlctKadex8tBQuo0zhmSxfDIZm5VnEDdG2vZ6kcykYFxgAz3wrkVyXQnwxyQIeYMIHQYT+257jBWD0yJIiC3PqmohMzTC/65XVgSsowG2kgnlR7pYY18nBQ8aVfJ64D79rH2pymM4xMU1Zk/OS14XiDcldhO0c0RhQxiPSY72XYxpiaKVYmzOcEvI1PzQa7+LVZ6pBIwn8ffWvhqa38b3IskTs4RBkYs9i+i9/AqdAQg2IOeWv2fuo5tEcFyefI9nATJXQchbBEQO2Cj3kaBe2X+81o97B22kYSwjOkgZybf53qZFQ6p/N0dL/VnuL1cYTGi8k6rMpkKGx4j+Mc/fcHUVNXTKhyO10FkvHiN+qSbJGepJ/aLXoLZ8RET0Bshv/4hAQgzeS7yl0n74cedqdnmAeHmQ2CyXvMM0MWpEvA2ezZIKU+WvUSaGpTt1kvMloerqnqxHLfT01Yh2n3iD29EWnrQsyjedi1I5SUgvQKBM9G+oAai15cO1con2QFz3UK7w7ZgzM+vPmbk2QqR87fzlbdTSAhrLXzqVfLnWBA/4+5aC+0BRMZ6iX9lH3QXtKU9D01K3HprdilL456y5lsl38VQaMbz9hk0LgquziMY01Znz2WE4ClHG9cF/e7stVmn89oNFUE9NZ1RAc97KzDEWHLoKwlCG6L20/2Gj7/M6PDhsvhY+FMzYRg+v/0jo2gPT0UTCfaLBDRVvKQgUSYPMG1dr6ox7ohepBUS0msHq/V7A6Y9WfKDgSLatqTzwhOXnuXAoFc1LsdlV/Nv7XHqg5TAohZGa1mOn44SyY1fyPMCxL1QmxvhBC7mxDyj9DUnBpbjdAzrBW0mUzZ51brDVW3f0A8oKL6FYBf0mwK6YxDMJogq94OPgpZyKHKBYvJXMfs6u0pYnEn/jPeTVQMK6uY9Egww5setjqwdQmwi1ea0/uoNw7QKPorCWZohFt4VB+HUy/ObjCDdxryIg/y0wXGMwFyftSyf0v/ESOVaUNOHg1aA0SQ0KOwx/oqBneMvSoxZc7SqvQaHcx3ZLg7I0FQgQ9799KuVGTfGNgWvzIMnHqMNnCyCLJMNoNQK9XA4Wkq+6tVuCUREehKj+szE6KlaSwgAPfb6JeGqIyBrjJK/wNw2yPaYB9wHia3A56M5r4OplAvdVjO1vrsc4I8LAy1zqqpo0yM1hfixHeLNDG6ufXaX/4mWxYpqL3hBHpPbnox49P3jj/wGgdZFaJe1JTer036xd0Xak5qCI6SV86xqAdAChv6sj7ESw0SU7w0leCi/08lfYfucRQHdzjO3JkA7lvHw0ouMCSCweP+ms5HlStT1HLlgQ/pkLQ0HiDkuoPtTY6fDW0UPlH3ebKJKJsiIlEwAnWQ1ExfQhfs1IRdbEO6sgyC7u2YqSye9WFoH3s0+d4P2X78UPcUsRitbiSflMds3+5ixk47wEAbwHOouv3l0AUb9zZIP32hh+8n3fJx3LXT4wqErJXRmufydvyJuKW5IkA+rD7B5y3hJGUFrf+je8x2WEZ93MMZZjKF3R4hY4E82J7y0z9znWEXqtnGce0dejOBkrf6CbP1VCh4ixhRvmOXO9yA0A2XQqeWYNfk1eUkRWlybRDBiE5SOOtjudxOpqC6Hv0XRqdL58/dsrEItVoppvb13l9MrZRKzOe/vtw9JP9aAkOa7ra6MbT/3YE4LlEJ5ticKWKe+rOGibg+N20Vx6Vg7J3byZG9+hIpULnZWH4Tq3LmlMA+oUfgAbbzPl3twbDuQozSElI95KSsXaBWevUxIWPQdY+4eolMlTtLwn+51SP6BWFEiioYy+r2Rza4OqKJPMbx7t0CZCtpMKxYQ5JCowbAH7J4Y3Eh3C04j1H/2a7qH3cVo01mg0KjVVR59qENmLLCnQ4LNMS3i2XshEK7QAIvi4D+egZPpMUywog3s+tqRiaGXIEMFp3rd3TuvLXVT9tpJGxjgQLGMKXmGL1MVjoN97by2NaOn0JoIbOQqeBIHTVbBYNON5DD3XP+rStPIfVbuHd+90TJpGh8BlfV0dLneK2wDMnndVGVvQLhvaQxu6sL3XsvtxmQzeFWUSHLeAlmTc9yNQKkXtOJWS9faewS8yotiXdJQ6EI1vpVOHgh46gljSllVDRx9qlH7i2QFU/dKpaQEbpAFUBI/eSUGbpgT2ORGcUGXXDWjQJQo+nCkQVnIMRUCP367os5Iw4Rb3LDvOi+/mwcBozzUa4WkjVcSIURKO3RTFCiY9j3O6C5MBS6Y0WbBooC0nOzhKxL8xMIIaM/tnyEzIdlABrz3f9XlCiQ0hh+C7/bNp14eUvnjcHWjBOSw8E7BjzeXkRQkpIuZSOriwZ8PiOLZxCkXFOQ4hbXa4Tu69lccJ9Hd0F1lxkg5QnAhhfx5WdcTkBH3SibBUMCLPb/cYypz6s4GGDMV5smYibldp//j9gbCEhqanpxLsoexOMik4SOt879z21iz+8V3wgG8CicQsmxcsqCc5QUqOZhnpO4qAFgzHF+noxN835P4xf5EsOcPvYWwtzK3WEYVGy5tuvxE5WZB246SGIDgeC4sMge0B4p70Tse4b6NjlPHW+90GmqnySqY83r0ilaew46qmwi4RzmOcPehbn4YPCoISjQ44RURV++dfU53vcKhkSj6cWuh75tdSSUNMysFwoP+lN2gGTwxOfrha9wWxDPpimhEBVrt6dcBIvdoUbCLTDQDZuUOVVhZP4sATqq8z7Ai0STnGxzKmAHG+3I+/tvrDN/OOTHwR6W5aWSRj+M5wmS5hfdvimlus2z4pE6RV+l6scSEX3XjFUVgbSuuufln4qZfmgBxNvIZmkPtMh4WHAtuqRVdgDOLksqdhjqc9jrNVpRsYL4L5fXaKhNXYNJfTorxbaoSpoqj6ZEp05xsc4y4Qryx7BRs3iYvuHRbCUsiCPmmGdUPXDn6H7woEjiz1YeriH6NPF5au5aVrtcw0DvEgLLKMuVq6QvzE1mu+x9AFhhIEE3jVvzGWs7x+IBGJ2hfG8Kb57q5sDsPmddrc0s2doavGt3j59SpKkbETAVxcSwwHbpAEsYTNPM1KhVl7EPpQp+gNotyPx7hI11xG47CrYE7+4xlCFpaDwvf9FWescjE9qNrcgCXvSeme0GAOo6QjsttWQcRguwWZb6OG1VPN2xZcfyUeEGLHhPkrziDDf4SHNaCcXXJ9CtFdyRMVueZNWqaoSKhpFI91MMLSXju3pGbSzJlM8FPf/oxZbRADvlZZCyb8fbb4mQVBZZ3GWV4hj4PCrLA1qQvEqs9XLsRnoal9WaSQhWRzLJmCurnGGRc6wxyAAejp0pAR70k0M8R+ziXphTbSz5jU2xp2cFe1EhegrqPqjFAtYWbYwsm9X969oYf76RSVpD5DfI8iDfFILBkfvnZaZtHikQ2tfNY1T0QOYafZ+dfiQjWZxqrDxXDWbc/jYZSbOzpgJ0HvC9wodOgTk5d5d9dmNrnM0LH8bvtI4zgktUZdf/DkYM10EF8yMhbFqvpMTi+TaLBUNd9aLSzSGAqu41xsKxsEYHFPhxozYZMPCafc4U5t8Ja7k34czb9pTsN2JFnwl8AmZSpI39KzBoEcD8fz0CAcio2KlaDIhPF8V0HkEbwc2c0mkpBazhOMI1d4cxnKG15nlJ+haP4D9g/H1z7jIEHS7enL9st+r19iJpqLFuJiKD2NT7LXyBzaAcFxIJ/fo4roeZSvHUyfgqUjSVcPiszEAuk4Fgqjxih+ln6TZW8b5sbDIvrB1Ul++c1B63XbFgHdVJTaRPzIXeh5f5u+QYvfa7pHyQV0ZUIv4SnfFMvTC0g0/fdaaBd9rcpxu/CBpbobKZgCIyVRDZGdPlZs8UGyu7+Hxb64E/k0YIIyG0d7ZSIcU1dOwyAQt25Ow5B4W/oUhgU+Gf+qB/Eqf+V11+GylEkiyGag2sSabnAwgaqTr549u7USX8FH6EnKLv1g9jl2zIU7C6GM3aeDn8kP+9aBM0Agrl165RV4/UHaXPnrBjs3YOHlrMK9jziNkwwt6+rC5FPPvSm2uVuOQouD4+Rk/8X2VoT+8bijB9PNpfsOsNhiSOVgntu7dzfzJItraFExs2ylPt0vanTgZJP3SIxPvZsgaDSBNmxIh0KPLS+EZkJ1Xy0gY8WVOZDbYF9v0GJta6+GUy7ek8lisYumJ1nyw90NF5n7L6H1aFMYqA/WI2COJA7pWaf9Ugf5pniETIJNyNXtonwZOLeCG380p2a2m5Fs4WDJIbVCtkJ77ah+h3HMvJJ0fzW8OXfnZDuzbWB935lP5zr2+vOc7CL44LjNt8p2deJJKd+d8n1mwKwxWxUjkxJRVlpIqwq1a+Sfeu1oNGDaOXyS/LVoiWAi4/RFFK77j8sVBWyTeqc13DCYWKdEbHTgEcIdtBewm3fvU99V8J4gYLJijdis2O/D+3FBz8kG/SwAXwjzKgO1TmXuA3syLPxxfnEUxttkUPpzQJgAzcN6o79tpHr3QWX3TVy4USKZJPX/G7/sFv7TB2RKaM9LvG8518UTl/oNK6/mqMpSOqsv0xRVzNjumgamqz/e3LG3e1lkrW5SquqlrDJIrN90AProjO2hsva2vAv1ZNPbHVfvH6K8KnMmDbXcZImS+YAXafdXLVILS/Q0MSKuRaLPQABT6AsH1SpBlkiSLXyhT/gT5IbfD6Z1Jx0n7l33o2uGW4lgd8BRn8WUeEHBHEn2SCXVQwlREQtvN7iSC2y8qSngF4ytc3vgOucrGccauebyUn9sdKmkhMom+XHRGLg4yr7NW/ZAq8UDCTjimw0unj204NYoihtZTNdXwgmCpqzA6Y4a3S/braI7FEXELgpjVSnB+dqkyFq3Tny2G8lAz1OtN0TZdE3wgbqL8XtsE5Ut1NayTqmPNmEhJVC0f6ZfMop0HP5VawTxA+lq1XoeRAoIGH0ojuV+9O13sh2V2zoxj5jVyNGuZDtqZVlEeSIRI05PVi7nZfKw+EuT5YTkdX/qnx/AmQXABJR8mEbt5A8Oab2RqMdG+P0zvDI0gODnGDSO2w4ZOrD1zi5LnYaIljibbOMhpDWcwsd6Ry5eUmiLQ24OpaErO6a3/sYLybm9xOJLqfn7DNg/5SKBxEfKNyyUYP4KtkSMQI5Xo7dHcIhqH4l3CRK/gB7WtFU6bj0mReNJIitL8grYbUyZpqDuMDT5s5WQsWjOEmRSbMiH7HIkEIPvRu0WxMnRCJKjGFWdlKGqK96T7jlsEHCjsPjk/9VEQ4W5qB2tRAFGJ5YGgbmyYxqxGxduvkNdd3IZKcIbvtEtH4X7aHeyV4Dcn4wkEzUNRRhISM51Av5I1mwi2lj3DP8d6K9iFzNVDCSb+eb9pBu+SEqYrvFC8WKSi8OcZDj50KV871120hgz6n6OZy1KOh8OzKNuCKFt9mVlUfJKzD9gcuL53q+oTHGGIKFz4+4/zLC13N3l3y4Fn9dzM02uGyBGoJXmF3jrwW9OguOsh1FVykE1suM6kC/e005VRngkgcn29tixbfGSx7k8JzTId+5wTXE1HgKXCtGlwA7L6FxS+RUGGP2az1Em91D7THACjjqlVdoDOltQ7Yb4S8n4kG/m/CvtFfQB0e/e/JMgICLGKds6v5THENB7WYOdJ0P5s3GQzdbeXjUAG5Y2WCUBs5LZ6xDZzv1L7jfUHqBbmnHW7U4g+UTYB/tW7B0Ya0JAbpzWFSoVQH6CbY6q9fM8ccelwWdxeWdjZm+TcmBAHpje+emw8T5mUgl7Omvks7D2xk04/HjynzVyBN2dI3dBgxTkB1keL9tMN0WgyjY0ddKI8pigHP9lOa8hb7F2bZIa/FqS6JJPPHnlyPbVl+weIG7j4ocmWH/OkvaT4qtcbnafk2ocwOkjSqUob66ehit1UDMwKXreD2R92MZugTHNe/PWAZesANg9eBbm2p+4kqK52j8MW3AhqaffDN+kK195DUM4FLVYm8BQhOF+OWoM5tTD8LImCNRenutbU6qRxpaMDXCBU37/K3Y7eobcg/IaZaBuw44FteI67Hdgufk5VqCDjlK7jDBUtVq07hpPI9ymWW/m3nNLQlusNGDSBNYXOUBDRWNnHira/1eo9GEwVgpXn2tG1PUUxT15p/fbfGXCvpsj0QlzwErC0ge/Oqlsh7E0QhpqDAcvlBJOiXDD/bv01SkM269rmghWHJPUbmpq4trj7H6cCMXMIwWgOLaTXR0w3tamzJpReC8FXDNwkxSCbmg/ag17JdPyptz7mR3k6KvXor6tFCfEv85TW7CDWLEap1AC12Ym+LK9/CxdKPnXz9Qz4xNXGn3sG1wAfthifQfjDyiCnLo2uhuMzI9yKxH4PUTt52mReMLmnHFrrLpDYcPC+cU7ge55guYhGv/ANB92YzoXrI+Hs6gdXnnfE8GGhfydGwvKBKCtpDecGnu41Mz28j9/LTVtSV9WZEoxANMgPGo4BDbY2p69ixYGQWATdyg9TRDAK7f/Lrlubat60yuVZ9wcwqZ7NBP71mX6NEgdvfK1EgMnkZzsDQl/wWDHdAoOYCo4pKwY5I/V26cKTO4aMYcV/YDdgglOtas2KtIXBJAcgotsV4YfF+CDN4T5WdX808VdXh3/UXLrAdcMDF3QIXj1HyUHIOkXBH7DXICbJt9eNiowRXiuB0d1J/FqjPFe2IlNdXnwFwpRusB5PLSv0Lk/AdI1gQmao8wwLmnoh/L9riMbMMsWAOI+5B71d+lGTKlxx4hQn4ixRfedyZUUsRcpGrgAS1XqCKzggl0/LFuyQpe9BsgvZGkEHQ4ELkl6bcLtiHZ+7uFxmRjnV7v8PP1Whug1igIT3OTMnmb/dGJPuGKY5fRdvWoatxfNU3ABi+fY7eHiPqC0gQDpAC19twVfWBtBur+ST+y7fzmSE5Q0C3mcp8/31XIdqm7sEZJHtFnXBgaTyG+fWRGAY70K10IBvKH2TE6IMzm1k92/Cn2payTupKTtojgP3uaWIgFVgV0lD0WGR0PanqiKtrBFwqznvb/rz2PgpSjWd2BESLQpxY+6tmKXZnjvY9xfR12CQ8o/aKz1t+XxCSzy0uE5f/kaFUCrwxjL8gT7SEUJshp//5/yvPFJHgJlgsvXp+gRQCSzz+vS6rl3BhMsbj/HzwJYz8GsWppOQDGVswlOHEaFE/qhImhDrt2DUfNxtt21GW7KwJRn9/mtYIjlnnwgESPEpwoLyTru3SsVGzRxnZG6x+BiseUs57lTdb3H8KG7UPeH1SSjy9wZHELnar9x5cOtOR7lOvyjWm4Ab18Q+qoMxxLCFit0V8SmOu7AU8XGY3eSXb6Ly+kaQmDkRlOstgmcj+rD34KNz7LTvLL0O1Z9J/nCjp+1flOFgtbd7Yg0t5eNrPuppxYxJfSpnJRNL4S3YTffnV+x+zVsuioseET/On2wNi/TnL2rAQIKswi7Er3Sv48D/+PLsa2WJOSk6DqcCLmusILDiz0FwKEhMewrxtNyM2IAE0/6hiopIQoUgC6U8CLirhWbfVibSnCGZlF5uywIcaUlcEaYP/evokbi1NSquO62XNnWR4+fB3M1N7LaI5pwdHYOKEjg9OaSiTtEDypKGOVxZhdQS0jEvZ46foNS4SBpwZfPn60p6pQldNUmimhWeU5LUnEpZYjPJU6hmAsh4AKaLFfJANrZ9ou428yoEIFuiY9UgOYkqtSUocWxyijxK+NTtuDdbh7NJcyLIl6CUBWQjZiL34Bk0Qe3vmT9tpIKus3r5CvEdEu5Va2Wxm8CQJT9bESzuFBeH0QIRybKFAUVqNa9tCXukd1jwLXYKWsuMuFda8R1UjVG2cvAZ+R3lBV+nLksL4Ti6lubX3hKFcSyFsG5rK9pJt5nlSGIkBLP/HFqLL/KX0S96NdOo4CS+GYPBk+lBZxz6Yie12vvUj8l4t1ik/5PmvbLOTPCcaoPeZ7APUQIKIcxcNUDin3R1okbeAUGwt7Ja3G0ntQokBhlajisyXeqbfPLrTTKpTauclKp+DGdyBsbzFHEYtIqZnlLe5wjluF/UID6EgwWPGj0FVKM59Jom3+0Y1QTb+IKqHZv/0FIEEuVItlJHSixdza2w0UN80Hyc/eUGv6SBybC/EEs9cOcLBR1eeQXXe7p7hfIhtxxBrGhk9n7jom/4LXF125WzPmMCUiNyE8iO7sVSmRf/iSNFBveZWGPeCirfJ8a43fk5jCfA3NPEJyMAamu3Q5im0DKo8aonWXtye9iE8vraixlVTAGSXFMjP3+XiOE9jrnXTDzARnt7+9gvHctQpaAI0za6N7bq9R1lb55jILwmx4Ih4OA0K1/Xx7B9jytPFBRhEO8xqXLhxotsIRjnGRvnkMK/KJ1YhE9T2mNmclLYgMSn+7dzik8BzoHt+EcXstV8yNpTspqsnS96ATq3A66NbF449w9JqViBt4gWi7yVzt3kR4XSJ8iEB5anMqG+EsSyrMQVv0sMeEysGx+yYs6G2xPJw3zqTq4RzDQXPhYra/VMlt7E8zzl4D7L3HS3kkWf4ZkmFmnjcENPQdkmohl6p/gqkOg+8McyzNxxb5Fl19DsSr3MTuSMqhSKDn95ibzYCEdrZXJiKaqu7BFBuju+jSObOPchog2IsE/u/3U/UK2mntvSnD0qNkPYoRTskBnLJ3NJamL0V4sEbryX8NMr7MKMJ0+h2+xMKY4KERpvUrd0c6ABXWHqLdY1QTugC/5dhdoLy3+KwgG5FnL0MZw6qvOvHkKQRoQrcKLuwUld15s05QxurH67A9eAr02a/vUWNBIgP6vOa69ZZuZKElWttIerRDGIAkZ54fw7HBctSZtfspPxaliwbOEH/Laxot3ZQonzvXknSVodzZHA1Jw7BcNRsYvl+KJ0Y6pMRPpIbaN/QSuHtnjUoej+vlVhq5021xMUPKxCK/D8rSRbOmduHG85/JrIimgo5wXWP83lLvRaxwCxeTGVt44fTUqsfUARmQcS3f5DbHR9SZ4nJYIEvcCjIqLezJ3I6S7xBop57j3ZyMQX0Xxr5mc6IUmrlOXM9fJG5iDZQQ9rWsGZ0Y26GzTAEsD6pjPuDa1XAT1MRpxyZ8zN53sl1YEV0E0EHvZqcnBnqMTXRh6zC9PwDXEk3OHs2zLLIjBhY5+7lDxp1X0qcm8XtWorat33mUx+kEDDgaDUdpclQq/ZM6mMYoF433nKbCKDxCozugSPVaRjNPosMDy8FujvIJSb763XuBGBIYLS9x+HZhYiUa9xod0xKV9aRt7yczWWlLgfK8qn4fULHMBSP48m/wTWfDBdTH8uDAKt5WM033+2bCpxDhmZtE+d7XP65yBTOf9/EWaCG+Gs9/5kVbWS0JlfoDH6Si2tVCzCRGfV0XZAUWfXOMJ5F9dkMagbwaeqVqqbVONDQGg8zID5MUV7IkazdAz4JLOXsn1RuZnoZNIGV2Na15+dRKYUAmXFmkWBJpPMBwT8N4bd8VZwBnhm3WzH9S0sbpoP0sgf2OmPvQ6smMyfkVK+OLjXYubmtioAhdwDb5/pLRg3PGwfHEz6v9OOe4AK8iw2cma49tV44In8Rc9jGcqSQlFXPdlC8366ke4U/ITFy0/SQBl1vWvGk40KycwWGaLf8cCtEi/4X2W8961i6lYnpfNQhGcQyC8s2oIOW+Pw545Thq3ZBEyNC8YDr/pzCEmBI8U3A4IiQJoHiD9kUMNd8wfzysC2Kqc4OGeWYsJxmDev4Jn4HV+vqpgN6xxSEMABhRMdTteHiJAgnQEX9BR2V1sNqh5EcMvQNYYa5+bblQn7Rli1UFCtQkP6ECmGkxmPNkg2CGS2mmf0/WEuTZSyPMtbbrnftPgleOmJ3jSm0m1EU9fQHQo1NZti+KczpJ8mSYIVtXzXh4rNJcL3Fm7Bbftpjmj5UnuDpPk8HvqKOj2DGJyk4R0Md1x7umiH0DTOXaLwO0EI94k7n6R8nfqiwekgUQZ1rRek0HViM5YN0JLWp4f4NRE8ErcGNSHZd58+9Kx8lmkc9ogfQmX0rX1kB8QQzNbH+eVDee0jOQNUgQcew3y+0QbifXrtLHXDIxsqsej41Kz7vfcQRE1zUnY2phYNILK8a657zyHNMzPiRhxs28s1JX2kiCMEloubOXnc8BzU+n7LM9wztf63eFWN/eWHXVivSdCWg5DfWsk2CF8aFJrOP277QEPdkWlOlewCVEkLjyd5wUn9ZzaKOJKnDQDLfliiRLTKlU8TOeQj8jOU8FfpM9tayJTDpxw6sVlZuJRAILfxn+QAGIB/W1FGDjuuVu62hFDBdvzVSfge95Ebf9pclp0GrpV3S+gwBWn5J7aGiim/fRyIN7YVVXJsnAnVeq90vDdAV0XearTqjT2Ck/AMkBW6T/ls/6VUVnFWs01wxkahKR0tRwyLRKgHefm3RWie/pTVQpUMZw+/7ozQSW+7vuZd8lsvT1iX5rwlpiaFnOnDbHsr1As6vLETd5HVbcBCGbJHcS7ax9Byd50jdYyagUtjAaHYX8ryyuR/bDkw1o4j8+hXMfbzy+CVmgrfRDyl4dn+5LxrqRAXLoDKpQREAHqdLSsVSJh1s8KnZ/SsUVq27cq+O6LMSBmhT4X3E750rmWwCsoCre6bT//oFWYALjp2SbcxnULBaTvnYDHtfEbO1m/3c9nJk8ZO5KHQTV88ivTWN/S2EXwmisTPdcupMrvI8e48QZdkZu9WHyKron7MKhGFJw6Z0KZ3tleVrvvJo89siUwByPY+Hs4gkKPBQbLQOaedcv/xeM+Ih8rl1eHEC/C65xWVciToVqSGp9HfbhVzFSrO6kBnv7mJwnRLvMEwqiNankVdJJMw4icU3lKyw/ecNSWIUddqlbThYMiq8nHjRRufs+28cq0OI9zhpvxFvFgSZE/eAYvm0x+9lZO+EH9NkBngaqU1NMYhdombNuy3awUN9p0mJQ//e9L65YbShgoc+ZUlNy+c6F6gDEHXV0JrzevPIZFAe2RyRa2dNqzLvihAAMCszYueqszzXRkSyobx5+LTLK2V3lfg3wbS9DzP3QW7VHdHbjZcttQRvtjrGveJnNn2DE2ZDIbvkCrT0H8RzbGDdmIq4P1ey+hoY/W6NuZKOz4dv4HUNznxdKV1Wf3MvqUv35r2jTKvpPWBUWNm5fytX/QJwp6qkIOsSx7Y67BSCbCDVLM8/VcMG+T0j+INrgL9sfT1ICtACH8BI0G6ViUZPVzzCmQHW2oVIwZjAoFl6+meO/pD8teO1E+1y03mCpYfW9S8qhtH2GhlFlebPf4NbezVv9xbXKWz0xezRNQWqUqtYRTUbuzK7KTvjG4rQHfzBpVmK4wDLnSIwdSzTSk1fPNeY0WOpPZTLlvQ59xwgfFrb326vT2hS1JAZ9E6sujFtKTiJ7bxI6o4cBhDaX+adXREThhR+MwA4TqD7rga/o9iY7d6TVRe14CS2S3iSQsD0R6ApnhG/2Wa0A0AY2NtWTjmabdKU+KgIRDP9RQYVjXiF1qC+xyNVG03I9vpmEpY/G/zC4nLOKgXAZ/uTikHI9Afbkhfgfgo9arWbix5eH7WUo9RQygDzwCnVSjbXc7MihEufVj6WGbK963pw8VjY3RS8IH1cy2yZbIcKLO5CgAUcXJfF2+McnDLKtXxyZaf7SPA6KJq+zF2NHyfoeTOwHhGqNcnHVr1hT73pcoyXyfvCYBnG1Bp/aR9t8hoI7CXM3UZOisWGA1SHZ2jf7k9GlRnp3mF/c1AV+JjvUsnZrsybEOQJg/dn/9eJkyykQHjbF56zgcPX6DdMG03WKUMlYz+uOZ+5DZy9E9MZOZ9GMoLFdrIPPQQLjv+GlCMpoyHPXkzIODjHAID2PrnaRpqWVHh0rnieDILKq+Emrd5RnjgE9pDUXWTmHaKuqqYlcgEz4zbi46dbWrAAFBjsQq1rLHIiPJEcwFLCOY4JNlXRXQJqCUKXk2d1RSBGzDP6HDSpo863BhVRFFF6uIpjQV7j5ebFe3UkkO/+coIo2BTAcgBqOtQ134s9a4QJvofuqBYMGOBMsWZ+sn/2AOxDx6SfAnDFGw==\";\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2 } from \"three\";\n\nconst DepthDownSample = {\n uniforms: {\n sceneDepth: new Uniform(null),\n resolution: new Uniform(new Vector2()),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n viewMatrixInv: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n logDepth: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform highp sampler2D sceneDepth;\n uniform vec2 resolution;\n uniform float near;\n uniform float far;\n uniform bool logDepth;\n uniform mat4 viewMatrixInv;\n uniform mat4 projectionMatrixInv;\n varying vec2 vUv;\n\n layout(location = 1) out vec4 gNormal;\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ = near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n if (logDepth) {\n return getWorldPosLog(vec3(coord, depth));\n }\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n void main(void) {\n vec2 uv = vUv - vec2(0.5) / resolution;\n vec2 pixelSize = vec2(1.0) / resolution;\n vec2[] uvSamples = vec2[4](\n uv,\n uv + vec2(pixelSize.x, 0.0),\n uv + vec2(0.0, pixelSize.y),\n uv + pixelSize\n );\n float depth00 = texture2D(sceneDepth, uvSamples[0]).r;\n float depth10 = texture2D(sceneDepth, uvSamples[1]).r;\n float depth01 = texture2D(sceneDepth, uvSamples[2]).r;\n float depth11 = texture2D(sceneDepth, uvSamples[3]).r;\n float minDepth = min(min(depth00, depth10), min(depth01, depth11));\n float maxDepth = max(max(depth00, depth10), max(depth01, depth11));\n float targetDepth = minDepth;\n\n if (mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) > 0.5) { \n targetDepth = maxDepth;\n }\n\n int chosenIndex = 0;\n float[] samples = float[4](depth00, depth10, depth01, depth11);\n\n for(int i = 0; i < 4; ++i) {\n if (samples[i] == targetDepth) {\n chosenIndex = i;\n break;\n }\n }\n\n gl_FragColor = vec4(samples[chosenIndex], 0.0, 0.0, 1.0);\n gNormal = vec4(\n computeNormal(\n getWorldPos(samples[chosenIndex], uvSamples[chosenIndex]), uvSamples[chosenIndex]\n ),\n 0.0\n );\n }`,\n};\n\nexport { DepthDownSample };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nconst EffectCompositer = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n tDiffuse: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n color: new Uniform(new Vector3()),\n blueNoise: new Uniform(null),\n downsampledDepth: new Uniform(null),\n time: new Uniform(0.0),\n intensity: new Uniform(10.0),\n renderMode: new Uniform(0.0),\n gammaCorrection: new Uniform(false),\n logDepth: new Uniform(false),\n ortho: new Uniform(false),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n screenSpaceRadius: new Uniform(false),\n radius: new Uniform(0.0),\n distanceFalloff: new Uniform(1.0),\n fog: new Uniform(false),\n fogExp: new Uniform(false),\n fogDensity: new Uniform(0.0),\n fogNear: new Uniform(Infinity),\n fogFar: new Uniform(Infinity),\n colorMultiply: new Uniform(true),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneDepth;\n uniform highp sampler2D downsampledDepth;\n uniform sampler2D tDiffuse;\n uniform sampler2D blueNoise;\n uniform vec2 resolution;\n uniform vec3 color;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform float intensity;\n uniform float renderMode;\n uniform float near;\n uniform float far;\n uniform bool gammaCorrection;\n uniform bool logDepth;\n uniform bool ortho;\n uniform bool screenSpaceRadius;\n uniform bool fog;\n uniform bool fogExp;\n uniform bool colorMultiply;\n uniform float fogDensity;\n uniform float fogNear;\n uniform float fogFar;\n uniform float radius;\n uniform float distanceFalloff;\n uniform vec3 cameraPos;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n return (zFar * zNear) / (zFar - d * (zFar - zNear));\n }\n \n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return (\n ortho\n ? linearize_depth_ortho(linDepth, nearZ, farZ)\n : linearize_depth(linDepth, nearZ, farZ)\n );\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n #include <common>\n #include <dithering_pars_fragment>\n\n void main(void) {\n vec4 sceneTexel = texture2D(sceneDiffuse, vUv);\n float depth = texture2D(sceneDepth, vUv).x;\n \n #ifdef HALFRES \n vec4 texel;\n if (depth == 1.0) {\n texel = vec4(0.0, 0.0, 0.0, 1.0);\n } else {\n vec3 worldPos = getWorldPos(depth, vUv);\n vec3 normal = computeNormal(getWorldPos(depth, vUv), vUv);\n\n float totalWeight = 0.0;\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(depth, vUv + vec2(radius, 0.0) / resolution))\n : radius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n for(float x = -1.0; x <= 1.0; x++) {\n for(float y = -1.0; y <= 1.0; y++) {\n vec2 offset = vec2(x, y);\n ivec2 p = ivec2((vUv * resolution * 0.5) + offset);\n vec2 pUv = vec2(p) / (resolution * 0.5);\n float sampleDepth = texelFetch(downsampledDepth,p, 0).x;\n vec4 sampleInfo = texelFetch(tDiffuse, p, 0);\n vec3 normalSample = sampleInfo.xyz * 2.0 - 1.0;\n vec3 worldPosSample = getWorldPos(sampleDepth, pUv);\n float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));\n float rangeCheck = exp(\n -1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)) * max(dot(normal, normalSample),\n 0.0\n );\n float weight = rangeCheck;\n totalWeight += weight;\n texel += sampleInfo * weight;\n }\n }\n if (totalWeight == 0.0) {\n texel = texture2D(tDiffuse, vUv);\n } else {\n texel /= totalWeight;\n }\n }\n #else\n vec4 texel = texture2D(tDiffuse, vUv);\n #endif\n\n #ifdef LOGDEPTH\n texel.a = clamp(texel.a, 0.0, 1.0);\n if (texel.a == 0.0) {\n texel.a = 1.0;\n }\n #endif\n\n float finalAo = pow(texel.a, intensity);\n float fogFactor;\n float fogDepth = distance(cameraPos, getWorldPos(depth, vUv));\n\n if (fog) {\n if (fogExp) {\n fogFactor = 1.0 - exp(-fogDensity * fogDensity * fogDepth * fogDepth);\n } else {\n fogFactor = smoothstep(fogNear, fogFar, fogDepth);\n }\n }\n\n finalAo = mix(finalAo, 1.0, fogFactor);\n vec3 aoApplied = color * mix(vec3(1.0), sceneTexel.rgb, float(colorMultiply));\n if (renderMode == 0.0) {\n gl_FragColor = vec4( mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);\n } else if (renderMode == 1.0) {\n gl_FragColor = vec4( mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);\n } else if (renderMode == 2.0) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (renderMode == 3.0) {\n if (vUv.x < 0.5) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {\n gl_FragColor = vec4(1.0);\n } else {\n gl_FragColor = vec4(mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);\n }\n } else if (renderMode == 4.0) {\n if (vUv.x < 0.5) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {\n gl_FragColor = vec4(1.0);\n } else {\n gl_FragColor = vec4(mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);\n }\n }\n\n #include <dithering_fragment>\n\n if (gammaCorrection) {\n gl_FragColor = LinearTosRGB(gl_FragColor);\n }\n }\n `,\n};\nexport { EffectCompositer };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nconst EffectShader = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n sceneNormal: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projViewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n samples: new Uniform([]),\n samplesR: new Uniform([]),\n bluenoise: new Uniform(null),\n distanceFalloff: new Uniform(1.0),\n radius: new Uniform(5.0),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n logDepth: new Uniform(false),\n ortho: new Uniform(false),\n screenSpaceRadius: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }\n `,\n\n fragmentShader: /* glsl */ `\n #define SAMPLES 16\n #define FSAMPLES 16.0\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneNormal;\n uniform highp sampler2D sceneDepth;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform mat4 projMat;\n uniform mat4 viewMat;\n uniform mat4 projViewMat;\n uniform vec3 cameraPos;\n uniform vec2 resolution;\n uniform float time;\n uniform vec3[SAMPLES] samples;\n uniform float[SAMPLES] samplesR;\n uniform float radius;\n uniform float distanceFalloff;\n uniform float near;\n uniform float far;\n uniform bool logDepth;\n uniform bool ortho;\n uniform bool screenSpaceRadius;\n uniform sampler2D bluenoise;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n return (zFar * zNear) / (zFar - d * (zFar - zNear));\n }\n\n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return (\n ortho\n ? linearize_depth_ortho(linDepth, nearZ, farZ)\n : linearize_depth(linDepth, nearZ, farZ)\n );\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n void main(void) {\n vec4 diffuse = texture2D(sceneDiffuse, vUv);\n float depth = texture2D(sceneDepth, vUv).x;\n\n if (depth == 1.0) {\n gl_FragColor = vec4(vec3(1.0), 1.0);\n return;\n }\n\n vec3 worldPos = getWorldPos(depth, vUv);\n\n #ifdef HALFRES\n vec3 normal = texture2D(sceneNormal, vUv).rgb;\n #else\n vec3 normal = computeNormal(worldPos, vUv);\n #endif\n\n vec4 noise = texture2D(bluenoise, gl_FragCoord.xy / 128.0);\n vec3 randomVec = normalize(noise.rgb * 2.0 - 1.0);\n vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));\n vec3 bitangent = cross(normal, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal);\n float occluded = 0.0;\n float totalWeight = 0.0;\n\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(depth, vUv + vec2(radius, 0.0) / resolution))\n : radius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n float bias = (0.1 / near) * fwidth(distance(worldPos, cameraPos)) / radiusToUse;\n for(float i = 0.0; i < FSAMPLES; i++) {\n vec3 sampleDirection = tbn * samples[int(i)];\n float moveAmt = samplesR[int(mod(i + noise.a * FSAMPLES, FSAMPLES))];\n vec3 samplePos = worldPos + radiusToUse * moveAmt * sampleDirection;\n vec4 offset = projMat * vec4(samplePos, 1.0);\n offset.xyz /= offset.w;\n offset.xyz = offset.xyz * 0.5 + 0.5;\n float sampleDepth = textureLod(sceneDepth, offset.xy, 0.0).x;\n #ifdef LOGDEPTH\n float distSample = linearize_depth_log(sampleDepth, near, far);\n #else\n float distSample = (\n ortho\n ? linearize_depth_ortho(sampleDepth, near, far)\n : linearize_depth(sampleDepth, near, far)\n );\n #endif\n float distWorld = (\n ortho\n ? linearize_depth_ortho(offset.z, near, far)\n : linearize_depth(offset.z, near, far)\n );\n float rangeCheck = smoothstep(0.0, 1.0, distanceFalloffToUse / (abs(distSample - distWorld)));\n vec2 diff = gl_FragCoord.xy - ( offset.xy * resolution);\n float weight = dot(sampleDirection, normal);\n occluded += rangeCheck * weight *\n (distSample + bias < distWorld ? 1.0 : 0.0) *\n (\n (\n dot(diff, diff) < 1.0 ||\n (sampleDepth == depth) ||\n (offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0) ? 0.0 : 1.0\n )\n );\n totalWeight += weight;\n }\n float occ = clamp(1.0 - occluded / totalWeight, 0.0, 1.0);\n gl_FragColor = vec4(0.5 + 0.5 * normal, occ);\n }`,\n};\n\nexport { EffectShader };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport {\n BufferAttribute,\n BufferGeometry,\n Mesh,\n OrthographicCamera,\n ShaderMaterial,\n Sphere,\n WebGLRenderer,\n} from \"three\";\n\nexport class FullScreenTriangle {\n private camera: OrthographicCamera = new OrthographicCamera();\n private geometry: BufferGeometry = new BufferGeometry();\n private mesh: Mesh<BufferGeometry, ShaderMaterial>;\n\n constructor(material: ShaderMaterial) {\n this.geometry.setAttribute(\n \"position\",\n new BufferAttribute(new Float32Array([-1, -1, 3, -1, -1, 3]), 2),\n );\n this.geometry.setAttribute(\"uv\", new BufferAttribute(new Float32Array([0, 0, 2, 0, 0, 2]), 2));\n\n this.geometry.boundingSphere = new Sphere();\n this.geometry.computeBoundingSphere = function () {};\n\n this.mesh = new Mesh(this.geometry, material);\n this.mesh.frustumCulled = false;\n }\n\n get material(): ShaderMaterial {\n return this.mesh.material as ShaderMaterial;\n }\n\n set material(value: ShaderMaterial) {\n this.mesh.material = value;\n }\n\n public render(renderer: WebGLRenderer): void {\n renderer.render(this.mesh, this.camera);\n }\n\n public dispose(): void {\n this.mesh.material.dispose();\n this.mesh.geometry.dispose();\n }\n}\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nexport const PoissionBlur = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n tDiffuse: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n r: new Uniform(5.0),\n blueNoise: new Uniform(null),\n radius: new Uniform(12.0),\n worldRadius: new Uniform(5.0),\n index: new Uniform(0.0),\n poissonDisk: new Uniform([]),\n distanceFalloff: new Uniform(1.0),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n logDepth: new Uniform(false),\n screenSpaceRadius: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1.0);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneDepth;\n uniform sampler2D tDiffuse;\n uniform sampler2D blueNoise;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform vec2 resolution;\n uniform float r;\n uniform float radius;\n uniform float worldRadius;\n uniform float index;\n uniform float near;\n uniform float far;\n uniform float distanceFalloff;\n uniform bool logDepth;\n uniform bool screenSpaceRadius;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n highp float z_n = 2.0 * d - 1.0;\n return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return linearize_depth(linDepth, nearZ, farZ);\n }\n\n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n #include <common>\n\n #define NUM_SAMPLES 16\n\n uniform vec2 poissonDisk[NUM_SAMPLES];\n\n void main(void) {\n const float pi = acos(-1.0);\n vec2 texelSize = vec2(1.0 / resolution.x, 1.0 / resolution.y);\n vec2 uv = vUv;\n vec4 data = texture2D(tDiffuse, vUv);\n float occlusion = data.a;\n float baseOcc = data.a;\n vec3 normal = data.rgb * 2.0 - 1.0;\n float count = 1.0;\n float d = texture2D(sceneDepth, vUv).x;\n if (d == 1.0) {\n gl_FragColor = data;\n return;\n }\n vec3 worldPos = getWorldPos(d, vUv);\n float size = radius;\n float angle;\n\n if (index == 0.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).x * PI2;\n } else if (index == 1.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).y * PI2;\n } else if (index == 2.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2;\n } else {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).w * PI2;\n }\n\n mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(d, vUv + vec2(worldRadius, 0.0) / resolution))\n : worldRadius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n\n for(int i = 0; i < NUM_SAMPLES; i++) {\n vec2 offset = (rotationMatrix * poissonDisk[i]) * texelSize * size;\n vec4 dataSample = texture2D(tDiffuse, uv + offset);\n float occSample = dataSample.a;\n vec3 normalSample = dataSample.rgb * 2.0 - 1.0;\n float dSample = texture2D(sceneDepth, uv + offset).x;\n vec3 worldPosSample = getWorldPos(dSample, uv + offset);\n float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));\n float rangeCheck = (\n (dSample == 1.0)\n ? 0.0\n : exp(\n -1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)\n ) * max(dot(normal, normalSample), 0.0) * (1.0 - abs(occSample - baseOcc))\n );\n occlusion += occSample * rangeCheck;\n count += rangeCheck;\n }\n\n if (count > 0.0) {\n occlusion /= count;\n }\n\n #ifdef LOGDEPTH\n occlusion = clamp(occlusion, 0.0, 1.0);\n if (occlusion == 0.0) {\n occlusion = 1.0;\n }\n #endif\n gl_FragColor = vec4(0.5 + 0.5 * normal, occlusion);\n }\n `,\n};\n", "import { Clock } from \"three\";\n\nimport { ease } from \"../helpers/math-helpers\";\n\nexport class TimeManager {\n private clock: Clock = new Clock();\n private roundMagnitude: number = 200000;\n private maxAverageFrames: number = 150;\n private deltaTimes: number[] = [];\n\n private targetAverageDeltaTime: number = 0;\n private lerpedAverageMagDelta: number = 0;\n private fpsUpdateTime: number = 0;\n private framesSinceLastFPSUpdate: number = 0;\n\n public time: number = 0;\n public deltaTime: number = 0;\n public rawDeltaTime: number = 0;\n public smoothDeltaTime: number = 0;\n public frame: number = 0;\n public fps: number = 0;\n public averageFPS: number = 0;\n\n update() {\n this.rawDeltaTime = this.clock.getDelta();\n this.frame++;\n this.time += this.rawDeltaTime;\n this.deltaTimes.push(this.rawDeltaTime);\n\n if (this.deltaTimes.length > this.maxAverageFrames) this.deltaTimes.shift();\n\n this.targetAverageDeltaTime =\n this.deltaTimes.reduce((prev, curr) => prev + curr, 0) / this.deltaTimes.length;\n\n this.lerpedAverageMagDelta += ease(\n this.targetAverageDeltaTime * this.roundMagnitude,\n this.lerpedAverageMagDelta,\n 0.12,\n );\n\n const revertMagnitude = this.lerpedAverageMagDelta / this.roundMagnitude;\n const smoothDT = Math.round(revertMagnitude * this.roundMagnitude) / this.roundMagnitude;\n\n this.smoothDeltaTime = smoothDT > this.rawDeltaTime * 1.75 ? this.rawDeltaTime : smoothDT;\n this.deltaTime = this.smoothDeltaTime;\n\n this.framesSinceLastFPSUpdate++;\n if (this.framesSinceLastFPSUpdate >= 60) {\n this.fps =\n Math.round((this.framesSinceLastFPSUpdate / (this.time - this.fpsUpdateTime)) * 100) / 100;\n\n this.fpsUpdateTime = this.time;\n this.framesSinceLastFPSUpdate = 0;\n }\n }\n}\n", "import {\n getRelativePositionAndRotationRelativeToObject,\n MElement,\n MMLCollisionTrigger,\n} from \"mml-web\";\nimport {\n Box3,\n BufferGeometry,\n Color,\n DoubleSide,\n Euler,\n Group,\n Line3,\n LineBasicMaterial,\n Matrix4,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n Quaternion,\n Ray,\n Scene,\n Vector3,\n} from \"three\";\nimport { VertexNormalsHelper } from \"three/examples/jsm/helpers/VertexNormalsHelper.js\";\nimport * as BufferGeometryUtils from \"three/examples/jsm/utils/BufferGeometryUtils.js\";\nimport { MeshBVH, MeshBVHHelper } from \"three-mesh-bvh\";\n\nexport type CollisionMeshState = {\n matrix: Matrix4;\n source: Group;\n meshBVH: MeshBVH;\n debugGroup?: Group;\n trackCollisions: boolean;\n};\n\nexport class CollisionsManager {\n private debug: boolean = false;\n private scene: Scene;\n private tempVector: Vector3 = new Vector3();\n private tempVector2: Vector3 = new Vector3();\n private tempVector3: Vector3 = new Vector3();\n private tempQuaternion: Quaternion = new Quaternion();\n private tempRay: Ray = new Ray();\n private tempMatrix = new Matrix4();\n private tempMatrix2 = new Matrix4();\n private tempBox = new Box3();\n private tempEuler = new Euler();\n private tempSegment = new Line3();\n private tempSegment2 = new Line3();\n\n public collisionMeshState: Map<Group, CollisionMeshState> = new Map();\n private collisionTrigger: MMLCollisionTrigger;\n private previouslyCollidingElements: null | Map<\n Object3D,\n { position: { x: number; y: number; z: number } }\n >;\n\n constructor(scene: Scene) {\n this.scene = scene;\n this.collisionTrigger = MMLCollisionTrigger.init();\n }\n\n public raycastFirst(ray: Ray): [number, Vector3, CollisionMeshState] | null {\n let minimumDistance: number | null = null;\n let minimumHit: CollisionMeshState | null = null;\n let minimumNormal: Vector3 | null = new Vector3();\n for (const [, collisionMeshState] of this.collisionMeshState) {\n this.tempRay.copy(ray).applyMatrix4(this.tempMatrix.copy(collisionMeshState.matrix).invert());\n const hit = collisionMeshState.meshBVH.raycastFirst(this.tempRay, DoubleSide);\n if (hit) {\n this.tempSegment.start.copy(this.tempRay.origin);\n this.tempSegment.end.copy(hit.point);\n this.tempSegment.applyMatrix4(collisionMeshState.matrix);\n const dist = this.tempSegment.distance();\n if (minimumDistance === null || dist < minimumDistance) {\n minimumDistance = dist;\n minimumHit = collisionMeshState;\n minimumNormal = (hit.normal ? minimumNormal.copy(hit.normal) : minimumNormal)\n // Apply the rotation of the mesh to the normal\n .applyQuaternion(this.tempQuaternion.setFromRotationMatrix(collisionMeshState.matrix))\n .normalize();\n }\n }\n }\n if (minimumDistance === null || minimumNormal === null || minimumHit === null) {\n return null;\n }\n return [minimumDistance, minimumNormal, minimumHit];\n }\n\n private createCollisionMeshState(group: Group, trackCollisions: boolean): CollisionMeshState {\n const geometries: Array<BufferGeometry> = [];\n group.updateWorldMatrix(true, false);\n const invertedRootMatrix = this.tempMatrix.copy(group.matrixWorld).invert();\n group.traverse((child: Object3D) => {\n const asMesh = child as Mesh;\n if (asMesh.isMesh) {\n const clonedGeometry = asMesh.geometry.clone();\n if (child !== group) {\n asMesh.updateWorldMatrix(true, false);\n clonedGeometry.applyMatrix4(\n this.tempMatrix2.multiplyMatrices(invertedRootMatrix, asMesh.matrixWorld),\n );\n }\n\n for (const key in clonedGeometry.attributes) {\n if (key !== \"position\") {\n clonedGeometry.deleteAttribute(key);\n }\n }\n if (clonedGeometry.index) {\n geometries.push(clonedGeometry.toNonIndexed());\n } else {\n geometries.push(clonedGeometry);\n }\n }\n });\n const newBufferGeometry = BufferGeometryUtils.mergeGeometries(geometries, false);\n newBufferGeometry.computeVertexNormals();\n const meshBVH = new MeshBVH(newBufferGeometry);\n\n const meshState: CollisionMeshState = {\n source: group,\n meshBVH,\n matrix: group.matrixWorld.clone(),\n trackCollisions,\n };\n if (this.debug) {\n // Have to cast to add the boundsTree property to the geometry so that the MeshBVHHelper can find it\n (newBufferGeometry as any).boundsTree = meshBVH;\n\n const wireframeMesh = new Mesh(newBufferGeometry, new MeshBasicMaterial({ wireframe: true }));\n\n const normalsHelper = new VertexNormalsHelper(wireframeMesh, 0.25, 0x00ff00);\n\n const visualizer = new MeshBVHHelper(wireframeMesh, 4);\n (visualizer.edgeMaterial as LineBasicMaterial).color = new Color(\"blue\");\n\n const debugGroup = new Group();\n debugGroup.add(wireframeMesh, normalsHelper, visualizer as unknown as Object3D);\n\n group.matrixWorld.decompose(debugGroup.position, debugGroup.quaternion, debugGroup.scale);\n visualizer.update();\n\n meshState.debugGroup = debugGroup;\n }\n return meshState;\n }\n\n public addMeshesGroup(group: Group, mElement?: MElement): void {\n if (mElement) {\n this.collisionTrigger.addCollider(group, mElement);\n }\n const meshState = this.createCollisionMeshState(group, mElement !== undefined);\n if (meshState.debugGroup) {\n this.scene.add(meshState.debugGroup);\n }\n this.collisionMeshState.set(group, meshState);\n }\n\n public updateMeshesGroup(group: Group): void {\n const meshState = this.collisionMeshState.get(group);\n if (meshState) {\n group.updateWorldMatrix(true, false);\n meshState.matrix.copy(group.matrixWorld);\n if (meshState.debugGroup) {\n group.matrixWorld.decompose(\n meshState.debugGroup.position,\n meshState.debugGroup.quaternion,\n meshState.debugGroup.scale,\n );\n }\n }\n }\n\n public removeMeshesGroup(group: Group): void {\n this.collisionTrigger.removeCollider(group);\n const meshState = this.collisionMeshState.get(group);\n if (meshState) {\n if (meshState.debugGroup) {\n this.scene.remove(meshState.debugGroup);\n }\n this.collisionMeshState.delete(group);\n }\n }\n\n private applyCollider(\n worldBasedCapsuleSegment: Line3,\n capsuleRadius: number,\n meshState: CollisionMeshState,\n ): Vector3 | null {\n // Create a matrix to convert from world-space to mesh-space\n const meshMatrix = this.tempMatrix.copy(meshState.matrix).invert();\n\n // Create the bounding box for the capsule if it were in mesh-space\n const meshRelativeCapsuleBoundingBox = this.tempBox;\n meshRelativeCapsuleBoundingBox.makeEmpty();\n meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.start);\n meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.end);\n meshRelativeCapsuleBoundingBox.min.subScalar(capsuleRadius);\n meshRelativeCapsuleBoundingBox.max.addScalar(capsuleRadius);\n meshRelativeCapsuleBoundingBox.applyMatrix4(meshMatrix);\n // Create a segment/line for the capsule in mesh-space\n const meshRelativeCapsuleSegment = this.tempSegment;\n meshRelativeCapsuleSegment.start.copy(worldBasedCapsuleSegment.start);\n meshRelativeCapsuleSegment.end.copy(worldBasedCapsuleSegment.end);\n meshRelativeCapsuleSegment.applyMatrix4(meshMatrix);\n\n // Keep track of where the segment started in mesh-space so that we can calculate the delta later\n const initialMeshRelativeCapsuleSegmentStart = this.tempVector3.copy(\n meshRelativeCapsuleSegment.start,\n );\n\n let collisionPosition: Vector3 | null = null;\n meshState.meshBVH.shapecast({\n intersectsBounds: (meshBox) => {\n // Determine if this portion of the mesh overlaps with the capsule bounding box and is therefore worth checking\n // all of the triangles within\n return meshBox.intersectsBox(meshRelativeCapsuleBoundingBox);\n },\n intersectsTriangle: (meshTriangle) => {\n const closestPointOnTriangle = this.tempVector;\n const closestPointOnSegment = this.tempVector2;\n // Find the closest point between this triangle and the capsule segment in mesh-space\n meshTriangle.closestPointToSegment(\n meshRelativeCapsuleSegment,\n closestPointOnTriangle,\n closestPointOnSegment,\n );\n // Create a line segment between the closest points\n const intersectionSegment = this.tempSegment2;\n intersectionSegment.start.copy(closestPointOnTriangle);\n intersectionSegment.end.copy(closestPointOnSegment);\n // Calculate the distance between the closest points in mesh-space\n const modelReferenceDistance = intersectionSegment.distance();\n\n // Calculate the distance between the points in world-space\n intersectionSegment.applyMatrix4(meshState.matrix);\n const realDistance = intersectionSegment.distance();\n\n // If the real distance is less than the capsule radius then there is actually a collision between the capsule\n // and the triangle\n if (realDistance < capsuleRadius) {\n if (!collisionPosition) {\n collisionPosition = new Vector3()\n .copy(closestPointOnSegment)\n .applyMatrix4(meshState.matrix);\n }\n // Calculate the ratio between the real distance and the mesh-space distance\n const ratio = realDistance / modelReferenceDistance;\n // Calculate the depth of the collision in world-space\n const realDepth = capsuleRadius - realDistance;\n // Convert that depth back into mesh-space as all calculations during collision are to a mesh-space segment\n const modelDepth = realDepth / ratio;\n\n // Apply a corrective movement to the segment in mesh-space\n const direction = closestPointOnSegment.sub(closestPointOnTriangle).normalize();\n meshRelativeCapsuleSegment.start.addScaledVector(direction, modelDepth);\n meshRelativeCapsuleSegment.end.addScaledVector(direction, modelDepth);\n }\n },\n });\n\n if (collisionPosition) {\n // If there was a collision, calculate the delta between the original mesh-space segment and the now-moved one\n const delta = this.tempVector\n .copy(meshRelativeCapsuleSegment.start)\n .sub(initialMeshRelativeCapsuleSegmentStart);\n\n // Use the matrix for the mesh to convert the delta vector back to world-space (remove the position component of the matrix first to avoid translation)\n this.tempMatrix.copy(meshState.matrix).setPosition(0, 0, 0);\n delta.applyMatrix4(this.tempMatrix);\n\n // There's a possibility that the matrix is invalid (or scale zero) and the delta is NaN - if so, don't apply the delta\n if (!(isNaN(delta.x) && isNaN(delta.y) && isNaN(delta.z))) {\n // Convert the potentially-modified mesh-space segment back to world-space\n worldBasedCapsuleSegment.start.add(delta);\n worldBasedCapsuleSegment.end.add(delta);\n }\n }\n\n return collisionPosition;\n }\n\n public applyColliders(tempSegment: Line3, radius: number) {\n const collidedElements = new Map<\n Object3D,\n {\n position: { x: number; y: number; z: number };\n }\n >();\n for (const meshState of this.collisionMeshState.values()) {\n const collisionPosition = this.applyCollider(tempSegment, radius, meshState);\n if (collisionPosition && meshState.trackCollisions) {\n const relativePosition = getRelativePositionAndRotationRelativeToObject(\n {\n position: collisionPosition,\n rotation: this.tempEuler.set(0, 0, 0),\n },\n meshState.source,\n );\n collidedElements.set(meshState.source, {\n position: relativePosition.position,\n });\n }\n }\n\n /*\n The reported collisions include elements that were reported in the previous tick to ensure that the case of an\n avatar rising to a negligible distance above the surface and immediately back down onto it does not result in a\n discontinuity in the collision lifecycle. If the element is not colliding in the next frame then it will be\n dropped.\n\n This results in a single tick delay of reporting leave events, but this is a reasonable trade-off to avoid\n flickering collisions.\n */\n const reportedCollidingElements = new Map(collidedElements);\n if (this.previouslyCollidingElements) {\n for (const [element, position] of this.previouslyCollidingElements) {\n if (!reportedCollidingElements.has(element)) {\n reportedCollidingElements.set(element, position);\n }\n }\n }\n\n // Store the elements that were genuinely collided with this tick for the next tick to preserve if they are missed\n this.previouslyCollidingElements = collidedElements;\n this.collisionTrigger.setCurrentCollisions(reportedCollidingElements);\n }\n}\n"],
|
5
|
-
"mappings": "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",
|
4
|
+
"sourcesContent": ["import { PerspectiveCamera, Raycaster, Vector3 } from \"three\";\n\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { remap } from \"../helpers/math-helpers\";\nimport { EventHandlerCollection } from \"../input/EventHandlerCollection\";\nimport { VirtualJoystick } from \"../input/VirtualJoystick\";\nimport { getTweakpaneActive } from \"../tweakpane/tweakPaneActivity\";\n\nexport class CameraManager {\n public readonly camera: PerspectiveCamera;\n\n public initialDistance: number = 3.3;\n\n private minDistance: number = 0.1;\n private maxDistance: number = 8;\n\n private initialFOV: number = 60;\n private fov: number = this.initialFOV;\n private minFOV: number = 85;\n private maxFOV: number = 60;\n private targetFOV: number = this.initialFOV;\n\n public minPolarAngle: number = Math.PI * 0.25;\n private maxPolarAngle: number = Math.PI * 0.95;\n\n private dampingFactor: number = 0.091;\n\n public targetDistance: number = this.initialDistance;\n private distance: number = this.initialDistance;\n private desiredDistance: number = this.initialDistance;\n\n private targetPhi: number | null;\n private phi: number = Math.PI / 2;\n private targetTheta: number | null;\n private theta: number = Math.PI / 2;\n public dragging: boolean = false;\n\n private target: Vector3 = new Vector3(0, 1.55, 0);\n private hadTarget: boolean = false;\n\n private rayCaster: Raycaster;\n\n private eventHandlerCollection: EventHandlerCollection;\n\n private isLerping: boolean = false;\n private finalTarget: Vector3 = new Vector3();\n private lerpTarget: Vector3 = new Vector3();\n\n private lerpFactor: number = 0;\n private lerpDuration: number = 2.1;\n\n private hasTouchControl: boolean = false;\n private lastTouchX: number = 0;\n private lastTouchY: number = 0;\n\n constructor(\n targetElement: HTMLElement,\n private collisionsManager: CollisionsManager,\n initialPhi = Math.PI / 2,\n initialTheta = -Math.PI / 2,\n ) {\n this.phi = initialPhi;\n this.targetPhi = initialPhi;\n this.theta = initialTheta;\n this.targetTheta = initialTheta;\n this.camera = new PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 0.1, 400);\n this.camera.position.set(0, 1.4, -this.initialDistance);\n this.rayCaster = new Raycaster();\n\n this.hasTouchControl = VirtualJoystick.checkForTouch();\n\n this.eventHandlerCollection = EventHandlerCollection.create([\n [targetElement, \"mousedown\", this.onMouseDown.bind(this)],\n [document, \"mouseup\", this.onMouseUp.bind(this)],\n [document, \"mousemove\", this.onMouseMove.bind(this)],\n [targetElement, \"wheel\", this.onMouseWheel.bind(this)],\n ]);\n\n if (this.hasTouchControl) {\n this.eventHandlerCollection.add(targetElement, \"touchstart\", this.onTouchStart.bind(this), {\n passive: false,\n });\n this.eventHandlerCollection.add(document, \"touchmove\", this.onTouchMove.bind(this), {\n passive: false,\n });\n this.eventHandlerCollection.add(document, \"touchend\", this.onTouchEnd.bind(this), {\n passive: false,\n });\n }\n }\n\n private onTouchStart(evt: TouchEvent): void {\n Array.from(evt.touches).forEach((touch) => {\n if (!VirtualJoystick.isTouchOnJoystick(touch)) {\n this.dragging = true;\n this.lastTouchX = touch.clientX;\n this.lastTouchY = touch.clientY;\n }\n });\n }\n\n private onTouchMove(evt: TouchEvent): void {\n if (!this.dragging || getTweakpaneActive()) {\n return;\n }\n evt.preventDefault();\n\n const touch = Array.from(evt.touches).find((t) => !VirtualJoystick.isTouchOnJoystick(t));\n if (touch) {\n const dx = touch.clientX - this.lastTouchX;\n const dy = touch.clientY - this.lastTouchY;\n this.lastTouchX = touch.clientX;\n this.lastTouchY = touch.clientY;\n\n if (this.targetTheta !== null && this.targetPhi !== null) {\n this.targetTheta += dx * 0.01;\n this.targetPhi -= dy * 0.01;\n this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));\n }\n }\n }\n\n private onTouchEnd(evt: TouchEvent): void {\n if (this.dragging) {\n const touchEnded = Array.from(evt.changedTouches).some(\n (t) => !VirtualJoystick.isTouchOnJoystick(t),\n );\n if (touchEnded) {\n this.dragging = false;\n }\n }\n }\n\n private onMouseDown(): void {\n this.dragging = true;\n }\n\n private onMouseUp(_event: MouseEvent): void {\n this.dragging = false;\n }\n\n private onMouseMove(event: MouseEvent): void {\n if (!this.dragging || getTweakpaneActive()) return;\n if (this.targetTheta === null || this.targetPhi === null) return;\n this.targetTheta += event.movementX * 0.01;\n this.targetPhi -= event.movementY * 0.01;\n this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));\n event.preventDefault();\n }\n\n private onMouseWheel(event: WheelEvent): void {\n const scrollAmount = event.deltaY * 0.001;\n this.targetDistance += scrollAmount;\n this.targetDistance = Math.max(\n this.minDistance,\n Math.min(this.maxDistance, this.targetDistance),\n );\n this.desiredDistance = this.targetDistance;\n event.preventDefault();\n }\n\n public setTarget(target: Vector3): void {\n if (!this.isLerping) {\n this.target.copy(target);\n } else {\n this.finalTarget.copy(target);\n this.lerpTarget.copy(this.target);\n this.lerpFactor = 0;\n }\n\n if (!this.hadTarget) {\n this.hadTarget = true;\n this.reverseUpdateFromPositions();\n }\n }\n\n public setLerpedTarget(target: Vector3, targetDistance: number): void {\n this.isLerping = true;\n this.targetDistance = targetDistance;\n this.desiredDistance = targetDistance;\n this.setTarget(target);\n }\n\n public reverseUpdateFromPositions(): void {\n const dx = this.camera.position.x - this.target.x;\n const dy = this.camera.position.y - this.target.y;\n const dz = this.camera.position.z - this.target.z;\n this.targetDistance = Math.sqrt(dx * dx + dy * dy + dz * dz);\n this.targetTheta = Math.atan2(dz, dx);\n this.targetPhi = Math.acos(dy / this.targetDistance);\n this.phi = this.targetPhi;\n this.theta = this.targetTheta;\n this.distance = this.targetDistance;\n this.desiredDistance = this.targetDistance;\n this.targetFOV = remap(\n this.targetDistance,\n this.minDistance,\n this.maxDistance,\n this.minFOV,\n this.maxFOV,\n );\n this.fov = this.targetFOV;\n }\n\n public adjustCameraPosition(): void {\n /*\n The purpose for the offsetDistance is to set the rayCaster further from the player\n than the camera is on the z relative axis, so we can avoid having a camera collider\n and expensive checks to prevent seeing clipped wals or floors or objects when we\n readjust the camera. 50cm (the current offset) should get a good balance for most\n indoor environments\n */\n const offsetDistance = 0.5;\n const offset = new Vector3(0, 0, offsetDistance);\n offset.applyEuler(this.camera.rotation);\n const rayOrigin = this.camera.position.clone().add(offset);\n const rayDirection = this.target.clone().sub(rayOrigin).normalize();\n\n this.rayCaster.set(rayOrigin, rayDirection);\n const firstRaycastHit = this.collisionsManager.raycastFirst(this.rayCaster.ray);\n const cameraToPlayerDistance = this.camera.position.distanceTo(this.target);\n\n if (firstRaycastHit !== null && firstRaycastHit[0] <= cameraToPlayerDistance) {\n this.targetDistance = cameraToPlayerDistance - firstRaycastHit[0];\n this.distance = this.targetDistance;\n } else {\n this.targetDistance += (this.desiredDistance - this.targetDistance) * this.dampingFactor * 4;\n }\n }\n\n public dispose() {\n this.eventHandlerCollection.clear();\n }\n\n private easeOutExpo(x: number): number {\n return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);\n }\n\n public updateAspect(aspect: number): void {\n this.camera.aspect = aspect;\n }\n\n public update(): void {\n if (this.isLerping && this.lerpFactor < 1) {\n this.lerpFactor += 0.01 / this.lerpDuration;\n this.lerpFactor = Math.min(1, this.lerpFactor);\n this.target.lerpVectors(this.lerpTarget, this.finalTarget, this.easeOutExpo(this.lerpFactor));\n } else {\n this.adjustCameraPosition();\n }\n\n if (\n this.phi !== null &&\n this.targetPhi !== null &&\n this.theta !== null &&\n this.targetTheta !== null\n ) {\n this.distance += (this.targetDistance - this.distance) * this.dampingFactor * 0.21;\n this.phi += (this.targetPhi - this.phi) * this.dampingFactor;\n this.theta += (this.targetTheta - this.theta) * this.dampingFactor;\n\n const x = this.target.x + this.distance * Math.sin(this.phi) * Math.cos(this.theta);\n const y = this.target.y + this.distance * Math.cos(this.phi);\n const z = this.target.z + this.distance * Math.sin(this.phi) * Math.sin(this.theta);\n\n this.targetFOV = remap(\n this.targetDistance,\n this.minDistance,\n this.maxDistance,\n this.minFOV,\n this.maxFOV,\n );\n this.fov += (this.targetFOV - this.fov) * this.dampingFactor;\n this.camera.fov = this.fov;\n this.camera.updateProjectionMatrix();\n\n this.camera.position.set(x, y, z);\n this.camera.lookAt(this.target);\n\n if (this.isLerping && this.lerpFactor >= 1) {\n this.isLerping = false;\n }\n }\n }\n}\n", "import { Quaternion, Vector3, Vector4 } from \"three\";\n\nexport const roundToDecimalPlaces = (value: number, decimalPlaces: number): number => {\n const mult = 10 ** decimalPlaces;\n return Math.round(value * mult) / mult;\n};\n\nexport const toArray = (\n origin: Vector3 | Vector4 | Quaternion,\n precision: number = 3,\n): number[] => {\n const array = [];\n array[0] = roundToDecimalPlaces(origin.x, precision);\n array[1] = roundToDecimalPlaces(origin.y, precision);\n array[2] = roundToDecimalPlaces(origin.z, precision);\n if (origin instanceof Vector4 || origin instanceof Quaternion) {\n array[3] = roundToDecimalPlaces(origin.w, precision);\n }\n return array;\n};\n\nexport const getSpawnPositionInsideCircle = (\n radius: number,\n positions: number,\n id: number,\n yPos: number = 0,\n): Vector3 => {\n if (id > 0) id += 3;\n const goldenAngle = Math.PI * (3 - Math.sqrt(5));\n const theta = id * goldenAngle;\n const scale = id / positions;\n const scaledRadius = scale * radius;\n const x = Math.cos(theta) * scaledRadius;\n const z = Math.sin(theta) * scaledRadius;\n return new Vector3(x, yPos, z);\n};\n\nexport const round = (n: number, digits: number): number => {\n return Number(n.toFixed(digits));\n};\n\nexport const ease = (target: number, n: number, factor: number): number => {\n return round((target - n) * factor, 5);\n};\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport const remap = (\n value: number,\n minValue: number,\n maxValue: number,\n minScaledValue: number,\n maxScaledValue: number,\n): number => {\n return (\n minScaledValue +\n ((maxScaledValue - minScaledValue) * (value - minValue)) / (maxValue - minValue)\n );\n};\n", "type ListenerFunc = (...args: any[]) => void;\n\ntype EventSpecificationTuple = [EventTarget, string, ListenerFunc, AddEventListenerOptions?];\n\nexport class EventHandlerCollection {\n private eventsByTarget: Map<EventTarget, Map<string, Set<ListenerFunc>>> = new Map();\n\n public add(\n target: EventTarget,\n key: string,\n listener: ListenerFunc,\n options?: AddEventListenerOptions,\n ): this {\n target.addEventListener(key, listener, options);\n\n let existingTarget = this.eventsByTarget.get(target);\n if (existingTarget === undefined) {\n existingTarget = new Map();\n this.eventsByTarget.set(target, existingTarget);\n }\n let existingKey = existingTarget.get(key);\n if (existingKey === undefined) {\n existingKey = new Set();\n existingTarget.set(key, existingKey);\n }\n existingKey.add(listener);\n\n return this;\n }\n\n public clear() {\n this.eventsByTarget.forEach((keyMap, target) => {\n keyMap.forEach((listenerSet, key) => {\n listenerSet.forEach((listenerFunc) => {\n target.removeEventListener(key, listenerFunc);\n });\n });\n });\n this.eventsByTarget.clear();\n }\n\n static create(initial?: Array<EventSpecificationTuple>): EventHandlerCollection {\n const instance = new EventHandlerCollection();\n if (initial !== undefined) {\n initial.forEach(([target, key, listenerFunc, options]) => {\n instance.add(target, key, listenerFunc, options);\n });\n }\n return instance;\n }\n}\n", "interface JoyStickAttributes {\n radius?: number;\n inner_radius?: number;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n mouse_support?: boolean;\n visible?: boolean;\n anchor?: \"left\" | \"right\";\n}\n\nexport class VirtualJoystick {\n public static JOYSTICK_DIV: HTMLDivElement | null = null;\n\n private radius: number;\n private inner_radius: number;\n private anchor: \"left\" | \"right\";\n private x: number;\n private y: number;\n private width: number;\n private height: number;\n private mouse_support: boolean;\n\n private div: HTMLDivElement;\n private base: HTMLSpanElement;\n private control: HTMLSpanElement;\n\n public left: boolean = false;\n public right: boolean = false;\n public up: boolean = false;\n public down: boolean = false;\n public hasDirection: boolean = false;\n\n constructor(attrs: JoyStickAttributes) {\n this.radius = attrs.radius || 50;\n this.inner_radius = attrs.inner_radius || this.radius / 2;\n this.anchor = attrs.anchor || \"left\";\n this.x = attrs.x || 0;\n this.y = attrs.y || 0;\n this.width = attrs.width || this.radius * 2 + this.inner_radius * 2;\n this.height = attrs.height || this.radius * 2 + this.inner_radius * 2;\n this.mouse_support = this.checkTouch() || attrs.mouse_support === true;\n\n this.initializeJoystick();\n }\n\n public static checkForTouch(): boolean {\n try {\n document.createEvent(\"TouchEvent\");\n return true;\n } catch (e) {\n return false;\n }\n }\n\n public static isTouchOnJoystick(touch: Touch): boolean {\n if (!VirtualJoystick.JOYSTICK_DIV) {\n return false;\n }\n const divRect = VirtualJoystick.JOYSTICK_DIV.getBoundingClientRect();\n return (\n touch.clientX >= divRect.left &&\n touch.clientX <= divRect.right &&\n touch.clientY >= divRect.top &&\n touch.clientY <= divRect.bottom\n );\n }\n\n private checkTouch() {\n return VirtualJoystick.checkForTouch();\n }\n\n private initializeJoystick(): void {\n if (!VirtualJoystick.JOYSTICK_DIV) {\n this.div = document.createElement(\"div\");\n const divStyle = this.div.style;\n divStyle.display = this.checkTouch() || this.mouse_support ? \"visible\" : \"none\";\n divStyle.position = \"fixed\";\n if (this.anchor === \"left\") {\n divStyle.left = `${this.x}px`;\n } else {\n divStyle.right = `${this.x}px`;\n }\n divStyle.bottom = `${this.y}px`;\n divStyle.width = `${this.width}px`;\n divStyle.height = `${this.height}px`;\n divStyle.zIndex = \"10000\";\n divStyle.overflow = \"hidden\";\n document.body.appendChild(this.div);\n VirtualJoystick.JOYSTICK_DIV = this.div;\n }\n\n this.setupBaseAndControl();\n this.bindEvents();\n }\n\n private setupBaseAndControl(): void {\n this.base = document.createElement(\"span\");\n let divStyle = this.base.style;\n divStyle.width = `${this.radius * 2}px`;\n divStyle.height = `${this.radius * 2}px`;\n divStyle.position = \"absolute\";\n divStyle.left = `${this.width / 2 - this.radius}px`;\n divStyle.bottom = `${this.height / 2 - this.radius}px`;\n divStyle.borderRadius = \"50%\";\n divStyle.borderColor = \"rgba(200,200,200,0.5)\";\n divStyle.borderWidth = \"2px\";\n divStyle.borderStyle = \"solid\";\n this.div.appendChild(this.base);\n\n this.control = document.createElement(\"span\");\n divStyle = this.control.style;\n divStyle.width = `${this.inner_radius * 2}px`;\n divStyle.height = `${this.inner_radius * 2}px`;\n divStyle.position = \"absolute\";\n divStyle.left = `${this.width / 2 - this.inner_radius}px`;\n divStyle.bottom = `${this.height / 2 - this.inner_radius}px`;\n divStyle.borderRadius = \"50%\";\n divStyle.backgroundColor = \"rgba(200,200,200,0.3)\";\n divStyle.borderWidth = \"1px\";\n divStyle.borderColor = \"rgba(200,200,200,0.8)\";\n divStyle.borderStyle = \"solid\";\n this.div.appendChild(this.control);\n }\n\n private bindEvents(): void {\n this.div.addEventListener(\"touchstart\", this.handleTouchStart.bind(this), false);\n this.div.addEventListener(\"touchmove\", this.handleTouchMove.bind(this), false);\n this.div.addEventListener(\"touchend\", this.clearFlags.bind(this), false);\n\n if (this.mouse_support) {\n this.div.addEventListener(\"mousedown\", this.handleMouseDown.bind(this));\n this.div.addEventListener(\"mousemove\", this.handleMouseMove.bind(this));\n this.div.addEventListener(\"mouseup\", this.handleMouseUp.bind(this));\n }\n }\n\n private handleTouchStart(evt: TouchEvent): void {\n evt.preventDefault();\n if (evt.touches) {\n const touch = evt.touches[0];\n this.updateControlAndDirection(touch);\n }\n }\n\n private handleTouchMove(evt: TouchEvent): void {\n evt.preventDefault();\n if (evt.touches.length > 0) {\n const touch = evt.touches[0];\n this.updateControlAndDirection(touch);\n }\n }\n\n private handleMouseDown(evt: MouseEvent): void {\n evt.preventDefault();\n this.updateControlAndDirection(evt);\n }\n\n private handleMouseMove(evt: MouseEvent): void {\n if (evt.buttons === 1) {\n evt.preventDefault();\n this.updateControlAndDirection(evt);\n }\n }\n\n private handleMouseUp(evt: MouseEvent): void {\n this.clearFlags();\n }\n\n private clearFlags = (): void => {\n this.left = false;\n this.right = false;\n this.up = false;\n this.down = false;\n this.hasDirection = false;\n this.control.style.left = `${this.width / 2 - this.inner_radius}px`;\n this.control.style.top = `${this.height / 2 - this.inner_radius}px`;\n };\n\n private updateControlAndDirection(input: Touch | MouseEvent): void {\n const rect = this.div.getBoundingClientRect();\n const dx = input.clientX - (rect.left + this.div.offsetWidth / 2);\n const dy = input.clientY - (rect.top + this.div.offsetHeight / 2);\n\n const distance = Math.min(Math.sqrt(dx * dx + dy * dy), this.radius);\n const angle = Math.atan2(dy, dx);\n const constrainedX = distance * Math.cos(angle);\n const constrainedY = distance * Math.sin(angle);\n\n this.control.style.left = `${constrainedX + this.width / 2 - this.inner_radius}px`;\n this.control.style.top = `${constrainedY + this.height / 2 - this.inner_radius}px`;\n\n this.up = this.isUp(dx, dy);\n this.down = this.isDown(dx, dy);\n this.left = this.isLeft(dx, dy);\n this.right = this.isRight(dx, dy);\n this.hasDirection = this.up || this.down || this.left || this.right;\n }\n\n private isUp(dx: number, dy: number): boolean {\n return dy < 0 && Math.abs(dx) <= 2 * Math.abs(dy);\n }\n\n private isDown(dx: number, dy: number): boolean {\n return dy > 0 && Math.abs(dx) <= 2 * Math.abs(dy);\n }\n\n private isLeft(dx: number, dy: number): boolean {\n return dx < 0 && Math.abs(dy) <= 2 * Math.abs(dx);\n }\n\n private isRight(dx: number, dy: number): boolean {\n return dx > 0 && Math.abs(dy) <= 2 * Math.abs(dx);\n }\n}\n", "let isTweakpaneActive = false;\n\nexport function setTweakpaneActive(status: boolean) {\n isTweakpaneActive = status;\n}\n\nexport function getTweakpaneActive() {\n return isTweakpaneActive;\n}\n", "import { Color, Group, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { Composer } from \"../rendering/composer\";\n\nimport { CharacterModel } from \"./CharacterModel\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { CharacterSpeakingIndicator } from \"./CharacterSpeakingIndicator\";\nimport { AnimationState } from \"./CharacterState\";\nimport { CharacterTooltip } from \"./CharacterTooltip\";\n\nexport type AnimationConfig = {\n idleAnimationFileUrl: string;\n jogAnimationFileUrl: string;\n sprintAnimationFileUrl: string;\n airAnimationFileUrl: string;\n};\n\nexport type CharacterDescription = {\n meshFileUrl?: string;\n mmlCharacterUrl?: string;\n mmlCharacterString?: string;\n};\n\nexport class Character extends Group {\n private model: CharacterModel | null = null;\n public color: Color = new Color();\n public tooltip: CharacterTooltip | null = null;\n public speakingIndicator: CharacterSpeakingIndicator | null = null;\n\n constructor(\n private readonly characterDescription: CharacterDescription,\n private readonly animationConfig: AnimationConfig,\n private readonly characterModelLoader: CharacterModelLoader,\n private readonly characterId: number,\n private readonly modelLoadedCallback: () => void,\n private readonly cameraManager: CameraManager,\n private readonly composer: Composer,\n private readonly isLocal: boolean,\n ) {\n super();\n this.tooltip = new CharacterTooltip();\n this.add(this.tooltip);\n this.load();\n }\n\n private async load(): Promise<void> {\n this.model = new CharacterModel(\n this.characterDescription,\n this.animationConfig,\n this.characterModelLoader,\n this.cameraManager,\n this.characterId,\n this.isLocal,\n );\n await this.model.init();\n this.add(this.model.mesh!);\n if (this.speakingIndicator === null) {\n this.speakingIndicator = new CharacterSpeakingIndicator(this.composer.postPostScene);\n }\n this.modelLoadedCallback();\n }\n\n public updateAnimation(targetAnimation: AnimationState) {\n this.model?.updateAnimation(targetAnimation);\n }\n\n public update(time: number, deltaTime: number) {\n if (!this.model) return;\n if (this.tooltip) {\n this.tooltip.update(this.cameraManager.camera);\n }\n if (this.speakingIndicator) {\n this.speakingIndicator.setTime(time);\n if (this.model.mesh && this.model.headBone) {\n this.speakingIndicator.setBillboarding(\n this.model.headBone?.getWorldPosition(new Vector3()),\n this.cameraManager.camera,\n );\n }\n }\n this.model.update(deltaTime);\n }\n\n getCurrentAnimation(): AnimationState {\n return this.model?.currentAnimation || AnimationState.idle;\n }\n}\n", "import {\n MMLCharacter,\n type MMLCharacterDescription,\n ModelLoader,\n parseMMLDescription,\n} from \"@mml-io/3d-web-avatar\";\nimport {\n AnimationAction,\n AnimationClip,\n AnimationMixer,\n Bone,\n LoopRepeat,\n Mesh,\n MeshStandardMaterial,\n Object3D,\n SkinnedMesh,\n} from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\n\nimport { AnimationConfig, CharacterDescription } from \"./Character\";\nimport { CharacterMaterial } from \"./CharacterMaterial\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { AnimationState } from \"./CharacterState\";\n\nexport class CharacterModel {\n public mesh: Object3D | null = null;\n public headBone: Bone | null = null;\n\n private materials: Map<string, CharacterMaterial> = new Map();\n\n public animations: Record<string, AnimationAction> = {};\n public animationMixer: AnimationMixer | null = null;\n public currentAnimation: AnimationState = AnimationState.idle;\n\n public mmlCharacterDescription: MMLCharacterDescription;\n\n constructor(\n private readonly characterDescription: CharacterDescription,\n private readonly animationConfig: AnimationConfig,\n private characterModelLoader: CharacterModelLoader,\n private readonly cameraManager: CameraManager,\n private readonly characterId: number,\n private readonly isLocal: boolean,\n ) {}\n\n public async init(): Promise<void> {\n await this.loadMainMesh();\n await this.setAnimationFromFile(this.animationConfig.idleAnimationFileUrl, AnimationState.idle);\n await this.setAnimationFromFile(\n this.animationConfig.jogAnimationFileUrl,\n AnimationState.walking,\n );\n await this.setAnimationFromFile(\n this.animationConfig.sprintAnimationFileUrl,\n AnimationState.running,\n );\n await this.setAnimationFromFile(this.animationConfig.airAnimationFileUrl, AnimationState.air);\n this.applyCustomMaterials();\n }\n\n private applyCustomMaterials(): void {\n if (!this.mesh) return;\n this.mesh.traverse((child: Object3D) => {\n if ((child as Mesh).isMesh || (child as SkinnedMesh).isSkinnedMesh) {\n const asMesh = child as Mesh;\n const originalMaterial = asMesh.material as MeshStandardMaterial;\n if (this.materials.has(originalMaterial.name)) {\n asMesh.material = this.materials.get(originalMaterial.name)!;\n } else {\n const material =\n originalMaterial.name === \"body_replaceable_color\"\n ? new CharacterMaterial(\n this.isLocal,\n this.cameraManager,\n this.characterId,\n originalMaterial,\n )\n : new CharacterMaterial(\n this.isLocal,\n this.cameraManager,\n this.characterId,\n originalMaterial,\n originalMaterial.color,\n );\n this.materials.set(originalMaterial.name, material);\n asMesh.material = material;\n }\n }\n });\n }\n\n public updateAnimation(targetAnimation: AnimationState) {\n if (this.currentAnimation !== targetAnimation) {\n this.transitionToAnimation(targetAnimation);\n }\n }\n\n private setMainMesh(mainMesh: Object3D): void {\n this.mesh = mainMesh;\n this.mesh.position.set(0, -0.44, 0);\n this.mesh.traverse((child: Object3D) => {\n if (child.type === \"SkinnedMesh\") {\n child.castShadow = true;\n child.receiveShadow = true;\n }\n });\n this.animationMixer = new AnimationMixer(this.mesh);\n }\n\n private async composeMMLCharacter(\n mmlCharacterDescription: MMLCharacterDescription,\n ): Promise<Object3D | undefined> {\n if (mmlCharacterDescription.base?.url.length === 0) {\n throw new Error(\n \"ERROR: An MML Character Description was provided but it's not a valid <m-character> string, or a valid URL\",\n );\n }\n\n let mergedCharacter: Object3D | null = null;\n if (mmlCharacterDescription) {\n const characterBase = mmlCharacterDescription.base?.url || null;\n if (characterBase) {\n this.mmlCharacterDescription = mmlCharacterDescription;\n const mmlCharacter = new MMLCharacter(new ModelLoader());\n mergedCharacter = await mmlCharacter.mergeBodyParts(\n characterBase,\n mmlCharacterDescription.parts,\n );\n if (mergedCharacter) {\n return mergedCharacter.children[0].children[0];\n }\n }\n }\n }\n\n private async loadCharacterFromDescription(): Promise<Object3D | null> {\n if (this.characterDescription.meshFileUrl) {\n return (\n (await this.characterModelLoader.load(this.characterDescription.meshFileUrl, \"model\")) ||\n null\n );\n }\n\n let mmlCharacterSource: string;\n if (this.characterDescription.mmlCharacterUrl) {\n const res = await fetch(this.characterDescription.mmlCharacterUrl);\n mmlCharacterSource = await res.text();\n } else if (this.characterDescription.mmlCharacterString) {\n mmlCharacterSource = this.characterDescription.mmlCharacterString;\n } else {\n throw new Error(\n \"ERROR: No Character Description was provided. Specify one of meshFileUrl, mmlCharacterUrl or mmlCharacterString\",\n );\n }\n\n const parsedMMLDescription = parseMMLDescription(mmlCharacterSource);\n const mmlCharacterDescription = parsedMMLDescription[0];\n if (parsedMMLDescription[1].length > 0) {\n console.warn(\"Errors parsing MML Character Description: \", parsedMMLDescription[1]);\n }\n const mmlCharacterBody = await this.composeMMLCharacter(mmlCharacterDescription);\n if (mmlCharacterBody) {\n return mmlCharacterBody;\n }\n return null;\n }\n\n private async loadMainMesh(): Promise<void> {\n const mainMesh = await this.loadCharacterFromDescription();\n if (typeof mainMesh !== \"undefined\") {\n this.setMainMesh(mainMesh as Object3D);\n } else {\n throw new Error(\"ERROR: No Character Model was loaded\");\n }\n }\n\n private cleanAnimationClips(skeletalMesh: Object3D, animationClip: AnimationClip): AnimationClip {\n const availableBones = new Set<string>();\n skeletalMesh.traverse((child) => {\n const asBone = child as Bone;\n if (asBone.isBone) {\n availableBones.add(child.name);\n }\n });\n animationClip.tracks = animationClip.tracks.filter((track) => {\n const [trackName, trackProperty] = track.name.split(\".\");\n const shouldAnimate =\n availableBones.has(trackName) && trackProperty !== \"position\" && trackProperty !== \"scale\";\n return shouldAnimate;\n });\n return animationClip;\n }\n\n private async setAnimationFromFile(\n animationFileUrl: string,\n animationType: AnimationState,\n ): Promise<void> {\n return new Promise(async (resolve, reject) => {\n const animation = await this.characterModelLoader.load(animationFileUrl, \"animation\");\n const cleanAnimation = this.cleanAnimationClips(this.mesh!, animation as AnimationClip);\n if (typeof animation !== \"undefined\" && cleanAnimation instanceof AnimationClip) {\n this.animations[animationType] = this.animationMixer!.clipAction(cleanAnimation);\n this.animations[animationType].stop();\n if (animationType === AnimationState.idle) {\n this.animations[animationType].play();\n }\n resolve();\n } else {\n reject(`failed to load ${animationType} from ${animationFileUrl}`);\n }\n });\n }\n\n private transitionToAnimation(\n targetAnimation: AnimationState,\n transitionDuration: number = 0.15,\n ): void {\n if (!this.mesh) return;\n\n const currentAction = this.animations[this.currentAnimation];\n this.currentAnimation = targetAnimation;\n const targetAction = this.animations[targetAnimation];\n\n if (!targetAction) return;\n\n if (currentAction) {\n currentAction.enabled = true;\n currentAction.fadeOut(transitionDuration);\n }\n\n if (!targetAction.isRunning()) targetAction.play();\n\n targetAction.setLoop(LoopRepeat, Infinity);\n targetAction.enabled = true;\n targetAction.fadeIn(transitionDuration);\n }\n\n update(time: number) {\n if (this.animationMixer) {\n this.animationMixer.update(time);\n this.materials.forEach((material) => material.update());\n }\n }\n}\n", "import { Color, MeshPhysicalMaterial, MeshStandardMaterial, Texture, UniformsUtils } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { ease } from \"../helpers/math-helpers\";\nimport { bayerDither } from \"../rendering/shaders/bayer-dither\";\nimport {\n injectBefore,\n injectBeforeMain,\n injectInsideMain,\n} from \"../rendering/shaders/shader-helpers\";\nimport { characterValues } from \"../tweakpane/blades/characterFolder\";\n\ntype TUniform<TValue = any> = { value: TValue };\n\nexport class CharacterMaterial extends MeshStandardMaterial {\n private uniforms: Record<string, TUniform> = {\n discardAll: { value: 1 },\n diffuseColor: { value: new Color() },\n map: { value: null },\n };\n private colorsCube216: Color[] = [];\n private targetAlpha: number = 1;\n private currentAlpha: number = 1;\n\n constructor(\n private isLocal: boolean,\n private cameraManager: CameraManager,\n private characterId: number,\n private originalMaterial: MeshStandardMaterial,\n private colorOverride?: Color,\n ) {\n super();\n this.copy(this.originalMaterial);\n this.generateColorCube();\n\n this.color = this.colorOverride || this.colorsCube216[this.characterId];\n this.envMapIntensity = characterValues.envMapIntensity;\n this.transparent = true;\n this.side = this.originalMaterial.side;\n\n this.onBeforeCompile = (shader) => {\n this.uniforms = UniformsUtils.clone(shader.uniforms);\n this.uniforms.nearClip = { value: 0.01 };\n this.uniforms.farClip = { value: 1000.0 };\n this.uniforms.ditheringNear = { value: 0.3 };\n this.uniforms.ditheringRange = { value: 0.5 };\n this.uniforms.time = { value: 0.0 };\n this.uniforms.diffuseRandomColor = { value: new Color() };\n this.uniforms.discardAll = { value: 0 };\n shader.uniforms = this.uniforms;\n\n shader.vertexShader = \"varying vec3 vWorldPosition;\\n\" + shader.vertexShader;\n shader.vertexShader = shader.vertexShader.replace(\n \"#include <worldpos_vertex>\",\n \"vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\nvWorldPosition = worldPosition.xyz;\",\n );\n shader.vertexShader = injectBeforeMain(shader.vertexShader, \"varying vec2 vUv;\");\n shader.vertexShader = injectInsideMain(shader.vertexShader, \"vUv = uv;\");\n\n shader.fragmentShader = injectBeforeMain(\n shader.fragmentShader,\n /* glsl */ `\n varying vec2 vUv;\n varying vec3 vWorldPosition;\n uniform float nearClip;\n uniform float farClip;\n uniform float ditheringNear;\n uniform float ditheringRange;\n uniform float time;\n uniform vec3 diffuseRandomColor;\n uniform int discardAll;\n ${bayerDither}\n `,\n );\n\n shader.fragmentShader = injectBefore(\n shader.fragmentShader,\n \"#include <output_fragment>\",\n /* glsl */ `\n if (discardAll == 1) {\n discard;\n } else {\n float distance = length(vWorldPosition - cameraPosition);\n float normalizedDistance = (distance - nearClip) / (farClip - nearClip);\n ivec2 p = ivec2(mod(gl_FragCoord.xy, 8.0));\n float d = 0.0;\n if (p.x <= 3 && p.y <= 3) {\n d = bayerDither(bayertl, p);\n } else if (p.x > 3 && p.y <= 3) {\n d = bayerDither(bayertr, p - ivec2(4, 0));\n } else if (p.x <= 3 && p.y > 3) {\n d = bayerDither(bayerbl, p - ivec2(0, 4));\n } else if (p.x > 3 && p.y > 3) {\n d = bayerDither(bayerbr, p - ivec2(4, 4));\n }\n if (distance <= ditheringNear + d * ditheringRange) discard; \n outgoingLight *= diffuseRandomColor; \n }\n `,\n );\n };\n this.needsUpdate = true;\n }\n\n private generateColorCube() {\n const saturation = 1.0;\n const lightness = 0.9;\n const goldenRatioConjugate = 0.618033988749895;\n let hue = 0;\n\n for (let i = 0; i < 216; i++) {\n const color = new Color();\n color.setHSL(hue, saturation, lightness);\n this.colorsCube216.push(color);\n hue = (hue + goldenRatioConjugate) % 1;\n }\n }\n\n public update() {\n if (this.isLocal) {\n this.targetAlpha = this.cameraManager.targetDistance < 0.4 ? 0.0 : 1.0;\n this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.07);\n if (this.currentAlpha > 0.999) {\n this.currentAlpha = 1;\n this.cameraManager.minPolarAngle = Math.PI * 0.25;\n }\n if (this.currentAlpha < 0.001) {\n this.currentAlpha = 0;\n this.cameraManager.minPolarAngle = Math.PI * 0.35;\n }\n this.uniforms.discardAll.value = this.currentAlpha === 0 ? 1 : 0;\n if (this.currentAlpha !== this.opacity) {\n this.opacity = this.currentAlpha;\n }\n }\n this.metalness = characterValues.metalness;\n this.roughness = characterValues.roughness;\n this.emissive = new Color().setRGB(\n characterValues.emissive.r,\n characterValues.emissive.g,\n characterValues.emissive.b,\n );\n this.emissiveIntensity = characterValues.emissiveIntensity;\n this.envMapIntensity = characterValues.envMapIntensity;\n }\n}\n", "export const bayerDither: string = /* glsl */ `\nconst mat4 bayertl = mat4( \n 0.0 / 64.0, 32.0 / 64.0, 8.0 / 64.0, 40.0 / 64.0,\n 48.0 / 64.0, 16.0 / 64.0, 56.0 / 64.0, 24.0 / 64.0,\n 12.0 / 64.0, 44.0 / 64.0, 4.0 / 64.0, 36.0 / 64.0,\n 60.0 / 64.0, 28.0 / 64.0, 52.0 / 64.0, 20.0 / 64.0\n);\n\nconst mat4 bayertr = mat4( \n 2.0 / 64.0, 34.0 / 64.0, 10.0 / 64.0, 42.0 / 64.0,\n 50.0 / 64.0, 18.0 / 64.0, 58.0 / 64.0, 26.0 / 64.0,\n 14.0 / 64.0, 46.0 / 64.0, 6.0 / 64.0, 38.0 / 64.0,\n 62.0 / 64.0, 30.0 / 64.0, 54.0 / 64.0, 22.0 / 64.0\n);\n\nconst mat4 bayerbl = mat4( \n 3.0 / 64.0, 35.0 / 64.0, 11.0 / 64.0, 43.0 / 64.0,\n 51.0 / 64.0, 19.0 / 64.0, 59.0 / 64.0, 27.0 / 64.0,\n 15.0 / 64.0, 47.0 / 64.0, 7.0 / 64.0, 39.0 / 64.0,\n 63.0 / 64.0, 31.0 / 64.0, 55.0 / 64.0, 23.0 / 64.0\n);\n\nconst mat4 bayerbr = mat4( \n 1.0 / 64.0, 33.0 / 64.0, 9.0 / 64.0, 41.0 / 64.0,\n 49.0 / 64.0, 17.0 / 64.0, 57.0 / 64.0, 25.0 / 64.0,\n 13.0 / 64.0, 45.0 / 64.0, 5.0 / 64.0, 37.0 / 64.0,\n 61.0 / 64.0, 29.0 / 64.0, 53.0 / 64.0, 21.0 / 64.0\n);\n\nfloat bayerDither(mat4 m, ivec2 p) {\n if (p.y == 0) {\n if (p.x == 0) { return m[0][0]; }\n else if (p.x == 1) { return m[1][0]; }\n else if (p.x == 2) { return m[2][0]; }\n else { return m[3][0]; }\n } else if (p.y == 1) {\n if (p.x == 0) { return m[0][1]; }\n else if (p.x == 1) { return m[1][1]; }\n else if (p.x == 2) { return m[2][1]; }\n else { return m[3][1]; }\n } else if (p.y == 2) {\n if (p.x == 0) { return m[0][1]; }\n else if (p.x == 1) { return m[1][2]; }\n else if (p.x == 2) { return m[2][2]; }\n else { return m[3][2]; }\n } else {\n if (p.x == 0) { return m[0][3]; }\n else if (p.x == 1) { return m[1][3]; }\n else if (p.x == 2) { return m[2][3]; }\n else { return m[3][3]; }\n }\n}\n`;\n", "export function injectBeforeMain(shaderSource: string, codeToInject: string): string {\n return shaderSource.replace(\n \"void main() {\",\n `\n\n${codeToInject}\n\nvoid main() {`,\n );\n}\n\nexport function injectInsideMain(shaderSource: string, codeToInject: string): string {\n return shaderSource.replace(\n \"void main() {\",\n `void main() {\n\n${codeToInject}\n\n `,\n );\n}\n\nexport function injectBefore(shaderSource: string, before: string, codeToInject: string): string {\n return shaderSource.replace(\n before,\n `\n${codeToInject}\n\n${before}\n `,\n );\n}\n\nexport function injectAfter(shaderSource: string, after: string, codeToInject: string): string {\n return shaderSource.replace(\n after,\n `\n${after}\n\n${codeToInject}\n\n `,\n );\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nexport const characterValues = {\n metalness: 0.2,\n roughness: 0.8,\n emissive: { r: 1.0, g: 1.0, b: 1.0 },\n emissiveIntensity: 0.01,\n envMapIntensity: 0.12,\n};\n\nconst characterOptions = {\n metalness: { min: 0, max: 1, step: 0.01 },\n roughness: { min: 0, max: 1, step: 0.01 },\n emissiveIntensity: { min: 0, max: 1, step: 0.01 },\n envMapIntensity: { min: 0, max: 1, step: 0.01 },\n};\n\nexport class CharacterFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"characterMaterial\", expanded: expand });\n this.folder.addBinding(characterValues, \"metalness\", characterOptions.metalness);\n this.folder.addBinding(characterValues, \"roughness\", characterOptions.roughness);\n this.folder.addBinding(characterValues, \"emissive\", {\n color: { type: \"float\" },\n });\n this.folder.addBinding(\n characterValues,\n \"emissiveIntensity\",\n characterOptions.emissiveIntensity,\n );\n this.folder.addBinding(characterValues, \"envMapIntensity\", characterOptions.envMapIntensity);\n }\n\n public setupChangeEvent(): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"emissive\": {\n const value = e.value as { r: number; g: number; b: number };\n characterValues.emissive = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n break;\n }\n default: {\n break;\n }\n }\n });\n }\n}\n", "export enum AnimationState {\n \"idle\" = 0,\n \"walking\" = 1,\n \"running\" = 2,\n \"jumpToAir\" = 3,\n \"air\" = 4,\n \"airToGround\" = 5,\n}\n\nexport type CharacterState = {\n id: number;\n position: {\n x: number;\n y: number;\n z: number;\n };\n rotation: {\n quaternionY: number;\n quaternionW: number;\n };\n state: AnimationState;\n};\n", "import {\n Camera,\n CircleGeometry,\n GLSL3,\n Mesh,\n Object3D,\n RawShaderMaterial,\n Scene,\n Vector3,\n} from \"three\";\n\nimport { ease } from \"../helpers/math-helpers\";\n\nexport class CharacterSpeakingIndicator {\n private vertexShader = /* glsl */ `\n in vec3 position;\n in vec2 uv;\n uniform mat4 modelViewMatrix;\n uniform mat4 projectionMatrix;\n out vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }`;\n\n private fragmentShader = /* glsl */ `\n precision highp float;\n\n uniform float time;\n uniform float alpha;\n in vec2 vUv;\n out vec4 fragColor;\n\n const float size = 1.7;\n const float distribution = 0.03;\n const float speed = 0.2;\n const float overdraw = 3.5;\n const float shapeK = 0.25;\n\n float sdHyperbola(vec2 p, float k, float wi) {\n p = abs(p);\n float k2 = k * k;\n float a = p.x + p.y;\n float i = 0.5 * (a - k2 / a) > wi ? -1.0 : 1.0;\n float x = clamp(0.5 * (a - k2 / a), 0.0, wi);\n vec2 q = vec2(x, sqrt(x * x + k2));\n float s = sign(p.x * p.x - p.y * p.y + k2);\n return s * length(p - q);\n }\n\n void main(void) {\n vec2 uv = (vUv * 2.0 - 1.0);\n float r = -(uv.x * uv.x + uv.y * uv.y);\n float z = 0.5 + 0.5 * sin((r + time * speed) / distribution);\n float a = clamp(smoothstep(-0.1, 0.2, size - length(uv * 2.0)), 0.0, 0.5);\n float h = clamp(sdHyperbola(uv, shapeK, 1.0), 0.0, 1.0) * overdraw;\n float fragAlpha = clamp(a * h, 0.0, 0.7);\n fragColor = vec4(z * fragAlpha) * alpha;\n }`;\n\n private uniforms = {\n time: { value: 0.0 },\n alpha: { value: 0.0 },\n };\n\n private geometry: CircleGeometry = new CircleGeometry(0.35, 21);\n private material: RawShaderMaterial = new RawShaderMaterial({\n vertexShader: this.vertexShader,\n fragmentShader: this.fragmentShader,\n uniforms: this.uniforms,\n transparent: true,\n glslVersion: GLSL3,\n });\n private mesh = new Mesh(this.geometry, this.material);\n\n private currentAlpha = 0.0;\n private targetAlpha = 0.0;\n\n constructor(private scene: Scene | Object3D) {\n this.scene.add(this.mesh);\n }\n\n public setBillboarding(position: Vector3, camera: Camera) {\n this.mesh.position.set(position.x, position.y - 0.15, position.z);\n this.mesh.lookAt(camera.position);\n }\n\n public setTime(value: number) {\n this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.06);\n this.uniforms.time.value = value;\n this.uniforms.alpha.value = this.currentAlpha;\n }\n\n public setSpeaking(value: boolean) {\n this.targetAlpha = value === true ? 1.0 : 0.0;\n }\n\n public dispose() {\n this.scene.remove(this.mesh);\n this.mesh.material.dispose();\n this.mesh.geometry.dispose();\n }\n}\n", "import {\n Camera,\n Color,\n FrontSide,\n LinearFilter,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n PlaneGeometry,\n} from \"three\";\n\nimport { THREECanvasTextTexture } from \"./CanvasText\";\n\nenum LabelAlignment {\n left = \"left\",\n center = \"center\",\n right = \"right\",\n}\n\nconst fontScale = 5;\nconst defaultLabelColor = new Color(0x000000);\nconst defaultFontColor = new Color(0xffffff);\nconst defaultLabelAlignment = LabelAlignment.center;\nconst defaultLabelFontSize = 8;\nconst defaultLabelPadding = 0;\nconst defaultLabelWidth = 0.25;\nconst defaultLabelHeight = 0.1;\nconst defaultLabelCastShadows = true;\n\nconst tooltipGeometry = new PlaneGeometry(1, 1, 1, 1);\n\nexport class CharacterTooltip extends Mesh {\n private tooltipMaterial: MeshBasicMaterial;\n private visibleOpacity: number = 0.85;\n private targetOpacity: number = 0;\n private fadingSpeed: number = 0.02;\n private secondsToFadeOut: number = 10;\n\n private props = {\n content: \"\",\n alignment: defaultLabelAlignment,\n width: defaultLabelWidth,\n height: defaultLabelHeight,\n fontSize: defaultLabelFontSize,\n padding: defaultLabelPadding,\n color: defaultLabelColor,\n fontColor: defaultFontColor,\n castShadows: defaultLabelCastShadows,\n };\n\n constructor() {\n super(tooltipGeometry);\n this.tooltipMaterial = new MeshBasicMaterial({\n map: null,\n transparent: true,\n opacity: 0,\n side: FrontSide,\n });\n this.material = this.tooltipMaterial;\n this.position.set(0, 1.6, 0);\n this.visible = false;\n }\n\n private redrawText(content: string) {\n if (!this.tooltipMaterial) {\n return;\n }\n if (this.tooltipMaterial.map) {\n this.tooltipMaterial.map.dispose();\n }\n const { texture, width, height } = THREECanvasTextTexture(content, {\n bold: true,\n fontSize: this.props.fontSize * fontScale,\n paddingPx: this.props.padding,\n textColorRGB255A1: {\n r: this.props.fontColor.r * 255,\n g: this.props.fontColor.g * 255,\n b: this.props.fontColor.b * 255,\n a: 1.0,\n },\n backgroundColorRGB255A1: {\n r: this.props.color.r * 255,\n g: this.props.color.g * 255,\n b: this.props.color.b * 255,\n a: 1.0,\n },\n dimensions: {\n width: this.props.width * (100 * fontScale),\n height: this.props.height * (100 * fontScale),\n },\n alignment: this.props.alignment,\n });\n\n this.tooltipMaterial.map = texture;\n this.tooltipMaterial.map.magFilter = LinearFilter;\n this.tooltipMaterial.map.minFilter = LinearFilter;\n this.tooltipMaterial.needsUpdate = true;\n\n this.scale.x = width / (100 * fontScale);\n this.scale.y = height / (100 * fontScale);\n this.position.y = 1.4;\n }\n\n setText(text: string, temporary: boolean = false) {\n this.redrawText(text);\n this.visible = true;\n this.targetOpacity = this.visibleOpacity;\n if (temporary) {\n setTimeout(() => {\n this.hide();\n }, this.secondsToFadeOut * 1000);\n }\n }\n\n hide() {\n this.targetOpacity = 0;\n }\n\n update(camera: Camera) {\n this.lookAt(camera.position);\n const opacity = this.tooltipMaterial.opacity;\n if (opacity < this.targetOpacity) {\n this.tooltipMaterial.opacity = Math.min(\n this.tooltipMaterial.opacity + this.fadingSpeed,\n this.targetOpacity,\n );\n } else if (opacity > this.targetOpacity) {\n this.tooltipMaterial.opacity = Math.max(\n this.tooltipMaterial.opacity - this.fadingSpeed,\n this.targetOpacity,\n );\n if (opacity >= 1 && this.tooltipMaterial.transparent) {\n this.tooltipMaterial.transparent = false;\n this.tooltipMaterial.needsUpdate = true;\n } else if (opacity > 0 && opacity < 1 && !this.tooltipMaterial.transparent) {\n this.tooltipMaterial.transparent = true;\n this.tooltipMaterial.needsUpdate = true;\n }\n if (this.tooltipMaterial.opacity <= 0) {\n this.visible = false;\n }\n }\n }\n}\n", "import { Texture, LinearFilter, RGBAFormat, MeshBasicMaterial } from \"three\";\n\ntype RGBA = {\n r: number;\n g: number;\n b: number;\n a: number;\n};\n\ntype CanvasTextOptions = {\n fontSize: number;\n textColorRGB255A1: RGBA;\n backgroundColorRGB255A1?: RGBA;\n font?: string;\n bold?: boolean;\n paddingPx?: number;\n alignment?: string;\n dimensions?: {\n width: number;\n height: number;\n };\n};\n\nfunction getTextAlignOffset(textAlign: CanvasTextAlign, width: number) {\n switch (textAlign) {\n case \"center\":\n return width / 2;\n case \"right\":\n return width;\n default:\n return 0;\n }\n}\n\nfunction printAtWordWrap(\n context: CanvasRenderingContext2D,\n fullText: string,\n x: number,\n y: number,\n lineHeight: number,\n fitWidth: number,\n padding: number,\n alignment: string,\n) {\n const lines = fullText.split(\"\\n\");\n let currentLine = 0;\n for (const text of lines) {\n fitWidth = fitWidth || 0;\n\n if (fitWidth <= 0) {\n context.fillText(text, x, y + lineHeight * currentLine);\n currentLine++;\n continue;\n }\n let words = text.split(\" \");\n let lastWordIndex = 1;\n while (words.length > 0 && lastWordIndex <= words.length) {\n const str = words.slice(0, lastWordIndex).join(\" \");\n const textWidth = context.measureText(str).width;\n if (textWidth + padding * 2 > fitWidth) {\n if (lastWordIndex === 1) {\n lastWordIndex = 2;\n }\n context.fillText(\n words.slice(0, lastWordIndex - 1).join(\" \"),\n x + padding,\n y + lineHeight * currentLine + padding,\n );\n currentLine++;\n words = words.splice(lastWordIndex - 1);\n lastWordIndex = 1;\n } else {\n lastWordIndex++;\n }\n }\n if (lastWordIndex > 0 && words.length > 0) {\n const xOffset = alignment === \"center\" ? 0 : padding;\n context.fillText(words.join(\" \"), x + xOffset, y + lineHeight * currentLine + padding);\n currentLine++;\n }\n }\n}\n\nexport function CanvasText(message: string, options: CanvasTextOptions): HTMLCanvasElement {\n const fontsize = options.fontSize;\n const textColor = options.textColorRGB255A1;\n const backgroundColor = options.backgroundColorRGB255A1 || { r: 255, g: 255, b: 255, a: 1 };\n const padding = options.paddingPx || 0;\n const font = options.font || \"Arial\";\n const fontString = (options.bold ? \"bold \" : \"\") + fontsize + \"px \" + font;\n\n const canvas = document.createElement(\"canvas\");\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const ct = canvas.getContext(\"2d\")!;\n\n // calculate text alignment offset\n const textAlign = (options.alignment as CanvasTextAlign) ?? \"left\";\n\n if (options.dimensions) {\n // NOTE: setting the canvas dimensions resets the context properties, so\n // we always do it first\n canvas.width = options.dimensions.width;\n canvas.height = options.dimensions.height;\n ct.clearRect(0, 0, canvas.width, canvas.height);\n ct.font = fontString;\n ct.textAlign = textAlign;\n ct.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n ct.lineWidth = 0;\n ct.fillRect(0, 0, canvas.width, canvas.height);\n ct.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n ct.font = fontString;\n printAtWordWrap(\n ct,\n message,\n getTextAlignOffset(textAlign, canvas.width),\n fontsize,\n fontsize,\n canvas.width,\n padding,\n textAlign,\n );\n } else {\n // NOTE: setting the canvas dimensions resets the context properties, so\n // we always do it first. However, we also need to take into account the\n // font size to measure the text in the first place.\n ct.font = fontString;\n const metrics = ct.measureText(message);\n const textWidth = metrics.width;\n const textHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;\n canvas.width = textWidth + padding * 2;\n canvas.height = textHeight + padding;\n ct.clearRect(0, 0, canvas.width, canvas.height);\n ct.font = fontString;\n ct.textAlign = textAlign;\n ct.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n ct.lineWidth = 0;\n ct.fillRect(0, 0, canvas.width, canvas.height);\n ct.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n ct.font = fontString;\n ct.fillText(message, padding + getTextAlignOffset(textAlign, textWidth), textHeight);\n }\n\n return canvas;\n}\n\nexport function THREECanvasTextTexture(\n text: string,\n options: CanvasTextOptions,\n): { texture: Texture; width: number; height: number } {\n const canvas = CanvasText(text, options);\n\n const texture = new Texture(canvas);\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n texture.format = RGBAFormat;\n texture.needsUpdate = true;\n\n return { texture, width: canvas.width, height: canvas.height };\n}\n\nexport function THREECanvasTextMaterial(\n text: string,\n options: CanvasTextOptions,\n): { material: MeshBasicMaterial; width: number; height: number } {\n const { texture, width, height } = THREECanvasTextTexture(text, options);\n\n const material = new MeshBasicMaterial();\n material.map = texture;\n material.transparent = true;\n material.depthWrite = false;\n material.needsUpdate = true;\n\n return { material, width, height };\n}\n", "import { PositionAndRotation } from \"mml-web\";\nimport { Euler, Group, Quaternion, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { ease } from \"../helpers/math-helpers\";\nimport { KeyInputManager } from \"../input/KeyInputManager\";\nimport { Composer } from \"../rendering/composer\";\nimport { TimeManager } from \"../time/TimeManager\";\n\nimport { AnimationConfig, Character, CharacterDescription } from \"./Character\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\nimport { LocalController } from \"./LocalController\";\nimport { RemoteController } from \"./RemoteController\";\nimport { encodeCharacterAndCamera } from \"./url-position\";\n\nexport class CharacterManager {\n private updateLocationHash = true;\n\n public readonly headTargetOffset = new Vector3(0, 1.3, 0);\n\n private id: number = 0;\n\n public remoteCharacters: Map<number, Character> = new Map();\n public remoteCharacterControllers: Map<number, RemoteController> = new Map();\n\n private localCharacterSpawned: boolean = false;\n private localController: LocalController;\n public localCharacter: Character | null = null;\n\n private speakingCharacters: Map<number, boolean> = new Map();\n\n public readonly group: Group;\n\n constructor(\n private readonly composer: Composer,\n private readonly characterModelLoader: CharacterModelLoader,\n private readonly collisionsManager: CollisionsManager,\n private readonly cameraManager: CameraManager,\n private readonly timeManager: TimeManager,\n private readonly keyInputManager: KeyInputManager,\n private readonly clientStates: Map<number, CharacterState>,\n private readonly sendUpdate: (update: CharacterState) => void,\n private readonly animationConfig: AnimationConfig,\n private readonly characterDescription: CharacterDescription,\n ) {\n this.group = new Group();\n }\n\n public spawnLocalCharacter(\n characterDescription: CharacterDescription,\n id: number,\n spawnPosition: Vector3 = new Vector3(),\n spawnRotation: Euler = new Euler(),\n ) {\n const character = new Character(\n characterDescription,\n this.animationConfig,\n this.characterModelLoader,\n id,\n () => {\n // character loaded callback\n },\n this.cameraManager,\n this.composer,\n true,\n );\n const quaternion = new Quaternion().setFromEuler(character.rotation);\n this.sendUpdate({\n id: id,\n position: {\n x: spawnPosition.x,\n y: spawnPosition.y,\n z: spawnPosition.z,\n },\n rotation: { quaternionY: quaternion.y, quaternionW: quaternion.w },\n state: AnimationState.idle,\n });\n this.id = id;\n this.localCharacter = character;\n this.localController = new LocalController(\n this.localCharacter,\n this.id,\n this.collisionsManager,\n this.keyInputManager,\n this.cameraManager,\n this.timeManager,\n );\n this.localCharacter.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n this.localCharacter.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);\n character.tooltip?.setText(`${id}`, true);\n this.group.add(character);\n this.localCharacterSpawned = true;\n }\n\n public spawnRemoteCharacter(\n characterDescription: CharacterDescription,\n id: number,\n spawnPosition: Vector3 = new Vector3(),\n spawnRotation: Euler = new Euler(),\n ) {\n const character = new Character(\n characterDescription,\n this.animationConfig,\n this.characterModelLoader,\n id,\n () => {\n // character loaded callback\n },\n this.cameraManager,\n this.composer,\n false,\n );\n\n this.remoteCharacters.set(id, character);\n const remoteController = new RemoteController(character, id);\n remoteController.character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n remoteController.character.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);\n this.remoteCharacterControllers.set(id, remoteController);\n character.tooltip?.setText(`${id}`);\n this.group.add(character);\n }\n\n public getLocalCharacterPositionAndRotation(): PositionAndRotation {\n if (this.localCharacter && this.localCharacter && this.localCharacter) {\n return {\n position: this.localCharacter.position,\n rotation: this.localCharacter.rotation,\n };\n }\n return {\n position: { x: 0, y: 0, z: 0 },\n rotation: { x: 0, y: 0, z: 0 },\n };\n }\n\n public clear() {\n for (const [id, character] of this.remoteCharacters) {\n this.group.remove(character);\n this.remoteCharacters.delete(id);\n this.remoteCharacterControllers.delete(id);\n }\n if (this.localCharacter) {\n this.group.remove(this.localCharacter);\n this.localCharacter = null;\n }\n }\n\n public setSpeakingCharacter(id: number, value: boolean) {\n this.speakingCharacters.set(id, value);\n }\n\n public update() {\n if (this.localCharacter) {\n this.localCharacter.update(this.timeManager.time, this.timeManager.deltaTime);\n if (this.speakingCharacters.has(this.id)) {\n this.localCharacter.speakingIndicator?.setSpeaking(this.speakingCharacters.get(this.id)!);\n }\n\n this.localController.update();\n if (this.timeManager.frame % 2 === 0) {\n this.sendUpdate(this.localController.networkState);\n }\n\n const targetOffset = new Vector3();\n targetOffset\n .add(this.headTargetOffset)\n .applyQuaternion(this.localCharacter.quaternion)\n .add(this.localCharacter.position);\n this.cameraManager.setTarget(targetOffset);\n\n for (const [id, update] of this.clientStates) {\n if (this.remoteCharacters.has(id) && this.speakingCharacters.has(id)) {\n const character = this.remoteCharacters.get(id);\n character?.speakingIndicator?.setSpeaking(this.speakingCharacters.get(id)!);\n }\n const { position } = update;\n if (!this.remoteCharacters.has(id) && this.localCharacterSpawned === true) {\n this.spawnRemoteCharacter(\n this.characterDescription!,\n id,\n new Vector3(position.x, position.y, position.z),\n );\n }\n\n const characterController = this.remoteCharacterControllers.get(id);\n if (characterController) {\n characterController.update(update, this.timeManager.time, this.timeManager.deltaTime);\n }\n }\n\n for (const [id, character] of this.remoteCharacters) {\n if (!this.clientStates.has(id)) {\n character.speakingIndicator?.dispose();\n this.group.remove(character);\n this.remoteCharacters.delete(id);\n this.remoteCharacterControllers.delete(id);\n }\n }\n\n if (this.updateLocationHash && this.timeManager.frame % 60 === 0) {\n window.location.hash = encodeCharacterAndCamera(\n this.localCharacter,\n this.cameraManager.camera,\n );\n }\n }\n }\n}\n", "import { Euler, Line3, Matrix4, Quaternion, Ray, Raycaster, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { CollisionMeshState, CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { KeyInputManager } from \"../input/KeyInputManager\";\nimport { TimeManager } from \"../time/TimeManager\";\n\nimport { Character } from \"./Character\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\n\nconst downVector = new Vector3(0, -1, 0);\n\nconst airResistance = 0.5;\nconst groundResistance = 0.99999999;\nconst airControlModifier = 0.05;\nconst groundWalkControl = 0.75;\nconst groundRunControl = 1.0;\nconst baseControl = 200;\nconst collisionDetectionSteps = 15;\nconst minimumSurfaceAngle = 0.9;\n\nexport class LocalController {\n public capsuleInfo = {\n radius: 0.4,\n segment: new Line3(new Vector3(), new Vector3(0, 1.05, 0)),\n };\n\n private gravity: number = -42;\n private jumpForce: number = 20;\n private coyoteTimeThreshold: number = 70;\n\n private coyoteTime: boolean = false;\n private canJump: boolean = true;\n private characterOnGround: boolean = false;\n private characterWasOnGround: boolean = false;\n private characterAirborneSince: number = 0;\n private currentHeight: number = 0;\n private currentSurfaceAngle = new Vector3();\n\n private characterVelocity: Vector3 = new Vector3();\n private vectorUp: Vector3 = new Vector3(0, 1, 0);\n private vectorDown: Vector3 = new Vector3(0, -1, 0);\n\n private rotationOffset: number = 0;\n private azimuthalAngle: number = 0;\n\n private tempMatrix: Matrix4 = new Matrix4();\n private tempSegment: Line3 = new Line3();\n private tempQuaternion: Quaternion = new Quaternion();\n private tempEuler: Euler = new Euler();\n private tempVector: Vector3 = new Vector3();\n private tempVector2: Vector3 = new Vector3();\n private tempVector3: Vector3 = new Vector3();\n private rayCaster: Raycaster = new Raycaster();\n\n private surfaceTempQuaternion = new Quaternion();\n private surfaceTempQuaternion2 = new Quaternion();\n private surfaceTempVector1 = new Vector3();\n private surfaceTempVector2 = new Vector3();\n private surfaceTempVector3 = new Vector3();\n private surfaceTempVector4 = new Vector3();\n private surfaceTempVector5 = new Vector3();\n private surfaceTempRay = new Ray();\n private lastFrameSurfaceState:\n | [\n CollisionMeshState,\n {\n lastMatrix: Matrix4;\n },\n ]\n | null = null;\n\n private forward: boolean;\n private backward: boolean;\n private left: boolean;\n private right: boolean;\n private run: boolean;\n private jump: boolean;\n private anyDirection: boolean;\n private conflictingDirections: boolean;\n\n public networkState: CharacterState;\n\n constructor(\n private readonly character: Character,\n private readonly id: number,\n private readonly collisionsManager: CollisionsManager,\n private readonly keyInputManager: KeyInputManager,\n private readonly cameraManager: CameraManager,\n private readonly timeManager: TimeManager,\n ) {\n this.networkState = {\n id: this.id,\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: AnimationState.idle,\n };\n }\n\n private updateControllerState(): void {\n this.forward = this.keyInputManager.forward;\n this.backward = this.keyInputManager.backward;\n this.left = this.keyInputManager.left;\n this.right = this.keyInputManager.right;\n this.run = this.keyInputManager.run;\n this.jump = this.keyInputManager.jump;\n this.anyDirection = this.keyInputManager.anyDirection;\n this.conflictingDirections = this.keyInputManager.conflictingDirection;\n }\n\n public update(): void {\n this.updateControllerState();\n\n this.rayCaster.set(this.character.position, this.vectorDown);\n const firstRaycastHit = this.collisionsManager.raycastFirst(this.rayCaster.ray);\n if (firstRaycastHit !== null) {\n this.currentHeight = firstRaycastHit[0];\n this.currentSurfaceAngle.copy(firstRaycastHit[1]);\n }\n\n if (this.anyDirection || !this.characterOnGround) {\n const targetAnimation = this.getTargetAnimation();\n this.character.updateAnimation(targetAnimation);\n } else {\n this.character.updateAnimation(AnimationState.idle);\n }\n\n if (this.anyDirection) {\n this.updateRotation();\n }\n\n for (let i = 0; i < collisionDetectionSteps; i++) {\n this.updatePosition(\n this.timeManager.deltaTime,\n this.timeManager.deltaTime / collisionDetectionSteps,\n i,\n );\n }\n\n if (this.character.position.y < 0) {\n this.resetPosition();\n }\n this.updateNetworkState();\n }\n\n private getTargetAnimation(): AnimationState {\n if (!this.character) return AnimationState.idle;\n\n const jumpHeight = this.characterVelocity.y > 0 ? 0.2 : 1.8;\n if (this.currentHeight > jumpHeight && !this.characterOnGround) {\n return AnimationState.air;\n }\n if (this.conflictingDirections) {\n return AnimationState.idle;\n }\n return this.run && this.anyDirection\n ? AnimationState.running\n : this.anyDirection\n ? AnimationState.walking\n : AnimationState.idle;\n }\n\n private updateRotationOffset(): void {\n if (this.conflictingDirections) return;\n if (this.forward) {\n this.rotationOffset = Math.PI;\n if (this.left) this.rotationOffset = Math.PI + Math.PI / 4;\n if (this.right) this.rotationOffset = Math.PI - Math.PI / 4;\n } else if (this.backward) {\n this.rotationOffset = Math.PI * 2;\n if (this.left) this.rotationOffset = -Math.PI * 2 - Math.PI / 4;\n if (this.right) this.rotationOffset = Math.PI * 2 + Math.PI / 4;\n } else if (this.left) {\n this.rotationOffset = Math.PI * -0.5;\n } else if (this.right) {\n this.rotationOffset = Math.PI * 0.5;\n }\n }\n\n private updateAzimuthalAngle(): void {\n const camToModelDistance = this.cameraManager.camera.position.distanceTo(\n this.character.position,\n );\n const isCameraFirstPerson = camToModelDistance < 2;\n if (isCameraFirstPerson) {\n const cameraForward = this.tempVector\n .set(0, 0, 1)\n .applyQuaternion(this.cameraManager.camera.quaternion);\n this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);\n } else {\n this.azimuthalAngle = Math.atan2(\n this.cameraManager.camera.position.x - this.character.position.x,\n this.cameraManager.camera.position.z - this.character.position.z,\n );\n }\n }\n\n private computeAngularDifference(rotationQuaternion: Quaternion): number {\n return 2 * Math.acos(Math.abs(this.character.quaternion.dot(rotationQuaternion)));\n }\n\n private updateRotation(): void {\n this.updateRotationOffset();\n this.updateAzimuthalAngle();\n const rotationQuaternion = this.tempQuaternion.setFromAxisAngle(\n this.vectorUp,\n this.azimuthalAngle + this.rotationOffset,\n );\n const angularDifference = this.computeAngularDifference(rotationQuaternion);\n const desiredTime = 0.07;\n const angularSpeed = angularDifference / desiredTime;\n const frameRotation = angularSpeed * this.timeManager.deltaTime;\n this.character.quaternion.rotateTowards(rotationQuaternion, frameRotation);\n }\n\n private applyControls(deltaTime: number) {\n const resistance = this.characterOnGround ? groundResistance : airResistance;\n\n // Dampen the velocity based on the resistance\n const speedFactor = Math.pow(1 - resistance, deltaTime);\n this.characterVelocity.multiplyScalar(speedFactor);\n\n const acceleration = this.tempVector.set(0, 0, 0);\n\n if (this.characterOnGround) {\n if (!this.jump) {\n this.canJump = true;\n }\n\n if (this.jump && this.canJump) {\n acceleration.y += this.jumpForce / deltaTime;\n this.canJump = false;\n } else {\n if (this.currentSurfaceAngle.y < minimumSurfaceAngle) {\n acceleration.y += this.gravity;\n }\n }\n } else if (this.jump && this.coyoteTime) {\n acceleration.y += this.jumpForce / deltaTime;\n this.canJump = false;\n } else {\n acceleration.y += this.gravity;\n this.canJump = false;\n }\n\n const control =\n (this.characterOnGround\n ? this.run\n ? groundRunControl\n : groundWalkControl\n : airControlModifier) * baseControl;\n\n const controlAcceleration = this.tempVector2.set(0, 0, 0);\n\n if (!this.conflictingDirections) {\n if (this.forward) {\n const forward = this.tempVector3\n .set(0, 0, -1)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle);\n controlAcceleration.add(forward);\n }\n\n if (this.backward) {\n const backward = this.tempVector3\n .set(0, 0, 1)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle);\n controlAcceleration.add(backward);\n }\n\n if (this.left) {\n const left = this.tempVector3\n .set(-1, 0, 0)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle);\n controlAcceleration.add(left);\n }\n\n if (this.right) {\n const right = this.tempVector3\n .set(1, 0, 0)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle);\n controlAcceleration.add(right);\n }\n }\n if (controlAcceleration.length() > 0) {\n controlAcceleration.normalize();\n controlAcceleration.multiplyScalar(control);\n }\n acceleration.add(controlAcceleration);\n this.characterVelocity.addScaledVector(acceleration, deltaTime);\n\n this.character.position.addScaledVector(this.characterVelocity, deltaTime);\n }\n\n private updatePosition(deltaTime: number, stepDeltaTime: number, iter: number): void {\n this.applyControls(stepDeltaTime);\n\n if (iter === 0) {\n const lastMovement = this.getMovementFromSurfaces(this.character.position, deltaTime);\n if (lastMovement) {\n this.character.position.add(lastMovement.position);\n const asQuaternion = this.tempQuaternion.setFromEuler(this.character.rotation);\n const lastMovementEuler = this.tempEuler.setFromQuaternion(lastMovement.rotation);\n lastMovementEuler.x = 0;\n lastMovementEuler.z = 0;\n lastMovement.rotation.setFromEuler(lastMovementEuler);\n asQuaternion.multiply(lastMovement.rotation);\n this.character.rotation.setFromQuaternion(asQuaternion);\n }\n }\n this.character.updateMatrixWorld();\n\n const avatarSegment = this.tempSegment;\n avatarSegment.copy(this.capsuleInfo.segment!);\n avatarSegment.start.applyMatrix4(this.character.matrixWorld).applyMatrix4(this.tempMatrix);\n avatarSegment.end.applyMatrix4(this.character.matrixWorld).applyMatrix4(this.tempMatrix);\n\n const positionBeforeCollisions = this.tempVector.copy(avatarSegment.start);\n this.collisionsManager.applyColliders(avatarSegment, this.capsuleInfo.radius!);\n this.character.position.copy(avatarSegment.start);\n const deltaCollisionPosition = avatarSegment.start.sub(positionBeforeCollisions);\n\n this.characterOnGround = deltaCollisionPosition.y > 0;\n\n if (this.characterWasOnGround && !this.characterOnGround) {\n this.characterAirborneSince = Date.now();\n }\n\n this.coyoteTime =\n this.characterVelocity.y < 0 &&\n !this.characterOnGround &&\n Date.now() - this.characterAirborneSince < this.coyoteTimeThreshold;\n\n this.characterWasOnGround = this.characterOnGround;\n }\n\n public getMovementFromSurfaces(userPosition: Vector3, deltaTime: number) {\n let lastMovement: { rotation: Quaternion; position: Vector3 } | null = null;\n\n // If we have a last frame state, we can calculate the movement of the mesh to apply it to the user\n if (this.lastFrameSurfaceState !== null) {\n const meshState = this.lastFrameSurfaceState[0];\n\n // Extract the matrix from the current frame and the last frame\n const currentFrameMatrix = meshState.matrix;\n const lastFrameMatrix = this.lastFrameSurfaceState[1].lastMatrix;\n\n if (lastFrameMatrix.equals(currentFrameMatrix)) {\n // No movement from this mesh - do nothing\n } else {\n // The mesh has moved since the last frame - calculate the movement\n\n // Get the position of the mesh in the last frame\n const lastMeshPosition = this.surfaceTempVector1;\n const lastMeshRotation = this.surfaceTempQuaternion;\n lastFrameMatrix.decompose(lastMeshPosition, lastMeshRotation, this.surfaceTempVector3);\n\n // Get the position of the mesh in the current frame\n const currentMeshPosition = this.surfaceTempVector2;\n const currentMeshRotation = this.surfaceTempQuaternion2;\n currentFrameMatrix.decompose(\n currentMeshPosition,\n currentMeshRotation,\n this.surfaceTempVector3,\n );\n\n // Calculate the difference between the new position and the old position to determine the movement due to translation of position\n const meshTranslationDelta = this.surfaceTempVector5\n .copy(currentMeshPosition)\n .sub(lastMeshPosition);\n\n // Calculate the relative position of the user to the mesh in the last frame\n const lastFrameRelativeUserPosition = this.surfaceTempVector3\n .copy(userPosition)\n .sub(lastMeshPosition);\n\n // Calculate the relative quaternion of the mesh in the last frame to the mesh in the current frame\n const meshRotationDelta = lastMeshRotation.invert().multiply(currentMeshRotation);\n\n // Apply the relative quaternion to the relative user position to determine the new position of the user given just the rotation\n const translationDueToRotation = this.surfaceTempVector4\n .copy(lastFrameRelativeUserPosition)\n .applyQuaternion(meshRotationDelta)\n .sub(lastFrameRelativeUserPosition);\n\n // Combine the mesh translation delta and the rotation translation delta to determine the total movement of the user\n const translationAndRotationPositionDelta = this.surfaceTempVector1\n .copy(meshTranslationDelta)\n .add(translationDueToRotation);\n\n lastMovement = {\n position: translationAndRotationPositionDelta,\n rotation: meshRotationDelta,\n };\n lastFrameMatrix.copy(currentFrameMatrix);\n }\n }\n\n const newPosition = this.surfaceTempVector3.copy(userPosition);\n if (lastMovement) {\n newPosition.add(lastMovement.position);\n }\n newPosition.setY(newPosition.y + 0.05);\n\n // Raycast down from the new position to see if there is a surface below the user which will be tracked in the next frame\n const ray = this.surfaceTempRay.set(newPosition, downVector);\n const hit = this.collisionsManager.raycastFirst(ray);\n if (hit && hit[0] < 0.8) {\n // There is a surface below the user\n const currentCollisionMeshState = hit[2];\n this.lastFrameSurfaceState = [\n currentCollisionMeshState,\n { lastMatrix: currentCollisionMeshState.matrix.clone() },\n ];\n } else {\n if (this.lastFrameSurfaceState !== null && lastMovement) {\n // Apply the last movement to the user's velocity\n this.characterVelocity.add(\n lastMovement.position.clone().divideScalar(deltaTime), // The position delta is the result of one tick which is deltaTime seconds, so we need to divide by deltaTime to get the velocity per second\n );\n }\n this.lastFrameSurfaceState = null;\n }\n return lastMovement;\n }\n\n private updateNetworkState(): void {\n const characterQuaternion = this.character.getWorldQuaternion(this.tempQuaternion);\n this.networkState = {\n id: this.id,\n position: {\n x: this.character.position.x,\n y: this.character.position.y,\n z: this.character.position.z,\n },\n rotation: { quaternionY: characterQuaternion.y, quaternionW: characterQuaternion.w },\n state: this.character.getCurrentAnimation(),\n };\n }\n\n private resetPosition(): void {\n this.characterVelocity.y = 0;\n this.character.position.y = 3;\n this.characterOnGround = false;\n }\n}\n", "import { Quaternion, Vector3 } from \"three\";\n\nimport { Character } from \"./Character\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\n\nexport class RemoteController {\n public currentAnimation: AnimationState = AnimationState.idle;\n\n public networkState: CharacterState;\n\n constructor(\n public readonly character: Character,\n public readonly id: number,\n ) {\n this.networkState = {\n id: this.id,\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: this.currentAnimation as AnimationState,\n };\n }\n\n public update(clientUpdate: CharacterState, time: number, deltaTime: number): void {\n if (!this.character) return;\n this.updateFromNetwork(clientUpdate);\n this.character.update(time, deltaTime);\n }\n\n private updateFromNetwork(clientUpdate: CharacterState): void {\n const { position, rotation, state } = clientUpdate;\n this.character.position.lerp(new Vector3(position.x, position.y, position.z), 0.15);\n const rotationQuaternion = new Quaternion(0, rotation.quaternionY, 0, rotation.quaternionW);\n this.character.quaternion.slerp(rotationQuaternion, 0.6);\n if (state !== this.currentAnimation) {\n this.currentAnimation = state;\n this.character.updateAnimation(state);\n }\n }\n}\n", "import { Object3D, Quaternion, Vector3 } from \"three\";\n\nimport { toArray } from \"../helpers/math-helpers\";\n\nexport function encodeCharacterAndCamera(character: Object3D, camera: Object3D): string {\n return [\n ...toArray(character.position),\n ...toArray(character.quaternion),\n ...toArray(camera.position),\n ...toArray(camera.quaternion),\n ].join(\",\");\n}\n\nexport function decodeCharacterAndCamera(hash: string): {\n character: { position: Vector3; quaternion: Quaternion };\n camera: { position: Vector3; quaternion: Quaternion };\n} {\n const values = hash.split(\",\").map(Number);\n return {\n character: {\n position: new Vector3(values[0], values[1], values[2]),\n quaternion: new Quaternion(values[3], values[4], values[5], values[6]),\n },\n camera: {\n position: new Vector3(values[7], values[8], values[9]),\n quaternion: new Quaternion(values[10], values[11], values[12], values[13]),\n },\n };\n}\n", "import { AnimationClip, LoadingManager, Object3D } from \"three\";\nimport { GLTF, GLTFLoader as ThreeGLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\n\nclass CachedGLTFLoader extends ThreeGLTFLoader {\n private blobCache: Map<string, string>;\n\n constructor(\n manager?: LoadingManager,\n private debug: boolean = false,\n ) {\n super(manager);\n this.blobCache = new Map();\n }\n\n setBlobUrl(originalUrl: string, blobUrl: string) {\n this.blobCache.set(originalUrl, blobUrl);\n }\n\n getBlobUrl(originalUrl: string): string | undefined {\n return this.blobCache.get(originalUrl);\n }\n\n load(\n url: string,\n onLoad: (gltf: GLTF) => void,\n onProgress?: ((event: ProgressEvent<EventTarget>) => void) | undefined,\n onError?: ((event: ErrorEvent) => void) | undefined,\n ): void {\n const blobUrl = this.getBlobUrl(url);\n if (blobUrl) {\n if (this.debug === true) {\n console.log(`Loading cached ${url.split(\"/\").pop()}`);\n }\n super.load(blobUrl, onLoad, onProgress, onError);\n } else {\n super.load(url, onLoad, onProgress, onError);\n }\n }\n}\n\nclass LRUCache<K, V> {\n private maxSize: number;\n private cache: Map<K, V>;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n this.cache = new Map();\n }\n\n get(key: K): V | undefined {\n const item = this.cache.get(key);\n if (item) {\n this.cache.delete(key);\n this.cache.set(key, item);\n }\n return item;\n }\n\n set(key: K, value: V): void {\n if (this.cache.size >= this.maxSize) {\n const oldestKey = this.cache.keys().next().value;\n this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n}\n\ninterface CachedModel {\n blob: Blob;\n originalExtension: string;\n}\n\nexport class CharacterModelLoader {\n private readonly loadingManager: LoadingManager;\n private readonly gltfLoader: CachedGLTFLoader;\n private modelCache: LRUCache<string, CachedModel>;\n private ongoingLoads: Map<string, Promise<CachedModel>> = new Map();\n\n constructor(\n maxCacheSize: number = 100,\n private debug: boolean = false,\n ) {\n this.loadingManager = new LoadingManager();\n this.gltfLoader = new CachedGLTFLoader(this.loadingManager, this.debug);\n this.modelCache = new LRUCache(maxCacheSize);\n }\n\n async load(fileUrl: string, fileType: \"model\"): Promise<Object3D | undefined>;\n async load(fileUrl: string, fileType: \"animation\"): Promise<AnimationClip | undefined>;\n async load(\n fileUrl: string,\n fileType: \"model\" | \"animation\",\n ): Promise<Object3D | AnimationClip | undefined> {\n const cachedModel = this.modelCache.get(fileUrl);\n\n if (cachedModel) {\n const blobURL = URL.createObjectURL(cachedModel.blob);\n this.gltfLoader.setBlobUrl(fileUrl, blobURL);\n return this.loadFromUrl(fileUrl, fileType, cachedModel.originalExtension);\n } else {\n if (this.debug === true) {\n console.log(`Loading ${fileUrl} from server`);\n }\n const ongoingLoad = this.ongoingLoads.get(fileUrl);\n if (ongoingLoad)\n return ongoingLoad.then((loadedModel) => {\n const blobURL = URL.createObjectURL(loadedModel.blob);\n return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);\n });\n\n const loadPromise: Promise<CachedModel> = fetch(fileUrl)\n .then((response) => response.blob())\n .then((blob) => {\n const originalExtension = fileUrl.split(\".\").pop() || \"\";\n const cached = { blob, originalExtension };\n this.modelCache.set(fileUrl, cached);\n this.ongoingLoads.delete(fileUrl);\n return cached;\n });\n\n this.ongoingLoads.set(fileUrl, loadPromise);\n return loadPromise.then((loadedModel) => {\n const blobURL = URL.createObjectURL(loadedModel.blob);\n return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);\n });\n }\n }\n\n private async loadFromUrl(\n url: string,\n fileType: \"model\" | \"animation\",\n extension: string,\n ): Promise<Object3D | AnimationClip | undefined> {\n if ([\"gltf\", \"glb\"].includes(extension)) {\n return new Promise((resolve, reject) => {\n this.gltfLoader.load(\n url,\n (object: GLTF) => {\n if (fileType === \"model\") {\n resolve(object.scene as Object3D);\n } else if (fileType === \"animation\") {\n resolve(object.animations[0] as AnimationClip);\n } else {\n const error = `Trying to load unknown ${fileType} type of element from file ${url}`;\n console.error(error);\n reject(error);\n }\n },\n undefined,\n (error) => {\n console.error(`Error loading GL(B|TF) from ${url}: ${error}`);\n reject(error);\n },\n );\n });\n } else {\n console.error(`Error: can't recognize ${url} extension: ${extension}`);\n }\n }\n}\n", "import { EventHandlerCollection } from \"./EventHandlerCollection\";\nimport { VirtualJoystick } from \"./VirtualJoystick\";\n\nenum Key {\n W = \"w\",\n A = \"a\",\n S = \"s\",\n D = \"d\",\n SHIFT = \"shift\",\n SPACE = \" \",\n}\n\nexport class KeyInputManager {\n private keys = new Map<string, boolean>();\n private eventHandlerCollection = new EventHandlerCollection();\n private directionJoystick: VirtualJoystick | null = null;\n\n constructor(private shouldCaptureKeyPress: () => boolean = () => true) {\n this.eventHandlerCollection.add(document, \"keydown\", this.onKeyDown.bind(this));\n this.eventHandlerCollection.add(document, \"keyup\", this.onKeyUp.bind(this));\n this.eventHandlerCollection.add(window, \"blur\", this.handleUnfocus.bind(this));\n this.directionJoystick = new VirtualJoystick({\n radius: 70,\n inner_radius: 20,\n x: 70,\n y: 0,\n mouse_support: false,\n });\n }\n\n private handleUnfocus(_event: FocusEvent): void {\n this.keys.clear();\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n if (this.shouldCaptureKeyPress()) {\n if (event.key.length === 2 && event.key[0] === \"F\") {\n // Ignore all Function keys\n return;\n }\n if (event.metaKey) {\n // Ignore all meta keys (e.g. Alt, Cmd)\n return;\n }\n this.keys.set(event.key.toLowerCase(), true);\n event.preventDefault();\n }\n }\n\n private onKeyUp(event: KeyboardEvent): void {\n this.keys.set(event.key.toLowerCase(), false);\n }\n\n public isKeyPressed(key: string): boolean {\n return this.keys.get(key) || false;\n }\n\n public isMovementKeyPressed(): boolean {\n return (\n [Key.W, Key.A, Key.S, Key.D].some((key) => this.isKeyPressed(key)) ||\n this.directionJoystick!.hasDirection\n );\n }\n\n get forward(): boolean {\n return this.isKeyPressed(Key.W) || this.directionJoystick!.up;\n }\n\n get backward(): boolean {\n return this.isKeyPressed(Key.S) || this.directionJoystick!.down;\n }\n\n get left(): boolean {\n return this.isKeyPressed(Key.A) || this.directionJoystick!.left;\n }\n\n get right(): boolean {\n return this.isKeyPressed(Key.D) || this.directionJoystick!.right;\n }\n\n get run(): boolean {\n return this.isKeyPressed(Key.SHIFT);\n }\n\n get jump(): boolean {\n return this.isKeyPressed(Key.SPACE);\n }\n\n get anyDirection(): boolean {\n return this.isMovementKeyPressed();\n }\n\n get conflictingDirection(): boolean {\n return (\n (this.isKeyPressed(Key.W) && this.isKeyPressed(Key.S)) ||\n (this.isKeyPressed(Key.A) && this.isKeyPressed(Key.D))\n );\n }\n\n public dispose() {\n this.eventHandlerCollection.clear();\n }\n}\n", "import {\n IMMLScene,\n Interaction,\n InteractionListener,\n InteractionManager,\n MElement,\n MMLClickTrigger,\n PositionAndRotation,\n PromptManager,\n PromptProps,\n ChatProbe,\n LoadingProgressManager,\n} from \"mml-web\";\nimport { AudioListener, Group, Object3D, PerspectiveCamera, Scene, WebGLRenderer } from \"three\";\n\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\n\nexport class MMLCompositionScene {\n public group: Group;\n\n public readonly mmlScene: IMMLScene;\n private readonly promptManager: PromptManager;\n private readonly interactionManager: InteractionManager;\n private readonly interactionListener: InteractionListener;\n private readonly chatProbes = new Set<ChatProbe>();\n private readonly clickTrigger: MMLClickTrigger;\n private readonly loadingProgressManager: LoadingProgressManager;\n\n constructor(\n targetElement: HTMLElement,\n private renderer: WebGLRenderer,\n private scene: Scene,\n private camera: PerspectiveCamera,\n private audioListener: AudioListener,\n private collisionsManager: CollisionsManager,\n private getUserPositionAndRotation: () => PositionAndRotation,\n ) {\n this.group = new Group();\n this.promptManager = PromptManager.init(targetElement);\n\n const { interactionListener, interactionManager } = InteractionManager.init(\n targetElement,\n this.camera,\n this.scene,\n );\n this.interactionManager = interactionManager;\n this.interactionListener = interactionListener;\n this.loadingProgressManager = new LoadingProgressManager();\n\n this.mmlScene = {\n getAudioListener: () => this.audioListener,\n getRenderer: () => this.renderer,\n getThreeScene: () => this.scene,\n getRootContainer: () => this.group,\n getCamera: () => this.camera,\n addCollider: (object: Object3D, mElement: MElement) => {\n this.collisionsManager.addMeshesGroup(object as Group, mElement);\n },\n updateCollider: (object: Object3D) => {\n this.collisionsManager.updateMeshesGroup(object as Group);\n },\n removeCollider: (object: Object3D) => {\n this.collisionsManager.removeMeshesGroup(object as Group);\n },\n getUserPositionAndRotation: this.getUserPositionAndRotation,\n addInteraction: (interaction: Interaction) => {\n this.interactionListener.addInteraction(interaction);\n },\n updateInteraction: (interaction: Interaction) => {\n this.interactionListener.updateInteraction(interaction);\n },\n removeInteraction: (interaction: Interaction) => {\n this.interactionListener.removeInteraction(interaction);\n },\n addChatProbe: (chatProbe: ChatProbe) => {\n this.chatProbes.add(chatProbe);\n },\n updateChatProbe: () => {\n // no-op\n },\n removeChatProbe: (chatProbe: ChatProbe) => {\n this.chatProbes.delete(chatProbe);\n },\n prompt: (promptProps: PromptProps, callback: (message: string | null) => void) => {\n this.promptManager.prompt(promptProps, callback);\n },\n getLoadingProgressManager: () => {\n return this.loadingProgressManager;\n },\n };\n\n this.clickTrigger = MMLClickTrigger.init(targetElement, this.mmlScene as IMMLScene);\n }\n\n onChatMessage(message: string) {\n for (const chatProbe of this.chatProbes) {\n chatProbe.trigger(message);\n }\n }\n\n dispose() {\n this.promptManager.dispose();\n this.clickTrigger.dispose();\n this.interactionManager.dispose();\n }\n}\n", "import * as EssentialsPlugin from \"@tweakpane/plugin-essentials\";\nimport {\n BloomEffect,\n EffectComposer,\n EffectPass,\n NormalPass,\n SSAOEffect,\n ToneMappingEffect,\n} from \"postprocessing\";\nimport { Scene, WebGLRenderer } from \"three\";\nimport { FolderApi, Pane } from \"tweakpane\";\n\nimport { BrightnessContrastSaturation } from \"../rendering/post-effects/bright-contrast-sat\";\nimport { GaussGrainEffect } from \"../rendering/post-effects/gauss-grain\";\nimport { Sun } from \"../sun/Sun\";\nimport { TimeManager } from \"../time/TimeManager\";\n\nimport { BrightnessContrastSaturationFolder } from \"./blades/bcsFolder\";\nimport { CharacterFolder } from \"./blades/characterFolder\";\nimport { EnvironmentFolder } from \"./blades/environmentFolder\";\nimport { PostExtrasFolder } from \"./blades/postExtrasFolder\";\nimport { RendererFolder, rendererValues } from \"./blades/rendererFolder\";\nimport { RendererStatsFolder } from \"./blades/rendererStatsFolder\";\nimport { SSAOFolder } from \"./blades/ssaoFolder\";\nimport { ToneMappingFolder } from \"./blades/toneMappingFolder\";\nimport { setTweakpaneActive } from \"./tweakPaneActivity\";\nimport { tweakPaneStyle } from \"./tweakPaneStyle\";\n\nexport class TweakPane {\n private gui: Pane;\n\n private renderStatsFolder: RendererStatsFolder;\n private rendererFolder: RendererFolder;\n private toneMappingFolder: ToneMappingFolder;\n private ssaoFolder: SSAOFolder;\n private bcsFolder: BrightnessContrastSaturationFolder;\n private postExtrasFolder: PostExtrasFolder;\n // @ts-ignore\n private character: CharacterFolder;\n private environment: EnvironmentFolder;\n\n private export: FolderApi;\n\n private saveVisibilityInLocalStorage: boolean = true;\n public guiVisible: boolean = false;\n\n constructor(\n private renderer: WebGLRenderer,\n private scene: Scene,\n private composer: EffectComposer,\n ) {\n const appWrapper = document.getElementById(\"app\")!;\n const tweakPaneWrapper = document.createElement(\"div\");\n tweakPaneWrapper.id = \"tweakpane-panel\";\n appWrapper.appendChild(tweakPaneWrapper);\n\n this.gui = new Pane({ container: tweakPaneWrapper! });\n this.gui.registerPlugin(EssentialsPlugin);\n\n if (this.saveVisibilityInLocalStorage) {\n const localStorageGuiVisible = localStorage.getItem(\"guiVisible\");\n if (localStorageGuiVisible !== null) {\n if (localStorageGuiVisible === \"true\") {\n this.guiVisible = true;\n } else if (localStorageGuiVisible === \"false\") {\n this.guiVisible = false;\n }\n }\n }\n\n const styleElement = document.createElement(\"style\");\n styleElement.type = \"text/css\";\n styleElement.appendChild(document.createTextNode(tweakPaneStyle));\n document.head.appendChild(styleElement);\n\n this.renderStatsFolder = new RendererStatsFolder(this.gui, true);\n this.rendererFolder = new RendererFolder(this.gui, false);\n this.toneMappingFolder = new ToneMappingFolder(this.gui, false);\n this.ssaoFolder = new SSAOFolder(this.gui, false);\n this.bcsFolder = new BrightnessContrastSaturationFolder(this.gui, false);\n this.postExtrasFolder = new PostExtrasFolder(this.gui, false);\n this.character = new CharacterFolder(this.gui, false);\n this.environment = new EnvironmentFolder(this.gui, false);\n\n this.toneMappingFolder.folder.hidden = rendererValues.toneMapping === 5 ? false : true;\n\n this.export = this.gui.addFolder({ title: \"import / export\", expanded: false });\n\n window.addEventListener(\"keydown\", this.processKey.bind(this));\n this.setupRenderPane = this.setupRenderPane.bind(this);\n this.setupGUIListeners.bind(this)();\n }\n\n private setupGUIListeners(): void {\n const gui = this.gui as any;\n const paneElement: HTMLElement = gui.containerElem_;\n paneElement.style.right = this.guiVisible ? \"0px\" : \"-450px\";\n this.gui.element.addEventListener(\"mouseenter\", () => setTweakpaneActive(true));\n this.gui.element.addEventListener(\"mousedown\", () => setTweakpaneActive(true));\n this.gui.element.addEventListener(\"mouseup\", () => setTweakpaneActive(false));\n this.gui.element.addEventListener(\"mouseleave\", () => setTweakpaneActive(false));\n }\n\n private processKey(e: KeyboardEvent): void {\n if (e.key === \"p\") this.toggleGUI();\n }\n\n public setupRenderPane(\n composer: EffectComposer,\n normalPass: NormalPass,\n ppssaoEffect: SSAOEffect,\n ppssaoPass: EffectPass,\n n8aopass: any,\n toneMappingEffect: ToneMappingEffect,\n toneMappingPass: EffectPass,\n brightnessContrastSaturation: typeof BrightnessContrastSaturation,\n bloomEffect: BloomEffect,\n gaussGrainEffect: typeof GaussGrainEffect,\n hasLighting: boolean,\n sun: Sun | null,\n setHDR: () => void,\n setAmbientLight: () => void,\n setFog: () => void,\n ): void {\n // RenderOptions\n this.rendererFolder.setupChangeEvent(\n this.scene,\n this.renderer,\n this.toneMappingFolder.folder,\n toneMappingPass,\n );\n\n this.toneMappingFolder.setupChangeEvent(toneMappingEffect);\n this.ssaoFolder.setupChangeEvent(composer, normalPass, ppssaoEffect, ppssaoPass, n8aopass);\n this.bcsFolder.setupChangeEvent(brightnessContrastSaturation);\n this.postExtrasFolder.setupChangeEvent(bloomEffect, gaussGrainEffect);\n this.environment.setupChangeEvent(setHDR, setAmbientLight, setFog, sun);\n this.environment.folder.hidden = hasLighting === false || sun === null;\n\n const exportButton = this.export.addButton({ title: \"export\" });\n exportButton.on(\"click\", () => {\n this.downloadSettingsAsJSON(this.gui.exportState());\n });\n const importButton = this.export.addButton({ title: \"import\" });\n importButton.on(\"click\", () => {\n this.importSettingsFromJSON((settings) => {\n this.gui.importState(settings);\n });\n });\n }\n\n public updateStats(timeManager: TimeManager): void {\n this.renderStatsFolder.update(this.renderer, this.composer, timeManager);\n }\n\n private formatDateForFilename(): string {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\"); // Months are 0-11\n const day = String(date.getDate()).padStart(2, \"0\");\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${year}-${month}-${day} ${hours}-${minutes}-${seconds}`;\n }\n\n private downloadSettingsAsJSON(settings: any): void {\n const jsonString = JSON.stringify(settings, null, 2);\n const blob = new Blob([jsonString], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.download = `settings ${this.formatDateForFilename()}.json`;\n a.href = url;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n private importSettingsFromJSON(callback: (settings: any) => void): void {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \".json\";\n input.addEventListener(\"change\", (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = (loadEvent) => {\n try {\n const settings = JSON.parse(loadEvent.target?.result as string);\n callback(settings);\n } catch (err) {\n console.error(\"Error parsing JSON:\", err);\n }\n };\n reader.readAsText(file);\n }\n });\n input.click();\n }\n\n private toggleGUI(): void {\n this.guiVisible = !this.guiVisible;\n const gui = this.gui as any;\n const paneElement: HTMLElement = gui.containerElem_;\n paneElement.style.right = this.guiVisible ? \"0px\" : \"-450px\";\n if (this.saveVisibilityInLocalStorage) {\n localStorage.setItem(\"guiVisible\", this.guiVisible === true ? \"true\" : \"false\");\n }\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { BrightnessContrastSaturation } from \"../../rendering/post-effects/bright-contrast-sat\";\n\nexport const bcsValues = {\n brightness: 0,\n contrast: 1,\n saturation: 1,\n};\n\nconst bcsOptions = {\n brightness: {\n amount: { min: -1.0, max: 1.0, step: 0.01 },\n },\n contrast: {\n amount: { min: 0.0, max: 2.0, step: 0.01 },\n },\n saturation: {\n amount: { min: 0.0, max: 2.0, step: 0.01 },\n },\n};\n\nexport class BrightnessContrastSaturationFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"brightness / contrast / sat\",\n expanded: expand,\n });\n this.folder.addBinding(bcsValues, \"brightness\", bcsOptions.brightness.amount);\n this.folder.addBinding(bcsValues, \"contrast\", bcsOptions.contrast.amount);\n this.folder.addBinding(bcsValues, \"saturation\", bcsOptions.saturation.amount);\n }\n\n public setupChangeEvent(brightnessContrastSaturation: typeof BrightnessContrastSaturation): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"brightness\":\n brightnessContrastSaturation.uniforms.brightness.value = e.value;\n break;\n case \"contrast\":\n brightnessContrastSaturation.uniforms.contrast.value = e.value;\n break;\n case \"saturation\":\n brightnessContrastSaturation.uniforms.saturation.value = e.value;\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, ButtonApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { Sun } from \"../../sun/Sun\";\n\nexport const sunValues = {\n sunPosition: {\n sunAzimuthalAngle: 214.5,\n sunPolarAngle: -41.5,\n },\n sunIntensity: 1,\n sunColor: { r: 1.0, g: 1.0, b: 1.0 },\n};\n\nconst sunOptions = {\n sunPosition: {\n sunAzimuthalAngle: { min: 0, max: 360, step: 1 },\n sunPolarAngle: { min: -90, max: 90, step: 1 },\n },\n sunIntensity: { min: 0, max: 3, step: 0.05 },\n};\n\nexport const envValues = {\n ambientLight: {\n ambientLightIntensity: 0.05,\n ambientLightColor: { r: 1, g: 1, b: 1 },\n },\n fog: {\n fogNear: 30,\n fogFar: 210,\n fogColor: { r: 0.42, g: 0.48, b: 0.59 },\n },\n};\n\nconst envOptions = {\n ambientLight: {\n ambientLightIntensity: { min: 0, max: 1, step: 0.01 },\n },\n fog: {\n fogNear: { min: 0, max: 80, step: 1 },\n fogFar: { min: 81, max: 300, step: 1 },\n },\n};\n\nexport class EnvironmentFolder {\n public folder: FolderApi;\n private sun: FolderApi;\n private sunButton: ButtonApi;\n private ambient: FolderApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"environment\", expanded: expand });\n\n this.sun = this.folder.addFolder({ title: \"sun\", expanded: true });\n\n this.ambient = this.folder.addFolder({ title: \"ambient\", expanded: true });\n\n this.sun.addBinding(\n sunValues.sunPosition,\n \"sunAzimuthalAngle\",\n sunOptions.sunPosition.sunAzimuthalAngle,\n );\n this.sun.addBinding(\n sunValues.sunPosition,\n \"sunPolarAngle\",\n sunOptions.sunPosition.sunPolarAngle,\n );\n this.sun.addBinding(sunValues, \"sunIntensity\", sunOptions.sunIntensity);\n this.sun.addBinding(sunValues, \"sunColor\", {\n color: { type: \"float\" },\n });\n this.sunButton = this.sun.addButton({ title: \"Set HDRI\" });\n\n this.ambient.addBinding(\n envValues.ambientLight,\n \"ambientLightIntensity\",\n envOptions.ambientLight.ambientLightIntensity,\n );\n this.ambient.addBinding(envValues.ambientLight, \"ambientLightColor\", {\n color: { type: \"float\" },\n });\n this.ambient.addBinding(envValues.fog, \"fogNear\", envOptions.fog.fogNear);\n this.ambient.addBinding(envValues.fog, \"fogFar\", envOptions.fog.fogFar);\n this.ambient.addBinding(envValues.fog, \"fogColor\", {\n color: { type: \"float\" },\n });\n }\n\n public setupChangeEvent(\n setHDR: () => void,\n setAmbientLight: () => void,\n setFog: () => void,\n sun: Sun | null,\n ): void {\n this.sun.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"sunAzimuthalAngle\": {\n const value = e.value as number;\n sun?.setAzimuthalAngle(value * (Math.PI / 180));\n break;\n }\n case \"sunPolarAngle\": {\n const value = e.value as number;\n sun?.setPolarAngle(value * (Math.PI / 180));\n break;\n }\n case \"sunIntensity\": {\n const value = e.value as number;\n sun?.setIntensity(value);\n break;\n }\n case \"sunColor\": {\n const value = e.value as { r: number; g: number; b: number };\n sunValues.sunColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n sun?.setColor();\n break;\n }\n default:\n break;\n }\n });\n this.sunButton.on(\"click\", () => {\n setHDR();\n });\n this.ambient.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"ambientLightIntensity\": {\n envValues.ambientLight.ambientLightIntensity = e.value as number;\n setAmbientLight();\n break;\n }\n case \"ambientLightColor\": {\n const value = e.value as { r: number; g: number; b: number };\n envValues.ambientLight.ambientLightColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n setAmbientLight();\n break;\n }\n case \"fogNear\": {\n envValues.fog.fogNear = e.value as number;\n setFog();\n break;\n }\n case \"fogFar\": {\n envValues.fog.fogFar = e.value as number;\n setFog();\n break;\n }\n case \"fogColor\": {\n const value = e.value as { r: number; g: number; b: number };\n envValues.fog.fogColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n setFog();\n break;\n }\n default:\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BloomEffect } from \"postprocessing\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { GaussGrainEffect } from \"../../rendering/post-effects/gauss-grain\";\n\nexport const extrasValues = {\n grain: 0.055,\n bloom: 3,\n};\n\nconst extrasOptions = {\n grain: {\n amount: { min: 0, max: 0.2, step: 0.002 },\n },\n bloom: {\n amount: { min: 0, max: 5, step: 0.05 },\n },\n};\n\nexport class PostExtrasFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"bloom / grain\", expanded: expand });\n this.folder.addBinding(extrasValues, \"bloom\", extrasOptions.bloom.amount);\n this.folder.addBinding(extrasValues, \"grain\", extrasOptions.grain.amount);\n }\n\n public setupChangeEvent(\n bloomEffect: BloomEffect,\n gaussGrainEffect: typeof GaussGrainEffect,\n ): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"bloom\":\n bloomEffect.intensity = e.value as number;\n break;\n case \"grain\":\n gaussGrainEffect.uniforms.amount.value = e.value as number;\n break;\n default:\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { EffectPass } from \"postprocessing\";\nimport { Scene, ShadowMapType, ToneMapping, WebGLRenderer } from \"three\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nexport const rendererValues = {\n shadowMap: 2,\n toneMapping: 5,\n exposure: 1,\n bgIntensity: 1,\n bgBlurriness: 0.0,\n};\n\nconst rendererOptions = {\n shadowMap: { min: 0, max: 2, step: 1 },\n toneMapping: { min: 0, max: 5, step: 1 },\n exposure: { min: 0, max: 3, step: 0.01 },\n bgIntensity: { min: 0, max: 1.3, step: 0.01 },\n bgBlurriness: { min: 0, max: 0.1, step: 0.001 },\n};\n\nconst shadowMapTypes: Record<number, string> = {\n 0: \"BasicShadowMap\",\n 1: \"PCFShadowMap\",\n 2: \"PCFSoftShadowMap\",\n};\n\nconst toneMappingTypes: Record<number, string> = {\n 0: \"NoToneMapping\",\n 1: \"LinearToneMapping\",\n 2: \"ReinhardToneMapping\",\n 3: \"CineonToneMapping\",\n 4: \"ACESFilmicToneMapping\",\n 5: \"CustomToneMapping\",\n};\n\nconst monitoredValues = {\n shadowMapType: shadowMapTypes[rendererValues.shadowMap],\n toneMappingType: toneMappingTypes[rendererValues.toneMapping],\n};\n\nconst setShadowMapType = (value: number): void => {\n monitoredValues.shadowMapType = shadowMapTypes[value];\n};\n\nconst setToneMappingType = (value: number): void => {\n monitoredValues.toneMappingType = toneMappingTypes[value];\n};\n\nexport class RendererFolder {\n private folder: FolderApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"rendererOptions\",\n expanded: expand,\n });\n\n this.folder.addBinding(rendererValues, \"shadowMap\", rendererOptions.shadowMap);\n this.folder.addBinding(monitoredValues, \"shadowMapType\", { readonly: true });\n this.folder.addBinding(rendererValues, \"toneMapping\", rendererOptions.toneMapping);\n this.folder.addBinding(monitoredValues, \"toneMappingType\", { readonly: true });\n this.folder.addBinding(rendererValues, \"exposure\", rendererOptions.exposure);\n this.folder.addBinding(rendererValues, \"bgIntensity\", rendererOptions.bgIntensity);\n this.folder.addBinding(rendererValues, \"bgBlurriness\", rendererOptions.bgBlurriness);\n }\n\n public setupChangeEvent(\n scene: Scene,\n renderer: WebGLRenderer,\n toneMappingFolder: FolderApi,\n toneMappingPass: EffectPass,\n ): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"shadowMap\": {\n const value = e.value as ShadowMapType;\n renderer.shadowMap.type = value;\n setShadowMapType(value);\n break;\n }\n case \"toneMapping\":\n renderer.toneMapping = e.value as ToneMapping;\n toneMappingFolder.hidden = e.value !== 5;\n toneMappingPass.enabled = e.value === 5 ? true : false;\n setToneMappingType(e.value as ToneMapping);\n break;\n case \"exposure\":\n renderer.toneMappingExposure = e.value as number;\n break;\n case \"bgIntensity\":\n scene.backgroundIntensity = e.value as number;\n break;\n case \"bgBlurriness\":\n scene.backgroundBlurriness = e.value as number;\n break;\n default:\n break;\n }\n });\n }\n}\n", "import { EffectComposer } from \"postprocessing\";\nimport { WebGLRenderer } from \"three\";\nimport { FolderApi } from \"tweakpane\";\n\nimport { TimeManager } from \"../../time/TimeManager\";\n\ntype StatsData = {\n triangles: string;\n geometries: string;\n textures: string;\n shaders: string;\n postPasses: string;\n drawCalls: string;\n rawDeltaTime: string;\n deltaTime: string;\n FPS: string;\n};\n\nexport class RendererStatsFolder {\n private folder: FolderApi;\n private performance: FolderApi;\n private defails: FolderApi;\n\n private statsData: StatsData = {\n triangles: \"0\",\n geometries: \"0\",\n textures: \"0\",\n shaders: \"0\",\n postPasses: \"0\",\n drawCalls: \"0\",\n rawDeltaTime: \"0\",\n deltaTime: \"0\",\n FPS: \"0\",\n };\n\n constructor(parentFolder: FolderApi, expanded: boolean = true) {\n this.folder = parentFolder.addFolder({ title: \"renderStats\", expanded: expanded });\n this.folder.addBinding(this.statsData, \"FPS\", { readonly: true });\n this.folder.addBinding(this.statsData, \"deltaTime\", { readonly: true });\n this.folder.addBinding(this.statsData, \"rawDeltaTime\", { readonly: true });\n this.folder.addBinding(this.statsData, \"triangles\", { readonly: true });\n this.folder.addBinding(this.statsData, \"geometries\", { readonly: true });\n this.folder.addBinding(this.statsData, \"textures\", { readonly: true });\n this.folder.addBinding(this.statsData, \"shaders\", { readonly: true });\n this.folder.addBinding(this.statsData, \"postPasses\", { readonly: true });\n this.folder.addBinding(this.statsData, \"drawCalls\", { readonly: true });\n }\n\n public update(renderer: WebGLRenderer, composer: EffectComposer, timeManager: TimeManager): void {\n const { geometries, textures } = renderer.info.memory;\n const { triangles, calls } = renderer.info.render;\n this.statsData.triangles = triangles.toString();\n this.statsData.geometries = geometries.toString();\n this.statsData.textures = textures.toString();\n this.statsData.shaders = renderer.info.programs!.length.toString();\n this.statsData.postPasses = composer.passes.length.toString();\n this.statsData.drawCalls = calls.toString();\n this.statsData.rawDeltaTime = (\n Math.round(timeManager.rawDeltaTime * 100000) / 100000\n ).toString();\n this.statsData.deltaTime = (Math.round(timeManager.deltaTime * 100000) / 100000).toString();\n this.statsData.FPS = timeManager.fps.toString();\n }\n}\n", "import { BindingApi, BladeApi, BladeController, TpChangeEvent, View } from \"@tweakpane/core\";\nimport { BlendFunction, EffectComposer, EffectPass, NormalPass, SSAOEffect } from \"postprocessing\";\nimport { Color } from \"three\";\nimport { FolderApi } from \"tweakpane\";\n\nexport const ppssaoValues = {\n enabled: false,\n blendFunction: BlendFunction.MULTIPLY,\n distanceScaling: true,\n depthAwareUpsampling: true,\n samples: 30,\n rings: 11,\n luminanceInfluence: 0.7,\n radius: 0.03,\n intensity: 2.5,\n bias: 0.05,\n fade: 0.03,\n resolutionScale: 0.5,\n color: { r: 0, g: 0, b: 0 },\n worldDistanceThreshold: 30,\n worldDistanceFalloff: 7,\n worldProximityThreshold: 0.5,\n worldProximityFalloff: 0.3,\n};\n\nconst ppssaoOptions = {\n samples: { min: 1, max: 50, step: 1 },\n rings: { min: 1, max: 50, step: 1 },\n luminanceInfluence: { min: 0, max: 1, step: 0.01 },\n radius: { min: 0, max: 0.1, step: 0.001 },\n intensity: { min: 0, max: 5, step: 0.1 },\n bias: { min: 0, max: 0.1, step: 0.001 },\n fade: { min: 0, max: 0.1, step: 0.001 },\n resolutionScale: { min: 0.25, max: 2, step: 0.25 },\n worldDistanceThreshold: { min: 0, max: 200, step: 1 },\n worldDistanceFalloff: { min: 0, max: 200, step: 1 },\n worldProximityThreshold: { min: 0, max: 2, step: 0.01 },\n worldProximityFalloff: { min: 0, max: 2, step: 0.01 },\n};\n\nexport const n8ssaoValues = {\n enabled: true,\n halfRes: true,\n aoRadius: 5,\n distanceFalloff: 3.0,\n intensity: 1.0,\n color: { r: 0, g: 0, b: 0 },\n aoSamples: 16,\n denoiseSamples: 4,\n denoiseRadius: 12,\n viewMode: \"Combined\",\n};\n\nexport const n8ssaoOptions = {\n radius: { min: 0.1, max: 6, step: 0.1 },\n distanceFalloff: { min: 1, max: 6, step: 0.1 },\n intensity: { min: 0.1, max: 5, step: 0.1 },\n aoSamples: [2, 4, 8, 16, 32, 64],\n denoiseSamples: [2, 4, 8, 16, 32, 64],\n denoiseRadius: [3, 6, 12],\n viewMode: [\"Combined\", \"AO\", \"No AO\", \"Split\", \"Split AO\", \"No AO\"],\n};\n\nconst ssaoMaterialParams = [\n \"fade\",\n \"bias\",\n \"minRadiusScale\",\n \"worldDistanceThreshold\",\n \"worldDistanceFalloff\",\n \"worldProximityThreshold\",\n \"worldProximityFalloff\",\n];\n\nexport class SSAOFolder {\n private folder: FolderApi;\n\n private ppssao: FolderApi;\n private n8ssao: FolderApi;\n\n private aoSamples: BindingApi;\n private denoiseSamples: BindingApi;\n private denoiseRadius: BindingApi;\n private aoDisplay: BindingApi;\n\n private postProcessingSSAOIndex: number = 1;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"ambientOcclusion\", expanded: expand });\n this.n8ssao = this.folder.addFolder({\n title: \"N8 ambientOcclusion\",\n expanded: n8ssaoValues.enabled,\n });\n this.ppssao = this.folder.addFolder({\n title: \"PP ambientOcclusion\",\n expanded: ppssaoValues.enabled,\n });\n\n // Post-processing SSAO\n {\n this.ppssao.addBinding({ enabled: ppssaoValues.enabled }, \"enabled\");\n this.ppssao.addBinding({ showEffectOnly: false }, \"showEffectOnly\");\n this.ppssao.addBinding(ppssaoValues, \"samples\", ppssaoOptions.samples);\n this.ppssao.addBinding(ppssaoValues, \"rings\", ppssaoOptions.rings);\n this.ppssao.addBinding(ppssaoValues, \"luminanceInfluence\", ppssaoOptions.luminanceInfluence);\n this.ppssao.addBinding(ppssaoValues, \"radius\", ppssaoOptions.radius);\n this.ppssao.addBinding(ppssaoValues, \"intensity\", ppssaoOptions.intensity);\n this.ppssao.addBinding(ppssaoValues, \"bias\", ppssaoOptions.bias);\n this.ppssao.addBinding(ppssaoValues, \"fade\", ppssaoOptions.fade);\n this.ppssao.addBinding(ppssaoValues, \"resolutionScale\", ppssaoOptions.resolutionScale);\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldDistanceThreshold\",\n ppssaoOptions.worldDistanceThreshold,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldDistanceFalloff\",\n ppssaoOptions.worldDistanceFalloff,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldProximityThreshold\",\n ppssaoOptions.worldProximityThreshold,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldProximityFalloff\",\n ppssaoOptions.worldProximityFalloff,\n );\n this.ppssao.addBinding(ppssaoValues, \"color\", { color: { alpha: false, type: \"float\" } });\n }\n\n // N8 SSAO\n {\n this.n8ssao.addBinding({ enabled: n8ssaoValues.enabled }, \"enabled\");\n this.n8ssao.addBinding({ halfRes: n8ssaoValues.halfRes }, \"halfRes\");\n this.n8ssao.addBinding(n8ssaoValues, \"aoRadius\", n8ssaoOptions.radius);\n this.n8ssao.addBinding(n8ssaoValues, \"distanceFalloff\", n8ssaoOptions.distanceFalloff);\n this.n8ssao.addBinding(n8ssaoValues, \"intensity\", n8ssaoOptions.intensity);\n this.n8ssao.addBinding(n8ssaoValues, \"color\", { color: { alpha: false, type: \"float\" } });\n\n this.aoSamples = this.n8ssao.addBinding(n8ssaoValues, \"aoSamples\", {\n view: \"radiogrid\",\n groupName: \"aoSamples\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.aoSamples[y * 3 + x]}`,\n value: n8ssaoOptions.aoSamples[y * 3 + x],\n }),\n label: \"aoSamples\",\n });\n\n this.denoiseSamples = this.n8ssao.addBinding(n8ssaoValues, \"denoiseSamples\", {\n view: \"radiogrid\",\n groupName: \"denoiseSamples\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.denoiseSamples[y * 3 + x]}`,\n value: n8ssaoOptions.denoiseSamples[y * 3 + x],\n }),\n label: \"denoiseSamples\",\n });\n\n this.denoiseRadius = this.n8ssao.addBinding(n8ssaoValues, \"denoiseRadius\", {\n view: \"radiogrid\",\n groupName: \"denoiseRadius\",\n size: [3, 1],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.denoiseRadius[y * 3 + x]}`,\n value: n8ssaoOptions.denoiseRadius[y * 3 + x],\n }),\n label: \"denoiseRadius\",\n });\n\n this.aoDisplay = this.n8ssao.addBinding(n8ssaoValues, \"viewMode\", {\n view: \"radiogrid\",\n groupName: \"viewMode\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.viewMode[y * 3 + x]}`,\n value: `${n8ssaoOptions.viewMode[y * 3 + x]}`,\n }),\n label: \"viewMode\",\n });\n }\n\n this.folder.addBlade({ view: \"separator\" });\n }\n\n public setupChangeEvent(\n composer: EffectComposer,\n normalPass: NormalPass,\n ppssaoEffect: SSAOEffect,\n ppssaoPass: EffectPass,\n n8aopass: any,\n ): void {\n this.ppssao.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"enabled\": {\n const value = e.value as boolean;\n if (e.value === true) {\n composer.addPass(normalPass, this.postProcessingSSAOIndex);\n composer.addPass(ppssaoPass, this.postProcessingSSAOIndex + 1);\n } else {\n composer.removePass(ppssaoPass);\n composer.removePass(normalPass);\n }\n ppssaoValues.enabled = value;\n normalPass.enabled = value;\n ppssaoPass.enabled = value;\n break;\n }\n case \"showEffectOnly\": {\n const value = e.value as boolean;\n const blend = value === true ? BlendFunction.NORMAL : BlendFunction.MULTIPLY;\n ppssaoEffect.blendMode.blendFunction = blend;\n break;\n }\n case \"resolutionScale\": {\n const value = e.value as number;\n ppssaoEffect.resolution.scale = value;\n break;\n }\n case \"color\": {\n const value = e.value as { r: number; g: number; b: number };\n ppssaoEffect.color = new Color().setRGB(value.r, value.g, value.b);\n break;\n }\n default: {\n break;\n }\n }\n\n if (ssaoMaterialParams.includes(target)) {\n (ppssaoEffect.ssaoMaterial as any)[target] = e.value;\n return;\n }\n (ppssaoEffect as any)[target] = e.value;\n });\n\n this.n8ssao.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"enabled\":\n if (e.value === true) {\n composer.addPass(n8aopass, this.postProcessingSSAOIndex + 2);\n } else {\n composer.removePass(n8aopass);\n }\n n8aopass.enabled = e.value;\n break;\n case \"halfRes\":\n n8aopass.configuration.halfRes = e.value;\n break;\n case \"aoRadius\":\n n8aopass.configuration.aoRadius = e.value;\n break;\n case \"distanceFalloff\":\n n8aopass.configuration.distanceFalloff = e.value;\n break;\n case \"intensity\":\n n8aopass.configuration.intensity = e.value;\n break;\n case \"color\":\n const value = (e as any).value;\n n8aopass.configuration.color = new Color().setRGB(value.r, value.g, value.b);\n break;\n default:\n break;\n }\n });\n\n this.aoSamples.on(\"change\", (e: any) => {\n n8aopass.configuration.aoSamples = e.value;\n });\n\n this.denoiseSamples.on(\"change\", (e: any) => {\n n8aopass.configuration.denoiseSamples = e.value;\n });\n\n this.denoiseRadius.on(\"change\", (e: any) => {\n n8aopass.configuration.denoiseRadius = e.value;\n });\n\n this.aoDisplay.on(\"change\", (e: any) => {\n n8aopass.setDisplayMode(e.value);\n });\n }\n}\n", "import { BindingApi, BladeApi, BladeController, TpChangeEvent, View } from \"@tweakpane/core\";\nimport { ToneMappingEffect, ToneMappingMode } from \"postprocessing\";\nimport { FolderApi } from \"tweakpane\";\n\nexport const toneMappingValues = {\n mode: 2 as ToneMappingMode,\n resolution: 512,\n whitePoint: 32.0,\n middleGrey: 21.0,\n minLuminance: 0.01,\n averageLuminance: 0.01,\n adaptationRate: 2.0,\n};\n\nconst toneMappingOptions = {\n mode: { min: 0, max: 4, step: 1 },\n resolution: { min: 64, max: 512, step: 64 },\n whitePoint: { min: 0, max: 32, step: 0.01 },\n middleGrey: { min: 0, max: 32, step: 0.01 },\n minLuminance: { min: 0, max: 32, step: 0.001 },\n averageLuminance: { min: 0.001, max: 0.2, step: 0.001 },\n adaptationRate: { min: 0.1, max: 2.0, step: 0.1 },\n};\n\nconst customToneMappingTypes: Record<number, string> = {\n 0: \"REINHARD\",\n 1: \"REINHARD2\",\n 2: \"REINHARD2_ADAPTIVE\",\n 3: \"OPTIMIZED_CINEON\",\n 4: \"ACES_FILMIC\",\n};\n\nconst customToneMappingBlade = {\n customToneMappingType: customToneMappingTypes[toneMappingValues.mode],\n};\n\nconst setCustomToneMappingType = (value: number): void => {\n customToneMappingBlade.customToneMappingType = customToneMappingTypes[value];\n};\n\nexport class ToneMappingFolder {\n public folder: FolderApi;\n private minLuminance: BindingApi;\n private avgLuminance: BindingApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"customToneMapping\",\n expanded: expand,\n });\n this.folder.addBinding(toneMappingValues, \"mode\", toneMappingOptions.mode);\n this.folder.addBinding(customToneMappingBlade, \"customToneMappingType\", { readonly: true });\n this.folder.addBinding(toneMappingValues, \"whitePoint\", toneMappingOptions.whitePoint);\n this.folder.addBinding(toneMappingValues, \"middleGrey\", toneMappingOptions.middleGrey);\n this.minLuminance = this.folder.addBinding(\n toneMappingValues,\n \"minLuminance\",\n toneMappingOptions.minLuminance,\n );\n this.minLuminance.hidden = toneMappingValues.mode === 2 ? true : false;\n this.avgLuminance = this.folder.addBinding(\n toneMappingValues,\n \"averageLuminance\",\n toneMappingOptions.averageLuminance,\n );\n this.avgLuminance.hidden = toneMappingValues.mode === 2 ? true : false;\n this.folder.addBinding(toneMappingValues, \"adaptationRate\", toneMappingOptions.adaptationRate);\n }\n\n public setupChangeEvent(toneMappingEffect: ToneMappingEffect): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n if (target === \"mode\") {\n this.minLuminance.hidden = toneMappingValues.mode === 2 ? true : false;\n this.avgLuminance.hidden = toneMappingValues.mode === 2 ? true : false;\n setCustomToneMappingType(e.value as number);\n }\n (toneMappingEffect as any)[target] = e.value;\n return;\n });\n }\n}\n", "export const tweakPaneStyle = `\n:root {\n --tp-base-background-color: rgba(12, 12, 12, 0.6);\n --tp-base-shadow-color: hsla(0, 0%, 0%, 0.2);\n --tp-button-background-color: hsla(0, 0%, 80%, 1);\n --tp-button-background-color-active: hsla(0, 0%, 100%, 1);\n --tp-button-background-color-focus: hsla(0, 0%, 95%, 1);\n --tp-button-background-color-hover: hsla(0, 0%, 85%, 1);\n --tp-button-foreground-color: hsla(0, 0%, 0%, 0.7);\n --tp-container-background-color: hsla(0, 0%, 0%, 0.3);\n --tp-container-background-color-active: hsla(0, 0%, 0%, 0.6);\n --tp-container-background-color-focus: hsla(0, 0%, 0%, 0.5);\n --tp-container-background-color-hover: hsla(0, 0%, 0%, 0.4);\n --tp-container-foreground-color: hsla(0, 0%, 90%, 0.6);\n --tp-groove-foreground-color: hsla(0, 0%, 0%, 0.2);\n --tp-input-background-color: hsla(0, 0%, 30%, 0.3);\n --tp-input-background-color-active: hsla(0, 0%, 0%, 0.6);\n --tp-input-background-color-focus: hsla(0, 0%, 0%, 0.5);\n --tp-input-background-color-hover: hsla(0, 0%, 0%, 0.4);\n --tp-input-foreground-color: hsla(0, 0%, 100%, 0.6);\n --tp-label-foreground-color: hsla(0, 0%, 100%, 0.6);\n --tp-monitor-background-color: hsla(0, 0%, 0%, 0.3);\n --tp-monitor-foreground-color: hsla(0, 0%, 100%, 0.3);\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-brkv {\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-dfwv {\n z-index: 100;\n color: white;\n width: 600px !important;\n display: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-fldv {\n margin: 1px 0px 0px 0px !important;\n}\n\n.tp-fldv_b {\n overflow: visible !important;\n}\n\n.tp-fldv_t {\n font-size: 13px;\n font-weight: 900;\n color: #ffffff;\n background-color: rgba(70, 70, 70, 0.3);\n border-top: 1px solid rgba(210, 210, 210, 0.1);\n border-radius: 3px;\n}\n\n.tp-lblv_l {\n font-size: 12px;\n padding-left: 0px !important;\n padding-right: 0px !important;\n}\n\n.tp-lblv_v {\n width: 150px;\n}\n\n.tp-sldtxtv_t {\n max-width: 50px;\n}\n\n.tp-sglv_i {\n font-size: 12px;\n color: rgba(255, 255, 255, 0.7);\n}\n\n.tp-ckbv_w {\n border: 1px solid rgba(200, 200, 250, 0.2);\n}\n`;\n", "import {\n EffectComposer,\n RenderPass,\n EffectPass,\n FXAAEffect,\n ShaderPass,\n BloomEffect,\n SSAOEffect,\n BlendFunction,\n TextureEffect,\n ToneMappingEffect,\n SMAAEffect,\n SMAAPreset,\n EdgeDetectionMode,\n PredicationMode,\n NormalPass,\n} from \"postprocessing\";\nimport {\n AmbientLight,\n Color,\n Fog,\n HalfFloatType,\n LinearSRGBColorSpace,\n LoadingManager,\n PMREMGenerator,\n PerspectiveCamera,\n SRGBColorSpace,\n Scene,\n ShadowMapType,\n ToneMapping,\n Vector2,\n WebGLRenderer,\n} from \"three\";\nimport { RGBELoader } from \"three/examples/jsm/loaders/RGBELoader.js\";\n\nimport { Sun } from \"../sun/Sun\";\nimport { TimeManager } from \"../time/TimeManager\";\nimport { bcsValues } from \"../tweakpane/blades/bcsFolder\";\nimport { envValues } from \"../tweakpane/blades/environmentFolder\";\nimport { extrasValues } from \"../tweakpane/blades/postExtrasFolder\";\nimport { rendererValues } from \"../tweakpane/blades/rendererFolder\";\nimport { n8ssaoValues, ppssaoValues } from \"../tweakpane/blades/ssaoFolder\";\nimport { toneMappingValues } from \"../tweakpane/blades/toneMappingFolder\";\nimport { TweakPane } from \"../tweakpane/TweakPane\";\n\nimport { BrightnessContrastSaturation } from \"./post-effects/bright-contrast-sat\";\nimport { GaussGrainEffect } from \"./post-effects/gauss-grain\";\nimport { N8SSAOPass } from \"./post-effects/n8-ssao/N8SSAOPass\";\n\nexport class Composer {\n private width: number = 1;\n private height: number = 1;\n private resizeListener: () => void;\n\n public resolution: Vector2 = new Vector2(this.width, this.height);\n\n private isEnvHDRI: boolean = false;\n\n private readonly scene: Scene;\n public postPostScene: Scene;\n private readonly camera: PerspectiveCamera;\n public readonly renderer: WebGLRenderer;\n\n public readonly effectComposer: EffectComposer;\n private readonly renderPass: RenderPass;\n\n private readonly normalPass: NormalPass;\n private readonly normalTextureEffect: TextureEffect;\n private readonly ppssaoEffect: SSAOEffect;\n private readonly ppssaoPass: EffectPass;\n private readonly n8aopass: N8SSAOPass;\n\n private readonly fxaaEffect: FXAAEffect;\n private readonly fxaaPass: EffectPass;\n private readonly bloomEffect: BloomEffect;\n private readonly bloomPass: EffectPass;\n private readonly toneMappingEffect: ToneMappingEffect;\n private readonly smaaEffect: SMAAEffect;\n\n private readonly toneMappingPass: EffectPass;\n private readonly smaaPass: EffectPass;\n\n private readonly bcs = BrightnessContrastSaturation;\n private readonly bcsPass: ShaderPass;\n\n private readonly gaussGrainEffect = GaussGrainEffect;\n private readonly gaussGrainPass: ShaderPass;\n\n private ambientLight: AmbientLight | null = null;\n\n public sun: Sun | null = null;\n public spawnSun: boolean;\n\n constructor(scene: Scene, camera: PerspectiveCamera, spawnSun: boolean = false) {\n this.scene = scene;\n this.postPostScene = new Scene();\n this.camera = camera;\n this.spawnSun = spawnSun;\n this.renderer = new WebGLRenderer({\n powerPreference: \"high-performance\",\n antialias: false,\n stencil: false,\n depth: false,\n });\n this.renderer.outputColorSpace = SRGBColorSpace;\n this.renderer.info.autoReset = false;\n this.renderer.setSize(this.width, this.height);\n this.renderer.shadowMap.enabled = true;\n this.renderer.shadowMap.type = rendererValues.shadowMap as ShadowMapType;\n this.renderer.toneMapping = rendererValues.toneMapping as ToneMapping;\n this.renderer.toneMappingExposure = rendererValues.exposure;\n\n this.setAmbientLight();\n this.setFog();\n\n this.effectComposer = new EffectComposer(this.renderer, {\n frameBufferType: HalfFloatType,\n });\n\n this.renderPass = new RenderPass(this.scene, this.camera);\n\n this.normalPass = new NormalPass(this.scene, this.camera);\n this.normalPass.enabled = ppssaoValues.enabled;\n this.normalTextureEffect = new TextureEffect({\n blendFunction: BlendFunction.SKIP,\n texture: this.normalPass.texture,\n });\n this.ppssaoEffect = new SSAOEffect(this.camera, this.normalPass.texture, {\n blendFunction: ppssaoValues.blendFunction,\n distanceScaling: ppssaoValues.distanceScaling,\n depthAwareUpsampling: ppssaoValues.depthAwareUpsampling,\n samples: ppssaoValues.samples,\n rings: ppssaoValues.rings,\n luminanceInfluence: ppssaoValues.luminanceInfluence,\n radius: ppssaoValues.radius,\n intensity: ppssaoValues.intensity,\n bias: ppssaoValues.bias,\n fade: ppssaoValues.fade,\n resolutionScale: ppssaoValues.resolutionScale,\n color: new Color().setRGB(ppssaoValues.color.r, ppssaoValues.color.g, ppssaoValues.color.b),\n worldDistanceThreshold: ppssaoValues.worldDistanceThreshold,\n worldDistanceFalloff: ppssaoValues.worldDistanceFalloff,\n worldProximityThreshold: ppssaoValues.worldProximityThreshold,\n worldProximityFalloff: ppssaoValues.worldProximityFalloff,\n });\n this.ppssaoPass = new EffectPass(this.camera, this.ppssaoEffect, this.normalTextureEffect);\n this.ppssaoPass.enabled = ppssaoValues.enabled;\n\n this.fxaaEffect = new FXAAEffect();\n this.bloomEffect = new BloomEffect({\n intensity: extrasValues.bloom,\n });\n\n this.n8aopass = new N8SSAOPass(this.scene, this.camera, this.width, this.height);\n this.n8aopass.configuration.aoRadius = n8ssaoValues.aoRadius;\n this.n8aopass.configuration.distanceFalloff = n8ssaoValues.distanceFalloff;\n this.n8aopass.configuration.intensity = n8ssaoValues.intensity;\n this.n8aopass.configuration.color = new Color().setRGB(\n n8ssaoValues.color.r,\n n8ssaoValues.color.g,\n n8ssaoValues.color.b,\n );\n this.n8aopass.configuration.aoSamples = n8ssaoValues.aoSamples;\n this.n8aopass.configuration.denoiseSamples = n8ssaoValues.denoiseSamples;\n this.n8aopass.configuration.denoiseRadius = n8ssaoValues.denoiseRadius;\n this.n8aopass.enabled = n8ssaoValues.enabled;\n\n this.fxaaPass = new EffectPass(this.camera, this.fxaaEffect);\n this.bloomPass = new EffectPass(this.camera, this.bloomEffect);\n\n this.toneMappingEffect = new ToneMappingEffect({\n mode: toneMappingValues.mode,\n resolution: toneMappingValues.resolution,\n whitePoint: toneMappingValues.whitePoint,\n middleGrey: toneMappingValues.middleGrey,\n minLuminance: toneMappingValues.minLuminance,\n averageLuminance: toneMappingValues.averageLuminance,\n adaptationRate: toneMappingValues.adaptationRate,\n });\n this.smaaEffect = new SMAAEffect({\n preset: SMAAPreset.ULTRA,\n edgeDetectionMode: EdgeDetectionMode.COLOR,\n predicationMode: PredicationMode.DEPTH,\n });\n\n this.toneMappingPass = new EffectPass(this.camera, this.toneMappingEffect);\n this.toneMappingPass.enabled =\n rendererValues.toneMapping === 5 || rendererValues.toneMapping === 0 ? true : false;\n\n this.bcsPass = new ShaderPass(this.bcs, \"tDiffuse\");\n this.bcs.uniforms.brightness.value = bcsValues.brightness;\n this.bcs.uniforms.contrast.value = bcsValues.contrast;\n this.bcs.uniforms.saturation.value = bcsValues.saturation;\n\n this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, \"tDiffuse\");\n this.smaaPass = new EffectPass(this.camera, this.smaaEffect);\n\n this.effectComposer.addPass(this.renderPass);\n if (ppssaoValues.enabled) {\n this.effectComposer.addPass(this.normalPass);\n this.effectComposer.addPass(this.ppssaoPass);\n }\n if (n8ssaoValues.enabled) {\n this.effectComposer.addPass(this.n8aopass);\n }\n this.effectComposer.addPass(this.fxaaPass);\n this.effectComposer.addPass(this.smaaPass);\n this.effectComposer.addPass(this.bloomPass);\n this.effectComposer.addPass(this.toneMappingPass);\n this.effectComposer.addPass(this.bcsPass);\n this.effectComposer.addPass(this.gaussGrainPass);\n\n if (this.spawnSun === true) {\n this.sun = new Sun();\n this.scene.add(this.sun);\n }\n\n this.resizeListener = () => {\n this.fitContainer();\n };\n window.addEventListener(\"resize\", this.resizeListener, false);\n this.fitContainer();\n }\n\n public setupTweakPane(tweakPane: TweakPane) {\n tweakPane.setupRenderPane(\n this.effectComposer,\n this.normalPass,\n this.ppssaoEffect,\n this.ppssaoPass,\n this.n8aopass,\n this.toneMappingEffect,\n this.toneMappingPass,\n this.bcs,\n this.bloomEffect,\n this.gaussGrainEffect,\n this.spawnSun,\n this.sun,\n this.setHDRIFromFile.bind(this),\n this.setAmbientLight.bind(this),\n this.setFog.bind(this),\n );\n }\n\n public dispose() {\n window.removeEventListener(\"resize\", this.resizeListener);\n }\n\n public fitContainer() {\n if (!this) {\n console.error(\"Composer not initialized\");\n return;\n }\n const parentElement = this.renderer.domElement.parentNode as HTMLElement;\n if (!parentElement) {\n return;\n }\n this.width = parentElement.clientWidth;\n this.height = parentElement.clientHeight;\n this.camera.aspect = this.width / this.height;\n this.camera.updateProjectionMatrix();\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.resolution.set(\n this.width * window.devicePixelRatio,\n this.height * window.devicePixelRatio,\n );\n this.effectComposer.setSize(\n this.width / window.devicePixelRatio,\n this.height / window.devicePixelRatio,\n );\n this.renderPass.setSize(this.width, this.height);\n if (ppssaoValues.enabled) {\n this.normalPass.setSize(this.width, this.height);\n this.normalTextureEffect.setSize(this.width, this.height);\n this.ppssaoPass.setSize(this.width, this.height);\n }\n if (n8ssaoValues.enabled) {\n this.n8aopass.setSize(this.width, this.height);\n }\n this.fxaaPass.setSize(this.width, this.height);\n this.smaaPass.setSize(this.width, this.height);\n this.bloomPass.setSize(this.width, this.height);\n this.toneMappingPass.setSize(this.width, this.height);\n this.gaussGrainPass.setSize(this.width, this.height);\n this.renderer.setSize(this.width, this.height);\n }\n\n public render(timeManager: TimeManager): void {\n this.renderer.info.reset();\n this.normalPass.texture.needsUpdate = true;\n this.gaussGrainEffect.uniforms.resolution.value = this.resolution;\n this.gaussGrainEffect.uniforms.time.value = timeManager.time;\n this.gaussGrainEffect.uniforms.alpha.value = 1.0;\n this.effectComposer.render();\n this.renderer.render(this.postPostScene, this.camera);\n }\n\n public useHDRI(url: string, fromFile: boolean = false): void {\n if ((this.isEnvHDRI && fromFile === false) || !this.renderer) return;\n const pmremGenerator = new PMREMGenerator(this.renderer);\n new RGBELoader(new LoadingManager()).load(\n url,\n (texture) => {\n const envMap = pmremGenerator!.fromEquirectangular(texture).texture;\n if (envMap) {\n envMap.colorSpace = LinearSRGBColorSpace;\n envMap.needsUpdate = true;\n this.scene.background = envMap;\n this.scene.backgroundIntensity = rendererValues.bgIntensity;\n this.isEnvHDRI = true;\n texture.dispose();\n pmremGenerator!.dispose();\n }\n },\n () => {},\n (error: ErrorEvent) => {\n console.error(`Can't load ${url}: ${JSON.stringify(error)}`);\n },\n );\n }\n\n public setHDRIFromFile(): void {\n if (!this.renderer) return;\n const fileInput = document.createElement(\"input\");\n fileInput.type = \"file\";\n fileInput.accept = \".hdr\";\n fileInput.addEventListener(\"change\", () => {\n const file = fileInput.files?.[0];\n if (!file) {\n console.log(\"no file\");\n return;\n }\n const fileURL = URL.createObjectURL(file);\n if (fileURL) {\n this.useHDRI(fileURL, true);\n URL.revokeObjectURL(fileURL);\n document.body.removeChild(fileInput);\n }\n });\n document.body.appendChild(fileInput);\n fileInput.click();\n }\n\n public setFog(): void {\n const fogColor = new Color().setRGB(\n envValues.fog.fogColor.r,\n envValues.fog.fogColor.g,\n envValues.fog.fogColor.b,\n );\n this.scene.fog = new Fog(fogColor, envValues.fog.fogNear, envValues.fog.fogFar);\n }\n\n public setAmbientLight(): void {\n if (this.ambientLight) {\n this.scene.remove(this.ambientLight);\n this.ambientLight.dispose();\n }\n const ambientLightColor = new Color().setRGB(\n envValues.ambientLight.ambientLightColor.r,\n envValues.ambientLight.ambientLightColor.g,\n envValues.ambientLight.ambientLightColor.b,\n );\n this.ambientLight = new AmbientLight(\n ambientLightColor,\n envValues.ambientLight.ambientLightIntensity,\n );\n this.scene.add(this.ambientLight);\n }\n}\n", "import { CameraHelper, Color, DirectionalLight, Group, OrthographicCamera, Vector3 } from \"three\";\n\nimport { sunValues } from \"../tweakpane/blades/environmentFolder\";\n\nexport class Sun extends Group {\n private readonly debug: boolean = false;\n private readonly sunOffset: Vector3 = new Vector3(\n sunValues.sunPosition.sunAzimuthalAngle * (Math.PI / 180),\n sunValues.sunPosition.sunPolarAngle * (Math.PI / 180),\n 100,\n );\n private readonly shadowResolution: number = 8192;\n private readonly shadowCamFrustum: number = 50;\n private readonly camHelper: CameraHelper | null = null;\n\n private readonly shadowCamera: OrthographicCamera;\n private readonly directionalLight: DirectionalLight;\n\n public target: Vector3 | null = null;\n\n constructor() {\n super();\n this.shadowCamera = new OrthographicCamera(\n -this.shadowCamFrustum,\n this.shadowCamFrustum,\n this.shadowCamFrustum,\n -this.shadowCamFrustum,\n 0.1,\n 200,\n );\n if (this.debug === true) {\n this.camHelper = new CameraHelper(this.shadowCamera);\n }\n this.directionalLight = new DirectionalLight(0xffffff, 0.5);\n this.directionalLight.intensity = sunValues.sunIntensity;\n this.directionalLight.shadow.normalBias = 0.01;\n this.directionalLight.shadow.radius = 0.02;\n this.directionalLight.shadow.camera = this.shadowCamera;\n this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);\n this.directionalLight.castShadow = true;\n this.setColor();\n\n this.updateCharacterPosition(new Vector3(0, 0, 0));\n\n this.add(this.directionalLight);\n if (this.debug === true && this.camHelper instanceof CameraHelper) {\n this.add(this.camHelper);\n }\n }\n\n public updateCharacterPosition(position: Vector3 | undefined) {\n if (!position) return;\n this.target = position;\n this.setSunPosition(this.sunOffset.x, this.sunOffset.y);\n }\n\n public setAzimuthalAngle(angle: number) {\n if (this.sunOffset) this.sunOffset.x = angle;\n if (this.target) this.updateCharacterPosition(this.target);\n }\n\n public setPolarAngle(angle: number) {\n if (this.sunOffset) this.sunOffset.y = angle;\n if (this.target) this.updateCharacterPosition(this.target);\n }\n\n public setIntensity(intensity: number) {\n this.directionalLight.intensity = intensity;\n }\n\n public setColor() {\n this.directionalLight.color = new Color().setRGB(\n sunValues.sunColor.r,\n sunValues.sunColor.g,\n sunValues.sunColor.b,\n );\n }\n\n private setSunPosition(azimuthalAngle: number, polarAngle: number) {\n if (!this.target) return;\n const distance = this.sunOffset.z;\n const sphericalPosition = new Vector3(\n distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),\n distance * Math.cos(polarAngle),\n distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle),\n );\n const newSunPosition = this.target.clone().add(sphericalPosition);\n this.directionalLight.position.set(newSunPosition.x, newSunPosition.y, newSunPosition.z);\n this.directionalLight.target.position.copy(this.target.clone());\n this.directionalLight.target.updateMatrixWorld();\n }\n}\n", "import { ShaderMaterial, Uniform } from \"three\";\n\nimport { vertexShader } from \"../shaders/vertex-shader\";\n\nexport const BrightnessContrastSaturation = new ShaderMaterial({\n uniforms: {\n tDiffuse: new Uniform(null),\n brightness: new Uniform(0.0),\n contrast: new Uniform(1.0),\n saturation: new Uniform(1.0),\n },\n vertexShader: vertexShader,\n fragmentShader: /* glsl */ `\n precision highp float;\n in vec2 vUv;\n\n uniform sampler2D tDiffuse;\n uniform float brightness;\n uniform float contrast;\n uniform float saturation;\n\n mat4 brightnessMatrix(float brightness) {\n return mat4(\n 1, 0, 0, 0,\n 0, 1, 0, 0,\n 0, 0, 1, 0,\n brightness, brightness, brightness, 1\n );\n }\n\n mat4 contrastMatrix(float contrast) {\n float t = (1.0 - contrast) / 2.0;\n\n return mat4(\n contrast, 0, 0, 0,\n 0, contrast, 0, 0,\n 0, 0, contrast, 0,\n t, t, t, 1\n );\n }\n\n mat4 saturationMatrix(float saturation) {\n vec3 luminance = vec3(0.3086, 0.6094, 0.0820);\n float oneMinusSat = 1.0 - saturation;\n vec3 red = vec3(luminance.x * oneMinusSat);\n red += vec3(saturation, 0, 0);\n vec3 green = vec3(luminance.y * oneMinusSat);\n green += vec3(0, saturation, 0);\n vec3 blue = vec3(luminance.z * oneMinusSat);\n blue += vec3(0, 0, saturation);\n return mat4(\n red, 0,\n green, 0,\n blue, 0,\n 0, 0, 0, 1\n );\n }\n\n void main(void) {\n vec4 color = texture(tDiffuse, vUv);\n gl_FragColor = (\n brightnessMatrix(brightness) *\n contrastMatrix(contrast) *\n saturationMatrix(saturation) *\n color\n );\n }\n `,\n dithering: true,\n});\n", "export const vertexShader = /* glsl */ `\n precision highp float;\n\n out vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `;\n", "import { ShaderMaterial, Uniform, Vector2 } from \"three\";\n\nimport { vertexShader } from \"../shaders/vertex-shader\";\n\nexport const GaussGrainEffect = new ShaderMaterial({\n uniforms: {\n tDiffuse: new Uniform(null),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n amount: new Uniform(0.0),\n alpha: new Uniform(0.0),\n },\n vertexShader: vertexShader,\n fragmentShader: /* glsl */ `\n precision highp float;\n in vec2 vUv;\n\n uniform sampler2D tDiffuse;\n uniform vec2 resolution;\n uniform float time;\n uniform float amount;\n uniform float alpha;\n\n const float PI = acos(-1.0);\n const float TAU = PI * 2.0;\n const float SQRTAU = sqrt(TAU);\n\n float gaussian(float z, float u, float o) {\n return (\n (1.0 / (o * SQRTAU)) *\n (exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))\n );\n }\n\n vec3 gaussgrain() {\n vec2 ps = vec2(1.0) / resolution.xy;\n vec2 uv = gl_FragCoord.xy * ps;\n float t = time;\n float seed = dot(uv, vec2(12.9898, 78.233));\n float noise = fract(sin(seed) * 43758.5453123 + t);\n noise = gaussian(noise, 0.0, 0.5);\n return vec3(noise);\n }\n\n void main(void) {\n vec2 uv = vUv;\n vec4 originalColor = texture(tDiffuse, uv);\n vec3 grain = gaussgrain();\n vec3 col = originalColor.rgb + (grain * amount);\n gl_FragColor = vec4(clamp(col, 0.0, 1.0), alpha);\n }\n `,\n dithering: true,\n});\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Pass } from \"postprocessing\";\nimport {\n Color,\n DataTexture,\n FloatType,\n Fog,\n FogExp2,\n HalfFloatType,\n LinearFilter,\n NearestFilter,\n NoColorSpace,\n OrthographicCamera,\n PerspectiveCamera,\n RGBAFormat,\n RedFormat,\n RepeatWrapping,\n Scene,\n ShaderMaterial,\n Texture,\n Uniform,\n Vector2,\n Vector3,\n WebGLMultipleRenderTargets,\n WebGLRenderTarget,\n WebGLRenderer,\n} from \"three\";\n\nimport { BlueNoise } from \"./BlueNoise\";\nimport { DepthDownSample } from \"./DepthDownSample\";\nimport { EffectCompositer } from \"./EffectCompositer\";\nimport { EffectShader } from \"./EffectShader\";\nimport { FullScreenTriangle } from \"./FullScreenTriangle\";\nimport { PoissionBlur } from \"./PoissionBlur\";\n\nconst bluenoiseBits: Uint8Array = Uint8Array.from(atob(BlueNoise), (c) => c.charCodeAt(0));\n\nexport type RenderModeType = \"Combined\" | \"AO\" | \"No AO\" | \"Split\" | \"Split AO\";\n\ntype PresetsType = \"Performance\" | \"Low\" | \"Medium\" | \"High\" | \"Ultra\";\n\ninterface IConfiguration {\n aoSamples: number;\n aoRadius: number;\n denoiseSamples: number;\n denoiseRadius: number;\n distanceFalloff: number;\n intensity: number;\n denoiseIterations: number;\n renderMode: number;\n color: Color;\n gammaCorrection: boolean;\n logarithmicDepthBuffer: boolean;\n screenSpaceRadius: boolean;\n halfRes: boolean;\n depthAwareUpsampling: boolean;\n colorMultiply: boolean;\n}\n\nfunction checkTimerQuery(\n timerQuery: WebGLQuery,\n gl: WebGL2RenderingContext,\n pass: N8SSAOPass,\n): void {\n const available = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT_AVAILABLE);\n if (available) {\n const elapsedTimeInNs = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT);\n const elapsedTimeInMs = elapsedTimeInNs / 1000000;\n pass.lastTime = elapsedTimeInMs;\n } else {\n setTimeout(() => checkTimerQuery(timerQuery, gl, pass), 1);\n }\n}\n\nclass N8SSAOPass extends Pass {\n private debugMode: boolean;\n\n public scene: Scene;\n public camera: PerspectiveCamera | OrthographicCamera;\n public lastTime: number = 0;\n\n private width: number;\n private height: number;\n\n public configuration: IConfiguration & ProxyHandler<IConfiguration>;\n\n private autosetGamma: boolean = true;\n private samples: Vector3[] = [];\n private samplesR: number[] = [];\n private samplesDenoise: Vector2[] = [];\n\n private copyQuadMaterial: ShaderMaterial = new ShaderMaterial({\n uniforms: { tDiffuse: new Uniform(null) },\n\n depthWrite: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }\n `,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D tDiffuse;\n varying vec2 vUv;\n void main(void) {\n gl_FragColor = texture2D(tDiffuse, vUv);\n }\n `,\n });\n\n private copyQuad: FullScreenTriangle = new FullScreenTriangle(this.copyQuadMaterial);\n\n private writeTargetInternal: WebGLRenderTarget;\n private readTargetInternal: WebGLRenderTarget;\n private outputTargetInternal: WebGLRenderTarget;\n private depthDownsampleTarget: WebGLMultipleRenderTargets | null;\n\n private depthDownsampleQuad: FullScreenTriangle | null;\n private effectShaderQuad: FullScreenTriangle | null;\n private effectCompositerQuad: FullScreenTriangle | null;\n private poissonBlurQuad: FullScreenTriangle | null;\n\n private depthTexture: Texture;\n private bluenoise: DataTexture;\n\n private r: Vector2;\n private c: Color;\n\n constructor(\n scene: Scene,\n camera: PerspectiveCamera | OrthographicCamera,\n width = 512,\n height = 512,\n ) {\n super();\n this.width = width;\n this.height = height;\n\n this.camera = camera;\n this.scene = scene;\n\n this.configuration = new Proxy(\n {\n aoSamples: 16,\n aoRadius: 5.0,\n denoiseSamples: 8,\n denoiseRadius: 12,\n distanceFalloff: 1.0,\n intensity: 5,\n denoiseIterations: 2.0,\n renderMode: 0,\n color: new Color(0, 0, 0),\n gammaCorrection: true,\n logarithmicDepthBuffer: false,\n screenSpaceRadius: false,\n halfRes: false,\n depthAwareUpsampling: true,\n colorMultiply: true,\n },\n {\n set: (target: any, propName: string, value: any) => {\n const oldProp = target[propName];\n target[propName] = value;\n if (propName === \"aoSamples\" && oldProp !== value) {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"denoiseSamples\" && oldProp !== value) {\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"halfRes\" && oldProp !== value) {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureHalfResTargets();\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n this.setSize(this.width, this.height);\n }\n if (propName === \"depthAwareUpsampling\" && oldProp !== value) {\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"gammaCorrection\") {\n this.autosetGamma = false;\n }\n return true;\n },\n },\n );\n\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n this.configureSampleDependentPasses();\n this.configureHalfResTargets();\n\n this.writeTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.readTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.outputTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.bluenoise = new DataTexture(bluenoiseBits, 128, 128);\n this.bluenoise.colorSpace = NoColorSpace;\n this.bluenoise.wrapS = RepeatWrapping;\n this.bluenoise.wrapT = RepeatWrapping;\n this.bluenoise.minFilter = NearestFilter;\n this.bluenoise.magFilter = NearestFilter;\n this.bluenoise.needsUpdate = true;\n this.lastTime = 0;\n this.needsDepthTexture = true;\n this.needsSwap = true;\n this.r = new Vector2();\n this.c = new Color();\n }\n\n private configureHalfResTargets(): void {\n if (this.configuration.halfRes) {\n this.depthDownsampleTarget = new WebGLMultipleRenderTargets(\n this.width / 2,\n this.height / 2,\n 2,\n {\n depthBuffer: false,\n },\n );\n this.depthDownsampleTarget.texture[0].format = RedFormat;\n this.depthDownsampleTarget.texture[0].type = FloatType;\n this.depthDownsampleTarget.texture[0].minFilter = NearestFilter;\n this.depthDownsampleTarget.texture[0].magFilter = NearestFilter;\n this.depthDownsampleTarget.texture[1].format = RGBAFormat;\n this.depthDownsampleTarget.texture[1].type = HalfFloatType;\n this.depthDownsampleTarget.texture[1].minFilter = NearestFilter;\n this.depthDownsampleTarget.texture[1].magFilter = NearestFilter;\n this.depthDownsampleQuad = new FullScreenTriangle(new ShaderMaterial(DepthDownSample));\n } else {\n if (this.depthDownsampleTarget) {\n this.depthDownsampleTarget.dispose();\n this.depthDownsampleTarget = null;\n }\n if (this.depthDownsampleQuad) {\n this.depthDownsampleQuad.dispose();\n this.depthDownsampleQuad = null;\n }\n }\n }\n\n private configureSampleDependentPasses(): void {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n }\n\n private configureAOPass(logarithmicDepthBuffer = false): void {\n this.samples = this.generateHemisphereSamples(this.configuration.aoSamples);\n this.samplesR = this.generateHemisphereSamplesR(this.configuration.aoSamples);\n const e = { ...EffectShader };\n e.fragmentShader = e.fragmentShader\n .replace(\"16\", this.configuration.aoSamples.toString())\n .replace(\"16.0\", this.configuration.aoSamples.toString() + \".0\");\n if (logarithmicDepthBuffer) {\n e.fragmentShader = \"#define LOGDEPTH\\n\" + e.fragmentShader;\n }\n if (this.configuration.halfRes) {\n e.fragmentShader = \"#define HALFRES\\n\" + e.fragmentShader;\n }\n if (this.effectShaderQuad) {\n this.effectShaderQuad.material.dispose();\n this.effectShaderQuad.material = new ShaderMaterial(e);\n } else {\n this.effectShaderQuad = new FullScreenTriangle(new ShaderMaterial(e));\n }\n }\n\n private configureDenoisePass(logarithmicDepthBuffer: boolean = false): void {\n this.samplesDenoise = this.generateDenoiseSamples(this.configuration.denoiseSamples, 11);\n const p = { ...PoissionBlur };\n p.fragmentShader = p.fragmentShader.replace(\"16\", this.configuration.denoiseSamples.toString());\n if (logarithmicDepthBuffer) {\n p.fragmentShader = \"#define LOGDEPTH\\n\" + p.fragmentShader;\n }\n if (this.poissonBlurQuad) {\n this.poissonBlurQuad.material.dispose();\n this.poissonBlurQuad.material = new ShaderMaterial(p);\n } else {\n this.poissonBlurQuad = new FullScreenTriangle(new ShaderMaterial(p));\n }\n }\n\n private configureEffectCompositer(logarithmicDepthBuffer: boolean = false): void {\n const e = { ...EffectCompositer };\n\n if (logarithmicDepthBuffer) {\n e.fragmentShader = \"#define LOGDEPTH\\n\" + e.fragmentShader;\n }\n\n if (this.configuration.halfRes && this.configuration.depthAwareUpsampling) {\n e.fragmentShader = \"#define HALFRES\\n\" + e.fragmentShader;\n }\n\n if (this.effectCompositerQuad) {\n this.effectCompositerQuad.material.dispose();\n this.effectCompositerQuad.material = new ShaderMaterial(e);\n } else {\n this.effectCompositerQuad = new FullScreenTriangle(new ShaderMaterial(e));\n }\n }\n\n private generateHemisphereSamples(n: number): Vector3[] {\n const points = [];\n for (let k = 0; k < n; k++) {\n const theta = 2.399963 * k;\n const r = Math.sqrt(k + 0.5) / Math.sqrt(n);\n const x = r * Math.cos(theta);\n const y = r * Math.sin(theta);\n\n const z = Math.sqrt(1 - (x * x + y * y));\n points.push(new Vector3(x, y, z));\n }\n return points;\n }\n\n private generateHemisphereSamplesR(n: number): number[] {\n const samplesR = [];\n for (let i = 0; i < n; i++) {\n samplesR.push((i + 1) / n);\n }\n return samplesR;\n }\n\n private generateDenoiseSamples(numSamples: number, numRings: number): Vector2[] {\n const angleStep = (2 * Math.PI * numRings) / numSamples;\n const invNumSamples = 1.0 / numSamples;\n const radiusStep = invNumSamples;\n const samples = [];\n let radius = invNumSamples;\n let angle = 0;\n for (let i = 0; i < numSamples; i++) {\n samples.push(\n new Vector2(Math.cos(angle), Math.sin(angle)).multiplyScalar(Math.pow(radius, 0.75)),\n );\n radius += radiusStep;\n angle += angleStep;\n }\n return samples;\n }\n\n public setSize(width: number, height: number): void {\n this.width = width;\n this.height = height;\n const c = this.configuration.halfRes ? 0.5 : 1;\n this.writeTargetInternal.setSize(width * c, height * c);\n this.readTargetInternal.setSize(width * c, height * c);\n if (this.configuration.halfRes && this.depthDownsampleTarget) {\n this.depthDownsampleTarget.setSize(width * c, height * c);\n }\n this.outputTargetInternal.setSize(width, height);\n }\n\n public setDepthTexture(depthTexture: DataTexture): void {\n this.depthTexture = depthTexture;\n }\n\n public render(\n renderer: WebGLRenderer,\n inputBuffer: WebGLRenderTarget,\n outputBuffer: WebGLRenderTarget,\n ): void {\n const xrEnabled = renderer.xr.enabled;\n renderer.xr.enabled = false;\n\n let ext: any;\n let timerQuery: WebGLQuery | null = null;\n let gl: WebGL2RenderingContext | WebGLRenderingContext | null = null;\n gl = renderer.getContext();\n\n if (this.debugMode) {\n ext = gl.getExtension(\"EXT_disjoint_timer_query_webgl2\");\n if (ext === null) {\n console.error(\"EXT_disjoint_timer_query_webgl2 not available, disabling debug mode.\");\n this.debugMode = false;\n gl = null;\n }\n }\n\n if (this.debugMode && gl) {\n timerQuery = (gl as WebGL2RenderingContext).createQuery()!;\n (gl as WebGL2RenderingContext).beginQuery(ext.TIME_ELAPSED_EXT, timerQuery);\n }\n\n if (\n renderer.capabilities.logarithmicDepthBuffer !== this.configuration.logarithmicDepthBuffer\n ) {\n this.configuration.logarithmicDepthBuffer = renderer.capabilities.logarithmicDepthBuffer;\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n }\n\n if (inputBuffer.texture.type !== this.outputTargetInternal.texture.type) {\n this.outputTargetInternal.texture.type = inputBuffer.texture.type;\n this.outputTargetInternal.texture.needsUpdate = true;\n }\n\n this.camera.updateMatrixWorld();\n this.r.set(this.width, this.height);\n let trueRadius = this.configuration.aoRadius;\n\n if (this.configuration.halfRes && this.configuration.screenSpaceRadius) {\n trueRadius *= 0.5;\n }\n\n if (this.configuration.halfRes && this.depthDownsampleQuad) {\n const depthDownsampleUniforms = this.depthDownsampleQuad.material.uniforms;\n renderer.setRenderTarget(this.depthDownsampleTarget);\n depthDownsampleUniforms.sceneDepth.value = this.depthTexture;\n depthDownsampleUniforms.resolution.value = this.r;\n depthDownsampleUniforms.near.value = this.camera.near;\n depthDownsampleUniforms.far.value = this.camera.far;\n depthDownsampleUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n depthDownsampleUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n depthDownsampleUniforms.logDepth.value = this.configuration.logarithmicDepthBuffer;\n this.depthDownsampleQuad.render(renderer);\n }\n\n if (!this.effectShaderQuad) return;\n\n const effectShaderUniforms = this.effectShaderQuad.material.uniforms;\n\n effectShaderUniforms.sceneDiffuse.value = inputBuffer.texture;\n effectShaderUniforms.sceneDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.texture[0]\n : this.depthTexture;\n effectShaderUniforms.sceneNormal.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.texture[1]\n : null;\n effectShaderUniforms.projMat.value = this.camera.projectionMatrix;\n effectShaderUniforms.viewMat.value = this.camera.matrixWorldInverse;\n effectShaderUniforms.projViewMat.value = this.camera.projectionMatrix\n .clone()\n .multiply(this.camera.matrixWorldInverse.clone());\n effectShaderUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n effectShaderUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n effectShaderUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n effectShaderUniforms.resolution.value = this.configuration.halfRes\n ? this.r\n .clone()\n .multiplyScalar(1 / 2)\n .floor()\n : this.r;\n effectShaderUniforms.time.value = performance.now() / 1000;\n effectShaderUniforms.samples.value = this.samples;\n effectShaderUniforms.samplesR.value = this.samplesR;\n effectShaderUniforms.bluenoise.value = this.bluenoise;\n effectShaderUniforms.radius.value = trueRadius;\n effectShaderUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n effectShaderUniforms.near.value = this.camera.near;\n effectShaderUniforms.far.value = this.camera.far;\n effectShaderUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n effectShaderUniforms.ortho.value = this.camera instanceof OrthographicCamera;\n effectShaderUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n\n // Start the AO\n renderer.setRenderTarget(this.writeTargetInternal);\n this.effectShaderQuad.render(renderer);\n // End the AO\n\n const poissonBlurUniforms = this.poissonBlurQuad!.material.uniforms;\n\n // Start the blur\n for (let i = 0; i < this.configuration.denoiseIterations; i++) {\n if (!poissonBlurUniforms || !this.poissonBlurQuad) return;\n [this.writeTargetInternal, this.readTargetInternal] = [\n this.readTargetInternal,\n this.writeTargetInternal,\n ];\n poissonBlurUniforms.tDiffuse.value = this.readTargetInternal.texture;\n poissonBlurUniforms.sceneDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.texture[0]\n : this.depthTexture;\n poissonBlurUniforms.projMat.value = this.camera.projectionMatrix;\n poissonBlurUniforms.viewMat.value = this.camera.matrixWorldInverse;\n poissonBlurUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n poissonBlurUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n poissonBlurUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n poissonBlurUniforms.resolution.value = this.configuration.halfRes\n ? this.r\n .clone()\n .multiplyScalar(1 / 2)\n .floor()\n : this.r;\n poissonBlurUniforms.time.value = performance.now() / 1000;\n poissonBlurUniforms.blueNoise.value = this.bluenoise;\n poissonBlurUniforms.radius.value =\n this.configuration.denoiseRadius * (this.configuration.halfRes ? 1 / 2 : 1);\n poissonBlurUniforms.worldRadius.value = trueRadius;\n poissonBlurUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n poissonBlurUniforms.index.value = i;\n poissonBlurUniforms.poissonDisk.value = this.samplesDenoise;\n poissonBlurUniforms.near.value = this.camera.near;\n poissonBlurUniforms.far.value = this.camera.far;\n poissonBlurUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n poissonBlurUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n renderer.setRenderTarget(this.writeTargetInternal);\n this.poissonBlurQuad.render(renderer);\n }\n // End the blur\n\n const effectCompositerUniforms = this.effectCompositerQuad!.material.uniforms;\n\n // Start the composition\n if (!effectCompositerUniforms || !this.effectCompositerQuad) return;\n effectCompositerUniforms.sceneDiffuse.value = inputBuffer.texture;\n effectCompositerUniforms.sceneDepth.value = this.depthTexture;\n effectCompositerUniforms.near.value = this.camera.near;\n effectCompositerUniforms.far.value = this.camera.far;\n effectCompositerUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n effectCompositerUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n effectCompositerUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n effectCompositerUniforms.ortho.value = this.camera instanceof OrthographicCamera;\n effectCompositerUniforms.downsampledDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.texture[0]\n : this.depthTexture;\n effectCompositerUniforms.resolution.value = this.r;\n effectCompositerUniforms.blueNoise.value = this.bluenoise;\n effectCompositerUniforms.intensity.value = this.configuration.intensity;\n effectCompositerUniforms.renderMode.value = this.configuration.renderMode;\n effectCompositerUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n effectCompositerUniforms.radius.value = trueRadius;\n effectCompositerUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n effectCompositerUniforms.gammaCorrection.value = this.autosetGamma\n ? this.renderToScreen\n : this.configuration.gammaCorrection;\n effectCompositerUniforms.tDiffuse.value = this.writeTargetInternal.texture;\n effectCompositerUniforms.color.value = this.c\n .copy(this.configuration.color)\n .convertSRGBToLinear();\n effectCompositerUniforms.colorMultiply.value = this.configuration.colorMultiply;\n effectCompositerUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n effectCompositerUniforms.fog.value = !!this.scene.fog;\n\n if (this.scene.fog) {\n if (this.scene.fog instanceof Fog && this.scene.fog.isFog === true) {\n effectCompositerUniforms.fogExp.value = false;\n effectCompositerUniforms.fogNear.value = this.scene.fog.near;\n effectCompositerUniforms.fogFar.value = this.scene.fog.far;\n } else if (this.scene.fog instanceof FogExp2) {\n effectCompositerUniforms.fogExp.value = true;\n effectCompositerUniforms.fogDensity.value = this.scene.fog.density;\n } else {\n console.error(`Unsupported fog type ${this.scene.fog.constructor.name} in SSAOPass.`);\n }\n }\n\n renderer.setRenderTarget(this.outputTargetInternal);\n this.effectCompositerQuad.render(renderer);\n renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);\n this.copyQuad.material.uniforms.tDiffuse.value = this.outputTargetInternal.texture;\n this.copyQuad.render(renderer);\n\n if (this.debugMode && gl && timerQuery) {\n (gl as WebGL2RenderingContext).endQuery(ext.TIME_ELAPSED_EXT);\n checkTimerQuery(timerQuery as WebGLQuery, gl as WebGL2RenderingContext, this);\n }\n\n renderer.xr.enabled = xrEnabled;\n }\n\n public enableDebugMode(): void {\n this.debugMode = true;\n }\n\n public disableDebugMode(): void {\n this.debugMode = false;\n }\n\n public setDisplayMode(mode: \"Combined\" | \"AO\" | \"No AO\" | \"Split\" | \"Split AO\"): void {\n this.configuration.renderMode = [\"Combined\", \"AO\", \"No AO\", \"Split\", \"Split AO\"].indexOf(\n mode,\n ) as number;\n }\n\n public setQualityMode(mode: PresetsType): void {\n if (mode === \"Performance\") {\n this.configuration.aoSamples = 8;\n this.configuration.denoiseSamples = 4;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"Low\") {\n this.configuration.aoSamples = 16;\n this.configuration.denoiseSamples = 4;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"Medium\") {\n this.configuration.aoSamples = 16;\n this.configuration.denoiseSamples = 8;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"High\") {\n this.configuration.aoSamples = 64;\n this.configuration.denoiseSamples = 8;\n this.configuration.denoiseRadius = 6;\n } else if (mode === \"Ultra\") {\n this.configuration.aoSamples = 64;\n this.configuration.denoiseSamples = 16;\n this.configuration.denoiseRadius = 6;\n }\n }\n}\n\nexport { N8SSAOPass };\n", "// Original code from: https://github.com/N8python/n8ao\n\n/* eslint-disable max-len */\nexport const BlueNoise: string =\n \"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\";\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2 } from \"three\";\n\nconst DepthDownSample = {\n uniforms: {\n sceneDepth: new Uniform(null),\n resolution: new Uniform(new Vector2()),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n viewMatrixInv: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n logDepth: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform highp sampler2D sceneDepth;\n uniform vec2 resolution;\n uniform float near;\n uniform float far;\n uniform bool logDepth;\n uniform mat4 viewMatrixInv;\n uniform mat4 projectionMatrixInv;\n varying vec2 vUv;\n\n layout(location = 1) out vec4 gNormal;\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ = near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n if (logDepth) {\n return getWorldPosLog(vec3(coord, depth));\n }\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n void main(void) {\n vec2 uv = vUv - vec2(0.5) / resolution;\n vec2 pixelSize = vec2(1.0) / resolution;\n vec2[] uvSamples = vec2[4](\n uv,\n uv + vec2(pixelSize.x, 0.0),\n uv + vec2(0.0, pixelSize.y),\n uv + pixelSize\n );\n float depth00 = texture2D(sceneDepth, uvSamples[0]).r;\n float depth10 = texture2D(sceneDepth, uvSamples[1]).r;\n float depth01 = texture2D(sceneDepth, uvSamples[2]).r;\n float depth11 = texture2D(sceneDepth, uvSamples[3]).r;\n float minDepth = min(min(depth00, depth10), min(depth01, depth11));\n float maxDepth = max(max(depth00, depth10), max(depth01, depth11));\n float targetDepth = minDepth;\n\n if (mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) > 0.5) { \n targetDepth = maxDepth;\n }\n\n int chosenIndex = 0;\n float[] samples = float[4](depth00, depth10, depth01, depth11);\n\n for(int i = 0; i < 4; ++i) {\n if (samples[i] == targetDepth) {\n chosenIndex = i;\n break;\n }\n }\n\n gl_FragColor = vec4(samples[chosenIndex], 0.0, 0.0, 1.0);\n gNormal = vec4(\n computeNormal(\n getWorldPos(samples[chosenIndex], uvSamples[chosenIndex]), uvSamples[chosenIndex]\n ),\n 0.0\n );\n }`,\n};\n\nexport { DepthDownSample };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nconst EffectCompositer = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n tDiffuse: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n color: new Uniform(new Vector3()),\n blueNoise: new Uniform(null),\n downsampledDepth: new Uniform(null),\n time: new Uniform(0.0),\n intensity: new Uniform(10.0),\n renderMode: new Uniform(0.0),\n gammaCorrection: new Uniform(false),\n logDepth: new Uniform(false),\n ortho: new Uniform(false),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n screenSpaceRadius: new Uniform(false),\n radius: new Uniform(0.0),\n distanceFalloff: new Uniform(1.0),\n fog: new Uniform(false),\n fogExp: new Uniform(false),\n fogDensity: new Uniform(0.0),\n fogNear: new Uniform(Infinity),\n fogFar: new Uniform(Infinity),\n colorMultiply: new Uniform(true),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneDepth;\n uniform highp sampler2D downsampledDepth;\n uniform sampler2D tDiffuse;\n uniform sampler2D blueNoise;\n uniform vec2 resolution;\n uniform vec3 color;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform float intensity;\n uniform float renderMode;\n uniform float near;\n uniform float far;\n uniform bool gammaCorrection;\n uniform bool logDepth;\n uniform bool ortho;\n uniform bool screenSpaceRadius;\n uniform bool fog;\n uniform bool fogExp;\n uniform bool colorMultiply;\n uniform float fogDensity;\n uniform float fogNear;\n uniform float fogFar;\n uniform float radius;\n uniform float distanceFalloff;\n uniform vec3 cameraPos;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n return (zFar * zNear) / (zFar - d * (zFar - zNear));\n }\n \n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return (\n ortho\n ? linearize_depth_ortho(linDepth, nearZ, farZ)\n : linearize_depth(linDepth, nearZ, farZ)\n );\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n #include <common>\n #include <dithering_pars_fragment>\n\n void main(void) {\n vec4 sceneTexel = texture2D(sceneDiffuse, vUv);\n float depth = texture2D(sceneDepth, vUv).x;\n \n #ifdef HALFRES \n vec4 texel;\n if (depth == 1.0) {\n texel = vec4(0.0, 0.0, 0.0, 1.0);\n } else {\n vec3 worldPos = getWorldPos(depth, vUv);\n vec3 normal = computeNormal(getWorldPos(depth, vUv), vUv);\n\n float totalWeight = 0.0;\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(depth, vUv + vec2(radius, 0.0) / resolution))\n : radius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n for(float x = -1.0; x <= 1.0; x++) {\n for(float y = -1.0; y <= 1.0; y++) {\n vec2 offset = vec2(x, y);\n ivec2 p = ivec2((vUv * resolution * 0.5) + offset);\n vec2 pUv = vec2(p) / (resolution * 0.5);\n float sampleDepth = texelFetch(downsampledDepth,p, 0).x;\n vec4 sampleInfo = texelFetch(tDiffuse, p, 0);\n vec3 normalSample = sampleInfo.xyz * 2.0 - 1.0;\n vec3 worldPosSample = getWorldPos(sampleDepth, pUv);\n float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));\n float rangeCheck = exp(\n -1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)) * max(dot(normal, normalSample),\n 0.0\n );\n float weight = rangeCheck;\n totalWeight += weight;\n texel += sampleInfo * weight;\n }\n }\n if (totalWeight == 0.0) {\n texel = texture2D(tDiffuse, vUv);\n } else {\n texel /= totalWeight;\n }\n }\n #else\n vec4 texel = texture2D(tDiffuse, vUv);\n #endif\n\n #ifdef LOGDEPTH\n texel.a = clamp(texel.a, 0.0, 1.0);\n if (texel.a == 0.0) {\n texel.a = 1.0;\n }\n #endif\n\n float finalAo = pow(texel.a, intensity);\n float fogFactor;\n float fogDepth = distance(cameraPos, getWorldPos(depth, vUv));\n\n if (fog) {\n if (fogExp) {\n fogFactor = 1.0 - exp(-fogDensity * fogDensity * fogDepth * fogDepth);\n } else {\n fogFactor = smoothstep(fogNear, fogFar, fogDepth);\n }\n }\n\n finalAo = mix(finalAo, 1.0, fogFactor);\n vec3 aoApplied = color * mix(vec3(1.0), sceneTexel.rgb, float(colorMultiply));\n if (renderMode == 0.0) {\n gl_FragColor = vec4( mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);\n } else if (renderMode == 1.0) {\n gl_FragColor = vec4( mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);\n } else if (renderMode == 2.0) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (renderMode == 3.0) {\n if (vUv.x < 0.5) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {\n gl_FragColor = vec4(1.0);\n } else {\n gl_FragColor = vec4(mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);\n }\n } else if (renderMode == 4.0) {\n if (vUv.x < 0.5) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {\n gl_FragColor = vec4(1.0);\n } else {\n gl_FragColor = vec4(mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);\n }\n }\n\n #include <dithering_fragment>\n\n if (gammaCorrection) {\n gl_FragColor = LinearTosRGB(gl_FragColor);\n }\n }\n `,\n};\nexport { EffectCompositer };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nconst EffectShader = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n sceneNormal: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projViewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n samples: new Uniform([]),\n samplesR: new Uniform([]),\n bluenoise: new Uniform(null),\n distanceFalloff: new Uniform(1.0),\n radius: new Uniform(5.0),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n logDepth: new Uniform(false),\n ortho: new Uniform(false),\n screenSpaceRadius: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }\n `,\n\n fragmentShader: /* glsl */ `\n #define SAMPLES 16\n #define FSAMPLES 16.0\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneNormal;\n uniform highp sampler2D sceneDepth;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform mat4 projMat;\n uniform mat4 viewMat;\n uniform mat4 projViewMat;\n uniform vec3 cameraPos;\n uniform vec2 resolution;\n uniform float time;\n uniform vec3[SAMPLES] samples;\n uniform float[SAMPLES] samplesR;\n uniform float radius;\n uniform float distanceFalloff;\n uniform float near;\n uniform float far;\n uniform bool logDepth;\n uniform bool ortho;\n uniform bool screenSpaceRadius;\n uniform sampler2D bluenoise;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n return (zFar * zNear) / (zFar - d * (zFar - zNear));\n }\n\n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return (\n ortho\n ? linearize_depth_ortho(linDepth, nearZ, farZ)\n : linearize_depth(linDepth, nearZ, farZ)\n );\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n void main(void) {\n vec4 diffuse = texture2D(sceneDiffuse, vUv);\n float depth = texture2D(sceneDepth, vUv).x;\n\n if (depth == 1.0) {\n gl_FragColor = vec4(vec3(1.0), 1.0);\n return;\n }\n\n vec3 worldPos = getWorldPos(depth, vUv);\n\n #ifdef HALFRES\n vec3 normal = texture2D(sceneNormal, vUv).rgb;\n #else\n vec3 normal = computeNormal(worldPos, vUv);\n #endif\n\n vec4 noise = texture2D(bluenoise, gl_FragCoord.xy / 128.0);\n vec3 randomVec = normalize(noise.rgb * 2.0 - 1.0);\n vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));\n vec3 bitangent = cross(normal, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal);\n float occluded = 0.0;\n float totalWeight = 0.0;\n\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(depth, vUv + vec2(radius, 0.0) / resolution))\n : radius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n float bias = (0.1 / near) * fwidth(distance(worldPos, cameraPos)) / radiusToUse;\n for(float i = 0.0; i < FSAMPLES; i++) {\n vec3 sampleDirection = tbn * samples[int(i)];\n float moveAmt = samplesR[int(mod(i + noise.a * FSAMPLES, FSAMPLES))];\n vec3 samplePos = worldPos + radiusToUse * moveAmt * sampleDirection;\n vec4 offset = projMat * vec4(samplePos, 1.0);\n offset.xyz /= offset.w;\n offset.xyz = offset.xyz * 0.5 + 0.5;\n float sampleDepth = textureLod(sceneDepth, offset.xy, 0.0).x;\n #ifdef LOGDEPTH\n float distSample = linearize_depth_log(sampleDepth, near, far);\n #else\n float distSample = (\n ortho\n ? linearize_depth_ortho(sampleDepth, near, far)\n : linearize_depth(sampleDepth, near, far)\n );\n #endif\n float distWorld = (\n ortho\n ? linearize_depth_ortho(offset.z, near, far)\n : linearize_depth(offset.z, near, far)\n );\n float rangeCheck = smoothstep(0.0, 1.0, distanceFalloffToUse / (abs(distSample - distWorld)));\n vec2 diff = gl_FragCoord.xy - ( offset.xy * resolution);\n float weight = dot(sampleDirection, normal);\n occluded += rangeCheck * weight *\n (distSample + bias < distWorld ? 1.0 : 0.0) *\n (\n (\n dot(diff, diff) < 1.0 ||\n (sampleDepth == depth) ||\n (offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0) ? 0.0 : 1.0\n )\n );\n totalWeight += weight;\n }\n float occ = clamp(1.0 - occluded / totalWeight, 0.0, 1.0);\n gl_FragColor = vec4(0.5 + 0.5 * normal, occ);\n }`,\n};\n\nexport { EffectShader };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport {\n BufferAttribute,\n BufferGeometry,\n Mesh,\n OrthographicCamera,\n ShaderMaterial,\n Sphere,\n WebGLRenderer,\n} from \"three\";\n\nexport class FullScreenTriangle {\n private camera: OrthographicCamera = new OrthographicCamera();\n private geometry: BufferGeometry = new BufferGeometry();\n private mesh: Mesh<BufferGeometry, ShaderMaterial>;\n\n constructor(material: ShaderMaterial) {\n this.geometry.setAttribute(\n \"position\",\n new BufferAttribute(new Float32Array([-1, -1, 3, -1, -1, 3]), 2),\n );\n this.geometry.setAttribute(\"uv\", new BufferAttribute(new Float32Array([0, 0, 2, 0, 0, 2]), 2));\n\n this.geometry.boundingSphere = new Sphere();\n this.geometry.computeBoundingSphere = function () {};\n\n this.mesh = new Mesh(this.geometry, material);\n this.mesh.frustumCulled = false;\n }\n\n get material(): ShaderMaterial {\n return this.mesh.material as ShaderMaterial;\n }\n\n set material(value: ShaderMaterial) {\n this.mesh.material = value;\n }\n\n public render(renderer: WebGLRenderer): void {\n renderer.render(this.mesh, this.camera);\n }\n\n public dispose(): void {\n this.mesh.material.dispose();\n this.mesh.geometry.dispose();\n }\n}\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nexport const PoissionBlur = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n tDiffuse: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n r: new Uniform(5.0),\n blueNoise: new Uniform(null),\n radius: new Uniform(12.0),\n worldRadius: new Uniform(5.0),\n index: new Uniform(0.0),\n poissonDisk: new Uniform([]),\n distanceFalloff: new Uniform(1.0),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n logDepth: new Uniform(false),\n screenSpaceRadius: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1.0);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneDepth;\n uniform sampler2D tDiffuse;\n uniform sampler2D blueNoise;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform vec2 resolution;\n uniform float r;\n uniform float radius;\n uniform float worldRadius;\n uniform float index;\n uniform float near;\n uniform float far;\n uniform float distanceFalloff;\n uniform bool logDepth;\n uniform bool screenSpaceRadius;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n highp float z_n = 2.0 * d - 1.0;\n return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return linearize_depth(linDepth, nearZ, farZ);\n }\n\n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n #include <common>\n\n #define NUM_SAMPLES 16\n\n uniform vec2 poissonDisk[NUM_SAMPLES];\n\n void main(void) {\n const float pi = acos(-1.0);\n vec2 texelSize = vec2(1.0 / resolution.x, 1.0 / resolution.y);\n vec2 uv = vUv;\n vec4 data = texture2D(tDiffuse, vUv);\n float occlusion = data.a;\n float baseOcc = data.a;\n vec3 normal = data.rgb * 2.0 - 1.0;\n float count = 1.0;\n float d = texture2D(sceneDepth, vUv).x;\n if (d == 1.0) {\n gl_FragColor = data;\n return;\n }\n vec3 worldPos = getWorldPos(d, vUv);\n float size = radius;\n float angle;\n\n if (index == 0.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).x * PI2;\n } else if (index == 1.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).y * PI2;\n } else if (index == 2.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2;\n } else {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).w * PI2;\n }\n\n mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(d, vUv + vec2(worldRadius, 0.0) / resolution))\n : worldRadius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n\n for(int i = 0; i < NUM_SAMPLES; i++) {\n vec2 offset = (rotationMatrix * poissonDisk[i]) * texelSize * size;\n vec4 dataSample = texture2D(tDiffuse, uv + offset);\n float occSample = dataSample.a;\n vec3 normalSample = dataSample.rgb * 2.0 - 1.0;\n float dSample = texture2D(sceneDepth, uv + offset).x;\n vec3 worldPosSample = getWorldPos(dSample, uv + offset);\n float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));\n float rangeCheck = (\n (dSample == 1.0)\n ? 0.0\n : exp(\n -1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)\n ) * max(dot(normal, normalSample), 0.0) * (1.0 - abs(occSample - baseOcc))\n );\n occlusion += occSample * rangeCheck;\n count += rangeCheck;\n }\n\n if (count > 0.0) {\n occlusion /= count;\n }\n\n #ifdef LOGDEPTH\n occlusion = clamp(occlusion, 0.0, 1.0);\n if (occlusion == 0.0) {\n occlusion = 1.0;\n }\n #endif\n gl_FragColor = vec4(0.5 + 0.5 * normal, occlusion);\n }\n `,\n};\n", "import { Clock } from \"three\";\n\nimport { ease } from \"../helpers/math-helpers\";\n\nexport class TimeManager {\n private clock: Clock = new Clock();\n private roundMagnitude: number = 200000;\n private maxAverageFrames: number = 150;\n private deltaTimes: number[] = [];\n\n private targetAverageDeltaTime: number = 0;\n private lerpedAverageMagDelta: number = 0;\n private fpsUpdateTime: number = 0;\n private framesSinceLastFPSUpdate: number = 0;\n\n public time: number = 0;\n public deltaTime: number = 0;\n public rawDeltaTime: number = 0;\n public smoothDeltaTime: number = 0;\n public frame: number = 0;\n public fps: number = 0;\n public averageFPS: number = 0;\n\n update() {\n this.rawDeltaTime = this.clock.getDelta();\n this.frame++;\n this.time += this.rawDeltaTime;\n this.deltaTimes.push(this.rawDeltaTime);\n\n if (this.deltaTimes.length > this.maxAverageFrames) this.deltaTimes.shift();\n\n this.targetAverageDeltaTime =\n this.deltaTimes.reduce((prev, curr) => prev + curr, 0) / this.deltaTimes.length;\n\n this.lerpedAverageMagDelta += ease(\n this.targetAverageDeltaTime * this.roundMagnitude,\n this.lerpedAverageMagDelta,\n 0.12,\n );\n\n const revertMagnitude = this.lerpedAverageMagDelta / this.roundMagnitude;\n const smoothDT = Math.round(revertMagnitude * this.roundMagnitude) / this.roundMagnitude;\n\n this.smoothDeltaTime = smoothDT > this.rawDeltaTime * 1.75 ? this.rawDeltaTime : smoothDT;\n this.deltaTime = this.smoothDeltaTime;\n\n this.framesSinceLastFPSUpdate++;\n if (this.framesSinceLastFPSUpdate >= 60) {\n this.fps =\n Math.round((this.framesSinceLastFPSUpdate / (this.time - this.fpsUpdateTime)) * 100) / 100;\n\n this.fpsUpdateTime = this.time;\n this.framesSinceLastFPSUpdate = 0;\n }\n }\n}\n", "import {\n getRelativePositionAndRotationRelativeToObject,\n MElement,\n MMLCollisionTrigger,\n} from \"mml-web\";\nimport {\n Box3,\n BufferGeometry,\n Color,\n DoubleSide,\n Euler,\n Group,\n Line3,\n LineBasicMaterial,\n Matrix4,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n Quaternion,\n Ray,\n Scene,\n Vector3,\n} from \"three\";\nimport { VertexNormalsHelper } from \"three/examples/jsm/helpers/VertexNormalsHelper.js\";\nimport * as BufferGeometryUtils from \"three/examples/jsm/utils/BufferGeometryUtils.js\";\nimport { MeshBVH, MeshBVHHelper } from \"three-mesh-bvh\";\n\nexport type CollisionMeshState = {\n matrix: Matrix4;\n source: Group;\n meshBVH: MeshBVH;\n debugGroup?: Group;\n trackCollisions: boolean;\n};\n\nexport class CollisionsManager {\n private debug: boolean = false;\n private scene: Scene;\n private tempVector: Vector3 = new Vector3();\n private tempVector2: Vector3 = new Vector3();\n private tempVector3: Vector3 = new Vector3();\n private tempQuaternion: Quaternion = new Quaternion();\n private tempRay: Ray = new Ray();\n private tempMatrix = new Matrix4();\n private tempMatrix2 = new Matrix4();\n private tempBox = new Box3();\n private tempEuler = new Euler();\n private tempSegment = new Line3();\n private tempSegment2 = new Line3();\n\n public collisionMeshState: Map<Group, CollisionMeshState> = new Map();\n private collisionTrigger: MMLCollisionTrigger;\n private previouslyCollidingElements: null | Map<\n Object3D,\n { position: { x: number; y: number; z: number } }\n >;\n\n constructor(scene: Scene) {\n this.scene = scene;\n this.collisionTrigger = MMLCollisionTrigger.init();\n }\n\n public raycastFirst(ray: Ray): [number, Vector3, CollisionMeshState] | null {\n let minimumDistance: number | null = null;\n let minimumHit: CollisionMeshState | null = null;\n let minimumNormal: Vector3 | null = new Vector3();\n for (const [, collisionMeshState] of this.collisionMeshState) {\n this.tempRay.copy(ray).applyMatrix4(this.tempMatrix.copy(collisionMeshState.matrix).invert());\n const hit = collisionMeshState.meshBVH.raycastFirst(this.tempRay, DoubleSide);\n if (hit) {\n this.tempSegment.start.copy(this.tempRay.origin);\n this.tempSegment.end.copy(hit.point);\n this.tempSegment.applyMatrix4(collisionMeshState.matrix);\n const dist = this.tempSegment.distance();\n if (minimumDistance === null || dist < minimumDistance) {\n minimumDistance = dist;\n minimumHit = collisionMeshState;\n minimumNormal = (hit.normal ? minimumNormal.copy(hit.normal) : minimumNormal)\n // Apply the rotation of the mesh to the normal\n .applyQuaternion(this.tempQuaternion.setFromRotationMatrix(collisionMeshState.matrix))\n .normalize();\n }\n }\n }\n if (minimumDistance === null || minimumNormal === null || minimumHit === null) {\n return null;\n }\n return [minimumDistance, minimumNormal, minimumHit];\n }\n\n private createCollisionMeshState(group: Group, trackCollisions: boolean): CollisionMeshState {\n const geometries: Array<BufferGeometry> = [];\n group.updateWorldMatrix(true, false);\n const invertedRootMatrix = this.tempMatrix.copy(group.matrixWorld).invert();\n group.traverse((child: Object3D) => {\n const asMesh = child as Mesh;\n if (asMesh.isMesh) {\n const clonedGeometry = asMesh.geometry.clone();\n if (child !== group) {\n asMesh.updateWorldMatrix(true, false);\n clonedGeometry.applyMatrix4(\n this.tempMatrix2.multiplyMatrices(invertedRootMatrix, asMesh.matrixWorld),\n );\n }\n\n for (const key in clonedGeometry.attributes) {\n if (key !== \"position\") {\n clonedGeometry.deleteAttribute(key);\n }\n }\n if (clonedGeometry.index) {\n geometries.push(clonedGeometry.toNonIndexed());\n } else {\n geometries.push(clonedGeometry);\n }\n }\n });\n const newBufferGeometry = BufferGeometryUtils.mergeGeometries(geometries, false);\n newBufferGeometry.computeVertexNormals();\n const meshBVH = new MeshBVH(newBufferGeometry);\n\n const meshState: CollisionMeshState = {\n source: group,\n meshBVH,\n matrix: group.matrixWorld.clone(),\n trackCollisions,\n };\n if (this.debug) {\n // Have to cast to add the boundsTree property to the geometry so that the MeshBVHHelper can find it\n (newBufferGeometry as any).boundsTree = meshBVH;\n\n const wireframeMesh = new Mesh(newBufferGeometry, new MeshBasicMaterial({ wireframe: true }));\n\n const normalsHelper = new VertexNormalsHelper(wireframeMesh, 0.25, 0x00ff00);\n\n const visualizer = new MeshBVHHelper(wireframeMesh, 4);\n (visualizer.edgeMaterial as LineBasicMaterial).color = new Color(\"blue\");\n\n const debugGroup = new Group();\n debugGroup.add(wireframeMesh, normalsHelper, visualizer as unknown as Object3D);\n\n group.matrixWorld.decompose(debugGroup.position, debugGroup.quaternion, debugGroup.scale);\n visualizer.update();\n\n meshState.debugGroup = debugGroup;\n }\n return meshState;\n }\n\n public addMeshesGroup(group: Group, mElement?: MElement): void {\n if (mElement) {\n this.collisionTrigger.addCollider(group, mElement);\n }\n const meshState = this.createCollisionMeshState(group, mElement !== undefined);\n if (meshState.debugGroup) {\n this.scene.add(meshState.debugGroup);\n }\n this.collisionMeshState.set(group, meshState);\n }\n\n public updateMeshesGroup(group: Group): void {\n const meshState = this.collisionMeshState.get(group);\n if (meshState) {\n group.updateWorldMatrix(true, false);\n meshState.matrix.copy(group.matrixWorld);\n if (meshState.debugGroup) {\n group.matrixWorld.decompose(\n meshState.debugGroup.position,\n meshState.debugGroup.quaternion,\n meshState.debugGroup.scale,\n );\n }\n }\n }\n\n public removeMeshesGroup(group: Group): void {\n this.collisionTrigger.removeCollider(group);\n const meshState = this.collisionMeshState.get(group);\n if (meshState) {\n if (meshState.debugGroup) {\n this.scene.remove(meshState.debugGroup);\n }\n this.collisionMeshState.delete(group);\n }\n }\n\n private applyCollider(\n worldBasedCapsuleSegment: Line3,\n capsuleRadius: number,\n meshState: CollisionMeshState,\n ): Vector3 | null {\n // Create a matrix to convert from world-space to mesh-space\n const meshMatrix = this.tempMatrix.copy(meshState.matrix).invert();\n\n // Create the bounding box for the capsule if it were in mesh-space\n const meshRelativeCapsuleBoundingBox = this.tempBox;\n meshRelativeCapsuleBoundingBox.makeEmpty();\n meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.start);\n meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.end);\n meshRelativeCapsuleBoundingBox.min.subScalar(capsuleRadius);\n meshRelativeCapsuleBoundingBox.max.addScalar(capsuleRadius);\n meshRelativeCapsuleBoundingBox.applyMatrix4(meshMatrix);\n // Create a segment/line for the capsule in mesh-space\n const meshRelativeCapsuleSegment = this.tempSegment;\n meshRelativeCapsuleSegment.start.copy(worldBasedCapsuleSegment.start);\n meshRelativeCapsuleSegment.end.copy(worldBasedCapsuleSegment.end);\n meshRelativeCapsuleSegment.applyMatrix4(meshMatrix);\n\n // Keep track of where the segment started in mesh-space so that we can calculate the delta later\n const initialMeshRelativeCapsuleSegmentStart = this.tempVector3.copy(\n meshRelativeCapsuleSegment.start,\n );\n\n let collisionPosition: Vector3 | null = null;\n meshState.meshBVH.shapecast({\n intersectsBounds: (meshBox) => {\n // Determine if this portion of the mesh overlaps with the capsule bounding box and is therefore worth checking\n // all of the triangles within\n return meshBox.intersectsBox(meshRelativeCapsuleBoundingBox);\n },\n intersectsTriangle: (meshTriangle) => {\n const closestPointOnTriangle = this.tempVector;\n const closestPointOnSegment = this.tempVector2;\n // Find the closest point between this triangle and the capsule segment in mesh-space\n meshTriangle.closestPointToSegment(\n meshRelativeCapsuleSegment,\n closestPointOnTriangle,\n closestPointOnSegment,\n );\n // Create a line segment between the closest points\n const intersectionSegment = this.tempSegment2;\n intersectionSegment.start.copy(closestPointOnTriangle);\n intersectionSegment.end.copy(closestPointOnSegment);\n // Calculate the distance between the closest points in mesh-space\n const modelReferenceDistance = intersectionSegment.distance();\n\n // Calculate the distance between the points in world-space\n intersectionSegment.applyMatrix4(meshState.matrix);\n const realDistance = intersectionSegment.distance();\n\n // If the real distance is less than the capsule radius then there is actually a collision between the capsule\n // and the triangle\n if (realDistance < capsuleRadius) {\n if (!collisionPosition) {\n collisionPosition = new Vector3()\n .copy(closestPointOnSegment)\n .applyMatrix4(meshState.matrix);\n }\n // Calculate the ratio between the real distance and the mesh-space distance\n const ratio = realDistance / modelReferenceDistance;\n // Calculate the depth of the collision in world-space\n const realDepth = capsuleRadius - realDistance;\n // Convert that depth back into mesh-space as all calculations during collision are to a mesh-space segment\n const modelDepth = realDepth / ratio;\n\n // Apply a corrective movement to the segment in mesh-space\n const direction = closestPointOnSegment.sub(closestPointOnTriangle).normalize();\n meshRelativeCapsuleSegment.start.addScaledVector(direction, modelDepth);\n meshRelativeCapsuleSegment.end.addScaledVector(direction, modelDepth);\n }\n },\n });\n\n if (collisionPosition) {\n // If there was a collision, calculate the delta between the original mesh-space segment and the now-moved one\n const delta = this.tempVector\n .copy(meshRelativeCapsuleSegment.start)\n .sub(initialMeshRelativeCapsuleSegmentStart);\n\n // Use the matrix for the mesh to convert the delta vector back to world-space (remove the position component of the matrix first to avoid translation)\n this.tempMatrix.copy(meshState.matrix).setPosition(0, 0, 0);\n delta.applyMatrix4(this.tempMatrix);\n\n // There's a possibility that the matrix is invalid (or scale zero) and the delta is NaN - if so, don't apply the delta\n if (!(isNaN(delta.x) && isNaN(delta.y) && isNaN(delta.z))) {\n // Convert the potentially-modified mesh-space segment back to world-space\n worldBasedCapsuleSegment.start.add(delta);\n worldBasedCapsuleSegment.end.add(delta);\n }\n }\n\n return collisionPosition;\n }\n\n public applyColliders(tempSegment: Line3, radius: number) {\n const collidedElements = new Map<\n Object3D,\n {\n position: { x: number; y: number; z: number };\n }\n >();\n for (const meshState of this.collisionMeshState.values()) {\n const collisionPosition = this.applyCollider(tempSegment, radius, meshState);\n if (collisionPosition && meshState.trackCollisions) {\n const relativePosition = getRelativePositionAndRotationRelativeToObject(\n {\n position: collisionPosition,\n rotation: this.tempEuler.set(0, 0, 0),\n },\n meshState.source,\n );\n collidedElements.set(meshState.source, {\n position: relativePosition.position,\n });\n }\n }\n\n /*\n The reported collisions include elements that were reported in the previous tick to ensure that the case of an\n avatar rising to a negligible distance above the surface and immediately back down onto it does not result in a\n discontinuity in the collision lifecycle. If the element is not colliding in the next frame then it will be\n dropped.\n\n This results in a single tick delay of reporting leave events, but this is a reasonable trade-off to avoid\n flickering collisions.\n */\n const reportedCollidingElements = new Map(collidedElements);\n if (this.previouslyCollidingElements) {\n for (const [element, position] of this.previouslyCollidingElements) {\n if (!reportedCollidingElements.has(element)) {\n reportedCollidingElements.set(element, position);\n }\n }\n }\n\n // Store the elements that were genuinely collided with this tick for the next tick to preserve if they are missed\n this.previouslyCollidingElements = collidedElements;\n this.collisionTrigger.setCurrentCollisions(reportedCollidingElements);\n }\n}\n"],
|
5
|
+
"mappings": "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",
|
6
6
|
"names": ["Vector3", "Vector3", "Color", "Vector3", "AnimationState", "Mesh", "Mesh", "Color", "LinearFilter", "Mesh", "MeshBasicMaterial", "Texture", "Color", "Mesh", "MeshBasicMaterial", "LinearFilter", "Color", "Vector3", "Euler", "Group", "Quaternion", "Vector3", "Quaternion", "Raycaster", "Vector3", "Vector3", "Quaternion", "Raycaster", "Quaternion", "Vector3", "Vector3", "Quaternion", "Quaternion", "Vector3", "Vector3", "Quaternion", "Vector3", "Group", "Euler", "Quaternion", "Group", "Color", "_a", "EffectComposer", "EffectPass", "SSAOEffect", "BlendFunction", "NormalPass", "Color", "Fog", "HalfFloatType", "LoadingManager", "Scene", "Vector2", "WebGLRenderer", "Color", "Group", "Vector3", "Group", "Vector3", "Color", "ShaderMaterial", "Uniform", "ShaderMaterial", "Uniform", "Color", "LinearFilter", "OrthographicCamera", "RGBAFormat", "ShaderMaterial", "Uniform", "Vector2", "Vector3", "Matrix4", "Uniform", "Vector2", "Matrix4", "Uniform", "Vector2", "Vector3", "Matrix4", "Uniform", "Vector2", "Vector3", "Mesh", "OrthographicCamera", "Matrix4", "Uniform", "Vector2", "Vector3", "ShaderMaterial", "Uniform", "Color", "LinearFilter", "Vector2", "RGBAFormat", "Vector3", "OrthographicCamera", "Vector2", "Scene", "WebGLRenderer", "EffectComposer", "HalfFloatType", "NormalPass", "BlendFunction", "SSAOEffect", "Color", "EffectPass", "LoadingManager", "Fog", "Color", "Euler", "Group", "Line3", "Matrix4", "Mesh", "MeshBasicMaterial", "Quaternion", "Ray", "Vector3"]
|
7
7
|
}
|