MediaWiki

Card.js:修订间差异

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献
无编辑摘要
律Rhyme留言 | 贡献
无编辑摘要
 
(未显示同一用户的49个中间版本)
第1行: 第1行:
(function() {
(function() {
     // 确保jQuery和MediaWiki API已加载
    'use strict';
     mw.loader.using(['mediawiki.api', 'mediawiki.util', 'jquery.ui'], function() {
   
        $(document).ready(function() {
     // 加载CSS
            // 卡牌编辑器对象
     mw.loader.load('/index.php?title=Mediawiki:Card.css&action=raw&ctype=text/css', 'text/css');
            var CardEditor = {
   
                characters: {}, // 存储所有角色的卡牌数据
    // 状态管理
                currentCharacter: null, // 当前选中的角色
    const state = {
                currentCard: null,
        currentFighter: '',
                currentVariantIndex: null,
        fighters: [],
                api: new mw.Api(),
        cards: [],
 
        currentCard: null,
                init: function() {
        defaultInfo: {
                    // 清空占位符
            order: '',
                    $('#mw-content-text').empty();
            ego: ''
                    this.createUI();
        },
                    this.bindEvents();
        editMode: 'base', // 'base', 'inspiration', 'god_inspiration'
                    this.loadCharacterList();
        currentGod: '凯尔肯',
                },
        currentInspirationIndex: null,
 
        currentGodInspirationIndex: null
                createUI: function() {
    };
                    var html = [
   
                        '<div id="card-editor">',
    // 卡牌数据结构
                            '<div class="ce-container">',
    function createEmptyCard() {
                                // 左侧输入区
        return {
                                '<div class="ce-left">',
            name: '',
                                    // 角色选择区
            base: {
                                    '<div class="ce-group">',
                displayname: '',
                                        '<div class="ce-group-title">战斗员选择</div>',
                art: '',
                                        '<div class="ce-row">',
                group: '',
                                            '<div class="ce-label">当前战斗员:</div>',
                rarity: '',
                                            '<div class="ce-select-wrapper">',
                god: '',
                                                '<input type="text" id="ce-character-select" class="ce-select-input" placeholder="选择或输入新战斗员..." readonly>',
                ap: '',
                                                '<div class="ce-select-dropdown" id="ce-character-dropdown" style="display:none;"></div>',
                type: '',
                                            '</div>',
                dict: '',
                                            '<span class="ce-btn ce-btn-small ce-btn-primary" id="ce-new-character" style="margin-left: 10px;">新建</span>',
                desc_global: '',
                                        '</div>',
                sub: '',
                                    '</div>',
                isinspiration: 0,
                                    '<div class="ce-group">',
                isgod_inspiration: 0
                                        '<div class="ce-group-title">卡牌数据</div>',
            },
                                        '<div class="ce-form">',
            var: {
                                            // 名称
                inspiration: [],
                                            '<div class="ce-row">',
                god_inspiration: {
                                                '<div class="ce-label">卡牌名称:</div>',
                    凯尔肯: [],
                                                '<input type="text" id="ce-name" class="ce-input" placeholder="请输入卡牌名称...">',
                    戴奥斯: [],
                                            '</div>',
                    尼希隆: [],
                                            // 卡组
                    赛克瑞德: [],
                                            '<div class="ce-row">',
                    维托: []
                                                '<div class="ce-label">卡组类型:</div>',
                }
                                                '<div class="ce-select-wrapper">',
            }
                                                    '<input type="text" id="ce-deck" class="ce-select-input" placeholder="点击选择或输入..." readonly>',
        };
                                                    '<div class="ce-select-dropdown" id="ce-deck-dropdown" style="display:none;">',
    }
                                                        '<div class="ce-select-option" data-value="">请选择</div>',
   
                                                        '<div class="ce-select-option" data-value="起始卡牌">起始卡牌</div>',
    // 创建空变体结构
                                                        '<div class="ce-select-option" data-value="独特卡牌">独特卡牌</div>',
    function createEmptyVariant() {
                                                        '<div class="ce-select-option" data-value="灵光一闪">灵光一闪</div>',
        return {
                                                        '<div class="ce-select-option" data-value="衍生卡牌">衍生卡牌</div>',
            ap: '',
                                                    '</div>',
            type: '',
                                                '</div>',
            desc_global: '',
                                            '</div>',
            dict: '',
                                            // 图片
            sub: '' // 新增:变体卡牌的衍生卡牌字段
                                            '<div class="ce-row">',
        };
                                                '<div class="ce-label">图片文件:</div>',
    }
                                                '<input type="text" id="ce-art" class="ce-input" placeholder="输入图片文件名...">',
   
                                            '</div>',
    // 创建元素辅助函数
                                            // 属性
    function createElement(tag, className, attributes = {}) {
                                            '<div class="ce-row">',
        const el = document.createElement(tag);
                                                '<div class="ce-label">属性:</div>',
        if (className) el.className = className;
                                                '<div class="ce-select-wrapper">',
        Object.entries(attributes).forEach(([key, value]) => {
                                                    '<input type="text" id="ce-attr" class="ce-select-input" placeholder="点击选择..." readonly>',
            if (key === 'textContent') {
                                                    '<div class="ce-select-dropdown" id="ce-attr-dropdown" style="display:none;">',
                el.textContent = value;
                                                        '<div class="ce-select-option" data-value="">请选择</div>',
            } else if (key.startsWith('on')) {
                                                        '<div class="ce-select-option" data-value="热情">热情</div>',
                el.addEventListener(key.substring(2).toLowerCase(), value);
                                                        '<div class="ce-select-option" data-value="秩序">秩序</div>',
            } else {
                                                        '<div class="ce-select-option" data-value="正义">正义</div>',
                el.setAttribute(key, value);
                                                        '<div class="ce-select-option" data-value="本能">本能</div>',
            }
                                                        '<div class="ce-select-option" data-value="虚无">虚无</div>',
        });
                                                    '</div>',
        return el;
                                                '</div>',
    }
                                            '</div>',
   
                                            // 稀有度
    // 创建自定义下拉选择器
                                            '<div class="ce-row">',
    function createSelect(options, selectedValue, onChange) {
                                                '<div class="ce-label">稀有度:</div>',
        const select = createElement('div', 'form-select');
                                                '<div class="ce-select-wrapper">',
        select.textContent = selectedValue || options[0] || '请选择';
                                                    '<input type="text" id="ce-rarity" class="ce-select-input" placeholder="点击选择..." readonly>',
        select.setAttribute('tabindex', '0');
                                                    '<div class="ce-select-dropdown" id="ce-rarity-dropdown" style="display:none;">',
       
                                                        '<div class="ce-select-option" data-value="">请选择</div>',
        const dropdown = createElement('div', 'dropdown-menu');
                                                        '<div class="ce-select-option" data-value="白">白</div>',
       
                                                        '<div class="ce-select-option" data-value="蓝">蓝</div>',
        options.forEach(option => {
                                                        '<div class="ce-select-option" data-value="橙">橙</div>',
            const item = createElement('div', 'dropdown-item');
                                                        '<div class="ce-select-option" data-value="彩">彩</div>',
            item.textContent = option;
                                                    '</div>',
            item.addEventListener('click', () => {
                                                '</div>',
                select.textContent = option;
                                            '</div>',
                dropdown.style.display = 'none';
                                            // AP
                if (onChange) onChange(option);
                                            '<div class="ce-row">',
            });
                                                '<div class="ce-label">AP (行动点):</div>',
            dropdown.appendChild(item);
                                                '<input type="text" id="ce-ap" class="ce-input" placeholder="输入AP数值...">',
        });
                                            '</div>',
       
                                            // 类型
        select.addEventListener('click', (e) => {
                                            '<div class="ce-row">',
            e.stopPropagation();
                                                '<div class="ce-label">卡牌类型:</div>',
            dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';
                                                '<div class="ce-select-wrapper">',
            const rect = select.getBoundingClientRect();
                                                    '<input type="text" id="ce-type" class="ce-select-input" placeholder="点击选择..." readonly>',
            dropdown.style.top = rect.bottom + 'px';
                                                    '<div class="ce-select-dropdown" id="ce-type-dropdown" style="display:none;">',
            dropdown.style.left = rect.left + 'px';
                                                        '<div class="ce-select-option" data-value="">请选择</div>',
            dropdown.style.width = rect.width + 'px';
                                                        '<div class="ce-select-option" data-value="攻击">攻击</div>',
        });
                                                        '<div class="ce-select-option" data-value="技能">技能</div>',
       
                                                        '<div class="ce-select-option" data-value="强化">强化</div>',
        document.addEventListener('click', () => {
                                                        '<div class="ce-select-option" data-value="状态异常">状态异常</div>',
            dropdown.style.display = 'none';
                                                    '</div>',
        });
                                                '</div>',
       
                                            '</div>',
        const wrapper = createElement('div');
                                            // 机制
        wrapper.style.position = 'relative';
                                            '<div class="ce-row">',
        wrapper.appendChild(select);
                                                '<div class="ce-label">卡牌机制:</div>',
        document.body.appendChild(dropdown);
                                                '<input type="text" id="ce-mechanism" class="ce-input" placeholder="请输入卡牌机制...">',
       
                                            '</div>',
        return { wrapper, select, dropdown };
                                            // 描述
    }
                                            '<div class="ce-row">',
   
                                                '<div class="ce-label">卡牌描述:</div>',
    // 创建自定义输入框
                                                '<div class="ce-desc-wrapper">',
    function createInput(type, value, onChange, placeholder = '') {
                                                    '<div class="ce-format-buttons">',
        const input = createElement('div', 'form-input');
                                                        '<span class="ce-btn ce-btn-small ce-btn-blue" id="ce-blue-text">蓝色文本</span>',
        input.setAttribute('contenteditable', 'true');
                                                        '<span class="ce-btn ce-btn-small ce-btn-green" id="ce-green-text">绿色文本</span>',
        input.textContent = value || '';
                                                        '<span class="ce-btn ce-btn-small ce-btn-lime" id="ce-green-stroke">绿色描边</span>',
        input.setAttribute('data-placeholder', placeholder);
                                                        '<span class="ce-btn ce-btn-small ce-btn-orange" id="ce-insert-br">插入换行</span>',
        input.style.minHeight = type === 'textarea' ? '100px' : 'auto';
                                                    '</div>',
       
                                                    '<textarea id="ce-desc" class="ce-textarea" placeholder="请输入卡牌描述..."></textarea>',
        if (!value) {
                                                '</div>',
            input.style.color = '#999';
                                            '</div>',
            input.textContent = placeholder;
                                            // 衍生卡牌
        }
                                            '<div class="ce-row">',
       
                                                '<div class="ce-label">衍生卡牌:</div>',
        input.addEventListener('focus', () => {
                                                '<input type="text" id="ce-derived" class="ce-input" placeholder="请输入衍生卡牌...">',
            if (input.textContent === placeholder) {
                                            '</div>',
                input.textContent = '';
                                        '</div>',
                input.style.color = '#333';
                                    '</div>',
            }
                                    // 按钮区
        });
                                    '<div class="ce-buttons">',
       
                                        '<span class="ce-btn ce-btn-primary" id="ce-add-card">添加卡牌</span>',
        input.addEventListener('blur', () => {
                                        '<span class="ce-btn ce-btn-primary" id="ce-add-variant">添加变体</span>',
            if (!input.textContent.trim()) {
                                        '<span class="ce-btn" id="ce-save-data">保存数据</span>',
                input.textContent = placeholder;
                                        '<span class="ce-btn" id="ce-clear-form">清空表单</span>',
                input.style.color = '#999';
                                    '</div>',
            }
                                '</div>',
            if (onChange) onChange(input.textContent === placeholder ? '' : input.textContent);
                                // 中间列表区
        });
                                '<div class="ce-middle">',
       
                                    '<div class="ce-group">',
        input.addEventListener('input', () => {
                                        '<div class="ce-group-title">卡牌列表</div>',
            if (onChange && input.textContent !== placeholder) {
                                        '<div class="ce-list-container">',
                onChange(input.textContent);
                                            '<div id="ce-card-list" class="ce-list"></div>',
            }
                                        '</div>',
        });
                                    '</div>',
       
                                    '<div class="ce-group">',
        return input;
                                        '<div class="ce-group-title">变体列表</div>',
    }
                                        '<div class="ce-list-container">',
   
                                            '<div id="ce-variant-list" class="ce-list"></div>',
    // 创建复选框
                                        '</div>',
    function createCheckbox(checked, onChange) {
                                    '</div>',
        const wrapper = createElement('div', 'checkbox-wrapper');
                                    '<div class="ce-buttons">',
        const checkbox = createElement('div', checked ? 'checkbox checked' : 'checkbox');
                                        '<span class="ce-btn ce-btn-danger" id="ce-delete-card">删除卡牌</span>',
        const label = createElement('div', '');
                                        '<span class="ce-btn ce-btn-danger" id="ce-delete-variant">删除变体</span>',
        label.textContent = '是';
                                    '</div>',
       
                                '</div>',
        wrapper.addEventListener('click', () => {
                                // 右侧代码区
            const newChecked = !checkbox.classList.contains('checked');
                                '<div class="ce-right">',
            if (newChecked) {
                                    '<div class="ce-group">',
                checkbox.classList.add('checked');
                                        '<div class="ce-group-title">Lua代码预览 - <span id="ce-code-character">未选择战斗员</span></div>',
            } else {
                                        '<textarea id="ce-code-display" class="ce-code" readonly></textarea>',
                checkbox.classList.remove('checked');
                                    '</div>',
            }
                                    '<div class="ce-buttons">',
            if (onChange) onChange(newChecked ? 1 : 0);
                                        '<span class="ce-btn" id="ce-reload-character">重新加载</span>',
        });
                                        '<span class="ce-btn ce-btn-primary" id="ce-save-to-wiki">保存到Wiki</span>',
       
                                        '<span class="ce-btn" id="ce-copy-code">复制代码</span>',
        wrapper.appendChild(checkbox);
                                        '<span class="ce-btn ce-btn-danger" id="ce-delete-character">删除战斗员</span>',
        wrapper.appendChild(label);
                                    '</div>',
        return wrapper;
                                '</div>',
    }
                            '</div>',
   
                        '</div>'
    // 创建表单组
                    ].join('');
    function createFormGroup(label, control) {
 
        const group = createElement('div', 'form-group');
                    $('#mw-content-text').html(html);
        const labelEl = createElement('div', 'form-label');
                },
        labelEl.textContent = label;
 
        group.appendChild(labelEl);
                bindEvents: function() {
        group.appendChild(control);
                    var self = this;
        return group;
 
    }
                    // 自定义下拉框事件
   
                    $(document).on('click', '.ce-select-input', function() {
    // 创建按钮
                        var dropdown = $(this).siblings('.ce-select-dropdown');
    function createButton(text, className, onClick) {
                        $('.ce-select-dropdown').not(dropdown).hide();
        const btn = createElement('div', 'btn ' + className);
                        dropdown.toggle();
        btn.textContent = text;
                    });
        btn.addEventListener('click', onClick);
 
        return btn;
                    $(document).on('click', '.ce-select-option', function() {
    }
                        var value = $(this).data('value');
   
                        var text = $(this).text();
    // 文本插入辅助函数
                        var input = $(this).parent().siblings('.ce-select-input');
    function insertTextAtCursor(element, text, wrap = false) {
                        input.val(value || '');
        element.focus();
                        input.data('value', value);
        const selection = window.getSelection();
                        $(this).parent().hide();
       
                    });
        if (wrap && selection.rangeCount > 0) {
 
            const range = selection.getRangeAt(0);
                    // 战斗员选择
            const selectedText = range.toString();
                    $(document).on('click', '#ce-character-dropdown .ce-select-option', function() {
           
                         var character = $(this).data('value');
            if (selectedText) {
                         self.selectCharacter(character);
                range.deleteContents();
                    });
                const textNode = document.createTextNode(text.replace('选择文字', selectedText));
 
                range.insertNode(textNode);
                    // 点击其他地方关闭下拉框
                return;
                    $(document).on('click', function(e) {
            }
                        if (!$(e.target).closest('.ce-select-wrapper').length) {
        }
                             $('.ce-select-dropdown').hide();
       
        document.execCommand('insertText', false, text);
    }
   
    // 辅助函数:提取字符串值
    function extractStringValue(text, key) {
        const pattern = new RegExp(key + '\\s*=\\s*"([^"]*)"', 'm');
        const match = text.match(pattern);
        return match ? match[1] : '';
    }
   
    // 辅助函数:提取数值
    function extractNumberValue(text, key) {
        const pattern = new RegExp(key + '\\s*=\\s*(\\d+)', 'm');
        const match = text.match(pattern);
        return match ? parseInt(match[1]) : 0;
    }
   
    // 辅助函数:提取任意值(包括X、Ø等)
    function extractValue(text, key) {
        const pattern = new RegExp(key + '\\s*=\\s*([^,\\n]+)', 'm');
        const match = text.match(pattern);
        if (match) {
            let value = match[1].trim();
            value = value.replace(/^["']|["']$/g, '');
            return value;
        }
        return '';
    }
   
    // 解析灵光一闪/神光一闪列表
    function parseInspirationList(content) {
        const inspirations = [];
       
        let depth = 0;
        let currentBlock = '';
        let inString = false;
       
        for (let i = 0; i < content.length; i++) {
            const char = content[i];
            const prevChar = i > 0 ? content[i - 1] : '';
           
            if (char === '"' && prevChar !== '\\') {
                inString = !inString;
            }
           
            if (!inString) {
                if (char === '{') {
                    if (depth > 0) {
                        currentBlock += char;
                    }
                    depth++;
                } else if (char === '}') {
                    depth--;
                    if (depth === 0 && currentBlock) {
                        const inspiration = {};
                       
                        const ap = extractValue(currentBlock, 'ap');
                        if (ap) inspiration.ap = ap;
                       
                        const type = extractStringValue(currentBlock, 'type');
                        if (type) inspiration.type = type;
                       
                        const desc = extractStringValue(currentBlock, 'desc_global');
                        if (desc) inspiration.desc_global = desc;
                       
                        const dict = extractStringValue(currentBlock, 'dict');
                        if (dict) inspiration.dict = dict;
                       
                        // 新增:解析变体的 sub 字段
                        const sub = extractStringValue(currentBlock, 'sub');
                         if (sub) inspiration.sub = sub;
                          
                        if (Object.keys(inspiration).length > 0) {
                             inspirations.push(inspiration);
                         }
                         }
                    });
                    // 按钮事件
                    $('#ce-new-character').on('click', function() { self.createNewCharacter(); });
                    $('#ce-add-card').on('click', function() { self.addCard(); });
                    $('#ce-add-variant').on('click', function() { self.addVariant(); });
                    $('#ce-save-data').on('click', function() { self.saveData(); });
                    $('#ce-clear-form').on('click', function() { self.clearForm(); });
                    $('#ce-delete-card').on('click', function() { self.deleteCard(); });
                    $('#ce-delete-variant').on('click', function() { self.deleteVariant(); });
                    $('#ce-reload-character').on('click', function() { self.reloadCurrentCharacter(); });
                    $('#ce-save-to-wiki').on('click', function() { self.saveToWiki(); });
                    $('#ce-copy-code').on('click', function() { self.copyCode(); });
                    $('#ce-delete-character').on('click', function() { self.deleteCharacter(); });
                    // 文本格式化按钮
                    $('#ce-blue-text').on('click', function() { self.insertTextFormat('蓝'); });
                    $('#ce-green-text').on('click', function() { self.insertTextFormat('绿'); });
                    $('#ce-green-stroke').on('click', function() { self.insertStrokeFormat(); });
                    $('#ce-insert-br').on('click', function() { self.insertBr(); });
                    // 列表项点击事件
                    $(document).on('click', '.ce-list-item', function() {
                        var $this = $(this);
                        var listId = $this.parent().attr('id');
                          
                          
                         $('.ce-list-item').removeClass('selected');
                         currentBlock = '';
                        $this.addClass('selected');
                    } else if (depth > 0) {
 
                        currentBlock += char;
                        if (listId === 'ce-card-list') {
                    }
                            var index = $this.data('index');
                } else if (depth > 0) {
                            self.onCardSelected(index);
                    currentBlock += char;
                        } else if (listId === 'ce-variant-list') {
                }
                            var index = $this.data('index');
            } else if (depth > 0) {
                            self.onVariantSelected(index);
                currentBlock += char;
                        }
            }
                    });
        }
                 },
       
 
        return inspirations;
                selectCharacter: function(character) {
    }
                    this.currentCharacter = character;
   
                    $('#ce-character-select').val(character);
    // 辅助函数:使用括号计数提取块内容
                     $('#ce-code-character').text(character);
    function extractBlock(content, startPattern) {
        const match = content.match(startPattern);
        if (!match) return null;
       
        let startIdx = match.index + match[0].length;
        let depth = 1;
        let endIdx = startIdx;
        let inString = false;
       
        for (let i = startIdx; i < content.length && depth > 0; i++) {
            const char = content[i];
            const prevChar = i > 0 ? content[i - 1] : '';
           
            if (char === '"' && prevChar !== '\\') {
                inString = !inString;
            }
           
            if (!inString) {
                if (char === '{') {
                    depth++;
                } else if (char === '}') {
                    depth--;
                    if (depth === 0) {
                        endIdx = i;
                        break;
                    }
                }
            }
        }
       
        return content.substring(startIdx, endIdx);
    }
   
    // 解析Lua代码
    function parseLuaCode(luaText) {
        const cards = [];
        const defaultInfo = {
            order: '',
            ego: ''
        };
       
        try {
            const orderMatch = luaText.match(/card\.order\s*=\s*\{\s*"([^"]+)"\s*\}/);
            if (orderMatch) {
                defaultInfo.order = orderMatch[1];
            }
           
            const egoMatch = luaText.match(/card\.info\s*=\s*\{[^}]*ego\s*=\s*"([^"]+)"/);
            if (egoMatch) {
                 defaultInfo.ego = egoMatch[1];
            }
           
            const cardPattern = /card\["([^"]+)"\]\s*=\s*\{/g;
            let cardMatch;
           
            while ((cardMatch = cardPattern.exec(luaText)) !== null) {
                const cardName = cardMatch[1];
                const cardStartIdx = cardMatch.index + cardMatch[0].length;
               
                let depth = 1;
                let cardEndIdx = cardStartIdx;
                let inString = false;
               
                for (let i = cardStartIdx; i < luaText.length && depth > 0; i++) {
                    const char = luaText[i];
                     const prevChar = i > 0 ? luaText[i - 1] : '';
                      
                      
                     // 清空当前数据
                     if (char === '"' && prevChar !== '\\') {
                    this.currentCard = null;
                        inString = !inString;
                    this.currentVariantIndex = null;
                     }
                     this.clearForm();
                      
                      
                     // 更新显示
                     if (!inString) {
                    this.updateCardList();
                        if (char === '{') {
                    this.updateVariantList();
                            depth++;
                    this.updateCode();
                        } else if (char === '}') {
                },
                            depth--;
 
                            if (depth === 0) {
                createNewCharacter: function() {
                                cardEndIdx = i;
                    var character = prompt('请输入新战斗员的名称:');
                                break;
                    if (!character || character.trim() === '') return;
                            }
                   
                         }
                    character = character.trim();
                   
                    // 检查是否已存在
                    if (this.characters[character]) {
                         alert('战斗员 "' + character + '" 已存在!');
                        return;
                     }
                     }
                      
                }
                     // 创建新战斗员
               
                     this.characters[character] = [];
                const cardContent = luaText.substring(cardStartIdx, cardEndIdx);
                     this.updateCharacterDropdown();
               
                     this.selectCharacter(character);
                const card = createEmptyCard();
                     alert('新战斗员 "' + character + '" 创建成功!');
                card.name = cardName;
                 },
               
 
                const baseContent = extractBlock(cardContent, /base\s*=\s*\{/);
                 deleteCharacter: function() {
                if (baseContent) {
                     if (!this.currentCharacter) {
                    card.base.displayname = extractStringValue(baseContent, 'displayname') || '';
                         alert('请先选择一个战斗员!');
                     card.base.art = extractStringValue(baseContent, 'art') || '';
                        return;
                     card.base.group = extractStringValue(baseContent, 'group') || '';
                    card.base.rarity = extractStringValue(baseContent, 'rarity') || '';
                    card.base.god = extractStringValue(baseContent, 'god') || '';
                     card.base.ap = extractValue(baseContent, 'ap') || '';
                     card.base.type = extractStringValue(baseContent, 'type') || '';
                     card.base.dict = extractStringValue(baseContent, 'dict') || '';
                     card.base.desc_global = extractStringValue(baseContent, 'desc_global') || '';
                    card.base.sub = extractStringValue(baseContent, 'sub') || '';
                    card.base.isinspiration = extractNumberValue(baseContent, 'isinspiration') || 0;
                    card.base.isgod_inspiration = extractNumberValue(baseContent, 'isgod_inspiration') || 0;
                 }
               
                const varContent = extractBlock(cardContent, /var\s*=\s*\{/);
                 if (varContent) {
                    const inspirationContent = extractBlock(varContent, /inspiration\s*=\s*\{/);
                     if (inspirationContent) {
                         card.var.inspiration = parseInspirationList(inspirationContent);
                     }
                     }
                      
                      
                     if (!confirm('确定要删除战斗员 "' + this.currentCharacter + '" 及其所有卡牌吗?\n此操作不可恢复!')) {
                    const godInspirationContent = extractBlock(varContent, /god_inspiration\s*=\s*\{/);
                         return;
                     if (godInspirationContent) {
                        // 修改:使用中文键名解析神光一闪
                        ['凯尔肯', '戴奥斯', '尼希隆', '赛克瑞德', '维托'].forEach(god => {
                            const godPattern = new RegExp('\\["?' + god + '"?\\]\\s*=\\s*\\{');
                            const godContent = extractBlock(godInspirationContent, godPattern);
                            if (godContent) {
                                card.var.god_inspiration[god] = parseInspirationList(godContent);
                            }
                         });
                     }
                     }
                   
                }
                    delete this.characters[this.currentCharacter];
               
                    this.currentCharacter = null;
                cards.push(card);
                    this.currentCard = null;
            }
                    this.currentVariantIndex = null;
           
                   
        } catch (error) {
                    $('#ce-character-select').val('');
            console.error('解析Lua代码失败:', error);
                    $('#ce-code-character').text('未选择战斗员');
        }
                   
       
                    this.updateCharacterDropdown();
        return { cards, defaultInfo };
                    this.clearForm();
    }
                    this.updateCardList();
   
                    this.updateVariantList();
    // Lua字符串转义
                    this.updateCode();
    function escapeLuaString(str) {
                   
        if (!str) return '';
                    alert('战斗员删除成功!');
        return str.replace(/\\/g, '\\\\')
                },
                  .replace(/"/g, '\\"')
 
                  .replace(/\n/g, '\\n')
                loadCharacterList: function() {
                  .replace(/\r/g, '\\r')
                    var self = this;
                  .replace(/\t/g, '\\t');
                    $('#ce-character-dropdown').html('<div class="ce-loading">正在加载战斗员列表...</div>');
    }
                   
   
                    // 搜索所有 模块:卡牌/+角色名 的页面
    // 生成Lua代码
                    this.api.get({
    function generateLuaCode() {
                        action: 'query',
        let code = 'local card = {}\n\n';
                        list: 'allpages',
       
                        apprefix: '卡牌/',
        if (state.defaultInfo.order) {
                        apnamespace: 828, // Module namespace
            code += `card.order = { "${escapeLuaString(state.defaultInfo.order)}" }\n\n`;
                        aplimit: 'max'
        }
                    }).then(function(data) {
       
                        if (data.query && data.query.allpages) {
        if (state.defaultInfo.ego) {
                            var pages = data.query.allpages;
            code += 'card.info = {\n';
                            var characterPromises = [];
            code += `    ego = "${escapeLuaString(state.defaultInfo.ego)}",\n`;
                           
            code += '}\n\n';
                            // 初始化空字典
        }
                            self.characters = {};
       
                           
        state.cards.forEach(card => {
                            for (var i = 0; i < pages.length; i++) {
            code += `card["${escapeLuaString(card.name)}"] = {\n`;
                                var title = pages[i].title;
            code += '   base = {\n';
                                var character = title.replace('模块:卡牌/', '');
           
                                 self.characters[character] = [];
            const base = card.base;
                               
            if (base.displayname) code += `        displayname = "${escapeLuaString(base.displayname)}",\n`;
                                 // 加载每个角色的数据
            if (base.art) code += `        art = "${escapeLuaString(base.art)}",\n`;
                                characterPromises.push(self.loadCharacterData(character));
            if (base.group) code += `        group = "${escapeLuaString(base.group)}",\n`;
            if (base.rarity) code += `        rarity = "${escapeLuaString(base.rarity)}",\n`;
            if (base.god) code += `        god = "${escapeLuaString(base.god)}",\n`;
            if (base.ap !== '') {
                if (isNaN(base.ap)) {
                    code += `        ap = "${escapeLuaString(base.ap)}",\n`;
                } else {
                    code += `        ap = ${base.ap},\n`;
                }
            }
            if (base.type) code += `        type = "${escapeLuaString(base.type)}",\n`;
            if (base.dict) code += `        dict = "${escapeLuaString(base.dict)}",\n`;
            if (base.desc_global) code += `        desc_global = "${escapeLuaString(base.desc_global)}",\n`;
            if (base.sub) code += `        sub = "${escapeLuaString(base.sub)}",\n`;
            if (base.isinspiration) code += `        isinspiration = ${base.isinspiration},\n`;
            if (base.isgod_inspiration) code += `        isgod_inspiration = ${base.isgod_inspiration},\n`;
           
            code += '    },\n';
           
            const hasInspiration = card.var.inspiration.length > 0;
            const hasGodInspiration = Object.values(card.var.god_inspiration).some(arr => arr.length > 0);
           
            if (hasInspiration || hasGodInspiration) {
                code += '    var = {\n';
               
                if (hasInspiration) {
                    code += '        inspiration = {\n';
                    card.var.inspiration.forEach(insp => {
                        code += '           {\n';
                        if (insp.ap !== '' && insp.ap !== undefined) {
                            if (isNaN(insp.ap)) {
                                 code += `                ap = "${escapeLuaString(insp.ap)}",\n`;
                            } else {
                                 code += `                ap = ${insp.ap},\n`;
                             }
                             }
                           
                            // 等待所有角色数据加载完成
                            $.when.apply($, characterPromises).then(function() {
                                self.updateCharacterDropdown();
                            });
                        } else {
                            self.updateCharacterDropdown();
                         }
                         }
                    }).fail(function() {
                        if (insp.type) code += `                type = "${escapeLuaString(insp.type)}",\n`;
                         $('#ce-character-dropdown').html('<div class="ce-error">加载失败,请稍后重试</div>');
                        if (insp.desc_global) code += `                desc_global = "${escapeLuaString(insp.desc_global)}",\n`;
                         if (insp.dict) code += `                dict = "${escapeLuaString(insp.dict)}",\n`;
                        // 新增:输出变体的 sub 字段
                        if (insp.sub) code += `                sub = "${escapeLuaString(insp.sub)}",\n`;
                        code += '            },\n';
                     });
                     });
                 },
                    code += '        },\n';
 
                 }
                 loadCharacterData: function(character) {
               
                     var self = this;
                 if (hasGodInspiration) {
                    var pageName = '模块:卡牌/' + character;
                     code += '        god_inspiration = {\n';
                      
                     Object.entries(card.var.god_inspiration).forEach(([god, inspList]) => {
                    return this.api.get({
                         if (inspList.length > 0) {
                        action: 'query',
                             // 修改:使用中文键名格式 ["尼希隆"]
                        prop: 'revisions',
                            code += `            ["${god}"] = {\n`;
                        titles: pageName,
                            inspList.forEach(insp => {
                        rvprop: 'content',
                                 code += '                {\n';
                        rvlimit: 1
                                 if (insp.ap !== '' && insp.ap !== undefined) {
                    }).then(function(data) {
                                     if (isNaN(insp.ap)) {
                         if (data.query && data.query.pages) {
                                        code += `                    ap = "${escapeLuaString(insp.ap)}",\n`;
                             for (var pageId in data.query.pages) {
                                     } else {
                                 var page = data.query.pages[pageId];
                                        code += `                    ap = ${insp.ap},\n`;
                                 if (page.revisions && page.revisions[0]) {
                                    }
                                     var content = page.revisions[0]['*'];
                                     self.characters[character] = self.parseCardData(content);
                                 }
                                 }
                             }
                                if (insp.type) code += `                    type = "${escapeLuaString(insp.type)}",\n`;
                                if (insp.desc_global) code += `                    desc_global = "${escapeLuaString(insp.desc_global)}",\n`;
                                if (insp.dict) code += `                    dict = "${escapeLuaString(insp.dict)}",\n`;
                                // 新增:输出变体的 sub 字段
                                if (insp.sub) code += `                    sub = "${escapeLuaString(insp.sub)}",\n`;
                                code += '                },\n';
                            });
                             code += '            },\n';
                         }
                         }
                     });
                     });
                 },
                    code += '        },\n';
                }
               
                code += '    },\n';
            }
           
            code += '}\n\n';
        });
       
        code += 'return card';
       
        return code;
    }
   
    // 加载战斗员列表
    async function loadFighters() {
        try {
            const api = new mw.Api();
            const result = await api.get({
                action: 'query',
                list: 'allpages',
                apprefix: '卡牌/',
                apnamespace: 828,
                aplimit: 500
            });
           
            if (result.query && result.query.allpages) {
                state.fighters = result.query.allpages.map(page => {
                    return page.title.replace('模块:卡牌/', '');
                });
            }
        } catch (error) {
            console.error('加载战斗员列表失败:', error);
        }
    }
   
    // 加载战斗员卡牌数据
    async function loadFighterCards(fighter) {
        if (!fighter) return [];
       
        try {
            const api = new mw.Api();
           
            const result = await api.get({
                action: 'query',
                prop: 'revisions',
                 titles: '模块:卡牌/' + fighter,
                rvprop: 'content',
                rvslots: 'main',
                formatversion: 2
            });
           
            if (!result.query || !result.query.pages || result.query.pages.length === 0) {
                console.error('未找到页面');
                return [];
            }
           
            const page = result.query.pages[0];
           
            if (page.missing) {
                console.error('页面不存在');
                return [];
            }
           
            const content = page.revisions[0].slots.main.content;
           
            const parsed = parseLuaCode(content);
           
            state.defaultInfo = parsed.defaultInfo;
           
            return parsed.cards;
           
        } catch (error) {
            console.error('加载卡牌数据失败:', error);
            return [];
        }
    }
   
    // 更新代码预览(不触发滚动)
    function updateCodePreview() {
        const codePreview = document.querySelector('.code-preview');
        if (codePreview) {
            codePreview.textContent = generateLuaCode();
        }
    }
   
    // 渲染变体卡牌编辑表单
    function renderVariantEditor(container) {
        if (!state.currentCard) return;
       
        if (state.editMode === 'inspiration' && state.currentInspirationIndex !== null) {
            const insp = state.currentCard.var.inspiration[state.currentInspirationIndex];
            if (!insp) return;
           
            const variantSection = createElement('div', 'variant-edit-section');
            const variantTitle = createElement('div', 'section-title');
            variantTitle.textContent = `灵光一闪 #${state.currentInspirationIndex + 1}`;
            variantTitle.style.borderColor = '#9c27b0';
            variantSection.appendChild(variantTitle);
           
            // 返回按钮
            const backBtn = createButton('← 返回基础信息', 'btn', () => {
                state.editMode = 'base';
                state.currentInspirationIndex = null;
                renderWithoutScroll();
            });
            backBtn.style.marginBottom = '15px';
            backBtn.style.width = '100%';
            variantSection.appendChild(backBtn);
           
            // AP输入
            const apInput = createInput('text', insp.ap, (value) => {
                insp.ap = value;
                updateCodePreview();
            }, 'AP (数字、X、Ø)');
            variantSection.appendChild(createFormGroup('AP:', apInput));
           
            // 类型选择
            const typeSelect = createSelect(
                ['', '攻击', '技能', '强化'],
                insp.type || '',
                (value) => {
                    insp.type = value;
                    updateCodePreview();
                }
            );
            variantSection.appendChild(createFormGroup('类型:', typeSelect.wrapper));
           
            // 机制输入
            const dictInput = createInput('text', insp.dict, (value) => {
                insp.dict = value;
                updateCodePreview();
            }, '多个机制使用、隔开');
            variantSection.appendChild(createFormGroup('机制:', dictInput));
           
            // 描述区域
            const descSection = createElement('div', 'form-group');
            const descLabel = createElement('div', 'form-label');
            descLabel.textContent = '描述:';
            descSection.appendChild(descLabel);
           
            // 描述工具栏
            const toolbar = createElement('div', 'button-group');
           
            const blueTextBtn = createButton('蓝色文本', 'btn btn-blue', () => {
                insertTextAtCursor(descInput, '{{文本|蓝|选择文字}}', true);
            });
            toolbar.appendChild(blueTextBtn);
           
            const greenTextBtn = createButton('绿色文本', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|选择文字}}', true);
            });
            toolbar.appendChild(greenTextBtn);
           
            const blueUnderlineBtn = createButton('蓝色下划线', 'btn btn-blue', () => {
                insertTextAtCursor(descInput, '{{文本|蓝|下划线|选择文字}}', true);
            });
            toolbar.appendChild(blueUnderlineBtn);
           
            const greenUnderlineBtn = createButton('绿色下划线', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|下划线|选择文字}}', true);
            });
            toolbar.appendChild(greenUnderlineBtn);
           
            const strokeTextBtn = createButton('绿色描边', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{描边|绿|选择文字}}', true);
            });
            toolbar.appendChild(strokeTextBtn);
           
            const dictBtn = createButton('词典', 'btn', () => {
                insertTextAtCursor(descInput, '{{词典|选择文字}}', true);
            });
            toolbar.appendChild(dictBtn);
           
            const wrapBtn = createButton('换行', 'btn', () => {
                insertTextAtCursor(descInput, '<br>');
            });
            toolbar.appendChild(wrapBtn);
           
            descSection.appendChild(toolbar);
           
            const descInput = createInput('textarea', insp.desc_global, (value) => {
                insp.desc_global = value;
                updateCodePreview();
            }, '变体描述');
            descInput.style.minHeight = '150px';
            descSection.appendChild(descInput);
           
            variantSection.appendChild(descSection);
           
            // 新增:衍生卡牌输入框
            const subInput = createInput('textarea', insp.sub || '', (value) => {
                insp.sub = value;
                updateCodePreview();
            }, '衍生卡牌');
            subInput.style.minHeight = '35px';
            variantSection.appendChild(createFormGroup('衍生卡牌:', subInput));
           
            // 删除按钮
            const deleteBtn = createButton('删除此变体', 'btn-danger', () => {
                if (confirm('确定要删除这个灵光一闪吗?')) {
                    state.currentCard.var.inspiration.splice(state.currentInspirationIndex, 1);
                    state.editMode = 'base';
                    state.currentInspirationIndex = null;
                    renderWithoutScroll();
                }
            });
            deleteBtn.style.marginTop = '20px';
            deleteBtn.style.width = '100%';
            variantSection.appendChild(deleteBtn);
           
            container.appendChild(variantSection);
           
        } else if (state.editMode === 'god_inspiration' && state.currentGodInspirationIndex !== null) {
            const insp = state.currentCard.var.god_inspiration[state.currentGod][state.currentGodInspirationIndex];
            if (!insp) return;
           
            const variantSection = createElement('div', 'variant-edit-section');
            const variantTitle = createElement('div', 'section-title');
            variantTitle.textContent = `${state.currentGod} 神光 #${state.currentGodInspirationIndex + 1}`;
            variantTitle.style.borderColor = '#673ab7';
            variantSection.appendChild(variantTitle);
           
            // 返回按钮
            const backBtn = createButton('← 返回基础信息', 'btn', () => {
                state.editMode = 'base';
                state.currentGodInspirationIndex = null;
                renderWithoutScroll();
            });
            backBtn.style.marginBottom = '15px';
            backBtn.style.width = '100%';
            variantSection.appendChild(backBtn);
           
            // AP输入
            const apInput = createInput('text', insp.ap, (value) => {
                insp.ap = value;
                updateCodePreview();
            }, 'AP (数字、X、Ø)');
            variantSection.appendChild(createFormGroup('AP:', apInput));
           
            // 类型选择
            const typeSelect = createSelect(
                ['', '攻击', '技能', '强化'],
                insp.type || '',
                (value) => {
                    insp.type = value;
                    updateCodePreview();
                }
            );
            variantSection.appendChild(createFormGroup('类型:', typeSelect.wrapper));
           
            // 机制输入
            const dictInput = createInput('text', insp.dict, (value) => {
                insp.dict = value;
                updateCodePreview();
            }, '多个机制使用、隔开');
            variantSection.appendChild(createFormGroup('机制:', dictInput));
           
            // 描述区域
            const descSection = createElement('div', 'form-group');
            const descLabel = createElement('div', 'form-label');
            descLabel.textContent = '描述:';
            descSection.appendChild(descLabel);
           
            // 描述工具栏
            const toolbar = createElement('div', 'button-group');
           
            const blueTextBtn = createButton('蓝色文本', 'btn btn-blue', () => {
                insertTextAtCursor(descInput, '{{文本|蓝|选择文字}}', true);
            });
            toolbar.appendChild(blueTextBtn);
           
            const greenTextBtn = createButton('绿色文本', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|选择文字}}', true);
            });
            toolbar.appendChild(greenTextBtn);
           
            const blueUnderlineBtn = createButton('蓝色下划线', 'btn btn-blue', () => {
                insertTextAtCursor(descInput, '{{文本|蓝|下划线|选择文字}}', true);
            });
            toolbar.appendChild(blueUnderlineBtn);
           
            const greenUnderlineBtn = createButton('绿色下划线', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|下划线|选择文字}}', true);
            });
            toolbar.appendChild(greenUnderlineBtn);
           
            const strokeTextBtn = createButton('绿色描边', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{描边|绿|选择文字}}', true);
            });
            toolbar.appendChild(strokeTextBtn);
           
            const dictBtn = createButton('词典', 'btn', () => {
                insertTextAtCursor(descInput, '{{词典|选择文字}}', true);
            });
            toolbar.appendChild(dictBtn);
           
            const wrapBtn = createButton('换行', 'btn', () => {
                insertTextAtCursor(descInput, '<br>');
            });
            toolbar.appendChild(wrapBtn);
           
            const circenBtn = createButton('凯尔肯', 'btn', () => {
                insertTextAtCursor(descInput, '{{图标|凯尔肯}}');
            });
            toolbar.appendChild(circenBtn);


                reloadCurrentCharacter: function() {
            const diallosBtn = createButton('戴奥斯', 'btn', () => {
                    if (!this.currentCharacter) {
                insertTextAtCursor(descInput, '{{图标|戴奥斯}}');
                        alert('请先选择一个战斗员!');
            });
                        return;
            toolbar.appendChild(diallosBtn);
                    }
                   
                    var self = this;
                    this.loadCharacterData(this.currentCharacter).then(function() {
                        self.updateCardList();
                        self.updateVariantList();
                        self.updateCode();
                        alert('战斗员 "' + self.currentCharacter + '" 的数据已重新加载!');
                    });
                },


                updateCharacterDropdown: function() {
            const nihiluBtn = createButton('尼希隆', 'btn', () => {
                    var html = '<div class="ce-select-option" data-value="">请选择战斗员</div>';
                insertTextAtCursor(descInput, '{{图标|尼希隆}}');
                    var characters = Object.keys(this.characters).sort();
            });
                   
            toolbar.appendChild(nihiluBtn);
                    for (var i = 0; i < characters.length; i++) {
                        var character = characters[i];
                        var cardCount = this.characters[character].length;
                        html += '<div class="ce-select-option" data-value="' + character + '">' +
                                character + ' (' + cardCount + ' 张卡牌)</div>';
                    }
                   
                    $('#ce-character-dropdown').html(html);
                },


                getCardData: function() {
            const secredBtn = createButton('赛克瑞德', 'btn', () => {
                    var variant = {};
                insertTextAtCursor(descInput, '{{图标|赛克瑞德}}');
                   
            });
                    var art = $('#ce-art').val().trim();
            toolbar.appendChild(secredBtn);
                    if (art) variant.art = art;
                   
                    var deck = $('#ce-deck').val().trim();
                    if (deck) variant['卡组'] = deck;
                   
                    var attr = $('#ce-attr').val().trim();
                    if (attr) variant['属性'] = attr;
                   
                    var rarity = $('#ce-rarity').val().trim();
                    if (rarity) variant['稀有度'] = rarity;
                   
                    var ap = $('#ce-ap').val().trim();
                    if (ap) {
                        if (ap.toUpperCase() === 'X') {
                            variant.AP = 'X';
                        } else if (/^\d+$/.test(ap)) {
                            variant.AP = parseInt(ap, 10);
                        }
                    }
                   
                    var mechanism = $('#ce-mechanism').val().trim();
                    if (mechanism) variant['机制'] = mechanism;
                   
                    var type = $('#ce-type').val().trim();
                    if (type) variant['类型'] = type;
                   
                    var desc = $('#ce-desc').val().trim();
                    if (desc) variant['描述'] = desc;
                   
                    var derived = $('#ce-derived').val().trim();
                    if (derived) variant['衍生卡牌'] = derived;
                   
                    return {
                        name: $('#ce-name').val().trim(),
                        variants: [variant]
                    };
                },


                setCardData: function(card, variantIndex) {
            const vitorBtn = createButton('维托', 'btn', () => {
                    $('#ce-name').val(card.name || '');
                insertTextAtCursor(descInput, '{{图标|维托}}');
                   
            });
                    if (card.variants && card.variants[variantIndex]) {
            toolbar.appendChild(vitorBtn);
                        var variant = card.variants[variantIndex];
                        var isVariant = variant['卡组'] === '灵光一闪' && variantIndex > 0;
                       
                        // 设置字段是否可编辑
                        $('#ce-name').prop('disabled', isVariant);
                        $('#ce-art').prop('disabled', isVariant);
                        $('#ce-attr').prop('disabled', isVariant);
                        $('#ce-rarity').prop('disabled', isVariant);
                        $('#ce-derived').prop('disabled', isVariant);
                       
                        // 设置值
                        $('#ce-art').val(variant.art || '');
                        $('#ce-deck').val(variant['卡组'] || '');
                        $('#ce-attr').val(variant['属性'] || '');
                        $('#ce-rarity').val(variant['稀有度'] || '');
                       
                        var ap = variant.AP;
                        $('#ce-ap').val(ap !== undefined ? String(ap) : '');
                       
                        $('#ce-mechanism').val(variant['机制'] || '');
                        $('#ce-type').val(variant['类型'] || '');
                        $('#ce-desc').val(variant['描述'] || '');
                        $('#ce-derived').val(variant['衍生卡牌'] || '');
                    }
                },


                clearForm: function() {
            descSection.appendChild(toolbar);
                    $('#ce-name').val('').prop('disabled', false);
           
                    $('#ce-art').val('').prop('disabled', false);
            const descInput = createInput('textarea', insp.desc_global, (value) => {
                    $('#ce-deck').val('');
                insp.desc_global = value;
                     $('#ce-attr').val('').prop('disabled', false);
                updateCodePreview();
                    $('#ce-rarity').val('').prop('disabled', false);
            }, '变体描述');
                    $('#ce-ap').val('');
            descInput.style.minHeight = '150px';
                    $('#ce-mechanism').val('');
            descSection.appendChild(descInput);
                    $('#ce-type').val('');
           
                    $('#ce-desc').val('');
            variantSection.appendChild(descSection);
                    $('#ce-derived').val('').prop('disabled', false);
           
                 },
            // 新增:衍生卡牌输入框
 
            const subInput = createInput('textarea', insp.sub || '', (value) => {
                 addCard: function() {
                insp.sub = value;
                    if (!this.currentCharacter) {
                updateCodePreview();
                        alert('请先选择或创建一个战斗员!');
            }, '衍生卡牌');
                        return;
            subInput.style.minHeight = '35px';
                    }
            variantSection.appendChild(createFormGroup('衍生卡牌:', subInput));
                   
           
                    var cardData = this.getCardData();
            // 删除按钮
                    if (!cardData.name) {
            const deleteBtn = createButton('删除此变体', 'btn-danger', () => {
                        alert('卡牌名称不能为空!');
                if (confirm('确定要删除这个神光一闪吗?')) {
                        return;
                    state.currentCard.var.god_inspiration[state.currentGod].splice(state.currentGodInspirationIndex, 1);
                    }
                    state.editMode = 'base';
                   
                     state.currentGodInspirationIndex = null;
                    this.characters[this.currentCharacter].push(cardData);
                    renderWithoutScroll();
                    this.currentCard = cardData;
                }
                    this.currentVariantIndex = 0;
            });
                    this.updateCardList();
            deleteBtn.style.marginTop = '20px';
                    this.updateVariantList();
            deleteBtn.style.width = '100%';
                    this.updateCode();
            variantSection.appendChild(deleteBtn);
                    this.clearForm();
           
                    alert('卡牌 "' + cardData.name + '" 添加成功!');
            container.appendChild(variantSection);
                },
        }
 
    }
                addVariant: function() {
   
                    if (!this.currentCard) {
    // 不触发滚动的渲染函数
                        alert('请先选择一个卡牌!');
    function renderWithoutScroll() {
                        return;
        const container = document.getElementById('card-manager-container');
                    }
        if (!container) return;
                   
       
                    var variantData = this.getCardData();
        // 保存当前滚动位置
                    var variant = variantData.variants[0];
        const scrollPositions = {
                     variant['卡组'] = '灵光一闪';
            input: 0,
                      
            list: 0,
                     // 复制主卡牌的某些属性
            preview: 0
                     var mainVariant = this.currentCard.variants[0];
        };
                     if (!variant.art && mainVariant.art) variant.art = mainVariant.art;
       
                    if (!variant['属性'] && mainVariant['属性']) variant['属性'] = mainVariant['属性'];
        const inputSection = container.querySelector('.card-input-section');
                     if (!variant['稀有度'] && mainVariant['稀有度']) variant['稀有度'] = mainVariant['稀有度'];
        const listSection = container.querySelector('.card-list-section');
                     if (!variant['衍生卡牌'] && mainVariant['衍生卡牌']) variant['衍生卡牌'] = mainVariant['衍生卡牌'];
        const previewSection = container.querySelector('.card-preview-section');
                   
       
                    this.currentCard.variants.push(variant);
        if (inputSection) scrollPositions.input = inputSection.scrollTop;
                     this.currentVariantIndex = this.currentCard.variants.length - 1;
        if (listSection) scrollPositions.list = listSection.scrollTop;
                     this.updateVariantList();
        if (previewSection) scrollPositions.preview = previewSection.scrollTop;
                    this.updateCode();
       
                    alert('为 "' + this.currentCard.name + '" 添加变体成功!');
        // 执行渲染
                 },
        render();
 
       
                 saveData: function() {
        // 恢复滚动位置
                     if (!this.currentCard || this.currentVariantIndex === null) {
        requestAnimationFrame(() => {
                         alert('请先选择要保存的卡牌或变体!');
            const newInputSection = container.querySelector('.card-input-section');
                         return;
            const newListSection = container.querySelector('.card-list-section');
            const newPreviewSection = container.querySelector('.card-preview-section');
           
            if (newInputSection) newInputSection.scrollTop = scrollPositions.input;
            if (newListSection) newListSection.scrollTop = scrollPositions.list;
            if (newPreviewSection) newPreviewSection.scrollTop = scrollPositions.preview;
        });
    }
   
    // 渲染函数
    function render() {
        const container = document.getElementById('card-manager-container');
        if (!container) return;
       
        container.innerHTML = '';
       
        const manager = createElement('div', 'card-manager');
       
        // 左侧输入区
        const inputSection = createElement('div', 'card-input-section');
       
        // 战斗员选择
        const title = createElement('div', 'section-title');
        title.textContent = '卡牌管理器';
        inputSection.appendChild(title);
       
        const fighterSelect = createSelect(state.fighters, state.currentFighter, async (value) => {
            state.currentFighter = value;
            const loading = createElement('div', 'loading-indicator');
            loading.textContent = '正在加载卡牌数据...';
            document.body.appendChild(loading);
           
            try {
                 const cards = await loadFighterCards(value);
                state.cards = cards;
                 state.currentCard = cards.length > 0 ? cards[0] : null;
                state.editMode = 'base';
                state.currentInspirationIndex = null;
                state.currentGodInspirationIndex = null;
                render();
            } catch (error) {
                alert('加载失败:' + error.message);
            } finally {
                if (loading.parentNode) {
                    document.body.removeChild(loading);
                }
            }
        });
        inputSection.appendChild(createFormGroup('选择战斗员:', fighterSelect.wrapper));
       
        // 默认信息区
        if (state.currentFighter) {
            const defaultSection = createElement('div', 'default-info-section');
            const defaultTitle = createElement('div', 'section-title');
            defaultTitle.textContent = '默认信息';
            defaultTitle.style.borderColor = '#ff9800';
            defaultSection.appendChild(defaultTitle);
           
            const orderInput = createInput('text', state.defaultInfo.order, (value) => {
                state.defaultInfo.order = value;
                updateCodePreview();
            }, 'card.order');
            defaultSection.appendChild(createFormGroup('卡牌顺序:', orderInput));
           
            const egoInput = createInput('text', state.defaultInfo.ego, (value) => {
                state.defaultInfo.ego = value;
                updateCodePreview();
            }, 'card.info.ego');
            defaultSection.appendChild(createFormGroup('属性:', egoInput));
           
            inputSection.appendChild(defaultSection);
        }
       
        // 卡牌编辑区 - 根据editMode显示不同内容
        if (state.currentCard) {
            if (state.editMode === 'base') {
                // 显示基础信息编辑
                const cardSection = createElement('div', '');
                cardSection.style.marginTop = '20px';
               
                const cardTitle = createElement('div', 'section-title');
                cardTitle.textContent = '卡牌信息';
                cardSection.appendChild(cardTitle);
               
                // 卡牌名称
                const nameInput = createInput('text', state.currentCard.name, (value) => {
                     state.currentCard.name = value;
                     updateCodePreview();
                     // 更新列表显示
                     const cardItems = document.querySelectorAll('.card-item');
                     cardItems.forEach((item, idx) => {
                        if (state.cards[idx] === state.currentCard) {
                            const nameEl = item.querySelector('.card-item-name');
                            if (nameEl) nameEl.textContent = value || '未命名卡牌';
                        }
                     });
                }, '卡牌名称');
                cardSection.appendChild(createFormGroup('卡牌名称:', nameInput));
               
                // 显示名称
                const displaynameInput = createInput('text', state.currentCard.base.displayname, (value) => {
                    state.currentCard.base.displayname = value;
                     updateCodePreview();
                }, '显示名称');
                cardSection.appendChild(createFormGroup('显示名称:', displaynameInput));
               
                // 图片
                const artInput = createInput('text', state.currentCard.base.art, (value) => {
                     state.currentCard.base.art = value;
                     updateCodePreview();
                }, '图片文件名');
                cardSection.appendChild(createFormGroup('图片:', artInput));
               
                // 分组
                const groupInput = createInput('text', state.currentCard.base.group, (value) => {
                    state.currentCard.base.group = value;
                    updateCodePreview();
                }, '分组');
                 cardSection.appendChild(createFormGroup('分组:', groupInput));
               
                 // 稀有度
                const raritySelect = createSelect(
                     ['', '白', '蓝', '橙', '彩'],
                    state.currentCard.base.rarity || '',
                    (value) => {
                         state.currentCard.base.rarity = value;
                         updateCodePreview();
                     }
                     }
                   
                );
                    var cardData = this.getCardData();
                cardSection.appendChild(createFormGroup('稀有度:', raritySelect.wrapper));
                    var isVariant = this.currentVariantIndex > 0;
               
                   
                // 神明
                    if (isVariant) {
                const godSelect = createSelect(
                        var variant = cardData.variants[0];
                    ['', '凯尔肯', '戴奥斯', '尼希隆', '赛克瑞德', '维托'],
                        variant['卡组'] = '灵光一闪';
                    state.currentCard.base.god || '',
                       
                     (value) => {
                        // 保留主卡牌的某些属性
                         state.currentCard.base.god = value;
                        var mainVariant = this.currentCard.variants[0];
                         updateCodePreview();
                        if (!variant.art) variant.art = mainVariant.art;
                        if (!variant['属性']) variant['属性'] = mainVariant['属性'];
                        if (!variant['稀有度']) variant['稀有度'] = mainVariant['稀有度'];
                        if (!variant['衍生卡牌']) variant['衍生卡牌'] = mainVariant['衍生卡牌'];
                       
                        this.currentCard.variants[this.currentVariantIndex] = variant;
                     } else {
                         this.currentCard.name = cardData.name;
                         this.currentCard.variants[0] = cardData.variants[0];
                     }
                     }
                   
                );
                    this.updateCardList();
                cardSection.appendChild(createFormGroup('神明:', godSelect.wrapper));
                     this.updateVariantList();
               
                    this.updateCode();
                // AP
                    alert('数据保存成功!');
                const apInput = createInput('text', state.currentCard.base.ap, (value) => {
                 },
                     state.currentCard.base.ap = value;
 
                    updateCodePreview();
                 deleteCard: function() {
                }, 'AP (可以是数字、X、Ø等)');
                     if (!this.currentCard || !this.currentCharacter) {
                cardSection.appendChild(createFormGroup('AP:', apInput));
                         alert('请先选择要删除的卡牌!');
                  
                         return;
                // 类型
                 const typeSelect = createSelect(
                     ['', '攻击', '技能', '强化'],
                    state.currentCard.base.type || '',
                    (value) => {
                         state.currentCard.base.type = value;
                         updateCodePreview();
                     }
                     }
                   
                );
                    if (confirm('确定要删除卡牌 "' + this.currentCard.name + '" 吗?')) {
                cardSection.appendChild(createFormGroup('类型:', typeSelect.wrapper));
                        var cards = this.characters[this.currentCharacter];
               
                        var index = cards.indexOf(this.currentCard);
                // 机制
                        cards.splice(index, 1);
                const dictInput = createInput('text', state.currentCard.base.dict, (value) => {
                        this.currentCard = null;
                    state.currentCard.base.dict = value;
                        this.currentVariantIndex = null;
                    updateCodePreview();
                        this.updateCardList();
                }, '多个机制使用、隔开');
                        this.updateVariantList();
                cardSection.appendChild(createFormGroup('机制:', dictInput));
                        this.updateCode();
               
                        this.clearForm();
                // 描述
                        alert('卡牌删除成功!');
                const descSection = createElement('div', 'form-group');
                     }
                const descLabel = createElement('div', 'form-label');
                 },
                descLabel.textContent = '描述:';
 
                descSection.appendChild(descLabel);
                 deleteVariant: function() {
               
                     if (!this.currentCard || this.currentVariantIndex === null) {
                // 描述工具栏
                        alert('请先选择要删除的变体!');
                const toolbar = createElement('div', 'button-group');
                        return;
               
                     }
                const blueTextBtn = createButton('蓝色文本', 'btn btn-blue', () => {
                      
                    insertTextAtCursor(descInput, '{{文本|蓝|选择文字}}', true);
                     if (this.currentVariantIndex === 0) {
                });
                        alert('不能删除主卡牌变体!');
                toolbar.appendChild(blueTextBtn);
                         return;
               
                const greenTextBtn = createButton('绿色文本', 'btn btn-green', () => {
                    insertTextAtCursor(descInput, '{{文本|绿|选择文字}}', true);
                });
                toolbar.appendChild(greenTextBtn);
               
                const blueUnderlineBtn = createButton('蓝色下划线', 'btn btn-blue', () => {
                     insertTextAtCursor(descInput, '{{文本|蓝|下划线|选择文字}}', true);
                 });
                toolbar.appendChild(blueUnderlineBtn);
               
                 const greenUnderlineBtn = createButton('绿色下划线', 'btn btn-green', () => {
                     insertTextAtCursor(descInput, '{{文本|绿|下划线|选择文字}}', true);
                });
                toolbar.appendChild(greenUnderlineBtn);
               
                const strokeTextBtn = createButton('绿色描边', 'btn btn-green', () => {
                    insertTextAtCursor(descInput, '{{描边|绿|选择文字}}', true);
                });
                toolbar.appendChild(strokeTextBtn);
               
                const dictBtn = createButton('词典', 'btn', () => {
                    insertTextAtCursor(descInput, '{{词典|选择文字}}', true);
                });
                toolbar.appendChild(dictBtn);
               
                const wrapBtn = createButton('换行', 'btn', () => {
                     insertTextAtCursor(descInput, '<br>');
                });
                toolbar.appendChild(wrapBtn);
               
                descSection.appendChild(toolbar);
               
                const descInput = createInput('textarea', state.currentCard.base.desc_global, (value) => {
                     state.currentCard.base.desc_global = value;
                     updateCodePreview();
                }, '卡牌描述');
                descInput.style.minHeight = '150px';
                descSection.appendChild(descInput);
               
                cardSection.appendChild(descSection);
               
                // 衍生卡牌
                const subInput = createInput('textarea', state.currentCard.base.sub, (value) => {
                    state.currentCard.base.sub = value;
                    updateCodePreview();
                }, '衍生卡牌');
                subInput.style.minHeight = '35px';
                cardSection.appendChild(createFormGroup('衍生卡牌:', subInput));
               
                // 是否存在灵光一闪
                const inspirationCheckbox = createCheckbox(state.currentCard.base.isinspiration, (value) => {
                    state.currentCard.base.isinspiration = value;
                    if (!value) {
                         state.currentCard.var.inspiration = [];
                     }
                     }
                      
                     updateCodePreview();
                     if (confirm('确定要删除这个变体吗?')) {
                     renderWithoutScroll();
                        this.currentCard.variants.splice(this.currentVariantIndex, 1);
                });
                        this.currentVariantIndex = 0;
                cardSection.appendChild(createFormGroup('是否存在灵光一闪:', inspirationCheckbox));
                        this.updateVariantList();
               
                         this.updateCode();
                // 是否存在神光一闪
                        this.setCardData(this.currentCard, 0);
                const godInspirationCheckbox = createCheckbox(state.currentCard.base.isgod_inspiration, (value) => {
                         alert('变体删除成功!');
                    state.currentCard.base.isgod_inspiration = value;
                    if (!value) {
                         state.currentCard.var.god_inspiration = {
                            凯尔肯: [],
                            戴奥斯: [],
                            尼希隆: [],
                            赛克瑞德: [],
                            维托: []
                         };
                     }
                     }
                 },
                    updateCodePreview();
 
                    renderWithoutScroll();
                 onCardSelected: function(index) {
                 });
                     if (!this.currentCharacter) return;
                cardSection.appendChild(createFormGroup('是否存在神光一闪:', godInspirationCheckbox));
                     this.currentCard = this.characters[this.currentCharacter][index];
               
                    this.currentVariantIndex = 0;
                 inputSection.appendChild(cardSection);
                    this.updateVariantList();
               
                    this.setCardData(this.currentCard, 0);
                // 保存卡牌按钮
                 },
                const saveCardBtn = createButton('保存卡牌', 'btn-primary', () => {
 
                     updateCodePreview();
                 onVariantSelected: function(index) {
                     alert('卡牌已保存到代码预览!');
                    if (!this.currentCard) return;
                });
                    this.currentVariantIndex = index;
                saveCardBtn.style.marginTop = '20px';
                    this.setCardData(this.currentCard, index);
                saveCardBtn.style.width = '100%';
                },
                inputSection.appendChild(saveCardBtn);
 
               
                updateCardList: function() {
            } else {
                    var html = '';
                // 显示变体编辑
                    if (this.currentCharacter && this.characters[this.currentCharacter]) {
                renderVariantEditor(inputSection);
                        var cards = this.characters[this.currentCharacter];
            }
                        for (var i = 0; i < cards.length; i++) {
        }
                            var card = cards[i];
       
                            var selected = (card === this.currentCard) ? ' selected' : '';
        // 添加新卡牌按钮
                            html += '<div class="ce-list-item' + selected + '" data-index="' + i + '">' +
        if (state.currentFighter && state.editMode === 'base') {
                                    card.name + '</div>';
            const addCardBtn = createButton('+ 新增卡牌', 'btn-success', () => {
                const newCard = createEmptyCard();
                newCard.name = '新卡牌' + (state.cards.length + 1);
                state.cards.push(newCard);
                state.currentCard = newCard;
                state.editMode = 'base';
                 state.currentInspirationIndex = null;
                state.currentGodInspirationIndex = null;
                 renderWithoutScroll();
            });
            addCardBtn.style.marginTop = '20px';
            addCardBtn.style.width = '100%';
            inputSection.appendChild(addCardBtn);
        }
       
        manager.appendChild(inputSection);
       
        // 中间列表区
        const listSection = createElement('div', 'card-list-section');
       
        // 卡牌列表
        const cardListContainer = createElement('div', 'list-container');
        cardListContainer.style.minHeight = '250px';
        const cardListHeader = createElement('div', 'list-header');
        const cardListTitle = createElement('div', 'list-title');
        cardListTitle.textContent = '卡牌列表';
        cardListHeader.appendChild(cardListTitle);
        cardListContainer.appendChild(cardListHeader);
       
        if (state.cards.length === 0) {
            const emptyState = createElement('div', 'empty-state');
            const emptyIcon = createElement('div', 'empty-state-icon');
            emptyIcon.textContent = '📋';
            const emptyText = createElement('div', 'empty-state-text');
            emptyText.textContent = '暂无卡牌,点击"新增卡牌"开始创建';
            emptyState.appendChild(emptyIcon);
            emptyState.appendChild(emptyText);
            cardListContainer.appendChild(emptyState);
        } else {
            state.cards.forEach((card, index) => {
                const cardItem = createElement('div', 'card-item' + (state.currentCard === card && state.editMode === 'base' ? ' active' : ''));
               
                const cardName = createElement('div', 'card-item-name');
                cardName.textContent = card.name || '未命名卡牌';
               
                const cardInfo = createElement('div', 'card-item-info');
                const infoText = [];
                if (card.base.type) infoText.push(card.base.type);
                if (card.base.ap !== '') infoText.push('AP:' + card.base.ap);
                if (card.base.rarity) infoText.push(card.base.rarity);
                cardInfo.textContent = infoText.join(' | ') || '暂无信息';
               
                cardItem.appendChild(cardName);
                cardItem.appendChild(cardInfo);
               
                cardItem.addEventListener('click', () => {
                    state.currentCard = card;
                    state.editMode = 'base';
                    state.currentInspirationIndex = null;
                    state.currentGodInspirationIndex = null;
                    renderWithoutScroll();
                });
               
                // 删除按钮
                const deleteBtn = createButton('删除', 'btn-danger', (e) => {
                    e.stopPropagation();
                    if (confirm('确定要删除卡牌"' + card.name + '"吗?')) {
                        state.cards.splice(index, 1);
                        if (state.currentCard === card) {
                            state.currentCard = state.cards[0] || null;
                            state.editMode = 'base';
                            state.currentInspirationIndex = null;
                            state.currentGodInspirationIndex = null;
                         }
                         }
                        renderWithoutScroll();
                     }
                     }
                });
                deleteBtn.style.cssText = 'margin-top:8px;width:100%;';
                cardItem.appendChild(deleteBtn);
               
                cardListContainer.appendChild(cardItem);
            });
        }
       
        listSection.appendChild(cardListContainer);
       
        // 灵光一闪列表
        if (state.currentCard && state.currentCard.base.isinspiration) {
            const inspirationSection = createElement('div', 'inspiration-section');
            inspirationSection.style.minHeight = '250px';
            const inspirationHeader = createElement('div', 'list-header');
            const inspirationTitle = createElement('div', 'list-title');
            inspirationTitle.textContent = '灵光一闪列表';
            inspirationHeader.appendChild(inspirationTitle);
           
            const addInspirationBtn = createButton('+ 添加', 'btn-primary', () => {
                const newIndex = state.currentCard.var.inspiration.length;
                state.currentCard.var.inspiration.push(createEmptyVariant());
                state.editMode = 'inspiration';
                state.currentInspirationIndex = newIndex;
                state.currentGodInspirationIndex = null;
                render();
            });
            inspirationHeader.appendChild(addInspirationBtn);
            inspirationSection.appendChild(inspirationHeader);
           
            if (state.currentCard.var.inspiration.length === 0) {
                const emptyState = createElement('div', 'empty-state');
                emptyState.style.padding = '20px';
                const emptyText = createElement('div', 'empty-state-text');
                emptyText.textContent = '暂无灵光一闪,点击"添加"创建';
                emptyState.appendChild(emptyText);
                inspirationSection.appendChild(emptyState);
            } else {
                state.currentCard.var.inspiration.forEach((insp, idx) => {
                    const inspItem = createElement('div',
                        'inspiration-item-simple' +
                        (state.editMode === 'inspiration' && state.currentInspirationIndex === idx ? ' active' : '')
                    );
                      
                      
                     if (html === '') {
                     const inspName = createElement('div', 'inspiration-item-name');
                        html = '<div class="ce-loading">暂无卡牌数据</div>';
                     inspName.textContent = `灵光 #${idx + 1}`;
                     }
                      
                      
                     $('#ce-card-list').html(html);
                     const inspInfo = createElement('div', 'inspiration-item-info');
                },
                     const infoText = [];
 
                     if (insp.type) infoText.push(insp.type);
                updateVariantList: function() {
                    if (insp.ap !== '') infoText.push('AP:' + insp.ap);
                     var html = '';
                     inspInfo.textContent = infoText.join(' | ') || '点击编辑';
                     if (this.currentCard) {
                        for (var i = 0; i < this.currentCard.variants.length; i++) {
                            var variant = this.currentCard.variants[i];
                            var deck = variant['卡组'] || '未知';
                            var name = i === 0 ? '主卡牌 (' + deck + ')' : '变体 ' + i + ' (灵光一闪)';
                            var selected = (i === this.currentVariantIndex) ? ' selected' : '';
                            html += '<div class="ce-list-item' + selected + '" data-index="' + i + '">' +
                                    name + '</div>';
                        }
                     }
                    $('#ce-variant-list').html(html);
                },
 
                insertTextFormat: function(color) {
                    var textarea = document.getElementById('ce-desc');
                    var start = textarea.selectionStart;
                    var end = textarea.selectionEnd;
                    var text = textarea.value;
                    var selectedText = text.substring(start, end);
                      
                      
                     var newText = '{{文本|' + color + '|' + selectedText + '}}';
                     inspItem.appendChild(inspName);
                     textarea.value = text.substring(0, start) + newText + text.substring(end);
                     inspItem.appendChild(inspInfo);
                      
                      
                     // 设置光标位置
                     inspItem.addEventListener('click', () => {
                    var cursorPos = start + newText.length;
                        state.editMode = 'inspiration';
                    textarea.setSelectionRange(cursorPos, cursorPos);
                        state.currentInspirationIndex = idx;
                    textarea.focus();
                        state.currentGodInspirationIndex = null;
                },
                        renderWithoutScroll();
 
                     });
                insertStrokeFormat: function() {
                    var textarea = document.getElementById('ce-desc');
                    var start = textarea.selectionStart;
                    var end = textarea.selectionEnd;
                    var text = textarea.value;
                     var selectedText = text.substring(start, end);
                      
                      
                     var newText = '{{描边|绿|' + selectedText + '}}';
                     inspirationSection.appendChild(inspItem);
                    textarea.value = text.substring(0, start) + newText + text.substring(end);
                });
            }
           
            listSection.appendChild(inspirationSection);
        }
       
        // 神光一闪列表
        if (state.currentCard && state.currentCard.base.isgod_inspiration) {
            const godInspirationSection = createElement('div', 'inspiration-section');
            godInspirationSection.style.minHeight = '250px';
            const godInspirationHeader = createElement('div', 'list-header');
            const godInspirationTitle = createElement('div', 'list-title');
            godInspirationTitle.textContent = '神光一闪列表';
            godInspirationHeader.appendChild(godInspirationTitle);
            godInspirationSection.appendChild(godInspirationHeader);
           
            // 神明选择标签
            const godSelectGroup = createElement('div', 'god-select-group');
            ['凯尔肯', '戴奥斯', '尼希隆', '赛克瑞德', '维托'].forEach(god => {
                const godTab = createElement('div', 'god-tab' + (state.currentGod === god ? ' active' : ''));
                godTab.textContent = god;
                godTab.addEventListener('click', () => {
                    state.currentGod = god;
                    renderWithoutScroll();
                });
                godSelectGroup.appendChild(godTab);
            });
            godInspirationSection.appendChild(godSelectGroup);
           
            // 当前神明的神光一闪列表
            const currentGodInspirations = state.currentCard.var.god_inspiration[state.currentGod];
           
            const addGodInspirationBtn = createButton('+ 添加 ' + state.currentGod + ' 神光', 'btn-primary', () => {
                const newIndex = currentGodInspirations.length;
                currentGodInspirations.push(createEmptyVariant());
                state.editMode = 'god_inspiration';
                state.currentGodInspirationIndex = newIndex;
                state.currentInspirationIndex = null;
                render();
            });
            addGodInspirationBtn.style.marginBottom = '10px';
            addGodInspirationBtn.style.width = '100%';
            godInspirationSection.appendChild(addGodInspirationBtn);
           
            if (currentGodInspirations.length === 0) {
                const emptyState = createElement('div', 'empty-state');
                emptyState.style.padding = '20px';
                const emptyText = createElement('div', 'empty-state-text');
                emptyText.textContent = `暂无 ${state.currentGod} 神光一闪`;
                emptyState.appendChild(emptyText);
                godInspirationSection.appendChild(emptyState);
            } else {
                currentGodInspirations.forEach((insp, idx) => {
                    const inspItem = createElement('div',
                        'inspiration-item-simple' +
                        (state.editMode === 'god_inspiration' &&
                        state.currentGodInspirationIndex === idx ? ' active' : '')
                    );
                      
                      
                     var cursorPos = start + newText.length;
                     const inspName = createElement('div', 'inspiration-item-name');
                    textarea.setSelectionRange(cursorPos, cursorPos);
                     inspName.textContent = `${state.currentGod} 神光 #${idx + 1}`;
                    textarea.focus();
                },
 
                insertBr: function() {
                    var textarea = document.getElementById('ce-desc');
                     var start = textarea.selectionStart;
                    var text = textarea.value;
                      
                      
                     textarea.value = text.substring(0, start) + '<br>' + text.substring(start);
                     const inspInfo = createElement('div', 'inspiration-item-info');
                    const infoText = [];
                    if (insp.type) infoText.push(insp.type);
                    if (insp.ap !== '') infoText.push('AP:' + insp.ap);
                    inspInfo.textContent = infoText.join(' | ') || '点击编辑';
                      
                      
                     var cursorPos = start + 4;
                     inspItem.appendChild(inspName);
                    textarea.setSelectionRange(cursorPos, cursorPos);
                     inspItem.appendChild(inspInfo);
                     textarea.focus();
                },
 
                escapeLuaString: function(s) {
                    if (typeof s !== 'string') return s;
                    return s.replace(/\\/g, '\\\\')
                          .replace(/"/g, '\\"')
                          .replace(/\n/g, '\\n');
                },
 
                generateLuaCode: function() {
                    if (!this.currentCharacter || !this.characters[this.currentCharacter]) {
                        return '-- 请先选择一个战斗员';
                    }
                      
                      
                     var cards = this.characters[this.currentCharacter];
                     inspItem.addEventListener('click', () => {
                    if (cards.length === 0) {
                        state.editMode = 'god_inspiration';
                         return '-- ' + this.currentCharacter + ' 暂无卡牌数据';
                        state.currentGodInspirationIndex = idx;
                     }
                        state.currentInspirationIndex = null;
                         renderWithoutScroll();
                     });
                      
                      
                     var lua = 'local p = {}\n\n';
                     godInspirationSection.appendChild(inspItem);
                   
                });
                    // 生成 cardOrder
            }
                    lua += 'local cardOrder = {\n';
           
                    for (var i = 0; i < cards.length; i++) {
            listSection.appendChild(godInspirationSection);
                        var card = cards[i];
        }
                        if (card.variants.length > 0 && card.variants[0]['卡组'] !== '衍生卡牌') {
       
                            lua += '    "' + this.escapeLuaString(card.name) + '",\n';
        manager.appendChild(listSection);
                        }
       
                    }
        // 右侧预览区
                    lua += '}\n\n';
        const previewSection = createElement('div', 'card-preview-section');
                   
        const previewTitle = createElement('div', 'section-title');
                    // 生成 card 数据
        previewTitle.textContent = 'Lua 代码预览';
                    lua += 'local card = {\n';
        previewSection.appendChild(previewTitle);
                    for (var i = 0; i < cards.length; i++) {
       
                        var card = cards[i];
        // 复制按钮
                        lua += '   ["' + this.escapeLuaString(card.name) + '"] = {\n';
        const copyBtn = createButton('复制代码', 'btn-primary', () => {
                       
            const code = generateLuaCode();
                        for (var j = 0; j < card.variants.length; j++) {
            navigator.clipboard.writeText(code).then(() => {
                            var variant = card.variants[j];
                alert('代码已复制到剪贴板!');
                            lua += '        {\n';
            }).catch(err => {
                           
                console.error('复制失败:', err);
                            var fieldOrder = ['art', '卡组', '属性', '稀有度', 'AP', '机制', '类型', '描述', '衍生卡牌'];
                const textarea = document.createElement('textarea');
                            for (var k = 0; k < fieldOrder.length; k++) {
                textarea.value = code;
                                var field = fieldOrder[k];
                textarea.style.position = 'fixed';
                                if (variant[field] !== undefined && variant[field] !== null) {
                textarea.style.opacity = '0';
                                    var value = variant[field];
                 document.body.appendChild(textarea);
                                    if (typeof value === 'string' && value.trim() !== '') {
                textarea.select();
                                        lua += '           ["' + field + '"] = "' +
                 document.execCommand('copy');
                                              this.escapeLuaString(value) + '",\n';
                document.body.removeChild(textarea);
                                    } else if (typeof value === 'number' || value === 'X') {
                alert('代码已复制到剪贴板!');
                                        if (value === 'X') {
            });
                                            lua += '           ["' + field + '"] = "X",\n';
        });
                                        } else {
        copyBtn.style.marginBottom = '10px';
                                            lua += '            ["' + field + '"] = ' + value + ',\n';
        copyBtn.style.width = '100%';
                                        }
        previewSection.appendChild(copyBtn);
                                    }
       
                                }
        // 保存按钮
                            }
        const saveBtn = createButton('保存到Wiki', 'btn-success', async () => {
                           
            if (!state.currentFighter) {
                            lua += '        },\n';
                alert('请先选择战斗员!');
                        }
                return;
                       
            }
                        lua += '    },\n';
           
                    }
            const code = generateLuaCode();
                    lua += '}\n\n';
            const pageName = '模块:卡牌/' + state.currentFighter;
                   
           
                    lua += 'p.card = card\n';
            const loading = createElement('div', 'loading-indicator');
                    lua += 'p.cardOrder = cardOrder\n\n';
            loading.textContent = '正在保存...';
                    lua += 'return p\n';
            document.body.appendChild(loading);
                   
           
                    return lua;
            try {
                 },
                const api = new mw.Api();
 
                await api.postWithToken('csrf', {
                updateCode: function() {
                    action: 'edit',
                    var code = this.generateLuaCode();
                    title: pageName,
                    $('#ce-code-display').val(code);
                    text: code,
                 },
                    summary: '通过卡牌管理器更新卡牌数据',
 
                    contentmodel: 'Scribunto'
                copyCode: function() {
                });
                    var codeDisplay = document.getElementById('ce-code-display');
                alert('保存成功!');
                    codeDisplay.select();
            } catch (error) {
                    document.execCommand('copy');
                console.error('保存失败:', error);
                    alert('代码已复制到剪贴板!');
                alert('保存失败:' + error);
                },
            } finally {
 
                if (loading.parentNode) {
                parseCardData: function(luaContent) {
                     document.body.removeChild(loading);
                    var cards = [];
                    try {
                        // 提取 card 表
                        var cardMatch = luaContent.match(/local\s+card\s*=\s*\{([\s\S]*?)\n\}/);
                        if (!cardMatch) return cards;
                       
                        var cardData = cardMatch[1];
                       
                        // 提取每个卡牌
                        var cardRegex = /\["(.+?)"\]\s*=\s*\{([\s\S]*?)\n    \},/g;
                        var match;
                       
                        while ((match = cardRegex.exec(cardData)) !== null) {
                            var cardName = match[1].replace(/\\"/g, '"').replace(/\\\\/g, '\\');
                            var variantsData = match[2];
                           
                            var card = {
                                name: cardName,
                                variants: []
                            };
                           
                            // 提取变体
                            var variantRegex = /\{([\s\S]*?)\},/g;
                            var variantMatch;
                           
                            while ((variantMatch = variantRegex.exec(variantsData)) !== null) {
                                var variant = {};
                                var fields = variantMatch[1];
                               
                                // 提取字段
                                var fieldRegex = /\["(.+?)"\]\s*=\s*(.+?),/g;
                                var fieldMatch;
                               
                                while ((fieldMatch = fieldRegex.exec(fields)) !== null) {
                                    var key = fieldMatch[1];
                                    var value = fieldMatch[2].trim();
                                   
                                    // 处理字符串值
                                    if (value.startsWith('"') && value.endsWith('"')) {
                                        value = value.slice(1, -1)
                                                  .replace(/\\"/g, '"')
                                                  .replace(/\\\\/g, '\\')
                                                  .replace(/\\n/g, '\n');
                                    } else if (!isNaN(value)) {
                                        value = parseInt(value, 10);
                                    }
                                   
                                    variant[key] = value;
                                }
                               
                                card.variants.push(variant);
                            }
                           
                            if (card.variants.length > 0) {
                                cards.push(card);
                            }
                        }
                    } catch (e) {
                        console.error('解析卡牌数据失败:', e);
                    }
                   
                    return cards;
                },
 
                saveToWiki: function() {
                    if (!this.currentCharacter) {
                        alert('请先选择一个战斗员!');
                        return;
                    }
                   
                    var cards = this.characters[this.currentCharacter];
                    if (cards.length === 0) {
                        alert('当前战斗员没有卡牌数据!');
                        return;
                    }
                   
                    var pageName = '模块:卡牌/' + this.currentCharacter;
                    var luaCode = this.generateLuaCode();
                   
                    if (!confirm('确定要保存到 ' + pageName + ' 吗?\n这将覆盖现有内容!')) {
                        return;
                    }
                   
                    var self = this;
                    this.api.postWithToken('csrf', {
                        action: 'edit',
                        title: pageName,
                        text: luaCode,
                        summary: '通过卡牌编辑器更新 ' + this.currentCharacter + ' 的卡牌数据',
                        recreate: true
                    }).done(function() {
                        alert('保存成功!\n页面:' + pageName);
                        // 更新下拉列表中的卡牌数量
                        self.updateCharacterDropdown();
                    }).fail(function(code, error) {
                        alert('保存失败:' + (error.error ? error.error.info : code));
                     });
                 }
                 }
             };
             }
 
            // 初始化编辑器
            CardEditor.init();
         });
         });
     });
        saveBtn.style.marginBottom = '10px';
        saveBtn.style.width = '100%';
        previewSection.appendChild(saveBtn);
       
        // 代码显示
        const codePreview = createElement('div', 'code-preview');
        codePreview.textContent = generateLuaCode();
        previewSection.appendChild(codePreview);
       
        manager.appendChild(previewSection);
       
        container.appendChild(manager);
    }
   
    // 初始化
    async function init() {
        let container = document.getElementById('card-manager-container');
        if (!container) {
            container = createElement('div', '');
            container.id = 'card-manager-container';
           
            const content = document.getElementById('mw-content-text');
            if (content) {
                content.insertBefore(container, content.firstChild);
            } else {
                document.body.appendChild(container);
            }
        }
       
        const loading = createElement('div', 'loading-indicator');
        loading.textContent = '正在初始化...';
        document.body.appendChild(loading);
       
        try {
            await loadFighters();
           
            if (state.fighters.length > 0) {
                state.currentFighter = state.fighters[0];
                state.cards = await loadFighterCards(state.currentFighter);
                if (state.cards.length > 0) {
                    state.currentCard = state.cards[0];
                }
            }
           
            render();
        } catch (error) {
            console.error('初始化失败:', error);
            alert('初始化失败:' + error.message);
        } finally {
            if (loading.parentNode) {
                document.body.removeChild(loading);
            }
        }
    }
   
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
     } else {
        init();
    }
   
    window.CardManager = {
        init: init,
        render: render,
        state: state,
        createCard: createEmptyCard,
        generateCode: generateLuaCode
    };
   
})();
})();

2025年10月29日 (三) 09:52的最新版本

(function() {
    'use strict';
    
    // 加载CSS
    mw.loader.load('/index.php?title=Mediawiki:Card.css&action=raw&ctype=text/css', 'text/css');
    
    // 状态管理
    const state = {
        currentFighter: '',
        fighters: [],
        cards: [],
        currentCard: null,
        defaultInfo: {
            order: '',
            ego: ''
        },
        editMode: 'base', // 'base', 'inspiration', 'god_inspiration'
        currentGod: '凯尔肯',
        currentInspirationIndex: null,
        currentGodInspirationIndex: null
    };
    
    // 卡牌数据结构
    function createEmptyCard() {
        return {
            name: '',
            base: {
                displayname: '',
                art: '',
                group: '',
                rarity: '',
                god: '',
                ap: '',
                type: '',
                dict: '',
                desc_global: '',
                sub: '',
                isinspiration: 0,
                isgod_inspiration: 0
            },
            var: {
                inspiration: [],
                god_inspiration: {
                    凯尔肯: [],
                    戴奥斯: [],
                    尼希隆: [],
                    赛克瑞德: [],
                    维托: []
                }
            }
        };
    }
    
    // 创建空变体结构
    function createEmptyVariant() {
        return {
            ap: '',
            type: '',
            desc_global: '',
            dict: '',
            sub: '' // 新增:变体卡牌的衍生卡牌字段
        };
    }
    
    // 创建元素辅助函数
    function createElement(tag, className, attributes = {}) {
        const el = document.createElement(tag);
        if (className) el.className = className;
        Object.entries(attributes).forEach(([key, value]) => {
            if (key === 'textContent') {
                el.textContent = value;
            } else if (key.startsWith('on')) {
                el.addEventListener(key.substring(2).toLowerCase(), value);
            } else {
                el.setAttribute(key, value);
            }
        });
        return el;
    }
    
    // 创建自定义下拉选择器
    function createSelect(options, selectedValue, onChange) {
        const select = createElement('div', 'form-select');
        select.textContent = selectedValue || options[0] || '请选择';
        select.setAttribute('tabindex', '0');
        
        const dropdown = createElement('div', 'dropdown-menu');
        
        options.forEach(option => {
            const item = createElement('div', 'dropdown-item');
            item.textContent = option;
            item.addEventListener('click', () => {
                select.textContent = option;
                dropdown.style.display = 'none';
                if (onChange) onChange(option);
            });
            dropdown.appendChild(item);
        });
        
        select.addEventListener('click', (e) => {
            e.stopPropagation();
            dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';
            const rect = select.getBoundingClientRect();
            dropdown.style.top = rect.bottom + 'px';
            dropdown.style.left = rect.left + 'px';
            dropdown.style.width = rect.width + 'px';
        });
        
        document.addEventListener('click', () => {
            dropdown.style.display = 'none';
        });
        
        const wrapper = createElement('div');
        wrapper.style.position = 'relative';
        wrapper.appendChild(select);
        document.body.appendChild(dropdown);
        
        return { wrapper, select, dropdown };
    }
    
    // 创建自定义输入框
    function createInput(type, value, onChange, placeholder = '') {
        const input = createElement('div', 'form-input');
        input.setAttribute('contenteditable', 'true');
        input.textContent = value || '';
        input.setAttribute('data-placeholder', placeholder);
        input.style.minHeight = type === 'textarea' ? '100px' : 'auto';
        
        if (!value) {
            input.style.color = '#999';
            input.textContent = placeholder;
        }
        
        input.addEventListener('focus', () => {
            if (input.textContent === placeholder) {
                input.textContent = '';
                input.style.color = '#333';
            }
        });
        
        input.addEventListener('blur', () => {
            if (!input.textContent.trim()) {
                input.textContent = placeholder;
                input.style.color = '#999';
            }
            if (onChange) onChange(input.textContent === placeholder ? '' : input.textContent);
        });
        
        input.addEventListener('input', () => {
            if (onChange && input.textContent !== placeholder) {
                onChange(input.textContent);
            }
        });
        
        return input;
    }
    
    // 创建复选框
    function createCheckbox(checked, onChange) {
        const wrapper = createElement('div', 'checkbox-wrapper');
        const checkbox = createElement('div', checked ? 'checkbox checked' : 'checkbox');
        const label = createElement('div', '');
        label.textContent = '是';
        
        wrapper.addEventListener('click', () => {
            const newChecked = !checkbox.classList.contains('checked');
            if (newChecked) {
                checkbox.classList.add('checked');
            } else {
                checkbox.classList.remove('checked');
            }
            if (onChange) onChange(newChecked ? 1 : 0);
        });
        
        wrapper.appendChild(checkbox);
        wrapper.appendChild(label);
        return wrapper;
    }
    
    // 创建表单组
    function createFormGroup(label, control) {
        const group = createElement('div', 'form-group');
        const labelEl = createElement('div', 'form-label');
        labelEl.textContent = label;
        group.appendChild(labelEl);
        group.appendChild(control);
        return group;
    }
    
    // 创建按钮
    function createButton(text, className, onClick) {
        const btn = createElement('div', 'btn ' + className);
        btn.textContent = text;
        btn.addEventListener('click', onClick);
        return btn;
    }
    
    // 文本插入辅助函数
    function insertTextAtCursor(element, text, wrap = false) {
        element.focus();
        const selection = window.getSelection();
        
        if (wrap && selection.rangeCount > 0) {
            const range = selection.getRangeAt(0);
            const selectedText = range.toString();
            
            if (selectedText) {
                range.deleteContents();
                const textNode = document.createTextNode(text.replace('选择文字', selectedText));
                range.insertNode(textNode);
                return;
            }
        }
        
        document.execCommand('insertText', false, text);
    }
    
    // 辅助函数:提取字符串值
    function extractStringValue(text, key) {
        const pattern = new RegExp(key + '\\s*=\\s*"([^"]*)"', 'm');
        const match = text.match(pattern);
        return match ? match[1] : '';
    }
    
    // 辅助函数:提取数值
    function extractNumberValue(text, key) {
        const pattern = new RegExp(key + '\\s*=\\s*(\\d+)', 'm');
        const match = text.match(pattern);
        return match ? parseInt(match[1]) : 0;
    }
    
    // 辅助函数:提取任意值(包括X、Ø等)
    function extractValue(text, key) {
        const pattern = new RegExp(key + '\\s*=\\s*([^,\\n]+)', 'm');
        const match = text.match(pattern);
        if (match) {
            let value = match[1].trim();
            value = value.replace(/^["']|["']$/g, '');
            return value;
        }
        return '';
    }
    
    // 解析灵光一闪/神光一闪列表
    function parseInspirationList(content) {
        const inspirations = [];
        
        let depth = 0;
        let currentBlock = '';
        let inString = false;
        
        for (let i = 0; i < content.length; i++) {
            const char = content[i];
            const prevChar = i > 0 ? content[i - 1] : '';
            
            if (char === '"' && prevChar !== '\\') {
                inString = !inString;
            }
            
            if (!inString) {
                if (char === '{') {
                    if (depth > 0) {
                        currentBlock += char;
                    }
                    depth++;
                } else if (char === '}') {
                    depth--;
                    if (depth === 0 && currentBlock) {
                        const inspiration = {};
                        
                        const ap = extractValue(currentBlock, 'ap');
                        if (ap) inspiration.ap = ap;
                        
                        const type = extractStringValue(currentBlock, 'type');
                        if (type) inspiration.type = type;
                        
                        const desc = extractStringValue(currentBlock, 'desc_global');
                        if (desc) inspiration.desc_global = desc;
                        
                        const dict = extractStringValue(currentBlock, 'dict');
                        if (dict) inspiration.dict = dict;
                        
                        // 新增:解析变体的 sub 字段
                        const sub = extractStringValue(currentBlock, 'sub');
                        if (sub) inspiration.sub = sub;
                        
                        if (Object.keys(inspiration).length > 0) {
                            inspirations.push(inspiration);
                        }
                        
                        currentBlock = '';
                    } else if (depth > 0) {
                        currentBlock += char;
                    }
                } else if (depth > 0) {
                    currentBlock += char;
                }
            } else if (depth > 0) {
                currentBlock += char;
            }
        }
        
        return inspirations;
    }
    
    // 辅助函数:使用括号计数提取块内容
    function extractBlock(content, startPattern) {
        const match = content.match(startPattern);
        if (!match) return null;
        
        let startIdx = match.index + match[0].length;
        let depth = 1;
        let endIdx = startIdx;
        let inString = false;
        
        for (let i = startIdx; i < content.length && depth > 0; i++) {
            const char = content[i];
            const prevChar = i > 0 ? content[i - 1] : '';
            
            if (char === '"' && prevChar !== '\\') {
                inString = !inString;
            }
            
            if (!inString) {
                if (char === '{') {
                    depth++;
                } else if (char === '}') {
                    depth--;
                    if (depth === 0) {
                        endIdx = i;
                        break;
                    }
                }
            }
        }
        
        return content.substring(startIdx, endIdx);
    }
    
    // 解析Lua代码
    function parseLuaCode(luaText) {
        const cards = [];
        const defaultInfo = {
            order: '',
            ego: ''
        };
        
        try {
            const orderMatch = luaText.match(/card\.order\s*=\s*\{\s*"([^"]+)"\s*\}/);
            if (orderMatch) {
                defaultInfo.order = orderMatch[1];
            }
            
            const egoMatch = luaText.match(/card\.info\s*=\s*\{[^}]*ego\s*=\s*"([^"]+)"/);
            if (egoMatch) {
                defaultInfo.ego = egoMatch[1];
            }
            
            const cardPattern = /card\["([^"]+)"\]\s*=\s*\{/g;
            let cardMatch;
            
            while ((cardMatch = cardPattern.exec(luaText)) !== null) {
                const cardName = cardMatch[1];
                const cardStartIdx = cardMatch.index + cardMatch[0].length;
                
                let depth = 1;
                let cardEndIdx = cardStartIdx;
                let inString = false;
                
                for (let i = cardStartIdx; i < luaText.length && depth > 0; i++) {
                    const char = luaText[i];
                    const prevChar = i > 0 ? luaText[i - 1] : '';
                    
                    if (char === '"' && prevChar !== '\\') {
                        inString = !inString;
                    }
                    
                    if (!inString) {
                        if (char === '{') {
                            depth++;
                        } else if (char === '}') {
                            depth--;
                            if (depth === 0) {
                                cardEndIdx = i;
                                break;
                            }
                        }
                    }
                }
                
                const cardContent = luaText.substring(cardStartIdx, cardEndIdx);
                
                const card = createEmptyCard();
                card.name = cardName;
                
                const baseContent = extractBlock(cardContent, /base\s*=\s*\{/);
                if (baseContent) {
                    card.base.displayname = extractStringValue(baseContent, 'displayname') || '';
                    card.base.art = extractStringValue(baseContent, 'art') || '';
                    card.base.group = extractStringValue(baseContent, 'group') || '';
                    card.base.rarity = extractStringValue(baseContent, 'rarity') || '';
                    card.base.god = extractStringValue(baseContent, 'god') || '';
                    card.base.ap = extractValue(baseContent, 'ap') || '';
                    card.base.type = extractStringValue(baseContent, 'type') || '';
                    card.base.dict = extractStringValue(baseContent, 'dict') || '';
                    card.base.desc_global = extractStringValue(baseContent, 'desc_global') || '';
                    card.base.sub = extractStringValue(baseContent, 'sub') || '';
                    card.base.isinspiration = extractNumberValue(baseContent, 'isinspiration') || 0;
                    card.base.isgod_inspiration = extractNumberValue(baseContent, 'isgod_inspiration') || 0;
                }
                
                const varContent = extractBlock(cardContent, /var\s*=\s*\{/);
                if (varContent) {
                    const inspirationContent = extractBlock(varContent, /inspiration\s*=\s*\{/);
                    if (inspirationContent) {
                        card.var.inspiration = parseInspirationList(inspirationContent);
                    }
                    
                    const godInspirationContent = extractBlock(varContent, /god_inspiration\s*=\s*\{/);
                    if (godInspirationContent) {
                        // 修改:使用中文键名解析神光一闪
                        ['凯尔肯', '戴奥斯', '尼希隆', '赛克瑞德', '维托'].forEach(god => {
                            const godPattern = new RegExp('\\["?' + god + '"?\\]\\s*=\\s*\\{');
                            const godContent = extractBlock(godInspirationContent, godPattern);
                            if (godContent) {
                                card.var.god_inspiration[god] = parseInspirationList(godContent);
                            }
                        });
                    }
                }
                
                cards.push(card);
            }
            
        } catch (error) {
            console.error('解析Lua代码失败:', error);
        }
        
        return { cards, defaultInfo };
    }
    
    // Lua字符串转义
    function escapeLuaString(str) {
        if (!str) return '';
        return str.replace(/\\/g, '\\\\')
                  .replace(/"/g, '\\"')
                  .replace(/\n/g, '\\n')
                  .replace(/\r/g, '\\r')
                  .replace(/\t/g, '\\t');
    }
    
    // 生成Lua代码
    function generateLuaCode() {
        let code = 'local card = {}\n\n';
        
        if (state.defaultInfo.order) {
            code += `card.order = { "${escapeLuaString(state.defaultInfo.order)}" }\n\n`;
        }
        
        if (state.defaultInfo.ego) {
            code += 'card.info = {\n';
            code += `    ego = "${escapeLuaString(state.defaultInfo.ego)}",\n`;
            code += '}\n\n';
        }
        
        state.cards.forEach(card => {
            code += `card["${escapeLuaString(card.name)}"] = {\n`;
            code += '    base = {\n';
            
            const base = card.base;
            if (base.displayname) code += `        displayname = "${escapeLuaString(base.displayname)}",\n`;
            if (base.art) code += `        art = "${escapeLuaString(base.art)}",\n`;
            if (base.group) code += `        group = "${escapeLuaString(base.group)}",\n`;
            if (base.rarity) code += `        rarity = "${escapeLuaString(base.rarity)}",\n`;
            if (base.god) code += `        god = "${escapeLuaString(base.god)}",\n`;
            if (base.ap !== '') {
                if (isNaN(base.ap)) {
                    code += `        ap = "${escapeLuaString(base.ap)}",\n`;
                } else {
                    code += `        ap = ${base.ap},\n`;
                }
            }
            if (base.type) code += `        type = "${escapeLuaString(base.type)}",\n`;
            if (base.dict) code += `        dict = "${escapeLuaString(base.dict)}",\n`;
            if (base.desc_global) code += `        desc_global = "${escapeLuaString(base.desc_global)}",\n`;
            if (base.sub) code += `        sub = "${escapeLuaString(base.sub)}",\n`;
            if (base.isinspiration) code += `        isinspiration = ${base.isinspiration},\n`;
            if (base.isgod_inspiration) code += `        isgod_inspiration = ${base.isgod_inspiration},\n`;
            
            code += '    },\n';
            
            const hasInspiration = card.var.inspiration.length > 0;
            const hasGodInspiration = Object.values(card.var.god_inspiration).some(arr => arr.length > 0);
            
            if (hasInspiration || hasGodInspiration) {
                code += '    var = {\n';
                
                if (hasInspiration) {
                    code += '        inspiration = {\n';
                    card.var.inspiration.forEach(insp => {
                        code += '            {\n';
                        if (insp.ap !== '' && insp.ap !== undefined) {
                            if (isNaN(insp.ap)) {
                                code += `                ap = "${escapeLuaString(insp.ap)}",\n`;
                            } else {
                                code += `                ap = ${insp.ap},\n`;
                            }
                        }
                        if (insp.type) code += `                type = "${escapeLuaString(insp.type)}",\n`;
                        if (insp.desc_global) code += `                desc_global = "${escapeLuaString(insp.desc_global)}",\n`;
                        if (insp.dict) code += `                dict = "${escapeLuaString(insp.dict)}",\n`;
                        // 新增:输出变体的 sub 字段
                        if (insp.sub) code += `                sub = "${escapeLuaString(insp.sub)}",\n`;
                        code += '            },\n';
                    });
                    code += '        },\n';
                }
                
                if (hasGodInspiration) {
                    code += '        god_inspiration = {\n';
                    Object.entries(card.var.god_inspiration).forEach(([god, inspList]) => {
                        if (inspList.length > 0) {
                            // 修改:使用中文键名格式 ["尼希隆"]
                            code += `            ["${god}"] = {\n`;
                            inspList.forEach(insp => {
                                code += '                {\n';
                                if (insp.ap !== '' && insp.ap !== undefined) {
                                    if (isNaN(insp.ap)) {
                                        code += `                    ap = "${escapeLuaString(insp.ap)}",\n`;
                                    } else {
                                        code += `                    ap = ${insp.ap},\n`;
                                    }
                                }
                                if (insp.type) code += `                    type = "${escapeLuaString(insp.type)}",\n`;
                                if (insp.desc_global) code += `                    desc_global = "${escapeLuaString(insp.desc_global)}",\n`;
                                if (insp.dict) code += `                    dict = "${escapeLuaString(insp.dict)}",\n`;
                                // 新增:输出变体的 sub 字段
                                if (insp.sub) code += `                    sub = "${escapeLuaString(insp.sub)}",\n`;
                                code += '                },\n';
                            });
                            code += '            },\n';
                        }
                    });
                    code += '        },\n';
                }
                
                code += '    },\n';
            }
            
            code += '}\n\n';
        });
        
        code += 'return card';
        
        return code;
    }
    
    // 加载战斗员列表
    async function loadFighters() {
        try {
            const api = new mw.Api();
            const result = await api.get({
                action: 'query',
                list: 'allpages',
                apprefix: '卡牌/',
                apnamespace: 828,
                aplimit: 500
            });
            
            if (result.query && result.query.allpages) {
                state.fighters = result.query.allpages.map(page => {
                    return page.title.replace('模块:卡牌/', '');
                });
            }
        } catch (error) {
            console.error('加载战斗员列表失败:', error);
        }
    }
    
    // 加载战斗员卡牌数据
    async function loadFighterCards(fighter) {
        if (!fighter) return [];
        
        try {
            const api = new mw.Api();
            
            const result = await api.get({
                action: 'query',
                prop: 'revisions',
                titles: '模块:卡牌/' + fighter,
                rvprop: 'content',
                rvslots: 'main',
                formatversion: 2
            });
            
            if (!result.query || !result.query.pages || result.query.pages.length === 0) {
                console.error('未找到页面');
                return [];
            }
            
            const page = result.query.pages[0];
            
            if (page.missing) {
                console.error('页面不存在');
                return [];
            }
            
            const content = page.revisions[0].slots.main.content;
            
            const parsed = parseLuaCode(content);
            
            state.defaultInfo = parsed.defaultInfo;
            
            return parsed.cards;
            
        } catch (error) {
            console.error('加载卡牌数据失败:', error);
            return [];
        }
    }
    
    // 更新代码预览(不触发滚动)
    function updateCodePreview() {
        const codePreview = document.querySelector('.code-preview');
        if (codePreview) {
            codePreview.textContent = generateLuaCode();
        }
    }
    
    // 渲染变体卡牌编辑表单
    function renderVariantEditor(container) {
        if (!state.currentCard) return;
        
        if (state.editMode === 'inspiration' && state.currentInspirationIndex !== null) {
            const insp = state.currentCard.var.inspiration[state.currentInspirationIndex];
            if (!insp) return;
            
            const variantSection = createElement('div', 'variant-edit-section');
            const variantTitle = createElement('div', 'section-title');
            variantTitle.textContent = `灵光一闪 #${state.currentInspirationIndex + 1}`;
            variantTitle.style.borderColor = '#9c27b0';
            variantSection.appendChild(variantTitle);
            
            // 返回按钮
            const backBtn = createButton('← 返回基础信息', 'btn', () => {
                state.editMode = 'base';
                state.currentInspirationIndex = null;
                renderWithoutScroll();
            });
            backBtn.style.marginBottom = '15px';
            backBtn.style.width = '100%';
            variantSection.appendChild(backBtn);
            
            // AP输入
            const apInput = createInput('text', insp.ap, (value) => {
                insp.ap = value;
                updateCodePreview();
            }, 'AP (数字、X、Ø)');
            variantSection.appendChild(createFormGroup('AP:', apInput));
            
            // 类型选择
            const typeSelect = createSelect(
                ['', '攻击', '技能', '强化'],
                insp.type || '',
                (value) => {
                    insp.type = value;
                    updateCodePreview();
                }
            );
            variantSection.appendChild(createFormGroup('类型:', typeSelect.wrapper));
            
            // 机制输入
            const dictInput = createInput('text', insp.dict, (value) => {
                insp.dict = value;
                updateCodePreview();
            }, '多个机制使用、隔开');
            variantSection.appendChild(createFormGroup('机制:', dictInput));
            
            // 描述区域
            const descSection = createElement('div', 'form-group');
            const descLabel = createElement('div', 'form-label');
            descLabel.textContent = '描述:';
            descSection.appendChild(descLabel);
            
            // 描述工具栏
            const toolbar = createElement('div', 'button-group');
            
            const blueTextBtn = createButton('蓝色文本', 'btn btn-blue', () => {
                insertTextAtCursor(descInput, '{{文本|蓝|选择文字}}', true);
            });
            toolbar.appendChild(blueTextBtn);
            
            const greenTextBtn = createButton('绿色文本', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|选择文字}}', true);
            });
            toolbar.appendChild(greenTextBtn);
            
            const blueUnderlineBtn = createButton('蓝色下划线', 'btn btn-blue', () => {
                insertTextAtCursor(descInput, '{{文本|蓝|下划线|选择文字}}', true);
            });
            toolbar.appendChild(blueUnderlineBtn);
            
            const greenUnderlineBtn = createButton('绿色下划线', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|下划线|选择文字}}', true);
            });
            toolbar.appendChild(greenUnderlineBtn);
            
            const strokeTextBtn = createButton('绿色描边', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{描边|绿|选择文字}}', true);
            });
            toolbar.appendChild(strokeTextBtn);
            
            const dictBtn = createButton('词典', 'btn', () => {
                insertTextAtCursor(descInput, '{{词典|选择文字}}', true);
            });
            toolbar.appendChild(dictBtn);
            
            const wrapBtn = createButton('换行', 'btn', () => {
                insertTextAtCursor(descInput, '<br>');
            });
            toolbar.appendChild(wrapBtn);
            
            descSection.appendChild(toolbar);
            
            const descInput = createInput('textarea', insp.desc_global, (value) => {
                insp.desc_global = value;
                updateCodePreview();
            }, '变体描述');
            descInput.style.minHeight = '150px';
            descSection.appendChild(descInput);
            
            variantSection.appendChild(descSection);
            
            // 新增:衍生卡牌输入框
            const subInput = createInput('textarea', insp.sub || '', (value) => {
                insp.sub = value;
                updateCodePreview();
            }, '衍生卡牌');
            subInput.style.minHeight = '35px';
            variantSection.appendChild(createFormGroup('衍生卡牌:', subInput));
            
            // 删除按钮
            const deleteBtn = createButton('删除此变体', 'btn-danger', () => {
                if (confirm('确定要删除这个灵光一闪吗?')) {
                    state.currentCard.var.inspiration.splice(state.currentInspirationIndex, 1);
                    state.editMode = 'base';
                    state.currentInspirationIndex = null;
                    renderWithoutScroll();
                }
            });
            deleteBtn.style.marginTop = '20px';
            deleteBtn.style.width = '100%';
            variantSection.appendChild(deleteBtn);
            
            container.appendChild(variantSection);
            
        } else if (state.editMode === 'god_inspiration' && state.currentGodInspirationIndex !== null) {
            const insp = state.currentCard.var.god_inspiration[state.currentGod][state.currentGodInspirationIndex];
            if (!insp) return;
            
            const variantSection = createElement('div', 'variant-edit-section');
            const variantTitle = createElement('div', 'section-title');
            variantTitle.textContent = `${state.currentGod} 神光 #${state.currentGodInspirationIndex + 1}`;
            variantTitle.style.borderColor = '#673ab7';
            variantSection.appendChild(variantTitle);
            
            // 返回按钮
            const backBtn = createButton('← 返回基础信息', 'btn', () => {
                state.editMode = 'base';
                state.currentGodInspirationIndex = null;
                renderWithoutScroll();
            });
            backBtn.style.marginBottom = '15px';
            backBtn.style.width = '100%';
            variantSection.appendChild(backBtn);
            
            // AP输入
            const apInput = createInput('text', insp.ap, (value) => {
                insp.ap = value;
                updateCodePreview();
            }, 'AP (数字、X、Ø)');
            variantSection.appendChild(createFormGroup('AP:', apInput));
            
            // 类型选择
            const typeSelect = createSelect(
                ['', '攻击', '技能', '强化'],
                insp.type || '',
                (value) => {
                    insp.type = value;
                    updateCodePreview();
                }
            );
            variantSection.appendChild(createFormGroup('类型:', typeSelect.wrapper));
            
            // 机制输入
            const dictInput = createInput('text', insp.dict, (value) => {
                insp.dict = value;
                updateCodePreview();
            }, '多个机制使用、隔开');
            variantSection.appendChild(createFormGroup('机制:', dictInput));
            
            // 描述区域
            const descSection = createElement('div', 'form-group');
            const descLabel = createElement('div', 'form-label');
            descLabel.textContent = '描述:';
            descSection.appendChild(descLabel);
            
            // 描述工具栏
            const toolbar = createElement('div', 'button-group');
            
            const blueTextBtn = createButton('蓝色文本', 'btn btn-blue', () => {
                insertTextAtCursor(descInput, '{{文本|蓝|选择文字}}', true);
            });
            toolbar.appendChild(blueTextBtn);
            
            const greenTextBtn = createButton('绿色文本', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|选择文字}}', true);
            });
            toolbar.appendChild(greenTextBtn);
            
            const blueUnderlineBtn = createButton('蓝色下划线', 'btn btn-blue', () => {
                insertTextAtCursor(descInput, '{{文本|蓝|下划线|选择文字}}', true);
            });
            toolbar.appendChild(blueUnderlineBtn);
            
            const greenUnderlineBtn = createButton('绿色下划线', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|下划线|选择文字}}', true);
            });
            toolbar.appendChild(greenUnderlineBtn);
            
            const strokeTextBtn = createButton('绿色描边', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{描边|绿|选择文字}}', true);
            });
            toolbar.appendChild(strokeTextBtn);
            
            const dictBtn = createButton('词典', 'btn', () => {
                insertTextAtCursor(descInput, '{{词典|选择文字}}', true);
            });
            toolbar.appendChild(dictBtn);
            
            const wrapBtn = createButton('换行', 'btn', () => {
                insertTextAtCursor(descInput, '<br>');
            });
            toolbar.appendChild(wrapBtn);
            
            const circenBtn = createButton('凯尔肯', 'btn', () => {
                insertTextAtCursor(descInput, '{{图标|凯尔肯}}');
            });
            toolbar.appendChild(circenBtn);

            const diallosBtn = createButton('戴奥斯', 'btn', () => {
                insertTextAtCursor(descInput, '{{图标|戴奥斯}}');
            });
            toolbar.appendChild(diallosBtn);

            const nihiluBtn = createButton('尼希隆', 'btn', () => {
                insertTextAtCursor(descInput, '{{图标|尼希隆}}');
            });
            toolbar.appendChild(nihiluBtn);

            const secredBtn = createButton('赛克瑞德', 'btn', () => {
                insertTextAtCursor(descInput, '{{图标|赛克瑞德}}');
            });
            toolbar.appendChild(secredBtn);

            const vitorBtn = createButton('维托', 'btn', () => {
                insertTextAtCursor(descInput, '{{图标|维托}}');
            });
            toolbar.appendChild(vitorBtn);

            descSection.appendChild(toolbar);
            
            const descInput = createInput('textarea', insp.desc_global, (value) => {
                insp.desc_global = value;
                updateCodePreview();
            }, '变体描述');
            descInput.style.minHeight = '150px';
            descSection.appendChild(descInput);
            
            variantSection.appendChild(descSection);
            
            // 新增:衍生卡牌输入框
            const subInput = createInput('textarea', insp.sub || '', (value) => {
                insp.sub = value;
                updateCodePreview();
            }, '衍生卡牌');
            subInput.style.minHeight = '35px';
            variantSection.appendChild(createFormGroup('衍生卡牌:', subInput));
            
            // 删除按钮
            const deleteBtn = createButton('删除此变体', 'btn-danger', () => {
                if (confirm('确定要删除这个神光一闪吗?')) {
                    state.currentCard.var.god_inspiration[state.currentGod].splice(state.currentGodInspirationIndex, 1);
                    state.editMode = 'base';
                    state.currentGodInspirationIndex = null;
                    renderWithoutScroll();
                }
            });
            deleteBtn.style.marginTop = '20px';
            deleteBtn.style.width = '100%';
            variantSection.appendChild(deleteBtn);
            
            container.appendChild(variantSection);
        }
    }
    
    // 不触发滚动的渲染函数
    function renderWithoutScroll() {
        const container = document.getElementById('card-manager-container');
        if (!container) return;
        
        // 保存当前滚动位置
        const scrollPositions = {
            input: 0,
            list: 0,
            preview: 0
        };
        
        const inputSection = container.querySelector('.card-input-section');
        const listSection = container.querySelector('.card-list-section');
        const previewSection = container.querySelector('.card-preview-section');
        
        if (inputSection) scrollPositions.input = inputSection.scrollTop;
        if (listSection) scrollPositions.list = listSection.scrollTop;
        if (previewSection) scrollPositions.preview = previewSection.scrollTop;
        
        // 执行渲染
        render();
        
        // 恢复滚动位置
        requestAnimationFrame(() => {
            const newInputSection = container.querySelector('.card-input-section');
            const newListSection = container.querySelector('.card-list-section');
            const newPreviewSection = container.querySelector('.card-preview-section');
            
            if (newInputSection) newInputSection.scrollTop = scrollPositions.input;
            if (newListSection) newListSection.scrollTop = scrollPositions.list;
            if (newPreviewSection) newPreviewSection.scrollTop = scrollPositions.preview;
        });
    }
    
    // 渲染函数
    function render() {
        const container = document.getElementById('card-manager-container');
        if (!container) return;
        
        container.innerHTML = '';
        
        const manager = createElement('div', 'card-manager');
        
        // 左侧输入区
        const inputSection = createElement('div', 'card-input-section');
        
        // 战斗员选择
        const title = createElement('div', 'section-title');
        title.textContent = '卡牌管理器';
        inputSection.appendChild(title);
        
        const fighterSelect = createSelect(state.fighters, state.currentFighter, async (value) => {
            state.currentFighter = value;
            const loading = createElement('div', 'loading-indicator');
            loading.textContent = '正在加载卡牌数据...';
            document.body.appendChild(loading);
            
            try {
                const cards = await loadFighterCards(value);
                state.cards = cards;
                state.currentCard = cards.length > 0 ? cards[0] : null;
                state.editMode = 'base';
                state.currentInspirationIndex = null;
                state.currentGodInspirationIndex = null;
                render();
            } catch (error) {
                alert('加载失败:' + error.message);
            } finally {
                if (loading.parentNode) {
                    document.body.removeChild(loading);
                }
            }
        });
        inputSection.appendChild(createFormGroup('选择战斗员:', fighterSelect.wrapper));
        
        // 默认信息区
        if (state.currentFighter) {
            const defaultSection = createElement('div', 'default-info-section');
            const defaultTitle = createElement('div', 'section-title');
            defaultTitle.textContent = '默认信息';
            defaultTitle.style.borderColor = '#ff9800';
            defaultSection.appendChild(defaultTitle);
            
            const orderInput = createInput('text', state.defaultInfo.order, (value) => {
                state.defaultInfo.order = value;
                updateCodePreview();
            }, 'card.order');
            defaultSection.appendChild(createFormGroup('卡牌顺序:', orderInput));
            
            const egoInput = createInput('text', state.defaultInfo.ego, (value) => {
                state.defaultInfo.ego = value;
                updateCodePreview();
            }, 'card.info.ego');
            defaultSection.appendChild(createFormGroup('属性:', egoInput));
            
            inputSection.appendChild(defaultSection);
        }
        
        // 卡牌编辑区 - 根据editMode显示不同内容
        if (state.currentCard) {
            if (state.editMode === 'base') {
                // 显示基础信息编辑
                const cardSection = createElement('div', '');
                cardSection.style.marginTop = '20px';
                
                const cardTitle = createElement('div', 'section-title');
                cardTitle.textContent = '卡牌信息';
                cardSection.appendChild(cardTitle);
                
                // 卡牌名称
                const nameInput = createInput('text', state.currentCard.name, (value) => {
                    state.currentCard.name = value;
                    updateCodePreview();
                    // 更新列表显示
                    const cardItems = document.querySelectorAll('.card-item');
                    cardItems.forEach((item, idx) => {
                        if (state.cards[idx] === state.currentCard) {
                            const nameEl = item.querySelector('.card-item-name');
                            if (nameEl) nameEl.textContent = value || '未命名卡牌';
                        }
                    });
                }, '卡牌名称');
                cardSection.appendChild(createFormGroup('卡牌名称:', nameInput));
                
                // 显示名称
                const displaynameInput = createInput('text', state.currentCard.base.displayname, (value) => {
                    state.currentCard.base.displayname = value;
                    updateCodePreview();
                }, '显示名称');
                cardSection.appendChild(createFormGroup('显示名称:', displaynameInput));
                
                // 图片
                const artInput = createInput('text', state.currentCard.base.art, (value) => {
                    state.currentCard.base.art = value;
                    updateCodePreview();
                }, '图片文件名');
                cardSection.appendChild(createFormGroup('图片:', artInput));
                
                // 分组
                const groupInput = createInput('text', state.currentCard.base.group, (value) => {
                    state.currentCard.base.group = value;
                    updateCodePreview();
                }, '分组');
                cardSection.appendChild(createFormGroup('分组:', groupInput));
                
                // 稀有度
                const raritySelect = createSelect(
                    ['', '白', '蓝', '橙', '彩'],
                    state.currentCard.base.rarity || '',
                    (value) => {
                        state.currentCard.base.rarity = value;
                        updateCodePreview();
                    }
                );
                cardSection.appendChild(createFormGroup('稀有度:', raritySelect.wrapper));
                
                // 神明
                const godSelect = createSelect(
                    ['', '凯尔肯', '戴奥斯', '尼希隆', '赛克瑞德', '维托'],
                    state.currentCard.base.god || '',
                    (value) => {
                        state.currentCard.base.god = value;
                        updateCodePreview();
                    }
                );
                cardSection.appendChild(createFormGroup('神明:', godSelect.wrapper));
                
                // AP
                const apInput = createInput('text', state.currentCard.base.ap, (value) => {
                    state.currentCard.base.ap = value;
                    updateCodePreview();
                }, 'AP (可以是数字、X、Ø等)');
                cardSection.appendChild(createFormGroup('AP:', apInput));
                
                // 类型
                const typeSelect = createSelect(
                    ['', '攻击', '技能', '强化'],
                    state.currentCard.base.type || '',
                    (value) => {
                        state.currentCard.base.type = value;
                        updateCodePreview();
                    }
                );
                cardSection.appendChild(createFormGroup('类型:', typeSelect.wrapper));
                
                // 机制
                const dictInput = createInput('text', state.currentCard.base.dict, (value) => {
                    state.currentCard.base.dict = value;
                    updateCodePreview();
                }, '多个机制使用、隔开');
                cardSection.appendChild(createFormGroup('机制:', dictInput));
                
                // 描述
                const descSection = createElement('div', 'form-group');
                const descLabel = createElement('div', 'form-label');
                descLabel.textContent = '描述:';
                descSection.appendChild(descLabel);
                
                // 描述工具栏
                const toolbar = createElement('div', 'button-group');
                
                const blueTextBtn = createButton('蓝色文本', 'btn btn-blue', () => {
                    insertTextAtCursor(descInput, '{{文本|蓝|选择文字}}', true);
                });
                toolbar.appendChild(blueTextBtn);
                
                const greenTextBtn = createButton('绿色文本', 'btn btn-green', () => {
                    insertTextAtCursor(descInput, '{{文本|绿|选择文字}}', true);
                });
                toolbar.appendChild(greenTextBtn);
                
                const blueUnderlineBtn = createButton('蓝色下划线', 'btn btn-blue', () => {
                    insertTextAtCursor(descInput, '{{文本|蓝|下划线|选择文字}}', true);
                });
                toolbar.appendChild(blueUnderlineBtn);
                
                const greenUnderlineBtn = createButton('绿色下划线', 'btn btn-green', () => {
                    insertTextAtCursor(descInput, '{{文本|绿|下划线|选择文字}}', true);
                });
                toolbar.appendChild(greenUnderlineBtn);
                
                const strokeTextBtn = createButton('绿色描边', 'btn btn-green', () => {
                    insertTextAtCursor(descInput, '{{描边|绿|选择文字}}', true);
                });
                toolbar.appendChild(strokeTextBtn);
                
                const dictBtn = createButton('词典', 'btn', () => {
                    insertTextAtCursor(descInput, '{{词典|选择文字}}', true);
                });
                toolbar.appendChild(dictBtn);
                
                const wrapBtn = createButton('换行', 'btn', () => {
                    insertTextAtCursor(descInput, '<br>');
                });
                toolbar.appendChild(wrapBtn);
                
                descSection.appendChild(toolbar);
                
                const descInput = createInput('textarea', state.currentCard.base.desc_global, (value) => {
                    state.currentCard.base.desc_global = value;
                    updateCodePreview();
                }, '卡牌描述');
                descInput.style.minHeight = '150px';
                descSection.appendChild(descInput);
                
                cardSection.appendChild(descSection);
                
                // 衍生卡牌
                const subInput = createInput('textarea', state.currentCard.base.sub, (value) => {
                    state.currentCard.base.sub = value;
                    updateCodePreview();
                }, '衍生卡牌');
                subInput.style.minHeight = '35px';
                cardSection.appendChild(createFormGroup('衍生卡牌:', subInput));
                
                // 是否存在灵光一闪
                const inspirationCheckbox = createCheckbox(state.currentCard.base.isinspiration, (value) => {
                    state.currentCard.base.isinspiration = value;
                    if (!value) {
                        state.currentCard.var.inspiration = [];
                    }
                    updateCodePreview();
                    renderWithoutScroll();
                });
                cardSection.appendChild(createFormGroup('是否存在灵光一闪:', inspirationCheckbox));
                
                // 是否存在神光一闪
                const godInspirationCheckbox = createCheckbox(state.currentCard.base.isgod_inspiration, (value) => {
                    state.currentCard.base.isgod_inspiration = value;
                    if (!value) {
                        state.currentCard.var.god_inspiration = {
                            凯尔肯: [],
                            戴奥斯: [],
                            尼希隆: [],
                            赛克瑞德: [],
                            维托: []
                        };
                    }
                    updateCodePreview();
                    renderWithoutScroll();
                });
                cardSection.appendChild(createFormGroup('是否存在神光一闪:', godInspirationCheckbox));
                
                inputSection.appendChild(cardSection);
                
                // 保存卡牌按钮
                const saveCardBtn = createButton('保存卡牌', 'btn-primary', () => {
                    updateCodePreview();
                    alert('卡牌已保存到代码预览!');
                });
                saveCardBtn.style.marginTop = '20px';
                saveCardBtn.style.width = '100%';
                inputSection.appendChild(saveCardBtn);
                
            } else {
                // 显示变体编辑
                renderVariantEditor(inputSection);
            }
        }
        
        // 添加新卡牌按钮
        if (state.currentFighter && state.editMode === 'base') {
            const addCardBtn = createButton('+ 新增卡牌', 'btn-success', () => {
                const newCard = createEmptyCard();
                newCard.name = '新卡牌' + (state.cards.length + 1);
                state.cards.push(newCard);
                state.currentCard = newCard;
                state.editMode = 'base';
                state.currentInspirationIndex = null;
                state.currentGodInspirationIndex = null;
                renderWithoutScroll();
            });
            addCardBtn.style.marginTop = '20px';
            addCardBtn.style.width = '100%';
            inputSection.appendChild(addCardBtn);
        }
        
        manager.appendChild(inputSection);
        
        // 中间列表区
        const listSection = createElement('div', 'card-list-section');
        
        // 卡牌列表
        const cardListContainer = createElement('div', 'list-container');
        cardListContainer.style.minHeight = '250px';
        const cardListHeader = createElement('div', 'list-header');
        const cardListTitle = createElement('div', 'list-title');
        cardListTitle.textContent = '卡牌列表';
        cardListHeader.appendChild(cardListTitle);
        cardListContainer.appendChild(cardListHeader);
        
        if (state.cards.length === 0) {
            const emptyState = createElement('div', 'empty-state');
            const emptyIcon = createElement('div', 'empty-state-icon');
            emptyIcon.textContent = '📋';
            const emptyText = createElement('div', 'empty-state-text');
            emptyText.textContent = '暂无卡牌,点击"新增卡牌"开始创建';
            emptyState.appendChild(emptyIcon);
            emptyState.appendChild(emptyText);
            cardListContainer.appendChild(emptyState);
        } else {
            state.cards.forEach((card, index) => {
                const cardItem = createElement('div', 'card-item' + (state.currentCard === card && state.editMode === 'base' ? ' active' : ''));
                
                const cardName = createElement('div', 'card-item-name');
                cardName.textContent = card.name || '未命名卡牌';
                
                const cardInfo = createElement('div', 'card-item-info');
                const infoText = [];
                if (card.base.type) infoText.push(card.base.type);
                if (card.base.ap !== '') infoText.push('AP:' + card.base.ap);
                if (card.base.rarity) infoText.push(card.base.rarity);
                cardInfo.textContent = infoText.join(' | ') || '暂无信息';
                
                cardItem.appendChild(cardName);
                cardItem.appendChild(cardInfo);
                
                cardItem.addEventListener('click', () => {
                    state.currentCard = card;
                    state.editMode = 'base';
                    state.currentInspirationIndex = null;
                    state.currentGodInspirationIndex = null;
                    renderWithoutScroll();
                });
                
                // 删除按钮
                const deleteBtn = createButton('删除', 'btn-danger', (e) => {
                    e.stopPropagation();
                    if (confirm('确定要删除卡牌"' + card.name + '"吗?')) {
                        state.cards.splice(index, 1);
                        if (state.currentCard === card) {
                            state.currentCard = state.cards[0] || null;
                            state.editMode = 'base';
                            state.currentInspirationIndex = null;
                            state.currentGodInspirationIndex = null;
                        }
                        renderWithoutScroll();
                    }
                });
                deleteBtn.style.cssText = 'margin-top:8px;width:100%;';
                cardItem.appendChild(deleteBtn);
                
                cardListContainer.appendChild(cardItem);
            });
        }
        
        listSection.appendChild(cardListContainer);
        
        // 灵光一闪列表
        if (state.currentCard && state.currentCard.base.isinspiration) {
            const inspirationSection = createElement('div', 'inspiration-section');
            inspirationSection.style.minHeight = '250px';
            const inspirationHeader = createElement('div', 'list-header');
            const inspirationTitle = createElement('div', 'list-title');
            inspirationTitle.textContent = '灵光一闪列表';
            inspirationHeader.appendChild(inspirationTitle);
            
            const addInspirationBtn = createButton('+ 添加', 'btn-primary', () => {
                const newIndex = state.currentCard.var.inspiration.length;
                state.currentCard.var.inspiration.push(createEmptyVariant());
                state.editMode = 'inspiration';
                state.currentInspirationIndex = newIndex;
                state.currentGodInspirationIndex = null;
                render();
            });
            inspirationHeader.appendChild(addInspirationBtn);
            inspirationSection.appendChild(inspirationHeader);
            
            if (state.currentCard.var.inspiration.length === 0) {
                const emptyState = createElement('div', 'empty-state');
                emptyState.style.padding = '20px';
                const emptyText = createElement('div', 'empty-state-text');
                emptyText.textContent = '暂无灵光一闪,点击"添加"创建';
                emptyState.appendChild(emptyText);
                inspirationSection.appendChild(emptyState);
            } else {
                state.currentCard.var.inspiration.forEach((insp, idx) => {
                    const inspItem = createElement('div', 
                        'inspiration-item-simple' + 
                        (state.editMode === 'inspiration' && state.currentInspirationIndex === idx ? ' active' : '')
                    );
                    
                    const inspName = createElement('div', 'inspiration-item-name');
                    inspName.textContent = `灵光 #${idx + 1}`;
                    
                    const inspInfo = createElement('div', 'inspiration-item-info');
                    const infoText = [];
                    if (insp.type) infoText.push(insp.type);
                    if (insp.ap !== '') infoText.push('AP:' + insp.ap);
                    inspInfo.textContent = infoText.join(' | ') || '点击编辑';
                    
                    inspItem.appendChild(inspName);
                    inspItem.appendChild(inspInfo);
                    
                    inspItem.addEventListener('click', () => {
                        state.editMode = 'inspiration';
                        state.currentInspirationIndex = idx;
                        state.currentGodInspirationIndex = null;
                        renderWithoutScroll();
                    });
                    
                    inspirationSection.appendChild(inspItem);
                });
            }
            
            listSection.appendChild(inspirationSection);
        }
        
        // 神光一闪列表
        if (state.currentCard && state.currentCard.base.isgod_inspiration) {
            const godInspirationSection = createElement('div', 'inspiration-section');
            godInspirationSection.style.minHeight = '250px';
            const godInspirationHeader = createElement('div', 'list-header');
            const godInspirationTitle = createElement('div', 'list-title');
            godInspirationTitle.textContent = '神光一闪列表';
            godInspirationHeader.appendChild(godInspirationTitle);
            godInspirationSection.appendChild(godInspirationHeader);
            
            // 神明选择标签
            const godSelectGroup = createElement('div', 'god-select-group');
            ['凯尔肯', '戴奥斯', '尼希隆', '赛克瑞德', '维托'].forEach(god => {
                const godTab = createElement('div', 'god-tab' + (state.currentGod === god ? ' active' : ''));
                godTab.textContent = god;
                godTab.addEventListener('click', () => {
                    state.currentGod = god;
                    renderWithoutScroll();
                });
                godSelectGroup.appendChild(godTab);
            });
            godInspirationSection.appendChild(godSelectGroup);
            
            // 当前神明的神光一闪列表
            const currentGodInspirations = state.currentCard.var.god_inspiration[state.currentGod];
            
            const addGodInspirationBtn = createButton('+ 添加 ' + state.currentGod + ' 神光', 'btn-primary', () => {
                const newIndex = currentGodInspirations.length;
                currentGodInspirations.push(createEmptyVariant());
                state.editMode = 'god_inspiration';
                state.currentGodInspirationIndex = newIndex;
                state.currentInspirationIndex = null;
                render();
            });
            addGodInspirationBtn.style.marginBottom = '10px';
            addGodInspirationBtn.style.width = '100%';
            godInspirationSection.appendChild(addGodInspirationBtn);
            
            if (currentGodInspirations.length === 0) {
                const emptyState = createElement('div', 'empty-state');
                emptyState.style.padding = '20px';
                const emptyText = createElement('div', 'empty-state-text');
                emptyText.textContent = `暂无 ${state.currentGod} 神光一闪`;
                emptyState.appendChild(emptyText);
                godInspirationSection.appendChild(emptyState);
            } else {
                currentGodInspirations.forEach((insp, idx) => {
                    const inspItem = createElement('div', 
                        'inspiration-item-simple' + 
                        (state.editMode === 'god_inspiration' && 
                         state.currentGodInspirationIndex === idx ? ' active' : '')
                    );
                    
                    const inspName = createElement('div', 'inspiration-item-name');
                    inspName.textContent = `${state.currentGod} 神光 #${idx + 1}`;
                    
                    const inspInfo = createElement('div', 'inspiration-item-info');
                    const infoText = [];
                    if (insp.type) infoText.push(insp.type);
                    if (insp.ap !== '') infoText.push('AP:' + insp.ap);
                    inspInfo.textContent = infoText.join(' | ') || '点击编辑';
                    
                    inspItem.appendChild(inspName);
                    inspItem.appendChild(inspInfo);
                    
                    inspItem.addEventListener('click', () => {
                        state.editMode = 'god_inspiration';
                        state.currentGodInspirationIndex = idx;
                        state.currentInspirationIndex = null;
                        renderWithoutScroll();
                    });
                    
                    godInspirationSection.appendChild(inspItem);
                });
            }
            
            listSection.appendChild(godInspirationSection);
        }
        
        manager.appendChild(listSection);
        
        // 右侧预览区
        const previewSection = createElement('div', 'card-preview-section');
        const previewTitle = createElement('div', 'section-title');
        previewTitle.textContent = 'Lua 代码预览';
        previewSection.appendChild(previewTitle);
        
        // 复制按钮
        const copyBtn = createButton('复制代码', 'btn-primary', () => {
            const code = generateLuaCode();
            navigator.clipboard.writeText(code).then(() => {
                alert('代码已复制到剪贴板!');
            }).catch(err => {
                console.error('复制失败:', err);
                const textarea = document.createElement('textarea');
                textarea.value = code;
                textarea.style.position = 'fixed';
                textarea.style.opacity = '0';
                document.body.appendChild(textarea);
                textarea.select();
                document.execCommand('copy');
                document.body.removeChild(textarea);
                alert('代码已复制到剪贴板!');
            });
        });
        copyBtn.style.marginBottom = '10px';
        copyBtn.style.width = '100%';
        previewSection.appendChild(copyBtn);
        
        // 保存按钮
        const saveBtn = createButton('保存到Wiki', 'btn-success', async () => {
            if (!state.currentFighter) {
                alert('请先选择战斗员!');
                return;
            }
            
            const code = generateLuaCode();
            const pageName = '模块:卡牌/' + state.currentFighter;
            
            const loading = createElement('div', 'loading-indicator');
            loading.textContent = '正在保存...';
            document.body.appendChild(loading);
            
            try {
                const api = new mw.Api();
                await api.postWithToken('csrf', {
                    action: 'edit',
                    title: pageName,
                    text: code,
                    summary: '通过卡牌管理器更新卡牌数据',
                    contentmodel: 'Scribunto'
                });
                alert('保存成功!');
            } catch (error) {
                console.error('保存失败:', error);
                alert('保存失败:' + error);
            } finally {
                if (loading.parentNode) {
                    document.body.removeChild(loading);
                }
            }
        });
        saveBtn.style.marginBottom = '10px';
        saveBtn.style.width = '100%';
        previewSection.appendChild(saveBtn);
        
        // 代码显示
        const codePreview = createElement('div', 'code-preview');
        codePreview.textContent = generateLuaCode();
        previewSection.appendChild(codePreview);
        
        manager.appendChild(previewSection);
        
        container.appendChild(manager);
    }
    
    // 初始化
    async function init() {
        let container = document.getElementById('card-manager-container');
        if (!container) {
            container = createElement('div', '');
            container.id = 'card-manager-container';
            
            const content = document.getElementById('mw-content-text');
            if (content) {
                content.insertBefore(container, content.firstChild);
            } else {
                document.body.appendChild(container);
            }
        }
        
        const loading = createElement('div', 'loading-indicator');
        loading.textContent = '正在初始化...';
        document.body.appendChild(loading);
        
        try {
            await loadFighters();
            
            if (state.fighters.length > 0) {
                state.currentFighter = state.fighters[0];
                state.cards = await loadFighterCards(state.currentFighter);
                if (state.cards.length > 0) {
                    state.currentCard = state.cards[0];
                }
            }
            
            render();
        } catch (error) {
            console.error('初始化失败:', error);
            alert('初始化失败:' + error.message);
        } finally {
            if (loading.parentNode) {
                document.body.removeChild(loading);
            }
        }
    }
    
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
    
    window.CardManager = {
        init: init,
        render: render,
        state: state,
        createCard: createEmptyCard,
        generateCode: generateLuaCode
    };
    
})();