<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { Sky } from 'three/examples/jsm/objects/Sky.js'
import { Water, createWaterNormalTexture } from './Water'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'

const containerRef = ref<HTMLDivElement>()
const pickedPosition = ref<{ x: number; y: number; z: number } | null>(null)
const cameraInfo = ref({
  position: { x: 0, y: 0, z: 0 },
  target: { x: 0, y: 0, z: 0 },
  distance: 0,
  minDistance: 0,
  maxDistance: 0,
})

const waterParams = ref({
  alpha: 0.65,
  sunColor: '#ffffff',
  waterColor: '#78a6a0',
  distortionScale: 30.0,
  noiseScale: 1.0,
  fresnelBias: 0.15,
  fresnelPower: 4.0,
  fresnelStrength: 1.0,
  flowSpeed: 0.5,
  flowDirectionX: 1.0,
  flowDirectionY: 1.0,
})

const showCoordinatePanel = ref(false)
const showCameraPanel = ref(false)
const showWaterPanel = ref(false)

let scene: THREE.Scene
let camera: THREE.PerspectiveCamera
let renderer: THREE.WebGLRenderer
let controls: OrbitControls
let sky: Sky
let water: Water
let waterMesh: THREE.Mesh
let sunDirection: THREE.Vector3
let animationId: number
let tilesetGroup: THREE.Group | null = null
let raycaster: THREE.Raycaster
let mouse: THREE.Vector2

function createSky() {
  sky = new Sky()
  sky.scale.setScalar(50000)
  scene.add(sky)

  const uniforms = sky.material.uniforms
  uniforms.turbidity.value = 6
  uniforms.rayleigh.value = 0.1
  uniforms.mieCoefficient.value = 0.005
  uniforms.mieDirectionalG.value = 0.7
  uniforms.sunPosition.value.set(20, 30, 10)

  uniforms.cloudScale.value = 0.0008
  uniforms.cloudSpeed.value = 0.00015
  uniforms.cloudCoverage.value = 0.6
  uniforms.cloudDensity.value = 0.6
  uniforms.cloudElevation.value = 0.9
}

function createWaterSurface() {
  const textureLoader = new THREE.TextureLoader()
  const waterNormals = createWaterNormalTexture(textureLoader)

  water = new Water(renderer, camera, scene, {
    textureWidth: 512,
    textureHeight: 512,
    waterNormals,
    alpha: waterParams.value.alpha,
    sunDirection,
    sunColor: new THREE.Color(waterParams.value.sunColor),
    waterColor: new THREE.Color(waterParams.value.waterColor),
    distortionScale: waterParams.value.distortionScale,
    noiseScale: waterParams.value.noiseScale,
    fresnelBias: waterParams.value.fresnelBias,
    fresnelPower: waterParams.value.fresnelPower,
    fresnelStrength: waterParams.value.fresnelStrength,
    flowDirection: new THREE.Vector2(waterParams.value.flowDirectionX, waterParams.value.flowDirectionY),
    side: THREE.DoubleSide,
    fog: true,
  })

  waterMesh = new THREE.Mesh(
    new THREE.PlaneGeometry(200, 200, 60, 60),
    water.material
  )
  waterMesh.add(water)
  waterMesh.rotation.x = -Math.PI / 2
  waterMesh.position.set(840.85714, 7.47851, 2179.50782)
  waterMesh.receiveShadow = true
  scene.add(waterMesh)
}

async function load3DTiles() {
  const tilesetUrl = 'http://localhost:9003/model/scence/tileset.json'
  const gltfLoader = new GLTFLoader()
  
  try {
    const response = await fetch(tilesetUrl)
    const tileset = await response.json()
    
    console.log('Tileset loaded:', tileset)
    console.log('Root tile:', tileset.root)
    console.log('Root tile content:', tileset.root?.content)
    console.log('Root tile children count:', tileset.root?.children?.length)
    
    tilesetGroup = new THREE.Group()
    
    async function loadTile(tile: any, parentGroup: THREE.Group, depth: number = 0): Promise<void> {
      console.log(`${'  '.repeat(depth)}Processing tile at depth ${depth}`)
      console.log(`${'  '.repeat(depth)}Tile content:`, tile.content)
      console.log(`${'  '.repeat(depth)}Tile has transform:`, !!tile.transform)
      
      if (tile.content && tile.content.uri) {
        const tileUrl = new URL(tile.content.uri, tilesetUrl).href
        console.log(`${'  '.repeat(depth)}Loading tile from: ${tileUrl}`)
        
        try {
          const response = await fetch(tileUrl, { method: 'HEAD' })
          if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`)
          }
          console.log(`${'  '.repeat(depth)}File exists, content-type: ${response.headers.get('content-type')}`)
          
          const gltf = await new Promise((resolve, reject) => {
            gltfLoader.load(
              tileUrl,
              (gltf) => resolve(gltf),
              (progress) => {
                if (progress.lengthComputable) {
                  const percentComplete = (progress.loaded / progress.total) * 100
                  console.log(`${'  '.repeat(depth)}Loading progress: ${percentComplete.toFixed(2)}%`)
                }
              },
              (error) => {
                console.error(`${'  '.repeat(depth)}GLTFLoader error:`, error)
                reject(error)
              }
            )
          }) as { scene: THREE.Group }
          
          if (gltf && gltf.scene) {
            const mesh = gltf.scene.clone()
            
            console.log(`${'  '.repeat(depth)}GLB scene children count:`, mesh.children.length)
            console.log(`${'  '.repeat(depth)}GLB scene:`, mesh)
            
            mesh.traverse((child) => {
              if (child instanceof THREE.Mesh) {
                console.log(`${'  '.repeat(depth)}Found mesh:`, child.name)
                console.log(`${'  '.repeat(depth)}Mesh geometry:`, child.geometry)
                console.log(`${'  '.repeat(depth)}Mesh material:`, child.material)
                console.log(`${'  '.repeat(depth)}Mesh position:`, child.position)
                console.log(`${'  '.repeat(depth)}Mesh visible:`, child.visible)
              }
            })
            
            if (tile.transform) {
              const matrix = new THREE.Matrix4().fromArray(tile.transform)
              mesh.applyMatrix4(matrix)
            }
            
            parentGroup.add(mesh)
            console.log(`${'  '.repeat(depth)}Successfully loaded tile: ${tile.content.uri}`)
          }
        } catch (error) {
          console.warn(`${'  '.repeat(depth)}Error loading tile:`, tile.content.uri, error)
        }
      }
      
      if (tile.children && tile.children.length > 0) {
        console.log(`${'  '.repeat(depth)}Tile has ${tile.children.length} children`)
        for (const child of tile.children) {
          await loadTile(child, parentGroup, depth + 1)
        }
      }
    }
    
    if (tileset.root) {
      await loadTile(tileset.root, tilesetGroup)
    }
    
    console.log('Tileset group children count:', tilesetGroup.children.length)
    
    scene.add(tilesetGroup)
    
    const boundingBox = new THREE.Box3().setFromObject(tilesetGroup)
    const center = boundingBox.getCenter(new THREE.Vector3())
    const size = boundingBox.getSize(new THREE.Vector3())
    const maxDim = Math.max(size.x, size.y, size.z)
    
    console.log('Tileset bounding box center:', center)
    console.log('Tileset size:', size)
    
    if (maxDim > 0) {
      tilesetGroup.position.copy(center).multiplyScalar(-1)

      waterMesh.position.set(840.85714, 7.47851, 2179.50782)

      controls.target.set(842.3117, 9.27789, 2178.09268)
      controls.update()

      console.log('Tileset positioned')
    }
    
  } catch (error) {
    console.error('Error loading 3D Tiles:', error)
    console.error('Error details:', (error as Error).message)
  }
}

function initScene() {
  const container = containerRef.value!

  scene = new THREE.Scene()
  scene.fog = new THREE.FogExp2(0xd4d4d4, 0.004)

  camera = new THREE.PerspectiveCamera(60, container.clientWidth / container.clientHeight, 0.1, 100000)
  camera.position.set(838.15445, 22.22044, 2209.96548)

  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(container.clientWidth, container.clientHeight)
  renderer.domElement.style.width = '100%'
  renderer.domElement.style.height = '100%'
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  renderer.toneMapping = THREE.ACESFilmicToneMapping
  renderer.toneMappingExposure = 1.0
  renderer.shadowMap.enabled = true
  renderer.shadowMap.type = THREE.PCFShadowMap
  container.appendChild(renderer.domElement)

  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.03
  controls.screenSpacePanning = false
  controls.minDistance = 0
  controls.maxDistance = Infinity
  controls.mouseButtons = {
    LEFT: THREE.MOUSE.PAN,
    MIDDLE: THREE.MOUSE.DOLLY,
    RIGHT: THREE.MOUSE.ROTATE,
  }
  controls.target.set(842.3117, 9.27789, 2178.09268)
  controls.maxPolarAngle = Math.PI / 2.1
  controls.minDistance = 20
  controls.maxDistance = 100

  createSky()

  const hemisphereLight = new THREE.HemisphereLight(0xd4d4d4, 0x3d6b4a, 0.6)
  scene.add(hemisphereLight)

  sunDirection = new THREE.Vector3(20, 30, 10).normalize()

  const sunLight = new THREE.DirectionalLight(0xffeedd, 2.0)
  sunLight.position.set(20, 30, 10)
  sunLight.castShadow = true
  sunLight.shadow.mapSize.width = 2048
  sunLight.shadow.mapSize.height = 2048
  sunLight.shadow.camera.near = 0.5
  sunLight.shadow.camera.far = 60
  sunLight.shadow.camera.left = -20
  sunLight.shadow.camera.right = 20
  sunLight.shadow.camera.top = 20
  sunLight.shadow.camera.bottom = -20
  scene.add(sunLight)

  createWaterSurface()

  load3DTiles()

  initRaycaster()

  animate()
}

function initRaycaster() {
  raycaster = new THREE.Raycaster()
  mouse = new THREE.Vector2()
  
  const container = containerRef.value!
  
  container.addEventListener('click', onMouseClick)
}

function onMouseClick(event: MouseEvent) {
  const container = containerRef.value!
  const rect = container.getBoundingClientRect()
  
  mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
  mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
  
  raycaster.setFromCamera(mouse, camera)
  
  const intersectObjects: THREE.Object3D[] = []
  
  if (tilesetGroup) {
    intersectObjects.push(tilesetGroup)
  }
  if (waterMesh) {
    intersectObjects.push(waterMesh)
  }
  
  const intersects = raycaster.intersectObjects(intersectObjects, true)
  
  if (intersects.length > 0) {
    const point = intersects[0].point
    pickedPosition.value = {
      x: Number((point.x * 100).toFixed(3)),
      y: Number((point.y * 100).toFixed(3)),
      z: Number((point.z * 100).toFixed(3))
    }
    
    console.log('Picked position (cm):', pickedPosition.value)
  }
}

function animate() {
  animationId = requestAnimationFrame(animate)
  sky.material.uniforms.time.value += 0.001
  water.material.uniforms.time.value += 0.005 * waterParams.value.flowSpeed
  water.render()

  controls.update()

  cameraInfo.value.position = {
    x: Number((camera.position.x * 100).toFixed(3)),
    y: Number((camera.position.y * 100).toFixed(3)),
    z: Number((camera.position.z * 100).toFixed(3)),
  }
  cameraInfo.value.target = {
    x: Number((controls.target.x * 100).toFixed(3)),
    y: Number((controls.target.y * 100).toFixed(3)),
    z: Number((controls.target.z * 100).toFixed(3)),
  }
  cameraInfo.value.distance = Number(camera.position.distanceTo(controls.target).toFixed(3))
  cameraInfo.value.minDistance = controls.minDistance
  cameraInfo.value.maxDistance = controls.maxDistance

  renderer.render(scene, camera)
}

function onResize() {
  if (!containerRef.value) return
  const width = containerRef.value.clientWidth
  const height = containerRef.value.clientHeight
  camera.aspect = width / height
  camera.updateProjectionMatrix()
  renderer.setSize(width, height)
}

onMounted(() => {
  initScene()
  window.addEventListener('resize', onResize)
})

onUnmounted(() => {
  cancelAnimationFrame(animationId)
  window.removeEventListener('resize', onResize)
  
  if (containerRef.value) {
    containerRef.value.removeEventListener('click', onMouseClick)
  }
  
  if (tilesetGroup) {
    scene.remove(tilesetGroup)
  }
  
  renderer.dispose()
  controls.dispose()
})

watch(() => waterParams.value, (newParams) => {
  if (water && water.material && water.material.uniforms) {
    water.material.uniforms.alpha.value = newParams.alpha
    water.material.uniforms.sunColor.value.set(newParams.sunColor)
    water.material.uniforms.waterColor.value.set(newParams.waterColor)
    water.material.uniforms.distortionScale.value = newParams.distortionScale
    water.material.uniforms.noiseScale.value = newParams.noiseScale
    water.material.uniforms.fresnelBias.value = newParams.fresnelBias
    water.material.uniforms.fresnelPower.value = newParams.fresnelPower
    water.material.uniforms.fresnelStrength.value = newParams.fresnelStrength
    water.material.uniforms.flowDirection.value.set(newParams.flowDirectionX, newParams.flowDirectionY)
  }
}, { deep: true })
</script>

<template>
  <div ref="containerRef" class="scene-container" />
  <div class="toolbar">
    <button class="toolbar-btn" :class="{ active: showCoordinatePanel }" @click="showCoordinatePanel = !showCoordinatePanel">坐标</button>
    <button class="toolbar-btn" :class="{ active: showCameraPanel }" @click="showCameraPanel = !showCameraPanel">相机</button>
    <button class="toolbar-btn" :class="{ active: showWaterPanel }" @click="showWaterPanel = !showWaterPanel">水面</button>
  </div>

  <div v-if="showCoordinatePanel && pickedPosition" class="panel coordinate-panel">
    <div class="panel-header">
      <span class="panel-title">拾取坐标 (cm)</span>
      <button class="toggle-btn" @click="showCoordinatePanel = false">×</button>
    </div>
    <div class="coordinate-item">
      <span class="coordinate-label">X:</span>
      <span class="coordinate-value">{{ pickedPosition.x }}</span>
    </div>
    <div class="coordinate-item">
      <span class="coordinate-label">Y:</span>
      <span class="coordinate-value">{{ pickedPosition.y }}</span>
    </div>
    <div class="coordinate-item">
      <span class="coordinate-label">Z:</span>
      <span class="coordinate-value">{{ pickedPosition.z }}</span>
    </div>
  </div>

  <div v-if="showCameraPanel" class="panel camera-panel">
    <div class="panel-header">
      <span class="panel-title">相机信息</span>
      <button class="toggle-btn" @click="showCameraPanel = false">×</button>
    </div>
    <div class="camera-section">
      <div class="section-label">位置 (cm)</div>
      <div class="camera-item">
        <span class="camera-label">X:</span>
        <span class="camera-value">{{ cameraInfo.position.x }}</span>
      </div>
      <div class="camera-item">
        <span class="camera-label">Y:</span>
        <span class="camera-value">{{ cameraInfo.position.y }}</span>
      </div>
      <div class="camera-item">
        <span class="camera-label">Z:</span>
        <span class="camera-value">{{ cameraInfo.position.z }}</span>
      </div>
    </div>
    <div class="camera-section">
      <div class="section-label">目标点 (cm)</div>
      <div class="camera-item">
        <span class="camera-label">X:</span>
        <span class="camera-value">{{ cameraInfo.target.x }}</span>
      </div>
      <div class="camera-item">
        <span class="camera-label">Y:</span>
        <span class="camera-value">{{ cameraInfo.target.y }}</span>
      </div>
      <div class="camera-item">
        <span class="camera-label">Z:</span>
        <span class="camera-value">{{ cameraInfo.target.z }}</span>
      </div>
    </div>
    <div class="camera-section">
      <div class="section-label">缩放距离 (m)</div>
      <div class="camera-item">
        <span class="camera-label">当前:</span>
        <span class="camera-value">{{ cameraInfo.distance }}</span>
      </div>
      <div class="camera-item">
        <span class="camera-label">最近:</span>
        <span class="camera-value">{{ cameraInfo.minDistance }}m</span>
      </div>
      <div class="camera-item">
        <span class="camera-label">最远:</span>
        <span class="camera-value">{{ cameraInfo.maxDistance }}m</span>
      </div>
    </div>
  </div>

  <div v-if="showWaterPanel" class="panel water-panel">
    <div class="panel-header">
      <span class="panel-title">水面参数调节</span>
      <button class="toggle-btn" @click="showWaterPanel = false">×</button>
    </div>
    <div class="water-section">
      <div class="section-label">透明度</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.alpha" min="0" max="1" step="0.01" />
        <span class="slider-value">{{ waterParams.alpha.toFixed(2) }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">水流速度</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.flowSpeed" min="0" max="3" step="0.1" />
        <span class="slider-value">{{ waterParams.flowSpeed.toFixed(1) }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">流向 X</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.flowDirectionX" min="-2" max="2" step="0.1" />
        <span class="slider-value">{{ waterParams.flowDirectionX.toFixed(1) }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">流向 Z</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.flowDirectionY" min="-2" max="2" step="0.1" />
        <span class="slider-value">{{ waterParams.flowDirectionY.toFixed(1) }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">水颜色</div>
      <div class="color-item">
        <input type="color" v-model="waterParams.waterColor" />
        <span class="color-value">{{ waterParams.waterColor }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">太阳光颜色</div>
      <div class="color-item">
        <input type="color" v-model="waterParams.sunColor" />
        <span class="color-value">{{ waterParams.sunColor }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">波纹强度</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.distortionScale" min="0" max="100" step="1" />
        <span class="slider-value">{{ waterParams.distortionScale.toFixed(0) }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">噪声缩放</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.noiseScale" min="0.1" max="5" step="0.1" />
        <span class="slider-value">{{ waterParams.noiseScale.toFixed(1) }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">菲涅尔偏移</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.fresnelBias" min="0" max="1" step="0.01" />
        <span class="slider-value">{{ waterParams.fresnelBias.toFixed(2) }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">菲涅尔功率</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.fresnelPower" min="0.1" max="10" step="0.1" />
        <span class="slider-value">{{ waterParams.fresnelPower.toFixed(1) }}</span>
      </div>
    </div>
    <div class="water-section">
      <div class="section-label">菲涅尔强度</div>
      <div class="slider-item">
        <input type="range" v-model.number="waterParams.fresnelStrength" min="0" max="3" step="0.1" />
        <span class="slider-value">{{ waterParams.fresnelStrength.toFixed(1) }}</span>
      </div>
    </div>
  </div>
</template>

<style scoped>
.scene-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

.toolbar {
  position: fixed;
  top: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 1001;
}

.toolbar-btn {
  padding: 10px 16px;
  border: none;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.85);
  color: #888;
  font-size: 13px;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.2s;
  min-width: 70px;
}

.toolbar-btn:hover {
  background: rgba(30, 30, 30, 0.9);
  color: #fff;
}

.toolbar-btn.active {
  color: #fff;
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.2);
}

.toolbar-btn:nth-child(1).active { color: #4fc3f7; }
.toolbar-btn:nth-child(2).active { color: #ff9800; }
.toolbar-btn:nth-child(3).active { color: #4dd0e1; }

.panel {
  position: fixed;
  top: 20px;
  left: 20px;
  background: rgba(0, 0, 0, 0.85);
  color: white;
  padding: 15px;
  border-radius: 8px;
  font-family: 'Courier New', monospace;
  z-index: 1000;
  max-height: calc(100vh - 40px);
  overflow-y: auto;
}

.coordinate-panel { min-width: 200px; }
.camera-panel { min-width: 200px; }
.water-panel { min-width: 240px; }

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}

.panel-title {
  font-weight: bold;
  font-size: 14px;
}

.coordinate-panel .panel-title { color: #4fc3f7; }
.camera-panel .panel-title { color: #ff9800; }
.water-panel .panel-title { color: #4dd0e1; }

.toggle-btn {
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.15);
  color: white;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s;
}

.toggle-btn:hover {
  background: rgba(255, 255, 255, 0.3);
}

.coordinate-item {
  display: flex;
  justify-content: space-between;
  margin: 5px 0;
}

.coordinate-label {
  color: #81c784;
  font-weight: bold;
}

.coordinate-value {
  color: #fff;
}

.camera-section {
  margin-bottom: 10px;
}

.section-label {
  color: #81c784;
  font-size: 11px;
  margin-bottom: 5px;
  font-weight: bold;
}

.camera-item {
  display: flex;
  justify-content: space-between;
  margin: 3px 0;
}

.camera-label {
  color: #4fc3f7;
}

.camera-value {
  color: #fff;
}

.water-section {
  margin-bottom: 12px;
}

.water-section .section-label {
  color: #81c784;
  font-size: 11px;
  margin-bottom: 6px;
  font-weight: bold;
}

.slider-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.slider-item input[type="range"] {
  flex: 1;
  height: 6px;
  -webkit-appearance: none;
  background: #444;
  border-radius: 3px;
  outline: none;
}

.slider-item input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  background: #4dd0e1;
  border-radius: 50%;
  cursor: pointer;
}

.slider-value {
  min-width: 45px;
  text-align: right;
  color: #fff;
  font-size: 11px;
}

.color-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.color-item input[type="color"] {
  width: 40px;
  height: 28px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  background: transparent;
}

.color-item input[type="color"]::-webkit-color-swatch-wrapper {
  padding: 0;
}

.color-item input[type="color"]::-webkit-color-swatch {
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 4px;
}

.color-value {
  color: #fff;
  font-size: 11px;
}
</style>
