<template>
    <div class="app-container">
      <!-- 左侧导航栏 -->
      <div class="sidebar">
        <h2>功能导航</h2>
        <ul>
          <li :class="{active: activeSection === 'match'}" @click="activeSection = 'match'">模板匹配</li>
          <li :class="{active: activeSection === 'compare'}" @click="activeSection = 'compare'">武器对比</li>
          <li :class="{active: activeSection === 'GOBedit'}" @click="activeSection = 'GOBedit'">物体编辑器</li><!--GOBedit：gameobject--->
        </ul>
      </div>
  
      <!-- 主内容区 -->
      <div class="main-content">
        <!-- 模板匹配部分 -->
        <section v-show="activeSection === 'match'" class="match-section">
          <h1><i class="icon icon-match"></i> WeaponTemplate 匹配到单位 GameObject</h1>
          
          <div class="upload-area">
            <div class="upload-card">
              <h3>上传 Weapon.xml</h3>
              <input type="file" @change="handleWeaponFile" class="file-upload" accept=".xml" />
            </div>
            
            <div class="upload-card">
              <h3>上传单位 XML</h3>
              <input type="file" @change="handleUnitFile" class="file-upload" accept=".xml" />
            </div>
          </div>
  
          <div class="result-card" v-if="resultList.length">
            <div class="card-header">
              <h3>匹配结果</h3>
              <button @click="autoSelectMatched" class="action-btn">
                <i class="icon icon-auto-select"></i> 自动选择匹配项
              </button>
            </div>
            
            <div class="table-responsive">
              <table class="result-table">
                <thead>
                  <tr>
                    <th width="50%">GameObject ID</th>
                    <th width="50%">匹配到的 WeaponTemplate</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="(item, index) in resultList" :key="index">
                    <td>{{ item.id }}</td>
                    <td>
                      <span v-if="item.templates && item.templates.length > 0">
                        {{ item.templates.join(', ') }}
                      </span>
                      <span v-else class="no-match">None</span>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </section>
  
        <!-- 武器对比部分 -->
        <section v-show="activeSection === 'compare'" class="compare-section">
          <h1><i class="icon icon-compare"></i> 武器对比工具</h1>
          
          <div class="control-panel">
            <div class="reload-card">
              <h3>重新导入 Weapon.xml</h3>
              <input type="file" @change="handleCompareWeaponFile" class="file-upload" accept=".xml" />
            </div>
            
            <div class="pagination-card">
              <div class="pagination-controls">
                <button @click="prevPage" :disabled="currentPage === 1" class="page-btn">
                  <i class="icon icon-prev"></i> 上一页
                </button>
                <span class="page-info">第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
                <button @click="nextPage" :disabled="currentPage >= totalPages" class="page-btn">
                  下一页 <i class="icon icon-next"></i>
                </button>
              </div>
            </div>
          </div>
  
          <div class="weapon-list-card">
            <div class="card-header">
              <h3>武器列表</h3>
              <div>
                <button @click="clearAllSelections" class="action-btn danger">
                  <i class="icon icon-clear"></i> 清空选择
                </button>
              </div>
            </div>
            
            <div class="table-responsive">
              <table class="weapon-table">
                <thead>
                  <tr>
                    <th width="60px">选择</th>
                    <th>武器 ID</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="weapon in pagedWeapons" :key="weapon.id">
                    <td>
                      <label class="checkbox-container">
                        <input type="checkbox" :value="weapon.id" v-model="selectedWeaponIds" />
                        <span class="checkmark"></span>
                      </label>
                    </td>
                    <td>{{ weapon.id }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
  
          <div class="compare-tools">
            <h3><i class="icon icon-attribute"></i> 属性对比</h3>
            
            <div class="toolbar">
              <button @click="toggleTableDirection" class="tool-btn" :class="{active: isReversed}">
                <i class="icon" :class="isReversed ? 'icon-restore' : 'icon-reverse'"></i>
                {{ isReversed ? '恢复默认视图' : '反转行列' }}
              </button>
              
              <button @click="transposeTable" class="tool-btn" :class="{active: isTransposed}">
                <i class="icon" :class="isTransposed ? 'icon-restore' : 'icon-transpose'"></i>
                {{ isTransposed ? '取消转置' : '转置表格' }}
              </button>

              <button @click="clearAllSelections" class="tool-btn danger">
                <i class="icon icon-clear"></i> 清空对比武器
              </button>              
            </div>
  
            <div class="attribute-selector-panel">
              <div class="attribute-controls">
                <div class="search-box">
                  <i class="icon icon-search"></i>
                  <input
                    v-model="attributeSearchText"
                    placeholder="搜索属性..."
                    @input="filterAttributes"
                    class="search-input"
                  />
                  <div class="button-group">
                    <button @click="toggleSelectAll" class="small-btn">
                      {{ selectAll ? '取消全选' : '全选' }}
                    </button>
                    <button @click="clearSelectedAttributes" class="small-btn danger">
                      清空
                    </button>
                  </div>
                </div>
                
                <div class="select-container">
                  <select
                    multiple
                    v-model="selectedAttributes"
                    class="multi-select"
                    size="10"
                  >
                    <option
                      v-for="attr in filteredAttributes"
                      :key="attr"
                      :value="attr"
                      class="select-option"
                    >
                      {{ attr }}
                    </option>
                  </select>
                  <div class="selection-info">
                    已选择 {{ selectedAttributes.length }} / {{ allAttributes.length }} 个属性
                  </div>
                </div>
              </div>
  
              <div class="selected-preview">
                <div class="preview-header">
                  <h4>已选属性预览</h4>
                  <span class="hint-text">点击属性可移除</span>
                </div>
                <div class="selected-tags">
                  <span
                    v-for="attr in selectedAttributes"
                    :key="attr"
                    class="tag"
                    @click="removeAttribute(attr)"
                  >
                    {{ attr }}
                    <i class="icon icon-close"></i>
                  </span>
                  <span v-if="selectedAttributes.length === 0" class="empty-hint">暂无选择</span>
                </div>
              </div>
            </div>
  
            <div class="comparison-result" v-if="selectedWeapons.length && selectedAttributes.length">
              <div class="table-responsive">
                <table class="comparison-table">
                  <thead>
                    <tr>
                      <th>{{ displayMode === 'normal' ? '属性名' : '武器 ID' }}</th>
                      <th v-for="weapon in selectedWeapons" :key="weapon.id">
                        {{ displayMode === 'normal' ? weapon.id : '属性名' }}
                      </th>
                    </tr>
                  </thead>
                  <tbody>
                    <template v-if="displayMode === 'normal'">
                      <tr v-for="attr in selectedAttributes" :key="attr">
                        <td class="attr-name">{{ attr }}</td>
                        <td v-for="weapon in selectedWeapons" :key="weapon.id" 
                            :class="getCellClass(getWeaponAttribute(weapon, attr))">
                          {{ getWeaponAttribute(weapon, attr) || '-' }}
                        </td>
                      </tr>
                    </template>
                    <template v-else>
                      <tr v-for="weapon in selectedWeapons" :key="weapon.id">
                        <td class="attr-name">{{ weapon.id }}</td>
                        <td v-for="attr in selectedAttributes" :key="attr"
                            :class="getCellClass(getWeaponAttribute(weapon, attr))">
                          {{ getWeaponAttribute(weapon, attr) || '-' }}
                        </td>
                      </tr>
                    </template>
                  </tbody>
                </table>
              </div>
            </div>
            <div v-else class="empty-state">
              <i class="icon icon-empty"></i>
              <p>{{ !selectedWeapons.length ? '请先选择要对比的武器' : '请选择要对比的属性' }}</p>
            </div>
          </div>
          <div class="additional-info">
            <div class="info-card">
              <h3><i class="icon icon-inheritance"></i> 继承关系</h3>
              <div class="table-responsive" v-if="selectedWeapons.length">
                <table class="info-table">
                  <thead>
                    <tr>
                      <th width="30%">武器 ID</th>
                      <th width="70%">继承链</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="weapon in selectedWeapons" :key="weapon.id">
                      <td>{{ weapon.id }}</td>
                      <td>{{ getInheritanceChain(weapon).join(' → ') }}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <div v-else class="empty-state small">
                <i class="icon icon-info"></i>
                <p>选择武器查看继承关系</p>
              </div>
            </div>
            
            <div class="info-card">
              <h3><i class="icon icon-ranking"></i> 继承排行榜</h3>
              <div v-if="inheritanceCount.length" class="ranking-list">
                <div v-for="(item, index) in inheritanceCount.slice(0, 5)" :key="index" class="ranking-item">
                  <span class="rank">{{ index + 1 }}</span>
                  <span class="weapon-name">{{ item.weapon }}</span>
                  <span class="count">{{ item.count }} 次</span>
                </div>
              </div>
              <div v-else class="empty-state small">
                <i class="icon icon-info"></i>
                <p>暂无继承数据</p>
              </div>
            </div>
          </div>

        </section>
        <!-- 物体编辑器部分 -->
        <section v-show="activeSection === 'GOBedit'" class="GOBeditor-section">
  <div class="file-input-container">
    <input type="file" @change="handleUnitFile" accept=".xml" class="file-input" title="加载单位.xml">
    <input type="file" @change="handleWeaponFile" accept=".xml" class="file-input" title="加载Weapon.xml">
    <button v-if="unitDoc" @click="exportUnitXml" class="export-btn">导出XML</button>
  </div>
  
  <div v-if="unitDoc" class="unit-editor">
    <div class="unit-list">
      <div v-for="gameObject in unitDoc.querySelectorAll('GameObject')" :key="gameObject.getAttribute('id')" 
           class="unit-item" @click="selectGameObject(gameObject)"
           :class="{ 'selected': selectedGameObject === gameObject }">
        {{ gameObject.getAttribute('id') || '未命名单位' }}
      </div>
    </div>
    
    <div v-if="selectedGameObject" class="unit-details">
      <h3>单位详细信息</h3>
      <!--ID面板-->
      <div class="detail-row">
        <span class="detail-label">ID:</span>
        <input class="detail-value edit-input" v-model="editableFields.id" @change="updateGameObject">
      </div>
      
      <!--CSF面板-->
      <div class="detail-group">
        <div class="group-header" @click="toggleGroup('csf')">
          <span>CSF相关描述</span>
          <span class="toggle-icon">{{ isGroupOpen('csf') ? '−' : '+' }}</span>
        </div>
        <div v-if="isGroupOpen('csf')" class="group-content">
          <div class="detail-row">
            <span class="detail-label">DisplayName:</span>
            <input class="detail-value edit-input" v-model="editableFields.displayName" @change="updateDisplayName">
          </div>
          <div class="detail-row">
            <span class="detail-label">TypeDescription:</span>
            <input class="detail-value edit-input" v-model="editableFields.typeDescription" @change="updateGameObject">
          </div>
          <div class="detail-row">
            <span class="detail-label">Description:</span>
            <input class="detail-value edit-input" v-model="editableFields.description" @change="updateGameObject">
          </div>
        </div>
      </div>
      
      <!--建造时间面板-->
      <div class="detail-row">
        <span class="detail-label">建造时间:</span>
        <input class="detail-value edit-input" v-model="editableFields.buildTime" @change="updateGameObject" type="number">
        <span class="unit-suffix">秒</span>
      </div>

      <!--科技需求面板-->
      <div class="detail-group">
        <div class="group-header" @click="toggleGroup('tech')">
          <span>科技需求</span>
          <span class="toggle-icon">{{ isGroupOpen('tech') ? '−' : '+' }}</span>
        </div>
        <div v-if="isGroupOpen('tech')" class="group-content">
          <div class="detail-row">
            <span class="detail-label">NeededUpgrade:</span>
            <input class="detail-value edit-input" v-model="editableFields.neededUpgrade" @change="updateNeededUpgrade">
          </div>
          <div class="detail-row">
            <span class="detail-label">建造数量上限:</span>
            <input class="detail-value edit-input" v-model="editableFields.maxSimultaneous" @change="updateGameObject" type="number">
          </div>
        </div>
      </div>
      
      <!--造价和生命值面板-->
      <div class="detail-group">
        <div class="group-header" @click="toggleGroup('costHealth')">
          <span>造价与生命值</span>
          <span class="toggle-icon">{{ isGroupOpen('costHealth') ? '−' : '+' }}</span>
        </div>
        <div v-if="isGroupOpen('costHealth')" class="group-content">
          <div class="detail-row">
            <span class="detail-label">造价:</span>
            <input class="detail-value edit-input" v-model="editableFields.buildCost" @change="updateBuildCost" type="number">
          </div>
          <div class="detail-row">
            <span class="detail-label">生命值:</span>
            <input class="detail-value edit-input" v-model="editableFields.maxHealth" @change="updateMaxHealth" type="number">
          </div>
        </div>
      </div>
      <!--DPS面板-->

      <!--射程面板-->
      <div class="detail-group">
        <div class="group-header" @click="toggleGroup('range')">
          <span>武器射程</span>
          <span class="toggle-icon">{{ isGroupOpen('range') ? '−' : '+' }}</span>
        </div>
        <div v-if="isGroupOpen('range')" class="group-content">
          <div v-if="weaponData.length === 0" class="detail-row">
            <span class="detail-label">无武器数据</span>
          </div>
          <template v-else>
            <div class="detail-row" v-for="(weapon, index) in weaponData" :key="index">
              <span class="detail-label">武器 {{ index + 1 }} ({{ weapon.id }}):</span>
              <div class="weapon-stats">
                <!-- 清雾范围未添加 -->
                <div>攻击范围: {{ weapon.attackRange || 0 }}</div>
                <div>最小射程: {{ weapon.minAttackRange || 0 }}</div>
                <div>伤害值: {{ weapon.Damage || 0 }}</div>
                <div>伤害范围: {{ weapon.Radius || 0 }}</div>
              </div>
            </div>
          </template>
        </div>
      </div>

      <!--移速面板-->
      <!--技能面板-->
      <!--碾压等级面板-->
      
    </div>    
  </div>
</section>



      </div>
    </div>
  </template>
  
  <script setup>
  
  import { ref, computed, onMounted } from 'vue'
//编辑器
  const weaponXmlData = ref(null)
  const weaponData = ref([])
  const selectedGameObject = ref(null)
  const openGroups = ref(['csf', 'tech', 'costHealth'])
  const editableFields = ref({
    id: '',
    displayName: '',
    typeDescription: '',
    description: '',
    buildTime: '',
    neededUpgrade: '',
    maxSimultaneous: '',
    buildCost: '',
    maxHealth: ''
  })

  function selectGameObject(gameObject) {
    selectedGameObject.value = gameObject
    updateEditableFields()
    updateWeaponData()
  }
  function updateEditableFields() {
    if (!selectedGameObject.value) return
    
    editableFields.value = {
      id: selectedGameObject.value.getAttribute('id') || '',
      displayName: extractDisplayName(selectedGameObject.value) || '',
      typeDescription: selectedGameObject.value.getAttribute('TypeDescription') || '',
      description: selectedGameObject.value.getAttribute('Description') || '',
      buildTime: selectedGameObject.value.getAttribute('BuildTime') || '',
      neededUpgrade: getNeededUpgrade(selectedGameObject.value) || '',
      maxSimultaneous: selectedGameObject.value.getAttribute('MaxSimultaneousOfType') || '',
      buildCost: getBuildCost(selectedGameObject.value) || '',
      maxHealth: getMaxHealth(selectedGameObject.value) || ''
    }
  }

  function updateGameObject() {
    if (!selectedGameObject.value) return
    
    // 更新基本属性
    selectedGameObject.value.setAttribute('id', editableFields.value.id)
    selectedGameObject.value.setAttribute('TypeDescription', editableFields.value.typeDescription)
    selectedGameObject.value.setAttribute('Description', editableFields.value.description)
    selectedGameObject.value.setAttribute('BuildTime', editableFields.value.buildTime)
    selectedGameObject.value.setAttribute('MaxSimultaneousOfType', editableFields.value.maxSimultaneous)
  }

  function updateDisplayName() {
    if (!selectedGameObject.value) return
    
    let displayNameNode = selectedGameObject.value.querySelector('DisplayName')
    if (!displayNameNode) {
      displayNameNode = unitDoc.value.createElement('DisplayName')
      selectedGameObject.value.appendChild(displayNameNode)
    }
    displayNameNode.textContent = editableFields.value.displayName
  }

  function updateNeededUpgrade() {
    if (!selectedGameObject.value) return
    
    let gameDependency = selectedGameObject.value.querySelector('GameDependency')
    if (!gameDependency) {
      gameDependency = unitDoc.value.createElement('GameDependency')
      selectedGameObject.value.appendChild(gameDependency)
    }
    gameDependency.setAttribute('NeededUpgrade', editableFields.value.neededUpgrade)
  }

  function updateBuildCost() {
    if (!selectedGameObject.value) return
    
    let resourceInfo = selectedGameObject.value.querySelector('ObjectResourceInfo')
    if (!resourceInfo) {
      resourceInfo = unitDoc.value.createElement('ObjectResourceInfo')
      selectedGameObject.value.appendChild(resourceInfo)
    }
    
    let buildCost = resourceInfo.querySelector('BuildCost')
    if (!buildCost) {
      buildCost = unitDoc.value.createElement('BuildCost')
      resourceInfo.appendChild(buildCost)
    }
    buildCost.setAttribute('Amount', editableFields.value.buildCost)
  }

  function updateMaxHealth() {
    if (!selectedGameObject.value) return
    
    let body = selectedGameObject.value.querySelector('Body')
    if (!body) {
      body = unitDoc.value.createElement('Body')
      selectedGameObject.value.appendChild(body)
    }
    
    let activeBody = body.querySelector('ActiveBody')
    if (!activeBody) {
      activeBody = unitDoc.value.createElement('ActiveBody')
      body.appendChild(activeBody)
    }
    activeBody.setAttribute('MaxHealth', editableFields.value.maxHealth)
  }
//导出
    function exportUnitXml() {
    if (!unitDoc.value || !selectedGameObject.value) return;
    
    const serializer = new XMLSerializer();
    const unitId = selectedGameObject.value.getAttribute('id') || 'unit';
    
    // 1. 导出主单位文件
    const unitXmlString = serializer.serializeToString(unitDoc.value);
    downloadFile(`${unitId}.xml`, unitXmlString);
    
    // 2. 创建符合规范的config.xml
    const configXml = document.implementation.createDocument(
      "uri:ea.com:eala:asset", 
      "AssetDeclaration"
    );
    
    // 添加XML声明
    const xmlDeclaration = '<?xml version="1.0" encoding="utf-8" ?>';
    
    // 添加Tags和Includes
    const tags = configXml.createElement("Tags");
    configXml.documentElement.appendChild(tags);
    
    const includes = configXml.createElement("Includes");
    const include = configXml.createElement("Include");
    include.setAttribute("type", "all");
    include.setAttribute("source", "DATA:GlobalData/GlobalDefines.xml");
    includes.appendChild(include);
    configXml.documentElement.appendChild(includes);
    
    // 添加Defines
    const defines = configXml.createElement("Defines");
    const define1 = configXml.createElement("Define");
    define1.setAttribute("name", "FACTION_WEAPON_SECONDARY_DAMAGE_AMOUNT");
    define1.setAttribute("value", "-500.0");
    defines.appendChild(define1);
    
    const define2 = configXml.createElement("Define");
    define2.setAttribute("name", "EMPERORS_RESOLVE_AFFECTS");
    define2.setAttribute("value", "ALLIES NEUTRALS ENEMIES");
    defines.appendChild(define2);
    configXml.documentElement.appendChild(defines);
    
    // 添加匹配的WeaponTemplate
    if (weaponData.value.length > 0 && weaponXmlData.value) {
      weaponData.value.forEach(weapon => {
        const weaponTemplate = weaponXmlData.value.querySelector(`WeaponTemplate[id="${weapon.id}"]`);
        if (weaponTemplate) {
          // 创建新的WeaponTemplate元素
          const newWeaponTemplate = configXml.createElement("WeaponTemplate");
          
          // 复制所有属性
          Array.from(weaponTemplate.attributes).forEach(attr => {
            newWeaponTemplate.setAttribute(attr.name, attr.value);
          });
          
          // 复制所有子节点
          Array.from(weaponTemplate.children).forEach(child => {
            const newChild = configXml.createElement(child.tagName);
            
            // 复制子节点属性
            Array.from(child.attributes).forEach(attr => {
              newChild.setAttribute(attr.name, attr.value);
            });
            
            // 如果有文本内容也复制
            if (child.textContent.trim()) {
              newChild.textContent = child.textContent;
            }
            
            // 处理Nuggets的子节点
            if (child.tagName === 'Nuggets') {
              Array.from(child.children).forEach(nugget => {
                const newNugget = configXml.createElement(nugget.tagName);
                
                Array.from(nugget.attributes).forEach(attr => {
                  newNugget.setAttribute(attr.name, attr.value);
                });
                
                newChild.appendChild(newNugget);
              });
            }
            
            newWeaponTemplate.appendChild(newChild);
          });
          
          configXml.documentElement.appendChild(newWeaponTemplate);
        }
      });
    }
    
    // 序列化config.xml
    let configXmlString = serializer.serializeToString(configXml);
    // 添加XML声明和格式化
    configXmlString = xmlDeclaration + '\n' + formatXml(configXmlString);
    
    // 下载config.xml
    setTimeout(() => {
      downloadFile('config.xml', configXmlString);
    }, 500);
  }

  // XML格式化函数
  function formatXml(xml) {
    const PADDING = '  ';
    const reg = /(>)(<)(\/*)/g;
    let formatted = '';
    let pad = 0;
    
    xml = xml.replace(reg, '$1\r\n$2$3');
    
    xml.split('\r\n').forEach(node => {
      let indent = 0;
      if (node.match(/.+<\/\w[^>]*>$/)) {
        indent = 0;
      } else if (node.match(/^<\/\w/)) {
        if (pad !== 0) pad -= 1;
      } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) {
        indent = 1;
      } else {
        indent = 0;
      }
      
      formatted += PADDING.repeat(pad) + node + '\r\n';
      pad += indent;
    });
    
    return formatted;
  }

  // 文件下载函数
  function downloadFile(filename, content) {
    const blob = new Blob([content], { type: 'text/xml' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  }
//导出结束

  function toggleGroup(groupName) {
    if (openGroups.value.includes(groupName)) {
      openGroups.value = openGroups.value.filter(g => g !== groupName)
    } else {
      openGroups.value.push(groupName)
    }
  }

  function isGroupOpen(groupName) {
    return openGroups.value.includes(groupName)
  }

  function extractDisplayName(gameObject) {
    const displayNameNode = gameObject.querySelector('DisplayName');
    return displayNameNode ? displayNameNode.textContent.trim() : null;
  }

  function getNeededUpgrade(gameObject) {
    const gameDependency = gameObject.querySelector('GameDependency')
    return gameDependency ? gameDependency.getAttribute('NeededUpgrade') : null
  }

  function getBuildCost(gameObject) {
    const resourceInfo = gameObject.querySelector('ObjectResourceInfo');
    if (!resourceInfo) return null;
    
    const buildCost = resourceInfo.querySelector('BuildCost');
    if (!buildCost) return null;
    
    return buildCost.getAttribute('Amount');
  }

  function getMaxHealth(gameObject) {
    const body = gameObject.querySelector('Body');
    if (!body) return null;
    
    const activeBody = body.querySelector('ActiveBody');
    if (!activeBody) return null;
    
    return activeBody.getAttribute('MaxHealth');
  }

//武器比对
  // 数据状态
  const activeSection = ref('match')
  const weaponXml = ref('')
  const unitDoc = ref(null)
  const resultList = ref([])
  const weaponTemplateIds = ref(new Set())
  const allWeapons = ref([])
  const selectedWeaponIds = ref([])
  const currentPage = ref(1)
  const pageSize = ref(20)
  const selectedAttributes = ref([])
  const isReversed = ref(false)
  const isTransposed = ref(false)
  const attributeSearchText = ref('')
  const selectAll = ref(false)
  const filteredAttributes = ref([])
  
// 计算属性
const allAttributes = computed(() => {
  const attrs = new Set();
  
  // 属性名翻译映射表
  //标了问号的就是我不确定是啥的
  const attributeTranslations = {
  // ================= 武器模板核心属性 =================
  'id': '武器ID',
  'inheritFrom': '继承自',
  'AttackRange': '射程',
  'MinimumAttackRange': '最小射程',
  'RangeBonusMinHeight': '射程加成最小高度',// 高度相关射程加成，没出现过
  'RangeBonus': '射程加成值',// 高度相关射程加成，没出现过
  'RangeBonusPerFoot': '每英尺射程加成',// 高度相关射程加成，没出现过
  'RequestAssistRange': '请求援助范围',// 意义不明且没出现过
  'AcceptableAimDelta': '允许瞄准偏差角',
  'AimDirection': '基准瞄准方向', // 意义不明
  'ScatterRadius': '散射半径',
  'ScatterLength': '散射长度',
  'ScatterIndependently': '多抛射物独立散射', //只在V4散弹那里出现一次
  'WeaponSpeed': '武器/抛射物速度',
  'MinWeaponSpeed': '最小抛射物速度',
  'MaxWeaponSpeed': '最大抛射物速度',
  'ScaleWeaponSpeed': '缩放抛射物速度',// 意义不明且没出现过
  'IgnoresContactPoints': '忽略碰撞体积(将武器瞄准目标几何中心)',
  'ScaleAttackRangeByAmmoRemaining': '射程随弹药剩余量缩放',//意义姑且不明，只在世纪轰炸机那里出现一次
  'CanBeDodged': '可被躲避',// 意义不明且没出现过
  'IdleAfterFiringDelaySeconds': '开火后待机延迟',//似乎是让自己在攻击后会瘫痪一段时间？
  'HoldAfterFiringDelaySeconds': '开火后保持延迟',// 意义不明且没出现过
  'HoldDuringReload': '保持先前姿态时即可装填', 
  'CanFireWhileMoving': '移动射击能力',
  'WeaponRecoil': '启用后坐力',
  'MinTargetPitch': '最小俯仰角',
  'MaxTargetPitch': '最大俯仰角',
  'PreferredTargetBone': '首选目标骨骼',
  'FireSound': '开火音效',
  'FireSoundPerClip': '整弹匣开火音效',
  'FiringLoopSound': '持续开火音效',
  'FiringLoopSoundContinuesDuringReload': '装填时保持开火音效',
  'FireFX': '开火特效',
  'FireVeteranFX': '升级后开火特效', // 升级后的单位不一定是三星单位
  'FireFlankFX': '侧翼开火特效',
  'PreAttackFX': '预攻击特效',
  'ClipSize': '弹匣容量',
  'ContinuousFireOne': '第一阶段连续射击次数',
  'ContinuousFireTwo': '第二阶段连续射击次数',
  'ContinuousFireCoastSeconds': '连续射击间隔', // 意义不明且没出现过
  'AutoReloadWhenIdleSeconds': '空闲时自动装弹时间',// 意义不明且没出现过
  'ShotsPerBarrel': '每炮管射弹数',
  'DamageDealtAtSelfPosition': '伤害作用于自身位置', //在鬼王和大和的撞击武器那里出现，似乎是用来让武器在路径全程都造成效果的？
  'RequiredFiringObjectStatus': '开火所需状态标志',
  'ForbiddenFiringObjectStatus': '禁止开火的状态标志',
  'CheckStatusFlagsInRangeChecks': '射程检查时包含状态标志',
  'ProjectileSelf': '发射自身作为抛射物', // 用于跳跃类单位和神风特攻队
  'MeleeWeapon': '近战武器',
  'ChaseWeapon': '追击武器', // 意义不明
  'LeechRangeWeapon': '吸血射程武器',
  'HitStoredTarget': '会攻击预设目标',
  'CapableOfFollowingWaypoints': '能否跟随路径点',
  'ShowsAmmoPips': '是否显示弹药指示器',
  'AllowAttackGarrisonedBldgs': '能否攻击驻军建筑',
  'PlayFXWhenStealthed': '隐身时是否播放特效',// 没出现过
  'ContinueAttackRange': '持续攻击范围', //意义姑且不明，只在世纪轰炸机那里出现一次
  'SuspendFXDelaySeconds': '特效暂停延迟',// 意义不明且没出现过
  'IsAimingWeapon': '是否为瞄准武器',
  'NoVictimNeeded': '是否需要攻击目标',
  'HitPercentage': '命中率', //用处可以很大，但原作中只是用来控制跳跃类单位让它不会把自己一头创死的
  'HitPassengerPercentage': '乘客命中概率',
  'PassengerProportionalAttack': '是否按乘客比例攻击',
  'HealthProportionalResolution': '生命值比例分辨率', // 在鬼王和大和的撞击武器那里出现，似乎是用来让武器在路径全程都造成效果的？
  'MaxAttackPassengers': '最大攻击乘客数',
  'FinishAttackOnceStarted': '强制完成已开始攻击',// 大部分近战武器都启用了这个，所以会出现二☆人☆幸☆终的情况
  'RestrictedHeightRange': '高度限制范围',
  'CannotTargetCastleVictims': '能否攻击城堡保护目标',
  'RequireFollowThru': '攻击动作必须完整执行', // 攻击动作必须完整执行
  'ShareTimers': '共享计时器',// 意义不明且没出现过
  'ShouldPlayUnderAttackEvaEvent': '是否播放受袭语音',
  'InstantLoadClipOnActivate': '激活武器时才开始装填(无法立刻发射)',
  'Flags': '行为控制标志集',
  'LockWhenUsing': '使用时锁定',// 意义不明且没出现过
  'BombardType': '轰炸类型武器',// 意义不明且没出现过
  'UseInnateAttributes': '使用先天属性',// 意义不明且没出现过
  'PreAttackType': '攻击前准备类型',
  'ReAcquireDetailType': '目标重锁定模式',
  'AutoReloadsClip': '自动装填机制 (AUTO-自动再装填/NONE-无法再装填/RETURN_TO_BASE-只能在基地再装填)',
  'SingleAmmoReloadedNotFullSound': '单发装填音效', // 在注释里出现过，CC3遗留代码
  'ClipReloadedSound': '弹匣重装音效', // 在注释里出现过，CC3遗留代码
  'RadiusDamageAffects': '范围伤害影响对象',
  'FXTrigger': '特效触发类型',
  'ProjectileCollidesWith': '抛射物碰撞对象类型',
  'RequiredAntiMask': '可攻击的目标类型',
  'ForbiddenAntiMask': '禁止攻击的目标类型',
  'StopFiringOnCanBeInvisible': '隐身时停止开火',// 没出现过
  'ProjectileStreamName': '投射物流名称',
  'ContactWeapon': '接触式武器', 
  'UseCenterForRangeCheck': '使用几何中心点计算射程', 
  'VirtualDamage': '自动分弹模式/虚拟伤害类型(NONE-不进行自动分弹/SOLO-自动分弹时只计算自己/SHARED-自动分弹时计算所有单位的总火力)', 
  'PreAttackWeapon': '预攻击武器', 
  'RevealShroudOnFire': '开火时揭露战争迷雾',
  'ShouldPlayTargetDeadEvaEvent': '目标死亡时播放语音',

  // ================= 时间控制元素属性 =================
  'MinSeconds': '最小持续时间(秒)',
  'MaxSeconds': '最大持续时间(秒)',

  // ================= AI智能提示属性 =================
  'IsAntiGarrisonWeapon': '反驻军武器',
  'MaxSpeedOfTarget': '可命中的目标最大速度',
  'UseLongLockOnTimeCode': '使用长锁定时间逻辑', // 如标枪兵锁定模式
  'UseAsWarheadForDamageCalculations': 'AI伤害计算弹头',

  // ================= 武器效果组件通用属性 =================
  'Radius': '作用半径',
  'PartitionFilterTestType': '属性过滤器作用区域形状',
  'ForbiddenTargetObjectStatus': '瘫痪/冲击波失效的目标对象状态',
  'ForbiddenTargetModelCondition': '瘫痪/冲击波失效的目标模型状态',
  'RequiredUpgrade': '所需升级',
  'ForbiddenUpgrade': '禁止升级',
  
  // ================= 伤害弹头属性 =================
  'Damage': '基础伤害值',
  'DamageTaperOff': '伤害衰减系数', // 随距离伤害递减
  'MinRadius': '最小作用半径', // 伤害生效最小距离，没出现过
  'DamageArc': '扇形伤害范围角度', // 扇形伤害区域
  'DamageArcInverted': '反转伤害扇形', // 反转扇形区域，没出现过
  'DamageMaxHeight': '伤害最大高度', // 不确定，仅电船的F使用这个参数
  'DamageMaxHeightAboveTerrain': '伤害最大离地高度',// 不确定，没出现过
  'FlankingBonus': '侧翼攻击加成', // 从侧面攻击伤害加成，没出现过
  'FlankedScalar': '被侧翼攻击倍率', // 被侧击时的伤害倍率，没出现过
  'DelayTimeSeconds': '伤害延迟时间(秒)', // 伤害生效延迟
  'DamageType': '伤害类型', // 穿甲/高爆等
  'DeathType': '死亡效果类型', // 爆炸/融化等
  'DamageFXType': '伤害特效类型',
  'DamageSubType': '伤害子类型', // 进一步细分伤害类型，没出现过
  'OnlyKillOwnerWhenTriggered': '仅在被触发时杀死拥有者',
  'DrainLifeMultiplier': '生命吸取倍率', // 吸血比例，没出现过，在RAAA中只出现了Leech的吸血弹头
  'DrainLife': '生命吸取', // 吸血效果开关，没出现过，在RAAA中只出现了Leech的吸血弹头
  'DamageSpeed': '伤害传播速度', // 只在将军刽子手的F弹头中出现过，可能是伤害蔓延速度
  'UnderAttackOverrideEvaEvent': '覆盖受袭语音事件',
  'VictimShroudRevealer': '目标战争迷雾揭示者', // 意义不明且没出现过
  'NotifyOwnerOnVictimDeath': '目标死亡通知拥有者', //Leech类属性——吸到武器了。投稿者：变态BUG锤
  'NotifyObserversOnPreDamageEffectPosition': '伤害位置预报', // 超武特有属性
  'ForceFXPositionToVictim': '特效绑定目标位置', // 意义不明，只在真空内爆弹和城管的弹头里出现过
  'RadiusAffectsBridges': '影响桥梁',
  'InvalidTargetStatus': '无效目标状态标志',
  'DamageScalarDetails': '伤害比例详情',
  'Scalar': '伤害比例',
  'Filter': '对象过滤器',

  // ================= 持续伤害弹头属性 =================
  'DamageInterval': '伤害间隔(秒)', // 仅空投有毒罐头使用
  'DamageDuration': '伤害总时长(秒)', // 仅空投有毒罐头使用
  'RemoveIfHealed': '治疗时移除效果', // 仅空投有毒罐头使用

  // ================= 生命吸取弹头属性 =================
  'PercentDamageToHeal': '伤害转化为治疗百分比',// 没出现过
  'PercentMaxHealthToTake': '最大生命值吸取比例', // 在苏联碾压回血技能处出现，按目标最大生命比例吸血

  // ================= 投射物弹头属性 =================
  'ProjectileTemplate': '抛射物模板',
  'WarheadTemplate': '弹头模板',
  'WeaponLaunchBoneSlotOverride': '武器发射骨骼槽', // 指定发射骨骼，没出现过
  'AttackOffset': '攻击位置偏移',
  'VeterancyLevel': '老兵等级',
  'SpecificBarrelOverride': '特定炮管覆盖',
  'x': 'X轴偏移',
  'y': 'Y轴偏移',
  'z': 'Z轴偏移',
  
  // ================= 压制弹头属性 =================
  'Suppression': '压制强度', // 士气打击值
  'DurationSeconds': '效果持续时间(秒)',
  'SuppressionTaperOff': '压制衰减系数', // 随距离压制效果递减
  'SuppressionArc': '压制扇形角度', // 扇形压制区域，没出现过
  'SuppressionArcInverted': '反转压制扇形', // 反转扇形区域，没出现过

  // ================= 激光弹头属性 =================
  'Lifetime': '激光持续时间',
  'LaserId': '激光ID', //谁能告诉我那一大串数字是啥？
  'HitGroundFX': '命中地面特效',
  'OverShootDistance': '激光延长线距离',

  // ================= 对象创建弹头属性 =================
  'WeaponOCL': '武器对象创建列表', // 武器会从OCL列表创建对象
  'TargetAsPrimaryObject': '设目标为主要对象', //意义姑且不明，只在天皇之怒和点防御无人机上出现

  // ================= 麻痹弹头属性 =================
  'EffectArc': '麻痹效果扇形角度',// 扇形麻痹区域，没出现过
  'DurationSeconds': '麻痹持续时间(秒)',
  'ParalyzeType': '麻痹类型', // EMP/瘫痪等
  'RemoveParalyzeType': '解除麻痹类型', // 狗叫和镰刀武器使用
  'ParalyzeFX': '麻痹特效',
  
  // ================= 信息战弹头属性 =================
  'InfoWarType': '信息战类型', // 没出现过
  'RadarJamRadius': '雷达干扰半径',// 没出现过
  'RadarJamDuration': '雷达干扰持续时间',// 没出现过
  
  // ================= 泰矿消耗弹头属性 =================
  'AmountToSpend': '消耗泰矿数量',

  // ================= 冲击波弹头属性 =================
  'ShockWaveAmount': '冲击波强度',
  'ShockWaveRadius': '冲击波半径',
  'ShockWaveArc': '扇形冲击波范围角度',
  'ShockWaveTaperOff': '冲击波衰减',
  'ShockWaveSpeed': '冲击波速度',// 没出现过
  'ShockWaveZMult': '垂直方向冲击波系数', // 垂直方向效果强度
  'CyclonicFactor': '气旋因子', // 意义不明且没出现过
  'ShockwaveDelaySeconds': '冲击波延迟时间(秒)',
  'InvertShockWave': '反转冲击波方向', //不确定，在且只在电磁奇点上出现
  'FlipDirection': '翻转方向',
  'OnlyWhenJustDied': '仅在目标刚死亡时触发',
  'ShockWaveClearRadius': '冲击波清除半径', //只在百合子那里出现一次，而且和默认值是一样的
  'ShockWaveClearWaveMult': '清除冲击波倍数',
  'ShockWaveClearFlingHeight': '清除抛射高度',
  'KillObjectFilter': '击杀对象过滤器',

  // ================= 特殊能力弹头属性 =================
  'SpecialPowerTemplate': '特殊能力模板',

  // ================= 属性修改弹头属性 =================
  'AttributeModifierName': '属性修改器名称',
  'AttributeModifierOwnerName': '属性修改器所有者', //不确定
  'DamageFXType': '伤害特效类型',
  'DamageArc': '伤害作用弧度',
  'AntiCategories': '反制类别', // 意义不明且没出现过
  'AntiFX': '反制特效', // 意义不明且没出现过

  // ================= 线性伤害弹头属性 =================
  //线性伤害指的是莎莎和波能坦克那种伤害类型
  'OffsetAngle': '线性伤害偏移角度', // 不确定且没出现过
  'LineWidth': '线性伤害宽度', // 波能坦克等
  'LineLengthLeadIn': '起始线长',// 没出现过
  'LineLengthLeadOut': '结束线长',// 没出现过
  'UseDynamicLineLength': '线性伤害使用动态线长',
  'OverShootDistance': '线性伤害延长距离', 

  // ================= 着色弹头属性 =================
  //Tint类属性会给整个建筑/单位上色
  'PreColorTime': '着色淡入时间', 
  'SustainedColorTime': '持续着色时间', 
  'PostColorTime': '着色淡出时间', 
  'Frequency': '脉冲频率', // 意义不明
  'Amplitude': '脉冲幅度', // 意义不明
  'Color': '着色颜色',
  'r': '红色分量',
  'g': '绿色分量',
  'b': '蓝色分量',

  // ================= 地形弹坑弹头属性 =================
  'Depth': '弹坑深度',// 没出现过
  'Lift': '地形隆起比例', // 弹坑边缘隆起程度，没出现过

  // ================= 泰伯利亚矿弹头属性 =================
  'FieldAmount': '矿场数量',// 没出现过
  'SpawnedInFieldBonus': '矿场内生成加成',// 没出现过

  // ================= 散射弹头属性 =================
  'ScatterMin': '最小散射角度',// 没出现过
  'ScatterMax': '最大散射角度',// 没出现过

  // ================= 附加弹头属性 =================
  'AttachModuleId': 'ATTR模块ID', 

  // ================= 生命值剥离弹头属性 =================
  'AmountToStrip': '生命值剥离百分比', //只在百合子那里出现一次，因为她是按生命值上限百分比扣血的

  // ================= 对象攻击弹头属性 =================
  'Weapon': '使用的武器',
  'FireOnVictimObject': '对目标使用武器', // 天皇之怒和点防御无人机使用
  'VictimMustBeAlive': '目标必须存活',// 没出现过
  'Filter': '对象过滤器',

  // ================= 通知目标弹头属性 =================
  'MinTimeToImpactFudgeFactor': '最小命中时间容差', //不确定，在且只在海翼和盟军的小火箭上出现
  'MaxTimeToImpactFudgeFactor': '最大命中时间容差', //不确定，在且只在海翼和盟军的小火箭上出现

  // ================= 规则与过滤属性 =================
  'Rule': '生效规则(ALL/ANY/NONE)',
  'Include': '包含对象类型',
  'Exclude': '排除对象类型',
  'Relationship': '阵营关系(敌/友/中等)',
  'StatusBitFlags': '目标需要的状态标志', // 意义不明
  'StatusBitFlagsExclude': '排除目标的状态标志',
  'RequiredModelConditions': '所需模型状态',
  
  // ================= 武器模板子元素属性 =================
  'SpecialObjectFilter': '特殊对象过滤器',
  'OverrideVoiceAttackSound': '覆盖攻击语音',// 意义不明且没出现过
  'OverrideVoiceEnterStateAttackSound': '覆盖状态切换攻击语音',// 意义不明且没出现过
  'SurpriseAttackObjectFilter': '突袭攻击对象过滤器',
  'CombinedAttackObjectFilter': '联合攻击对象过滤器',
  'HitStoredObjectFilter': '命中存储对象过滤器',
  'ScatterRadiusVsType': '散射类型设置',
  'IncompatibleAttributeModifier': '不兼容属性修改器',
  
  // ================= 其他弹头属性 =================
  'SpawnTemplate': '生成模板',
  'SpawnProbability': '生成概率',
  'SpawnedModelConditionFlags': '生成模型状态标志',
  'Amount': '伤害量',
  'PercentDamageToContained': '对包含单位的伤害比例',
  'DamageObjectFilter': '伤害对象过滤器',
  'MaxUnitsToDamage': '最大伤害单位数',
  'WindowBlastFX': '窗口爆炸特效',
  'EventName': '事件名称',
  'SendToEnemies': '发送给敌人',
  'SendToAllies': '发送给盟友',
  'SendToNeutral': '发送给中立单位',
  
  // ================= 散射类型子属性 =================
  'ScatterRadiusVsType.Radius': '散射半径',
  'ScatterRadiusVsType.RequiredModelConditions': '散射所需模型状态'
    // 可以根据需要添加更多翻译
  };
  
  // 递归提取节点及其子节点的所有属性
  const extractAttributes = (node, parentName = '') => {
    // 添加当前节点的属性
    Array.from(node.attributes || []).forEach(attr => {
      const translation = attributeTranslations[attr.name];
      // 格式化为"原属性名(翻译)"的形式，如果没有翻译则只显示原属性名
      const displayName = translation ? `${attr.name}(${translation})` : attr.name;
      
      // 如果有父节点名称，则添加前缀
      const fullName = parentName ? `${parentName}下的${displayName}` : displayName;
      
      if (!parentName) {
        // 顶层属性加粗
        attrs.add(`**${fullName}**`);
      } else {
        attrs.add(fullName);
      }
    });
    
    // 递归处理子节点
    Array.from(node.children || []).forEach(child => {
      // 使用当前节点的名称作为子节点的父节点名称
      const nodeName = node.attributes?.name?.value || node.nodeName;
      extractAttributes(child, nodeName);
    });
  };

  // 遍历所有武器，提取属性和子节点属性
  allWeapons.value.forEach(w => {
    extractAttributes(w.node);
  });
  
  return Array.from(attrs);
});



  const pagedWeapons = computed(() => {
    const start = (currentPage.value - 1) * pageSize.value
    return allWeapons.value.slice(start, start + pageSize.value)
  })
  
  const totalPages = computed(() => {
    return Math.ceil(allWeapons.value.length / pageSize.value)
  })
  
  const selectedWeapons = computed(() => {
    return allWeapons.value.filter(w => selectedWeaponIds.value.includes(w.id))
  })
  
  const inheritanceCount = computed(() => {
    const inheritanceMap = new Map()
    allWeapons.value.forEach(weapon => {
      const parent = weapon.node.getAttribute('inheritFrom')
      if (parent) {
        inheritanceMap.set(parent, (inheritanceMap.get(parent) || 0) + 1)
      }
    })
    return Array.from(inheritanceMap.entries())
      .map(([weapon, count]) => ({ weapon, count }))
      .sort((a, b) => b.count - a.count)
  })
  
  const displayMode = computed(() => {
    if (isReversed.value && isTransposed.value) return 'normal'
    if (isReversed.value) return 'reversed'
    if (isTransposed.value) return 'transposed'
    return 'normal'
  })
// 方法
function getWeaponAttribute(weapon, attr, searchChildren = true) {
  // 处理所有可能的属性显示格式：
  // 1. 加粗格式：**WeaponSpeed**
  // 2. 带父节点前缀：Weapon下的Speed
  // 3. 带翻译格式：Speed(速度)
  // 4. 组合格式：Weapon下的Speed(速度)
  
  let rawAttr = attr;
  
  // 1. 去除Markdown加粗标记
  rawAttr = rawAttr.replace(/\*\*/g, '');
  
  // 2. 去除"下的"前缀部分
  if (rawAttr.includes('下的')) {
    rawAttr = rawAttr.split('下的')[1];
  }
  
  // 3. 去除括号翻译部分
  if (rawAttr.includes('(')) {
    rawAttr = rawAttr.split('(')[0];
  }

  // 4. 去除可能存在的首尾空格
  rawAttr = rawAttr.trim();

  // 5. 优先检查当前节点
  const value = weapon.node.getAttribute(rawAttr);
  if (value !== null) return value;

  // 6. 若未找到且允许查找子节点，则递归搜索
  if (searchChildren && weapon.node.children) {
    for (const child of weapon.node.children) {
      const childValue = getWeaponAttribute({ node: child }, rawAttr, true);
      if (childValue !== null) return childValue;
    }
  }

  // 7. 最终未找到返回 null
  return null;
}
  function filterAttributes() {
    filteredAttributes.value = allAttributes.value.filter(attr => 
      attr.toLowerCase().includes(attributeSearchText.value.toLowerCase())
    )
    selectAll.value = false
  }
  
  function toggleSelectAll() {
    selectAll.value = !selectAll.value
    if (selectAll.value) {
      selectedAttributes.value = [...filteredAttributes.value]
    } else {
      selectedAttributes.value = []
    }
  }
  
  function clearSelectedAttributes() {
    selectedAttributes.value = []
  }
  
  function removeAttribute(attr) {
    selectedAttributes.value = selectedAttributes.value.filter(a => a !== attr)
  }
  
  function prevPage() {
    if (currentPage.value > 1) currentPage.value--
  }
  
  function nextPage() {
    if (currentPage.value < totalPages.value) currentPage.value++
  }
  
  function toggleTableDirection() {
    isReversed.value = !isReversed.value
  }
  
  function transposeTable() {
    isTransposed.value = !isTransposed.value
  }
  
  function getCellClass(value) {
    return value ? 'has-value' : 'no-value'
  }
  
  function clearAllSelections() {
    selectedWeaponIds.value = []
  }
  
  function autoSelectMatched() {
    const allMatchedTemplates = new Set()
    resultList.value.forEach(item => {
      if (item.templates && item.templates.length > 0) {
        item.templates.forEach(t => allMatchedTemplates.add(t))
      }
    })
    
    selectedWeaponIds.value = Array.from(allMatchedTemplates)
    activeSection.value = 'compare'
  }
  
  function handleWeaponFile(e) {
    const file = e.target.files[0]
    if (!file) return
    const reader = new FileReader()
    reader.onload = () => {
      const parser = new DOMParser()
      const newContent = reader.result
      weaponXmlData.value = parser.parseFromString(reader.result, 'text/xml')
      weaponXml.value = newContent
      localStorage.setItem('weaponXml', newContent)
      parseWeaponFile(newContent)
      updateWeaponData()
    }
    reader.readAsText(file)
  }
///武器数据更新xml
  function updateWeaponData() {
  if (!selectedGameObject.value || !weaponXmlData.value) {
    weaponData.value = []
    return
  } 
  const weapons = [] 
  // 查找单位的所有武器模板
  for (let slotName of ['WeaponSlotHardpoint', 'WeaponSlotTurret', 'WeaponSlotHierarchicalTurret', 'WeaponSlotContained']) {
    const weaponNodes = selectedGameObject.value.querySelectorAll(`Behaviors > WeaponSetUpdate > ${slotName} > Weapon`)
    weaponNodes.forEach(weaponNode => {
      const templateId = weaponNode.getAttribute('Template')
      if (templateId) {
        const weaponTemplate = weaponXmlData.value.querySelector(`WeaponTemplate[id="${templateId}"]`)
        if (weaponTemplate) {
          const attackRange = weaponTemplate.getAttribute('AttackRange')
          const minAttackRange = weaponTemplate.getAttribute('MinimumAttackRange')
          
          // 查找DamageNugget
          let Radius = 0
          let Damage = 0
          const damageNugget = weaponTemplate.querySelector('Nuggets > DamageNugget')
          if (damageNugget) {
            Radius = damageNugget.getAttribute('Radius') || 0
            Damage = damageNugget.getAttribute('Damage') || 0
          }
          
          weapons.push({
            id: templateId,
            attackRange,
            minAttackRange,
            Damage,
            Radius
          })
        }
      }
    })
  }
  
  weaponData.value = weapons
}

////////
  function handleCompareWeaponFile(e) {
    handleWeaponFile(e)
  }
  
  function handleUnitFile(e) {
    const file = e.target.files[0]
    if (!file) return
    const reader = new FileReader()
    reader.onload = () => {
      const parser = new DOMParser()
      unitDoc.value = parser.parseFromString(reader.result, 'text/xml')
      tryMatchAndDisplay()
    }
    reader.readAsText(file)
  }
  
  function parseWeaponFile(fileContent) {
    const parser = new DOMParser()
    const xml = parser.parseFromString(fileContent, 'text/xml')
    const templates = xml.querySelectorAll('WeaponTemplate')
    weaponTemplateIds.value = new Set(
      Array.from(templates).map(t => t.getAttribute('id')).filter(Boolean)
    )
    
    allWeapons.value = Array.from(templates).map(node => ({
      id: node.getAttribute('id'),
      node
    }))
    
    tryMatchAndDisplay()
  }
  
  function tryMatchAndDisplay() {
    if (!unitDoc.value || weaponTemplateIds.value.size === 0) return
    resultList.value = []
    const gameObjects = unitDoc.value.querySelectorAll('GameObject')
    gameObjects.forEach(go => {
      const goId = go.getAttribute('id') || '(无 ID)'
      const matchedTemplates = new Set()
  
      for (let slotName of ['WeaponSlotHardpoint', 'WeaponSlotTurret', 'WeaponSlotHierarchicalTurret', 'WeaponSlotContained']) {
        const weapons = go.querySelectorAll(`Behaviors > WeaponSetUpdate > ${slotName} > Weapon`)
        weapons.forEach(w => {
          const tmpl = w.getAttribute('Template')
          if (tmpl && weaponTemplateIds.value.has(tmpl)) {
            matchedTemplates.add(tmpl)
          }
        })
        if (matchedTemplates.size) break
      }
  
      resultList.value.push({
        id: goId,
        templates: Array.from(matchedTemplates)
      })
    })
  }
  
  function getInheritanceChain(weapon) {
    const chain = [weapon.id]
    let current = weapon.node.getAttribute('inheritFrom')
    while (current) {
      chain.push(current)
      const parent = allWeapons.value.find(w => w.id === current)
      if (!parent) break
      current = parent.node.getAttribute('inheritFrom')
    }
    return chain
  }
  
  // 初始化
  onMounted(() => {
    const storedWeaponXml = localStorage.getItem('weaponXml')
    if (storedWeaponXml) {
      weaponXml.value = storedWeaponXml
      parseWeaponFile(storedWeaponXml)
    }
    filterAttributes()
  })
  </script>
  
  <style scoped>
  /* 基础样式 */
  :root {
    --primary-color: #409eff;
    --success-color: #67c23a;
    --warning-color: #e6a23c;
    --danger-color: #f56c6c;
    --info-color: #909399;
    --text-primary: #303133;
    --text-regular: #606266;
    --text-secondary: #909399;
    --border-color: #dcdfe6;
    --bg-color: #f5f7fa;
  }
  
  * {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }
  
  body {
    font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
      'Microsoft YaHei', Arial, sans-serif;
    color: var(--text-primary);
    line-height: 1.5;
    background-color: #f0f2f5;
  }
  
  /* 布局样式 */
  .app-container {
    display: flex;
    min-height: 100vh;
  }
  
  .sidebar {
    width: 220px;
    background-color: #001529;
    color: white;
    padding: 20px 0;
  }
  
  .sidebar h2 {
    padding: 0 20px;
    margin-bottom: 20px;
    font-size: 18px;
    font-weight: 600;
  }
  
  .sidebar ul {
    list-style: none;
  }
  
  .sidebar li {
    padding: 12px 20px;
    cursor: pointer;
    transition: all 0.3s;
    display: flex;
    align-items: center;
  }
  
  .sidebar li:hover {
    background-color: #1890ff;
  }
  
  .sidebar li.active {
    background-color: #1890ff;
  }
  
  .sidebar li i {
    margin-right: 8px;
  }
  
  .main-content {
    flex: 1;
    padding: 20px;
    background-color: #f0f2f5;
    overflow-y: auto;
  }
  
  /* 卡片样式 */
  .upload-card, .result-card, .weapon-list-card, 
  .compare-tools, .info-card, .reload-card, 
  .pagination-card {
    background-color: white;
    border-radius: 8px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
    padding: 20px;
    margin-bottom: 20px;
  }
  
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
  }
  
  .card-header h3 {
    margin: 0;
    font-size: 16px;
    color: var(--text-primary);
  }
  
  /* 上传区域 */
  .upload-area {
    display: flex;
    gap: 20px;
    margin-bottom: 20px;
  }
  
  .upload-card {
    flex: 1;
    text-align: center;
  }
  
  .upload-card h3 {
    margin-bottom: 15px;
    color: var(--text-primary);
  }
  
  .file-upload {
    /* display: none; */
  }
  
  .file-upload + label {
    display: inline-block;
    padding: 10px 20px;
    background-color: var(--primary-color);
    color: white;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.3s;
  }
  
  .file-upload + label:hover {
    background-color: #66b1ff;
  }
  
  /* 表格样式 */
  .table-responsive {
    overflow-x: auto;
  }
  
  .result-table, .weapon-table, .comparison-table, .info-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
  }
  
  .result-table th, .result-table td,
  .weapon-table th, .weapon-table td,
  .comparison-table th, .comparison-table td,
  .info-table th, .info-table td {
    padding: 12px 15px;
    border: 1px solid var(--border-color);
    text-align: left;
  }
  
  .result-table th, .weapon-table th,
  .comparison-table th, .info-table th {
    background-color: #fafafa;
    font-weight: 600;
    color: var(--text-primary);
  }
  
  .result-table tr:nth-child(even),
  .weapon-table tr:nth-child(even),
  .info-table tr:nth-child(even) {
    background-color: #f9f9f9;
  }
  
  .result-table tr:hover,
  .weapon-table tr:hover,
  .info-table tr:hover {
    background-color: #f5f5f5;
  }
  
  .no-match {
    color: var(--text-secondary);
    font-style: italic;
  }
  
  /* 分页样式 */
  .pagination-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 15px;
  }
  
  .page-btn {
    padding: 8px 16px;
    background-color: white;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    transition: all 0.3s;
  }
  
  .page-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  
  .page-btn:hover:not(:disabled) {
    color: var(--primary-color);
    border-color: var(--primary-color);
  }
  
  .page-info {
    font-size: 14px;
    color: var(--text-regular);
  }
  
  /* 按钮样式 */
  .action-btn {
    padding: 8px 16px;
    background-color: var(--primary-color);
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    transition: background-color 0.3s;
  }
  
  .action-btn:hover {
    background-color: #66b1ff;
  }
  
  .action-btn.danger {
    background-color: var(--danger-color);
  }
  
  .action-btn.danger:hover {
    background-color: #f78989;
  }
  
  .tool-btn {
    padding: 8px 16px;
    background-color: rgb(149, 149, 149);
    border: 1px solid var(--border-color);
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    transition: all 0.3s;
  }
  
  .tool-btn:hover {
    color: var(--primary-color);
    border-color: var(--primary-color);
  }
  
  .tool-btn.active {
    background-color: rgb(206, 206, 206);
    color: rgb(0, 0, 0);
    border-color: var(--primary-color);
  }
  
  .small-btn {
    padding: 6px 12px;
    font-size: 12px;
    border-radius: 3px;
    background-color: white;
    border: 1px solid var(--border-color);
    cursor: pointer;
    transition: all 0.3s;
  }
  
  .small-btn:hover {
    color: var(--primary-color);
    border-color: var(--primary-color);
  }
  
  .small-btn.danger {
    color: var(--danger-color);
    border-color: var(--danger-color);
  }
  
  .small-btn.danger:hover {
    background-color: #fef0f0;
  }
  
  /* 属性选择器 */
  .attribute-selector-panel {
    display: flex;
    gap: 20px;
    margin-bottom: 20px;
  }
  
  .attribute-controls {
    flex: 1;
    max-width: 350px;
  }
  
  .search-box {
    position: relative;
    margin-bottom: 10px;
    display: flex;
    gap: 10px;
  }
  
  .search-box .icon-search {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-secondary);
  }
  
  .search-input {
    flex: 1;
    padding: 8px 12px 8px 32px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    font-size: 14px;
    transition: border-color 0.3s;
  }
  
  .search-input:focus {
    border-color: var(--primary-color);
    outline: none;
  }
  
  .button-group {
    display: flex;
    gap: 8px;
  }
  
  .select-container {
    position: relative;
  }
  
  .multi-select {
    width: 100%;
    padding: 8px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: white;
    font-size: 14px;
    min-height: 200px;
    transition: border-color 0.3s;
  }
  
  .multi-select:focus {
    border-color: var(--primary-color);
    outline: none;
  }
  
  .select-option {
    padding: 8px 12px;
    cursor: pointer;
  }
  
  .select-option:hover {
    background-color: #f5f7fa;
  }
  
  .selection-info {
    margin-top: 8px;
    font-size: 12px;
    color: var(--text-secondary);
    text-align: right;
  }
  
  /* 已选属性预览 */
  .selected-preview {
    flex: 1;
    min-width: 0;
    background: white;
    border-radius: 6px;
    border: 1px solid var(--border-color);
  }
  
  .preview-header {
    padding: 12px 15px;
    border-bottom: 1px solid var(--border-color);
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .preview-header h4 {
    margin: 0;
    font-size: 14px;
    color: var(--text-primary);
  }
  
  .hint-text {
    font-size: 12px;
    color: var(--text-secondary);
  }
  
  .selected-tags {
    padding: 12px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    max-height: 200px;
    overflow-y: auto;
  }
  
  .tag {
    display: inline-flex;
    align-items: center;
    background: #f0f7ff;
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 13px;
    color: var(--primary-color);
    cursor: pointer;
    transition: all 0.3s;
  }
  
  .tag:hover {
    background: #d9ecff;
  }
  
  .tag .icon-close {
    margin-left: 6px;
    font-size: 12px;
    opacity: 0.7;
  }
  
  .tag:hover .icon-close {
    opacity: 1;
  }
  
  .empty-hint {
    color: var(--text-secondary);
    font-size: 13px;
    font-style: italic;
  }
  
  /* 对比结果表格 */
  .comparison-table {
    width: 100%;
    border-collapse: collapse;
  }
  
  .comparison-table th, .comparison-table td {
    padding: 12px 15px;
    border: 1px solid var(--border-color);
  }
  
  .comparison-table th {
    background-color: #fafafa;
    font-weight: 600;
  }
  
  .attr-name {
    font-weight: 600;
    background-color: #fafafa !important;
  }
  
  .has-value {
    background-color: #f6ffed;
  }
  
  .no-value {
    background-color: #fff2f0;
    color: var(--text-secondary);
  }
  
  /* 空状态 */
  .empty-state {
    padding: 40px 0;
    text-align: center;
    color: var(--text-secondary);
  }
  
  .empty-state.small {
    padding: 20px 0;
  }
  
  .empty-state .icon {
    font-size: 48px;
    margin-bottom: 15px;
    opacity: 0.5;
  }
  
  .empty-state.small .icon {
    font-size: 24px;
  }
  
  .empty-state p {
    margin-top: 10px;
  }
  
  /* 继承排行榜 */
  .ranking-list {
    padding: 10px 0;
  }
  
  .ranking-item {
    display: flex;
    align-items: center;
    padding: 10px 15px;
    border-bottom: 1px dashed var(--border-color);
  }
  
  .ranking-item:last-child {
    border-bottom: none;
  }
  
  .rank {
    width: 24px;
    height: 24px;
    background-color: #f5f5f5;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    margin-right: 12px;
  }
  
  .ranking-item:nth-child(1) .rank {
    background-color: #fff7e6;
    color: #faad14;
  }
  
  .ranking-item:nth-child(2) .rank {
    background-color: #fff2f0;
    color: #ff4d4f;
  }
  
  .ranking-item:nth-child(3) .rank {
    background-color: #f6ffed;
    color: #52c41a;
  }
  
  .weapon-name {
    flex: 1;
    font-size: 14px;
  }
  
  .count {
    font-size: 13px;
    color: var(--text-secondary);
  }
  
  /* 复选框样式 */
  .checkbox-container {
    display: block;
    position: relative;
    padding-left: 25px;
    cursor: pointer;
    user-select: none;
  }
  
  .checkbox-container input {
    position: absolute;
    opacity: 0;
    cursor: pointer;
    height: 0;
    width: 0;
  }
  
  .checkmark {
    position: absolute;
    top: 0;
    left: 0;
    height: 18px;
    width: 18px;
    background-color: white;
    border: 1px solid var(--border-color);
    border-radius: 3px;
  }
  
  .checkbox-container:hover input ~ .checkmark {
    border-color: var(--primary-color);
  }
  
  .checkbox-container input:checked ~ .checkmark {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
  }
  
  .checkmark:after {
    content: "";
    position: absolute;
    display: none;
  }
  
  .checkbox-container input:checked ~ .checkmark:after {
    display: block;
  }
  
  .checkbox-container .checkmark:after {
    left: 6px;
    top: 2px;
    width: 5px;
    height: 10px;
    border: solid rgb(19, 38, 255);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
  }
  
  /* 图标样式 */
  .icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: middle;
    fill: currentColor;
  }
  
  /* 响应式设计 */
  @media (max-width: 992px) {
    .app-container {
      flex-direction: column;
    }
    
    .sidebar {
      width: 100%;
      padding: 10px;
    }
    
    .sidebar ul {
      display: flex;
    }
    
    .sidebar li {
      padding: 10px 15px;
    }
    
    .upload-area {
      flex-direction: column;
    }
    
    .attribute-selector-panel {
      flex-direction: column;
    }
    
    .attribute-controls {
      max-width: 100%;
    }
  }
  
  @media (max-width: 768px) {
    .pagination-controls {
      flex-direction: column;
      gap: 10px;
    }
    
    .card-header {
      flex-direction: column;
      align-items: flex-start;
      gap: 10px;
    }
    
    .button-group {
      flex-wrap: wrap;
    }
  }
  .GOBeditor-section {
  padding: 20px;
  font-family: Arial, sans-serif;
}

.file-input-container {
  margin-bottom: 20px;
}

.unit-editor {
  display: flex;
  gap: 20px;
}

.unit-list {
  width: 250px;
  border-right: 1px solid #ddd;
  padding-right: 10px;
  max-height: 80vh;
  overflow-y: auto;
}

.unit-item {
  padding: 8px 12px;
  cursor: pointer;
  border-radius: 4px;
  margin-bottom: 5px;
  background-color: #f5f5f5;
}

.unit-item:hover {
  background-color: #e0e0e0;
}

.unit-details {
  flex: 1;
  padding: 10px;
  background-color: #f9f9f9;
  border-radius: 5px;
}

.detail-row {
  display: flex;
  margin-bottom: 10px;
}

.detail-label {
  font-weight: bold;
  min-width: 150px;
  color: #333;
}

.detail-value {
  color: #666;
}

.detail-group {
  margin-bottom: 15px;
  border: 1px solid #ddd;
  border-radius: 5px;
  overflow: hidden;
}

.group-header {
  padding: 8px 12px;
  background-color: #e9e9e9;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.group-header:hover {
  background-color: #e0e0e0;
}

.group-content {
  padding: 10px 15px;
  background-color: white;
}

.toggle-icon {
  font-weight: bold;
}
/* 新增样式 */
.weapon-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-left: 10px;
  padding: 8px;
  background-color: #f0f0f0;
  border-radius: 4px;
}

.weapon-stats div {
  white-space: nowrap;
}

/* 调整文件输入容器样式 */
.file-input-container {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 20px;
}

.file-input {
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: white;
}
  </style>