<template>
  <div>
    <div id="map" class="map-container"></div>
    <!-- <countarea-panel
      :buildid="tbuildId"
      :countdic="countDic"
      :show="buildData ? buildData.CountareaPanelOpen : false"
      v-if="buildData ? buildData.CountareaPanelDisplay : false"
    ></countarea-panel> -->
    <image-video :cameraData.sync="cameraData" :visible.sync="cameraVisible"></image-video>
  </div>
</template>

<script>
import 'maptalks/dist/maptalks.css'
import * as maptalks from 'maptalks'
import * as mqtt from 'mqtt'
import { getMQTTCilentId } from '@/utils/mqtt'
import {
  getRailListJson,
  getAreaListJson,
  getCameraListJson,
  getPerimeterListJson,
} from '@/api/positioning/map'
import CountareaPanel from '@/components/CountareaPanel'
import ImageVideo from '@/components/ImageVideo'

import {
  getRobotList,
  getRecognizeList,
  getAreaTree,
  getNaviList,
  getPositionList,
  getSenceList,
  getTaskList,
  getRobotToken,
  getPatrolRecordList,
  getAlarmList,
  getRealtimeList,
} from '@/api/robotSLG/public'

export default {
  name: 'Map',
  components: { CountareaPanel, ImageVideo },
  data() {
    return {
      locationData: null,
      baseRelativeCoordinate0: null,
      baseRelativeCoordinate1: null,
      baseRelativeExtent: null,
      baseGPSCoordinate0: null,
      baseGPSCoordinate1: null,
      baseGPSExtent: null,
      baseExtent: null,
      //
      buildNo: 0, //默认建筑编号，和建筑数据内容在数组中的下标一致
      buildPanelPos: 0,
      floorNo: 0, //默认楼层编号，和楼层数据在FloorList数组的下标一致
      floorPanelPos: 0,
      floorNoArray: [], //楼层数据，需为数组格式（接口参数规定）
      postExtent: null,
      //
      buildData: null,
      //
      map: null,
      mapLayer: null,
      personLayer: null,
      railLayer: null,
      railAlarmLayer: null,
      cameraLayer: null,
      perimeterLayer: null,
      perimeterAlarmLayer: null,
      historyLayer: null,
      //巡检机器人增加
      robotNavLayer: null,
      robotLayer: null,
      //
      debugPanel: null,
      floorPanel: null,
      buildPanel: null,

      mqttClient: null,
      topicArray: [],
      topicCount: null,

      areaList: [],
      perimeterList: [],

      personAlarm: {},
      railAlarm: {},
      areaAlarm: {},
      arearailAlarm: {},
      alarmingPerson: [],
      alarmingRail: [],
      countDic: {},

      cameraData: {},
      cameraVisible: false,

      //机器人修改
      robotToken: '',
      patrolRecord: [],
      realltimeData: [],
      naviList: [],
      runningTaskList: [],
    }
  },
  computed: {
    VUE_APP_BASE_API() {
      return process.env.VUE_APP_BASE_API
    },
    VUE_APP_BASE_WS() {
      return 'ws://' + window.location.host + process.env.VUE_APP_BASE_API
    },
    tbuildId() {
      return this.buildData ? this.buildData.BuildId || '' : ''
    },
  },
  created() {
    window.moveBuildPanel = this.moveBuildPanel
    window.changeBuild = this.changeBuild
    window.moveFloorPanel = this.moveFloorPanel
    window.changeFloor = this.changeFloor
    //机器人相关
    this.initRobotInfo().then(() => {
      this.getNaviListOption().then(() => {
        this.addRobotNav() //添加机器人
        this.getRunningTask()
      })
      // 获取正在执行巡检任务
      setInterval(() => {
        if (this.runningTask == null || this.runningTask.id === '23') {
          console.log('寻找执行中任务')
          this.getRunningTask()
        }
      }, 5000)
    })
  },
  mounted() {
    this.$nextTick(async (_) => {
      await this.getLocationData()
    })
    this.$nextTick(() => {
      if (this.$route.query.type) {
        this.railLayer.show()
      }
    })
  },
  beforeDestroy() {
    this.mqttClient?.end()
  },
  methods: {
    // 机器人登录获取token
    async initRobotInfo() {
      try {
        let res = await getRobotToken(ROBOT)
        if (res.code === 1) {
          this.robotToken = res.data
        }
      } catch (error) {}
    },
    //机器人最新巡检记录实时信息
    async getPatrolRealltimeROption() {
      try {
        let res = await getRealtimeList({
          token: this.robotToken,
          pageIndex: 1,
          pageSize: 100,
          robotId: this.patrolRecord.id,
        })
        if (res.code === 1) {
          this.realltimeData = res.data.list
          console.log('实时信息')
          console.log(this.realltimeData)
        } else {
          this.initRobotInfo()
        }
        PatrolR
      } catch (error) {}
    },

    //机器人导航点数据
    async getNaviListOption() {
      try {
        let res = await getNaviList({ token: this.robotToken, pageIndex: 1, pageSize: 100 })
        if (res.code === 1) {
          this.naviList = res.data.list
          //设置添加所有导航点并隐藏
          this.setNavPointList()
        } else {
          this.initRobotInfo()
        }
      } catch (error) {}
    },
    //机器人正在执行任务
    async getRunningTask() {
      try {
        let res = await getTaskList({
          token: this.robotToken,
          pageIndex: 1,
          pageSize: 10,
          state: 'RUNNING',
          // titleList: '20230519120000',
        })
        if (res.code === 1) {
          if (res.data.list && res.data.list.length > 0) {
            this.runningTaskList = res.data.list[0]
            // console.log(this.runningTaskList)
            if (this.runningTaskList.id !== '23') {
              //更新地图为巡检任务点
              this.showTaskPoint()
              //实时获取任务对应巡检记录更新导航点状态
              this.getPatrolRecordROption(this.runningTaskList)
            }
          }
        } else {
          this.initRobotInfo()
        }
      } catch (error) {}
    },
    //机器人最新巡检记录
    async getPatrolRecordROption(c) {
      // console.log(c);
      try {
        let res = await getPatrolRecordList({
          token: this.robotToken,
          pageIndex: 1,
          pageSize: 100,
          taskIdList: [c.id],
          // taskIdList: ["4121"],
        })
        if (res.code === 1) {
          this.patrolRecord = res.data.list[0]
          console.log('记录信息')
          console.log(this.patrolRecord)
          //根据最新巡检记录更新导航点状态
          this.updateTaskPointState()
          // this.chengeRobot(this.)
          this.getPatrolRealltimeROption()
        } else {
          this.initRobotInfo()
        }
        PatrolR
      } catch (error) {}
    },
    //导航图层添加所有导航点
    setNavPointList() {
      this.robotNavLayer.clear()
      if (this.naviList) {
        this.naviList.forEach((check) => {
          var m = new maptalks.Marker(
            this.getNewCoordinate(+check.coordinateY * 100, +check.coordinateX * 100),
            {
              id: check.id,
              visible: false,
              symbol: {
                markerFile: this.VUE_APP_BASE_API + '/../static/images/waitP.svg',
                markerWidth: 40,
                markerHeight: 40,
                markerDx: 0,
                markerDy: 20,
              },
              properties: {
                id: check.id,
                name: check.alias,
                data: check,
              },
            }
          ).addTo(this.robotNavLayer)
          m.on('click', '')
        })
      }
      return m
    },
    //显示任务点
    showTaskPoint() {
      if (this.runningTaskList) {
        this.runningTaskList.positionList.forEach((a) => {
          let p = this.robotNavLayer.getGeometryById(a.naviId)
          // console.log(p)
          p.options.visible = true
        })
      }
    },
    //更新任务状态
    updateTaskPointState() {
      if (this.patrolRecord) {
        let p = this.robotNavLayer.getGeometryById(this.patrolRecord.naviId)
        // console.log(p)
        p.updateSymbol({
          markerFile: this.VUE_APP_BASE_API + '/../static/images/finishP.svg',
          markerWidth: 40,
          markerHeight: 40,
          markerDx: 0,
          markerDy: 20,
        })

        return marker
      }
    },
    //初始化机器人位置
    addRobotNav() {
      //获取一个初始点
      if (this.naviList) {
        let p = this.naviList[0]
        let marker = new maptalks.Marker(
          this.getNewCoordinate(+p.coordinateY * 100, +p.coordinateX * 100),
          {
            id: p.Id,
            visible: true,
            symbol: [
              {
                markerFile: this.VUE_APP_BASE_API + '/../static/images/robot.svg',
                // markerFile: this.VUE_APP_BASE_API + '/../static/images/waitP.svg',
                markerWidth: 40,
                markerHeight: 40,
                markerDx: 0,
                markerDy: 20,
                textName: p.alias,
                textDx: 0,
                textDy: 20,
              },
              {
                textName: '',
                textWeight: 'bold',
                textStyle: 'normal',
                textSize: 0,
                textFill: '#FF0000',
                textOpacity: 1,
                textDx: 0,
                textDy: -20,
              },
            ],
            properties: {
              id: p.Id,
              name: p.alias,
            },
          }
        ).addTo(this.robotLayer)
        return marker
      }
      // marker.setInfoWindow({
      //   title: person.Name,
      //   width: 300,
      //   autoCloseOn: 'click contextmenu',
      //   content:
      //     '<table width = "100%" style="border-bottom: 0px solid rgb(231, 234, 236) !important">\
      //                   <tr>\
      //                     <td width = "40%" rowspan="5" align="center">\
      //                       <img src="' +
      //     (person.PhotoPath
      //       ? this.VUE_APP_BASE_API + person.PhotoPath
      //       : 'static/images/default.png') +
      //     '" style="width: 85px; height: 140px; object-fit: contain"/>\
      //                     </td>\
      //                     <td class="tdname">类型：</td>\
      //                     <td class="tddata">' +
      //     person.TypeName +
      //     '</td>\
      //                   <tr>\
      //                     <td class="tdname">部门：</td>\
      //                     <td class="tddata">' +
      //     person.DepartmentName +
      //     '</td>\
      //                   </tr>\
      //                   <tr>\
      //                     <td class="tdname">职位：</td>\
      //                     <td class="tddata">' +
      //     person.PositionName +
      //     '</td>\
      //                   </tr>\
      //                   <tr>\
      //                     <td class="tdname">电话：</td>\
      //                     <td class="tddata">' +
      //     person.Telephone +
      //     '</td>\
      //                   </tr>\
      //                   <tr>\
      //                     <td class="tdname">SN：</td>\
      //                     <td class="tddata">' +
      //     person.LabelMAC +
      //     '</td>\
      //                   </tr>\
      //                   <tr style="height:10px"/>\
      //                </table>',
      // })

      // this.personAlarming(person.Id)
    },
    //
    chengeRobot(robot) {
      let p = this.robotLayer.getGeometryById(robot.naviId)
      if (p) {
        p.animate(
          {
            translate: this.getRobotOffset(p, robot),
          },
          {
            duration: 1000,
          }
        )
      } else {
        this.addRobotNav(robot)
      }
    },
    //机器人移动
    getRobotOffset(geometry, robot) {
      let start = geometry.getCoordinates()
      let end = this.getNewCoordinate(+robot.coordinateY * 100, +robot.coordinateX * 100)
      return end.sub(start)
    },
    //地图初始化数据
    async getLocationData() {
      this.locationData = this.$setting

      if (this.locationData) {
        this.buildNo = this.locationData.DefaultBuild // 默认建筑(在BuildList数组的位置)
        this.buildData = this.locationData.BuildList[this.buildNo] //默认建筑数据
        this.mapBaseLayer = this.locationData.MapBaseLayer //地图底图

        this.floorNo = this.buildData.DefaultFloor //默认楼层(在FloorList数组的位置)

        if (this.buildData.FloorList[this.floorNo].No instanceof Array) {
          // 楼层数据，数组格式
          this.floorNoArray = this.buildData.FloorList[this.floorNo].No
        } else {
          this.floorNoArray = [this.buildData.FloorList[this.floorNo].No]
        }

        this.baseRelativeCoordinate0 = new maptalks.Coordinate(this.buildData.RelativeCoordinate0) //左上角相对坐标，单位：毫米
        this.baseRelativeCoordinate1 = new maptalks.Coordinate(this.buildData.RelativeCoordinate1) //右下角相对坐标，单位：毫米
        //Extent 表示地图上的边界框，一个具有最小和最大坐标的矩形经纬度
        // baseRelativeExtent 生成了一个相对坐标的边界矩形
        this.baseRelativeExtent = new maptalks.Extent(
          this.baseRelativeCoordinate0,
          this.baseRelativeCoordinate1
        )

        if (this.buildData.MultiMap) {
          //同一个服务器上是否有同一个BuildId的多个地图
          this.postExtent = [
            this.baseRelativeCoordinate0.x,
            this.baseRelativeCoordinate0.y,
            this.baseRelativeCoordinate1.x,
            this.baseRelativeCoordinate1.y,
          ]
        } else {
          this.postExtent = null
        }

        if (this.buildData.Projection == 'identity') {
          // Projection 地图投影  值为EPSG:3857
          // baseExtent  生成一个GPS坐标的矩形
          this.baseExtent = new maptalks.Extent(
            new maptalks.Coordinate(0, 0),
            new maptalks.Coordinate(
              this.baseRelativeCoordinate1.x - this.baseRelativeCoordinate0.x,
              this.baseRelativeCoordinate0.y - this.baseRelativeCoordinate1.y
            )
          )
        } else {
          // GPSCoordinate0  左上角GPS坐标（WGS84） x:经度 y:纬度
          // GPSCoordinate1  右下角GPS坐标（WGS84） x:经度 y:纬度
          this.baseGPSCoordinate0 = new maptalks.Coordinate(this.buildData.GPSCoordinate0)
          this.baseGPSCoordinate1 = new maptalks.Coordinate(this.buildData.GPSCoordinate1)
          this.baseGPSExtent = new maptalks.Extent(this.baseGPSCoordinate0, this.baseGPSCoordinate1)
          this.baseExtent = this.baseGPSExtent
        }
        await this.createMap()
      } else {
        console.log('获取定位配置文件失败')
      }
    },
    async createMap() {
      let zoom, maxZoom, minZoom, baseLayer, resolution0, resolutionMax

      if (this.buildData.Projection == 'identity') {
        zoom = this.buildData.RelativeMapZoom // 相对坐标地图缩放
        maxZoom = this.buildData.RelativeMapMaxZoom //相对坐标地图最大缩放
        minZoom = this.buildData.RelativeMapMinZoom //相对坐标地图最小缩放
        resolution0 = this.buildData.RelativeResolution0 //相对坐标地图最大分辨率
        resolutionMax = this.buildData.RelativeResolutionMax //相对坐标地图最大分辨率倍数
        baseLayer = null
      } else {
        zoom = this.buildData.GPSMapZoom //GPS地图缩放
        maxZoom = this.buildData.GPSMapMaxZoom //GPS地图最大缩放
        minZoom = this.buildData.GPSMapMinZoom //GPS地图最小缩放
        resolution0 = this.buildData.GPSResolution0 //GPS地图最大分辨率
        resolutionMax = this.buildData.GPSResolutionMax //GPS地图最大分辨率倍数
        baseLayer = new maptalks.TileLayer('base', this.mapBaseLayer) //地图来源
      }

      if (this.map) this.map.remove()
      this.map = new maptalks.Map('map', {
        center: this.baseExtent.getCenter(), //地图中点
        //centerCross: true,
        zoom: zoom,
        maxZoom: maxZoom,
        minZoom: minZoom,
        bearing: this.buildData.MapBearing, //地图旋转角度
        pitch: this.buildData.MapPitch, //地图倾斜角度
        maxExtent: this.baseExtent, //地图最大范围，平移超出范围会反弹回来
        zoomControl: {
          // 缩放控件
          position: 'top-left',
          slider: false,
          zoomLevel: false,
        },
        scaleControl: true, //比例尺控件
        spatialReference: {
          // Map 的空间引用，默认使用的是google的地图投影 EPSG: 3857
          projection: this.buildData.Projection,
          resolutions: (function () {
            const resolutions = []
            for (let i = 0; i <= resolutionMax; i++) {
              resolutions[i] = resolution0 / Math.pow(2, i)
            }
            return resolutions
          })(),
        },
        baseLayer: baseLayer, //基础图层
      })
      //将地图设置为适合给定范围的最大缩放级别
      this.map.fitExtent(this.baseExtent, 0)
      // 图片图层
      this.mapLayer = new maptalks.ImageLayer(
        'map',
        [
          {
            url: this.buildData.FloorList[this.floorNo].MapPath,
            extent: this.baseExtent,
            opacity: 1,
          },
        ],
        {
          forceRenderOnMoving: true,
          forceRenderOnZooming: true,
          forceRenderOnRotating: true,
        }
      ).addTo(this.map)
      // 矢量图层
      this.robotNavLayer = new maptalks.VectorLayer('robotNav', {
        zIndex: 2,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)

      this.robotLayer = new maptalks.VectorLayer('robot', {
        zIndex: 1,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)

      this.personLayer = new maptalks.VectorLayer('person', {
        zIndex: 100,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)

      this.cameraLayer = new maptalks.VectorLayer('camera', {
        zIndex: 10,
        visible: this.buildData.CameraLayerDisplay,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)

      this.railLayer = new maptalks.VectorLayer('rail', {
        zIndex: 1,
        visible: false,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)

      this.railAlarmLayer = new maptalks.VectorLayer('railAlarm', {
        zIndex: 2,
        visible: true,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)

      this.perimeterLayer = new maptalks.VectorLayer('perimeter', {
        zIndex: 3,
        visible: true,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)

      this.perimeterAlarmLayer = new maptalks.VectorLayer('perimeterAlarm', {
        zIndex: 40,
        visible: true,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)

      this.historyLayer = new maptalks.VectorLayer('history', {
        zIndex: 20,
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
      }).addTo(this.map)
      // 右上角工具栏
      let _this = this
      new maptalks.control.Toolbar({
        items: [
          {
            item: '复位地图',
            click: function () {
              _this.map.animateTo(
                {
                  //center: baseExtent.getCenter(),
                  //zoom: 13,
                  bearing: _this.buildData.MapBearing,
                  pitch: _this.buildData.MapPitch,
                },
                {
                  duration: 1000,
                },
                (frame) => {
                  if (frame.state.playState === 'finished') {
                    _this.map.fitExtent(_this.baseExtent, 0, {
                      duration: 1000,
                    })
                  }
                }
              )
            },
          },
          // {
          //   item: '围栏',
          //   children: [
          //     {
          //       item: '显示',
          //       click: function () {
          //         _this.railLayer.show()
          //       },
          //     },
          //     {
          //       item: '隐藏',
          //       click: function () {
          //         _this.railLayer.hide()
          //       },
          //     },
          //   ],
          // },
          // {
          //   item: '摄像头',
          //   children: [
          //     {
          //       item: '显示',
          //       click: function () {
          //         _this.cameraLayer.show()
          //       },
          //     },
          //     {
          //       item: '隐藏',
          //       click: function () {
          //         _this.cameraLayer.hide()
          //       },
          //     },
          //   ],
          // },
        ],
      }).addTo(this.map)
      // 右下角信息栏
      if (this.buildData.DebugPanelDisplay) {
        this.debugPanel = new maptalks.control.Panel({
          position: 'bottom-right',
          draggable: false,
          custom: true,
          content: '<div class="map-debugpanel">hello </div>',
          closeButton: false,
        }).addTo(this.map)

        this.map.on('click', (e) => this.update(e))
      }
      // 楼层控制器
      if (this.buildData.FloorPanelDisplay) {
        this.createFloorPanel()
      }
      // 地图选择器
      // if (this.locationData.BuildPanelDisplay) {
      //   this.createBuildPanel()
      // }

      // await this.getRail()
      // await this.getArea()
      // await this.getCamera()
      // await this.getPerimeter()
      // this.getLocation()

      this.startMQTT()

      // if (!this.interval1)
      //   this.interval1 = setInterval(() => {
      //     //this.getLocation()
      //     this.getRailAlarm()
      //   }, 1000)
      // 点选重叠图形
      this.map.on('contextmenu', (e) => this.identifyAndSelect(e))
    },
    //开始MQTT接收
    startMQTT() {
      this.personAlarm = {}
      this.railAlarm = {}
      this.areaAlarm = {}
      this.arearailAlarm = {}
      this.alarmingPerson = []
      this.alarmingRail = []

      this.topicArray.splice(0)
      this.floorNoArray.forEach((f) => {
        this.topicArray.push('Positioning/Positioning/' + this.buildData.BuildId + '/' + f + '/#')
        this.topicArray.push('Positioning/Alarm/Person/' + this.buildData.BuildId + '/' + f + '/#')
        this.topicArray.push('Positioning/Alarm/Rail/' + this.buildData.BuildId + '/' + f + '/#')
      })
      this.topicArray.push('Positioning/Alarm/Rail/' + this.buildData.BuildId + '/0/#')
      this.topicArray.push('Positioning/Alarm/Area/' + this.buildData.BuildId + '/#')
      this.topicArray.push('Perimeter/' + this.buildData.BuildId + '/0/#')
      this.topicArray.push('Perimeter/#')
      this.topicCount = 'CountArea/CountDic/' + this.buildData.BuildId

      if (this.mqttClient && this.mqttClient.connected) {
        this.mqttClient.subscribe(this.topicArray)
        this.mqttClient.subscribe(this.topicCount)
        return
      }

      // 连接选项
      const options = {
        clean: true, // true: 清除会话, false: 保留会话
        keepalive: 60,
        connectTimeout: 4000, // 超时时间
        // 认证信息
        clientId: getMQTTCilentId('map'),
        username: 'client',
        password: '19c9547ad2029be96774fce5f1b9f099',
      }
      const connectUrl = this.VUE_APP_BASE_WS + '/MQTTOverWebSocket'
      //console.log(connectUrl)
      this.mqttClient = mqtt.connect(connectUrl, options)

      let _this = this
      this.mqttClient.on('connect', function () {
        //订阅主题
        console.log('定位MQTT正在连接')
        _this.mqttClient.subscribe(_this.topicArray)
        _this.mqttClient.subscribe(_this.topicCount)
      })
      this.mqttClient.on('message', (topic, message) => {
        if (topic == 'Online') {
          console.log('定位MQTT收到消息：', topic, message.toString())
        } else if (topic.startsWith('Positioning/Positioning/')) {
          this.chengePerson(JSON.parse(message.toString()))
          //console.log(JSON.parse(message.toString()))
        } else if (topic.startsWith('Positioning/Alarm/')) {
          let alarm = JSON.parse(message.toString())
          switch (alarm.AlarmSource) {
            case 1:
              this.personAlarm[alarm.Id] = alarm.AlarmList
              this.personAlarming(alarm.Id)
              break
            case 2:
              this.railAlarm[alarm.Id] = alarm.AlarmList
              this.railAlarming(alarm.Id)
              break
            case 3:
              this.areaAlarm[alarm.Id] = alarm.AlarmList
              let area = this.areaList.find((v) => v.id == alarm.Id)
              if (area && area.railIds && area.railIds.length > 0) {
                area.railIds.forEach((a) => {
                  if (this.arearailAlarm[a]) {
                    if (alarm.AlarmList.length > 0) {
                      if (this.arearailAlarm[a].indexOf(area.id) == -1)
                        this.arearailAlarm[a].push(area.id)
                    } else {
                      let i = this.arearailAlarm[a].indexOf(area.id)
                      if (i >= 0) this.arearailAlarm[a].splice(i, 1)
                    }
                  } else {
                    this.arearailAlarm[a] = []
                    if (alarm.AlarmList.length > 0) this.arearailAlarm[a].push(area.id)
                  }
                  this.railAlarming(a)
                })
              }
              break
            default:
              break
          }
        } else if (topic.startsWith('CountArea/CountDic/')) {
          let count = JSON.parse(message.toString())
          this.countDic = count
        } else if (topic.startsWith('Perimeter/')) {
          let perimeter = JSON.parse(message.toString())
          if (
            perimeter.buildId == this.buildData.BuildId &&
            (this.floorNoArray.indexOf(perimeter.floorNo) > -1 || perimeter.FloorNo == 0)
          ) {
            //console.log(perimeter)
            this.chengePerimeter(perimeter)
          }
        }
      })
    },
    chengePerson(person) {
      if (person.Display == 1) {
        let p = this.personLayer.getGeometryById(person.Id)
        if (p) {
          this.personMove(p, person)
        } else {
          this.addPerson(person)
        }
      } else {
        let p = this.personLayer.getGeometryById(person.Id)
        if (p) {
          p.remove()
        }
      }
    },
    chengePerimeter(perimeter) {
      let s = this.perimeterLayer.getGeometryById(perimeter.segmentId)
      if (!s) s = this.addPerimeter(perimeter.segmentId)
      if (s) {
        switch (perimeter.alarmType) {
          case 0: //无报警
            s.setSymbol({
              lineColor: '#00ff00',
              lineWidth: 4,
              lineOpacity: 1,
            })
            break
          case 1: //离线
            s.setSymbol({
              lineColor: '#ababab',
              lineWidth: 4,
              lineOpacity: 1,
            })
            break
          case 2: //警告
            s.setSymbol({
              lineColor: '#00ff00',
              lineWidth: 4,
              lineOpacity: 1,
            })
            s.openInfoWindow()
            break
          case 3: //报警
            s.setSymbol({
              lineColor: '#00ff00',
              lineWidth: 4,
              lineOpacity: 1,
            })
            s.openInfoWindow()
            break
          default:
            break
        }
        this.changPerimeterAlarm(perimeter.segmentId, perimeter.alarmType, perimeter.camera)
      }
    },
    addPerimeter(id) {
      let perimeter
      let segment
      for (let p in this.perimeterList) {
        perimeter = this.perimeterList[p]
        segment = perimeter.segments.find((b) => b.id == id)
        if (segment) break
      }
      let s
      if (perimeter && segment) {
        s = new maptalks.LineString(
          segment.points.map((p) => this.getNewCoordinate(p.x, p.y)),
          {
            id: segment.id,
            symbol: {
              lineColor: '#00ff00',
              lineWidth: 4,
              lineOpacity: 1,
            },
            properties: {
              id: segment.id,
              name: perimeter.name + '分段' + segment.code,
            },
          }
        )
          .addTo(this.perimeterLayer)
          .setInfoWindow({
            width: 150,
            content: perimeter.name + '分段' + segment.code,
          })
      }
      return s
    },
    changPerimeterAlarm(id, alarmType, camera) {
      let color
      switch (alarmType) {
        case 0: //无报警
          return
        case 1: //离线
          return
        case 2: //警告
          color = '#ffff00'
          break
        case 3: //报警
          color = '#ff0000'
          break
        default:
          break
      }
      let g = this.perimeterAlarmLayer.getGeometryById(id)
      if (g) {
        if (g.getSymbol().lineColor == '#ff0000') color = '#ff0000'
        g.setSymbol({
          lineColor: color,
          lineWidth: 6,
          lineOpacity: 1,
        })
        return
      }
      let perimeter
      let segment
      for (let p in this.perimeterList) {
        perimeter = this.perimeterList[p]
        segment = perimeter.segments.find((b) => b.id == id)
        if (segment) break
      }
      if (perimeter && segment) {
        let s = new maptalks.LineString(
          segment.points.map((p) => this.getNewCoordinate(p.x, p.y)),
          {
            id: segment.id,
            symbol: {
              lineColor: color,
              lineWidth: 6,
              lineOpacity: 1,
            },
          }
        ).addTo(this.perimeterAlarmLayer)
        s.on('click', (param) => this.perimeterAlarmLayer.removeGeometry(param.target))
        setTimeout(() => this.flashPerimeterAlarm(id), 500)

        if (alarmType == 2 || alarmType == 3) {
          this.cameraVisible = true
          this.cameraData = camera
        }
      }
    },
    flashPerimeterAlarm(id) {
      let g = this.perimeterAlarmLayer.getGeometryById(id)
      if (g) {
        let s = g.getSymbol()
        s.lineOpacity = s.lineOpacity == 1 ? 0 : 1
        if (g) {
          g.setSymbol(s)
          setTimeout(() => this.flashPerimeterAlarm(id), 500)
        }
      }
    },
    // 获取围栏
    async getRail() {
      this.railLayer.clear()
      this.railAlarmLayer.clear()
      let params = {
        BuildId: this.buildData.BuildId,
        FloorNoArray: this.floorNoArray,
        Extent: this.postExtent,
        // riskLevelArray: [1, 2, 3, 4] //四色图参数
      }
      try {
        let res = await getRailListJson(params)
        let data = res.data.content
        if (data.length > 0) {
          data.forEach((r) => {
            let inExtent = true
            let points = []
            r.points.forEach((p) => {
              if (!this.baseRelativeExtent.contains(new maptalks.Coordinate(p.x, p.y)))
                inExtent = false
              points.push(this.getNewCoordinate(p.x, p.y))
            })
            if (inExtent) {
              this.railLayer.addGeometry(
                new maptalks.Polygon(points, {
                  symbol: {
                    lineColor: 'rgb(0,196,240)',
                    lineWidth: 2,
                    lineOpacity: 1,
                    polygonFill: 'rgb(135,196,240)',
                    polygonOpacity: 0.6,
                  },
                })
              )
              this.railAlarmLayer.addGeometry(
                new maptalks.Polygon(points, {
                  id: r.id,
                  visible: false,
                  symbol: {
                    lineColor: '#C06173',
                    lineWidth: 2,
                    lineOpacity: 1,
                    polygonFill: '#E08193',
                    polygonOpacity: 0.6,
                  },
                })
              )
              this.railAlarming(r.id)
            }
          })
        }
      } catch (error) {
        console.log(error)
        this.$message.error(error)
      }
    },
    // 获取摄像头
    async getCamera() {
      this.cameraLayer.clear()
      let params = {
        buildId: this.buildData.BuildId,
        floorNoArray: this.floorNoArray,
        extent: this.postExtent,
      }
      try {
        let res = await getCameraListJson(params)
        let data = res.data.content
        if (data.length > 0) {
          data.forEach((c) => {
            var m = new maptalks.Marker(this.getNewCoordinate(c.location.x, c.location.y), {
              id: c.id,
              visible: true,
              symbol: {
                markerFile: this.VUE_APP_BASE_API + c.iconPath,
                markerWidth: 40,
                markerHeight: 40,
                markerDx: 0,
                markerDy: 20,
              },
              properties: {
                id: c.id,
                name: c.name,
                data: c,
              },
            }).addTo(this.cameraLayer)
            m.on('click', this.cameraClickHandler)
          })
        }
      } catch (error) {
        console.log(error)
        this.$message.error(error)
      }
    },
    cameraClickHandler(param) {
      let c = param.target.getProperties()
      this.cameraVisible = true
      this.cameraData = c.data
    },
    // 获取区域
    async getArea() {
      let params = {
        BuildId: this.buildData.BuildId,
        // riskLevelArray: [1, 2, 3, 4] //四色图参数
      }
      try {
        let res = await getAreaListJson(params)
        let data = res.data.content
        this.areaList = data
      } catch (error) {
        console.log(error)
        this.$message.error(error)
      }
    },
    // 获取周界
    async getPerimeter() {
      this.perimeterLayer.clear()
      this.perimeterAlarmLayer.clear()
      this.perimeterList = []
      let params = {
        BuildId: this.buildData.BuildId,
        FloorNoArray: this.floorNoArray,
        Extent: this.postExtent,
      }
      try {
        let res = await getPerimeterListJson(params)
        let data = res.data.content
        if (data.length > 0) {
          this.perimeterList = data
        }
      } catch (error) {
        console.log(error)
        this.$message.error(error)
      }
    },
    // 创建地图选择按钮模块
    createBuildPanel() {
      if (this.buildNo <= 1) {
        this.buildPanelPos = 0
      } else if (this.buildNo >= this.locationData.BuildList.length - 3) {
        this.buildPanelPos = this.locationData.BuildList.length - 3
      } else {
        this.buildPanelPos = this.buildNo - 1
      }

      let mapdiv = document.getElementById('map')
      let mapdivh = mapdiv.clientHeight || mapdiv.offsetHeight

      this.buildPanel = new maptalks.control.Panel({
        position: { top: mapdivh / 2 - 60, left: '20' },
        draggable: false,
        custom: true,
        content: this.makeBuildPanelContent(),
        closeButton: false,
      }).addTo(this.map)
    },
    // 左下按钮页面内容生成
    makeBuildPanelContent() {
      let content
      content = '<table class="map-buildpanel" cellpadding="0" frame=void rules=none>'
      content +=
        '<tr><td><button onclick="moveBuildPanel(0)"><div class="up-arrows"></div></button></td></tr>'
      for (let i = this.buildPanelPos; i <= this.buildPanelPos + 2; i++) {
        if (i == this.buildNo) {
          content +=
            '<tr><td><button style="background: rgb(28,188,156);">' +
            this.locationData.BuildList[i].BuildAbbName +
            '</button></td></tr>'
        } else {
          if (this.locationData.BuildList[i]) {
            content +=
              '<tr><td><button onclick="changeBuild(' +
              i +
              ')">' +
              this.locationData.BuildList[i].BuildAbbName +
              '</button></td></tr>'
          } else {
            content += '<tr><td><button></button></td></tr>'
          }
        }
      }

      content +=
        '<tr><td><button onclick="moveBuildPanel(1)"><div class="down-arrows"></div></button></td></tr>'
      content += '</table>'
      return content
    },
    // 点击地图按钮上下箭头
    moveBuildPanel(s) {
      let b = this.buildPanelPos
      if (s == 0) {
        if (b > 0) b--
      } else if (s == 1) {
        if (b < this.buildData.FloorList.length - 3) b++
      }
      if (b != this.buildPanelPos) {
        this.buildPanelPos = b
        this.buildPanel.setContent(this.makeBuildPanelContent())
      }
    },
    // 切换地图按钮操作
    changeBuild(b) {
      this.buildNo = b
      this.buildPanel.setContent(this.makeBuildPanelContent())

      this.buildData = this.locationData.BuildList[this.buildNo]

      this.floorNo = this.buildData.DefaultFloor
      if (this.buildData.FloorList[this.floorNo].No instanceof Array) {
        this.floorNoArray = this.buildData.FloorList[this.floorNo].No
      } else {
        this.floorNoArray = [this.buildData.FloorList[this.floorNo].No]
      }

      this.baseRelativeCoordinate0 = new maptalks.Coordinate(this.buildData.RelativeCoordinate0)
      this.baseRelativeCoordinate1 = new maptalks.Coordinate(this.buildData.RelativeCoordinate1)
      this.baseRelativeExtent = new maptalks.Extent(
        this.baseRelativeCoordinate0,
        this.baseRelativeCoordinate1
      )

      if (this.buildData.MultiMap) {
        this.postExtent = [
          this.baseRelativeCoordinate0.x,
          this.baseRelativeCoordinate0.y,
          this.baseRelativeCoordinate1.x,
          this.baseRelativeCoordinate1.y,
        ]
      } else {
        this.postExtent = null
      }

      if (this.buildData.Projection == 'identity') {
        this.baseExtent = new maptalks.Extent(
          new maptalks.Coordinate(0, 0),
          new maptalks.Coordinate(
            this.baseRelativeCoordinate1.x - this.baseRelativeCoordinate0.x,
            this.baseRelativeCoordinate0.y - this.baseRelativeCoordinate1.y
          )
        )
      } else {
        this.baseGPSCoordinate0 = new maptalks.Coordinate(this.buildData.GPSCoordinate0)
        this.baseGPSCoordinate1 = new maptalks.Coordinate(this.buildData.GPSCoordinate1)
        this.baseGPSExtent = new maptalks.Extent(this.baseGPSCoordinate0, this.baseGPSCoordinate1)
        this.baseExtent = this.baseGPSExtent
      }

      if (this.mqttClient && this.mqttClient.connected) {
        if (this.topicArray && this.topicArray.length > 0) {
          this.topicArray.push(this.topicCount)
          this.mqttClient.unsubscribe(this.topicArray, () => {
            if (this.personLayer) this.personLayer.clear()
            this.createMap()
          })
          return
        }
      }

      this.createMap()
    },
    // 创建右下楼层切换按钮模块
    createFloorPanel() {
      if (this.floorNo <= 1) {
        this.floorPanelPos = 0
      } else if (this.floorNo >= this.buildData.FloorList.length - 3) {
        this.floorPanelPos = this.buildData.FloorList.length - 3
      } else {
        this.floorPanelPos = this.floorNo - 1
      }

      let mapdiv = document.getElementById('map')
      let mapdivh = mapdiv.clientHeight || mapdiv.offsetHeight

      if (this.floorPanel) this.floorPanel.remove()

      this.floorPanel = new maptalks.control.Panel({
        position: { top: mapdivh / 2 - 60, right: '20' },
        draggable: false,
        custom: true,
        content: this.makeFloorPanelContent(),
        closeButton: false,
      }).addTo(this.map)
    },
    // 楼层选择按钮模块页面内容生成
    makeFloorPanelContent() {
      let content
      content = '<table class="map-floorpanel" cellpadding="0" frame=void rules=none>'
      content +=
        '<tr><td><button onclick="moveFloorPanel(0)"><div class="up-arrows"></div></button></td></tr>'
      for (let i = this.floorPanelPos; i <= this.floorPanelPos + 2; i++) {
        if (i == this.floorNo) {
          content +=
            '<tr><td><button style="background: rgb(28,188,156)">' +
            this.buildData.FloorList[i].Name +
            '</button></td></tr>'
        } else {
          if (this.buildData.FloorList[i]) {
            content +=
              '<tr><td><button onclick="changeFloor(' +
              i +
              ')">' +
              this.buildData.FloorList[i].Name +
              '</button></td></tr>'
          } else {
            content += '<tr><td><button></button></td></tr>'
          }
        }
      }

      content +=
        '<tr><td><button onclick="moveFloorPanel(1)"><div class="down-arrows"></div></button></td></tr>'
      content += '</table>'
      return content
    },
    // 点击切换楼层按钮上下箭头
    moveFloorPanel(s) {
      let f = this.floorPanelPos
      if (s == 0) {
        if (f > 0) f--
      } else if (s == 1) {
        if (f < this.buildData.FloorList.length - 3) f++
      }
      if (f != this.floorPanelPos) {
        this.floorPanelPos = f
        this.floorPanel.setContent(this.makeFloorPanelContent())
      }
    },
    // 点击切换楼层
    changeFloor(f) {
      this.floorNo = f
      this.floorPanel.setContent(this.makeFloorPanelContent())

      if (this.buildData.FloorList[this.floorNo].No instanceof Array) {
        this.floorNoArray = this.buildData.FloorList[this.floorNo].No
      } else {
        this.floorNoArray = [this.buildData.FloorList[this.floorNo].No]
      }

      if (this.mqttClient && this.mqttClient.connected) {
        if (this.topicArray && this.topicArray.length > 0)
          this.mqttClient.unsubscribe(this.topicArray, () => {
            if (this.personLayer) this.personLayer.clear()
            this.startMQTT()
          })
      }

      this.mapLayer.setImages([
        {
          url: this.buildData.FloorList[this.floorNo].MapPath,
          extent: this.baseExtent,
          opacity: 1,
        },
      ])
      this.getRail()
      this.getCamera()
    },
    // 右下角信息栏显示内容生成
    update(e) {
      let projection = this.map.getProjection()
      let coordinate = e.coordinate,
        prj = projection.project(coordinate)

      this.debugPanel.setContent(
        '<div class="map-debugpanel">' +
          [
            'Coordinate : [' + coordinate.x.toFixed(5) + ', ' + coordinate.y.toFixed(5) + ']',
            'Projected Coordinate : [' + prj.x.toFixed(5) + ', ' + prj.y.toFixed(5) + ']',
            'Zoom : ' + this.map.getZoom(),
          ].join('<br>') +
          '</div>'
      )
    },

    addPerson(person) {
      let marker = new maptalks.Marker(
        this.getNewCoordinate(person.Positioning.X, person.Positioning.Y),
        {
          id: person.Id,
          visible: true,
          symbol: [
            {
              markerFile: this.VUE_APP_BASE_API + person.IconPath,
              markerWidth: 40,
              markerHeight: 40,
              markerDx: 0,
              markerDy: 20,
              textName: person.Name,
              textDx: 0,
              textDy: 20,
            },
            {
              textName: '',
              textWeight: 'bold',
              textStyle: 'normal',
              textSize: 0,
              textFill: '#FF0000',
              textOpacity: 1,
              textDx: 0,
              textDy: -20,
            },
          ],
          properties: {
            id: person.Id,
            name: person.Name,
          },
        }
      ).addTo(this.personLayer)
      marker.setInfoWindow({
        title: person.Name,
        width: 300,
        autoCloseOn: 'click contextmenu',
        content:
          '<table width = "100%" style="border-bottom: 0px solid rgb(231, 234, 236) !important">\
                        <tr>\
                          <td width = "40%" rowspan="5" align="center">\
                            <img src="' +
          (person.PhotoPath
            ? this.VUE_APP_BASE_API + person.PhotoPath
            : 'static/images/default.png') +
          '" style="width: 85px; height: 140px; object-fit: contain"/>\
                          </td>\
                          <td class="tdname">类型：</td>\
                          <td class="tddata">' +
          person.TypeName +
          '</td>\
                        <tr>\
                          <td class="tdname">部门：</td>\
                          <td class="tddata">' +
          person.DepartmentName +
          '</td>\
                        </tr>\
                        <tr>\
                          <td class="tdname">职位：</td>\
                          <td class="tddata">' +
          person.PositionName +
          '</td>\
                        </tr>\
                        <tr>\
                          <td class="tdname">电话：</td>\
                          <td class="tddata">' +
          person.Telephone +
          '</td>\
                        </tr>\
                        <tr>\
                          <td class="tdname">SN：</td>\
                          <td class="tddata">' +
          person.LabelMAC +
          '</td>\
                        </tr>\
                        <tr style="height:10px"/>\
                     </table>',
      })

      this.personAlarming(person.Id)

      return marker
    },
    personMove(geometry, person) {
      geometry.animate(
        {
          translate: this.getOffset(geometry, person),
        },
        {
          duration: 1000,
        }
      )
    },
    personAlarming(personId, repeat = false) {
      let p = this.personLayer.getGeometryById(personId)
      let pa = this.personAlarm[personId]

      if (p) {
        if (pa && pa.length > 0) {
          if (!repeat) {
            if (this.alarmingPerson.indexOf(personId) >= 0) return
            else this.alarmingPerson.push(personId)
          }

          let str = ''
          pa.forEach((v) => {
            switch (v.AlarmType) {
              case 11:
                str += '越界(进入),'
                break
              case 12:
                str += '越界(离开),'
                break
              case 20:
                str += '滞留,'
                break
              case 50:
                str += '静止,'
                break
              case 60:
                str += 'SOS,'
                break
              default:
                break
            }
          })
          str = str.substr(0, str.length - 1)
          if (p.getSymbol()[1].textName != str) {
            p.updateSymbol([{}, { textName: str }])
          }

          if (p.getSymbol()[1].textSize == 0) {
            p.updateSymbol([{}, { textSize: 16 }])
          } else {
            p.updateSymbol([{}, { textSize: 0 }])
          }

          setTimeout(() => {
            this.personAlarming(personId, true)
          }, 500)
        } else {
          let index = this.alarmingPerson.indexOf(personId)
          if (index >= 0) this.alarmingPerson.splice(index, 1)
          p.updateSymbol([{}, { textSize: 0 }])
        }
      }
    },
    railAlarming(railId, repeat = false) {
      let r = this.railAlarmLayer.getGeometryById(railId)
      let ra = this.railAlarm[railId]
      let aa = this.arearailAlarm[railId]

      if (r) {
        if ((ra && ra.length > 0) || (aa && aa.length > 0)) {
          if (!repeat) {
            if (this.alarmingRail.indexOf(railId) >= 0) return
            else this.alarmingRail.push(railId)
          }

          if (r.isVisible()) r.hide()
          else r.show()
          setTimeout(() => {
            this.railAlarming(railId, true)
          }, 500)
        } else {
          let index = this.alarmingRail.indexOf(railId)
          if (index >= 0) this.alarmingRail.splice(index, 1)
          r.hide()
        }
      }
    },
    getOffset(geometry, person) {
      let start = geometry.getCoordinates()
      let end = this.getNewCoordinate(person.Positioning.X, person.Positioning.Y)
      return end.sub(start)
    },
    getNewCoordinate(x, y) {
      if (this.buildData.Projection == 'identity') {
        return new maptalks.Coordinate(
          x - this.baseRelativeCoordinate0.x,
          this.baseRelativeCoordinate0.y - y
        )
      } else {
        return this.map.locate(
          this.baseGPSCoordinate0,
          (x - this.baseRelativeCoordinate0.x) / 1000,
          -(y - this.baseRelativeCoordinate0.y) / 1000
        )
      }
    },
    identifyAndSelect(e) {
      let _this = this
      //identify
      this.map.identify(
        {
          coordinate: e.coordinate,
          layers: [this.personLayer, this.cameraLayer, this.perimeterLayer],
        },
        function (geos) {
          if (geos.length === 0) {
            _this.map.removeMenu()
            return
          }
          var options = { items: [] }
          geos.forEach(function (g) {
            var personN = g.getProperties().name
            options.items.push({
              item: personN,
              click: function () {
                // console.log(g.toJSON());
                //g.openInfoWindow()
                g.fire('click')
              },
            })
          })
          _this.map.setMenu(options).openMenu(e.coordinate)
        }
      )
    },
  },
}
</script>

<style lang="scss" scoped>
.map-container {
  width: 100%;
  height: calc(64vh - 98px);
}
::v-deep #title {
  width: 100%;
  height: 50px;
  display: table;
  text-align: center;
  background-color: #3c8dbc;
  p {
    margin: auto;
    display: table-cell;
    vertical-align: middle;
    text-align: center;
    color: white;
    font-family: SimHei, STHeiti;
    font-size: 25px;
    font-weight: bold;
    letter-spacing: 5px;
  }
}

::v-deep .page-main {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow-y: auto;
}

::v-deep .left {
  width: 20%;
  height: 100%;
  float: left;
  background-color: #101c45;
}

::v-deep .right {
  width: 20%;
  height: 100%;
  float: left;
  background-color: #101c45;
}

::v-deep .map {
  width: 100%;
  height: 100%;
  height: calc(100vh - 84px);
  float: left;
}

::v-deep .map-debugpanel {
  background: rgba(135, 196, 240, 0.8);
  width: 450px;
  height: 120px;
  border: 2px #fff solid;
  padding: 10px;
  color: #fff;
}

::v-deep .map-debugpanel input {
  color: #bbb;
}

::v-deep .map-debugpanel a {
  color: #fff;
  float: right;
  margin-right: 15px;
}

::v-deep .map-floorpanel {
  background: rgb(52, 73, 94);
  width: 40px;
  height: 120px;
  padding: 0px;
  color: #fff;
  border: 0px solid rgb(231, 234, 236) !important;
}

::v-deep .map-floorpanel tr {
  text-align: center;
  height: 30px;
}

::v-deep .map-floorpanel td {
  text-align: center;
  height: 30px;
}

::v-deep .map-floorpanel button {
  width: 40px;
  height: 30px;
  border: none;
  background: rgb(52, 73, 94);
  color: #fff;
}

::v-deep .map-buildpanel {
  background: rgb(52, 73, 94);
  width: 40px;
  height: 120px;
  padding: 0px;
  color: #fff;
  border: 0px solid rgb(231, 234, 236) !important;
}

::v-deep .map-buildpanel tr {
  text-align: center;
  height: 30px;
}

::v-deep .map-buildpanel td {
  text-align: center;
  height: 30px;
}

::v-deep .map-buildpanel button {
  width: 40px;
  height: 30px;
  border: none;
  background: rgb(52, 73, 94);
  color: #fff;
  font-size: 14px;
  cursor: pointer;
}

::v-deep .up-arrows {
  width: 0;
  height: 0;
  border-bottom: 20px solid white;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
}

::v-deep .down-arrows {
  width: 0;
  height: 0;
  border-top: 20px solid white;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
}
</style>
