MediaWiki

Card.js:修订间差异

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献
无编辑摘要
律Rhyme留言 | 贡献
无编辑摘要
 
(未显示同一用户的27个中间版本)
第1行: 第1行:
(function() {
(function() {
     'use strict';
     'use strict';
 
   
     // 加载CSS
     // 加载CSS
     mw.loader.load('/index.php?title=Mediawiki:Card.css&action=raw&ctype=text/css', 'text/css');
     mw.loader.load('/index.php?title=Mediawiki:Card.css&action=raw&ctype=text/css', 'text/css');
 
   
     console.log('Card Manager: 脚本已加载');
    // 状态管理
 
     const state = {
    class CardManager {
        currentFighter: '',
         constructor() {
        fighters: [],
             console.log('Card Manager: 初始化中...');
        cards: [],
             this.currentFighter = '';
        currentCard: null,
            this.cards = {};
         defaultInfo: {
            this.currentCard = null;
             order: '',
            this.fighters = ['示例战斗员1', '示例战斗员2'];
             ego: ''
           
        },
            this.defaultData = {
        editMode: 'base', // 'base', 'inspiration', 'god_inspiration'
                order: [],
        currentGod: '凯尔肯',
                ego: ''
        currentInspirationIndex: null,
            };
        currentGodInspirationIndex: null
           
    };
            this.cardData = {
   
                name: '',
    // 卡牌数据结构
    function createEmptyCard() {
        return {
            name: '',
            base: {
                 displayname: '',
                 displayname: '',
                 art: '',
                 art: '',
第28行: 第32行:
                 god: '',
                 god: '',
                 ap: '',
                 ap: '',
                 type: '攻击',
                 type: '',
                 dict: '',
                 dict: '',
                 desc_global: '',
                 desc_global: '',
                 sub: '',
                 sub: '',
                 isinspiration: false,
                 isinspiration: 0,
                 isgod_inspiration: false,
                 isgod_inspiration: 0
                 inspirations: [],
            },
                 god_inspirations: {
            var: {
                     circen: [],
                 inspiration: [],
                     diallos: [],
                 god_inspiration: {
                     nihilum: [],
                     凯尔肯: [],
                     secred: [],
                     戴奥斯: [],
                     vitor: []
                     尼希隆: [],
                     赛克瑞德: [],
                     维托: []
                 }
                 }
             };
             }
        };
    }
   
    // 创建空变体结构
    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;
         }
         }
 
       
         async init() {
         input.addEventListener('focus', () => {
             console.log('Card Manager: 开始初始化');
             if (input.textContent === placeholder) {
            await this.loadFighters();
                input.textContent = '';
             this.render();
                input.style.color = '#333';
             console.log('Card Manager: 初始化完成');
            }
         }
        });
 
       
         async loadFighters() {
        input.addEventListener('blur', () => {
             try {
             if (!input.textContent.trim()) {
                 const api = new mw.Api();
                input.textContent = placeholder;
                const response = await api.get({
                input.style.color = '#999';
                    action: 'query',
             }
                    list: 'categorymembers',
            if (onChange) onChange(input.textContent === placeholder ? '' : input.textContent);
                    cmtitle: 'Category:战斗员',
         });
                    cmlimit: 500
       
                });
         input.addEventListener('input', () => {
               
             if (onChange && input.textContent !== placeholder) {
                if (response.query && response.query.categorymembers) {
                 onChange(input.textContent);
                    this.fighters = response.query.categorymembers.map(page => page.title);
            }
                    console.log('Card Manager: 加载了', this.fighters.length, '个战斗员');
        });
                }
       
             } catch (error) {
        return input;
                 console.error('Card Manager: 加载战斗员列表失败:', error);
    }
   
    // 创建复选框
    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);
 
         });
         render() {
       
            console.log('Card Manager: 开始渲染');
         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();
              
              
             const contentDiv = document.getElementById('mw-content-text');
             if (selectedText) {
            if (!contentDiv) {
                range.deleteContents();
                 console.error('Card Manager: 找不到内容容器');
                const textNode = document.createTextNode(text.replace('选择文字', selectedText));
                 range.insertNode(textNode);
                 return;
                 return;
             }
             }
            contentDiv.innerHTML = '';
            const container = document.createElement('div');
            container.className = 'card-manager';
           
            const leftPanel = document.createElement('div');
            leftPanel.className = 'card-input-panel';
            leftPanel.appendChild(this.renderFighterSelect());
            leftPanel.appendChild(this.renderDefaultInfo());
            leftPanel.appendChild(this.renderCardInput());
           
            const middlePanel = document.createElement('div');
            middlePanel.className = 'card-list-panel';
            middlePanel.appendChild(this.renderCardLists());
           
            const rightPanel = document.createElement('div');
            rightPanel.className = 'card-preview-panel';
            rightPanel.appendChild(this.renderPreview());
           
            container.appendChild(leftPanel);
            container.appendChild(middlePanel);
            container.appendChild(rightPanel);
           
            contentDiv.appendChild(container);
           
            console.log('Card Manager: 渲染完成');
         }
         }
 
       
         renderFighterSelect() {
         document.execCommand('insertText', false, text);
            const container = document.createElement('div');
    }
             container.className = 'form-group';
   
    // 辅助函数:提取字符串值
    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] : '';
              
              
             const label = document.createElement('div');
             if (char === '"' && prevChar !== '\\') {
            label.className = 'form-label';
                inString = !inString;
             label.textContent = '当前战斗员';
             }
              
              
             const selectContainer = document.createElement('div');
             if (!inString) {
            selectContainer.className = 'custom-select';
                if (char === '{') {
           
                    if (depth > 0) {
            const display = document.createElement('div');
                        currentBlock += char;
            display.className = 'select-display';
                    }
            display.textContent = this.currentFighter || '请选择战斗员...';
                    depth++;
           
                } else if (char === '}') {
            const arrow = document.createElement('span');
                    depth--;
            arrow.className = 'select-arrow';
                    if (depth === 0 && currentBlock) {
            arrow.textContent = '';
                        const inspiration = {};
            display.appendChild(arrow);
                       
           
                        const ap = extractValue(currentBlock, 'ap');
            const dropdown = document.createElement('div');
                        if (ap) inspiration.ap = ap;
            dropdown.className = 'select-dropdown';
                       
           
                        const type = extractStringValue(currentBlock, 'type');
            this.fighters.forEach(fighter => {
                        if (type) inspiration.type = type;
                const option = document.createElement('div');
                       
                option.className = 'select-option';
                        const desc = extractStringValue(currentBlock, 'desc_global');
                option.textContent = fighter;
                        if (desc) inspiration.desc_global = desc;
                 if (fighter === this.currentFighter) {
                       
                     option.classList.add('selected');
                        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;
                 }
                 }
                option.onclick = async () => {
             } else if (depth > 0) {
                    this.currentFighter = fighter;
                 currentBlock += char;
                    display.firstChild.textContent = fighter;
             }
                    dropdown.querySelectorAll('.select-option').forEach(o => o.classList.remove('selected'));
                    option.classList.add('selected');
                    dropdown.classList.remove('active');
                    await this.loadFighterData();
                };
                dropdown.appendChild(option);
             });
           
            display.onclick = (e) => {
                 e.stopPropagation();
                dropdown.classList.toggle('active');
            };
           
            document.addEventListener('click', () => {
                dropdown.classList.remove('active');
             });
           
            selectContainer.appendChild(display);
            selectContainer.appendChild(dropdown);
           
            container.appendChild(label);
            container.appendChild(selectContainer);
           
            return container;
         }
         }
 
       
         renderDefaultInfo() {
         return inspirations;
            const container = document.createElement('div');
    }
             container.className = 'default-info-section';
   
    // 辅助函数:使用括号计数提取块内容
    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] : '';
              
              
             const title = document.createElement('div');
             if (char === '"' && prevChar !== '\\') {
            title.className = 'section-title';
                inString = !inString;
            title.textContent = '默认信息';
             }
             container.appendChild(title);
              
              
             const orderGroup = document.createElement('div');
             if (!inString) {
            orderGroup.className = 'form-group';
                if (char === '{') {
           
                    depth++;
            const orderLabel = document.createElement('div');
                 } else if (char === '}') {
            orderLabel.className = 'form-label';
                    depth--;
            orderLabel.textContent = '卡牌顺序(card.order)';
                    if (depth === 0) {
           
                        endIdx = i;
            const orderInput = document.createElement('div');
                        break;
            orderInput.className = 'custom-input';
                    }
            orderInput.contentEditable = true;
                }
            orderInput.id = 'order-input';
             }
            orderInput.textContent = this.defaultData.order.join(',');
            orderInput.addEventListener('input', () => {
                this.defaultData.order = orderInput.textContent.split(',').map(s => s.trim()).filter(s => s);
                 this.updatePreview();
            });
           
            orderGroup.appendChild(orderLabel);
            orderGroup.appendChild(orderInput);
            container.appendChild(orderGroup);
           
            const egoGroup = document.createElement('div');
            egoGroup.className = 'form-group';
           
            const egoLabel = document.createElement('div');
            egoLabel.className = 'form-label';
            egoLabel.textContent = '属性(ego)';
           
            const egoInput = document.createElement('div');
            egoInput.className = 'custom-input';
            egoInput.contentEditable = true;
            egoInput.id = 'ego-input';
            egoInput.textContent = this.defaultData.ego;
            egoInput.addEventListener('input', () => {
                this.defaultData.ego = egoInput.textContent;
                this.updatePreview();
            });
           
             egoGroup.appendChild(egoLabel);
            egoGroup.appendChild(egoInput);
            container.appendChild(egoGroup);
           
            return container;
         }
         }
 
       
         renderCardInput() {
         return content.substring(startIdx, endIdx);
            const container = document.createElement('div');
    }
           
   
            const title = document.createElement('div');
    // 解析Lua代码
            title.className = 'section-title';
    function parseLuaCode(luaText) {
            title.textContent = '卡牌数据';
        const cards = [];
            container.appendChild(title);
        const defaultInfo = {
           
             order: '',
            container.appendChild(this.createInputField('卡牌名称', 'name'));
             ego: ''
            container.appendChild(this.createInputField('显示名称(displayname)', 'displayname'));
        };
            container.appendChild(this.createInputField('图片(art)', 'art'));
       
            container.appendChild(this.createGroupSelect());
        try {
            container.appendChild(this.createRaritySelect());
             const orderMatch = luaText.match(/card\.order\s*=\s*\{\s*"([^"]+)"\s*\}/);
            container.appendChild(this.createGodSelect());
             if (orderMatch) {
            container.appendChild(this.createInputField('AP', 'ap'));
                 defaultInfo.order = orderMatch[1];
            container.appendChild(this.createTypeSelect());
            container.appendChild(this.createInputField('机制(dict)', 'dict'));
           
            const descGroup = document.createElement('div');
            descGroup.className = 'form-group';
              
            const descLabel = document.createElement('div');
             descLabel.className = 'form-label';
            descLabel.textContent = '描述(desc_global)';
           
            const formatButtons = this.createFormatButtons();
           
             const descInput = document.createElement('div');
            descInput.className = 'custom-textarea';
            descInput.contentEditable = true;
            descInput.textContent = this.cardData.desc_global;
            descInput.id = 'desc-input';
            descInput.addEventListener('input', () => {
                this.cardData.desc_global = descInput.textContent;
                this.updatePreview();
            });
           
            descGroup.appendChild(descLabel);
            descGroup.appendChild(formatButtons);
            descGroup.appendChild(descInput);
            container.appendChild(descGroup);
           
            container.appendChild(this.createInputField('衍生卡牌(sub)', 'sub'));
            container.appendChild(this.createCheckboxField('是否存在灵光一闪', 'isinspiration'));
            container.appendChild(this.createCheckboxField('是否存在神光一闪', 'isgod_inspiration'));
           
            // 添加灵光一闪变体显示
             if (this.cardData.isinspiration && this.cardData.inspirations.length > 0) {
                 container.appendChild(this.renderInspirations());
             }
             }
              
              
             // 添加神光一闪变体显示
             const egoMatch = luaText.match(/card\.info\s*=\s*\{[^}]*ego\s*=\s*"([^"]+)"/);
             if (this.cardData.isgod_inspiration) {
             if (egoMatch) {
                 container.appendChild(this.renderGodInspirations());
                 defaultInfo.ego = egoMatch[1];
             }
             }
              
              
             const btnGroup = document.createElement('div');
             const cardPattern = /card\["([^"]+)"\]\s*=\s*\{/g;
            btnGroup.className = 'btn-group';
             let cardMatch;
           
            const saveBtn = document.createElement('div');
            saveBtn.className = 'btn btn-primary';
            saveBtn.textContent = '保存卡牌';
            saveBtn.onclick = () => this.saveCard();
           
            const newBtn = document.createElement('div');
            newBtn.className = 'btn btn-success';
            newBtn.textContent = '新建卡牌';
            newBtn.onclick = () => this.newCard();
           
            btnGroup.appendChild(saveBtn);
            btnGroup.appendChild(newBtn);
            container.appendChild(btnGroup);
           
            return container;
        }
 
        renderInspirations() {
            const container = document.createElement('div');
            container.className = 'variant-section';
              
            const title = document.createElement('div');
            title.className = 'section-title';
            title.textContent = '灵光一闪变体';
            container.appendChild(title);
              
              
             this.cardData.inspirations.forEach((inspiration, index) => {
             while ((cardMatch = cardPattern.exec(luaText)) !== null) {
                 const variantBox = document.createElement('div');
                 const cardName = cardMatch[1];
                 variantBox.className = 'variant-box';
                 const cardStartIdx = cardMatch.index + cardMatch[0].length;
                  
                  
                 const variantTitle = document.createElement('div');
                 let depth = 1;
                 variantTitle.className = 'variant-title';
                 let cardEndIdx = cardStartIdx;
                 variantTitle.textContent = `变体 ${index + 1}`;
                 let inString = false;
                variantBox.appendChild(variantTitle);
                  
                  
                 const variantContent = document.createElement('div');
                 for (let i = cardStartIdx; i < luaText.length && depth > 0; i++) {
                variantContent.className = 'variant-content';
                    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;
                            }
                        }
                    }
                }
                  
                  
                 if (inspiration.ap) {
                 const cardContent = luaText.substring(cardStartIdx, cardEndIdx);
                    const apLine = document.createElement('div');
                    apLine.textContent = `AP: ${inspiration.ap}`;
                    variantContent.appendChild(apLine);
                }
                  
                  
                 if (inspiration.type) {
                 const card = createEmptyCard();
                    const typeLine = document.createElement('div');
                card.name = cardName;
                    typeLine.textContent = `类型: ${inspiration.type}`;
                    variantContent.appendChild(typeLine);
                }
                  
                  
                 if (inspiration.dict) {
                const baseContent = extractBlock(cardContent, /base\s*=\s*\{/);
                     const dictLine = document.createElement('div');
                 if (baseContent) {
                     dictLine.textContent = `机制: ${inspiration.dict}`;
                    card.base.displayname = extractStringValue(baseContent, 'displayname') || '';
                     variantContent.appendChild(dictLine);
                    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;
                 }
                 }
                  
                  
                 if (inspiration.desc_global) {
                const varContent = extractBlock(cardContent, /var\s*=\s*\{/);
                     const descLine = document.createElement('div');
                 if (varContent) {
                     descLine.className = 'variant-desc';
                    const inspirationContent = extractBlock(varContent, /inspiration\s*=\s*\{/);
                    descLine.textContent = `描述: ${inspiration.desc_global}`;
                    if (inspirationContent) {
                     variantContent.appendChild(descLine);
                        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);
                            }
                        });
                     }
                 }
                 }
                  
                  
                 variantBox.appendChild(variantContent);
                 cards.push(card);
                container.appendChild(variantBox);
             }
             });
              
              
             return container;
        } 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';
         }
         }
 
       
         renderGodInspirations() {
         state.cards.forEach(card => {
             const container = document.createElement('div');
            code += `card["${escapeLuaString(card.name)}"] = {\n`;
             container.className = 'variant-section';
            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`;
              
              
             const title = document.createElement('div');
             code += '   },\n';
            title.className = 'section-title';
            title.textContent = '神光一闪变体';
            container.appendChild(title);
              
              
             const gods = ['circen', 'diallos', 'nihilum', 'secred', 'vitor'];
             const hasInspiration = card.var.inspiration.length > 0;
             const godNames = {
             const hasGodInspiration = Object.values(card.var.god_inspiration).some(arr => arr.length > 0);
                'circen': '瑟肯',
                'diallos': '迪亚罗斯',
                'nihilum': '虚无',
                'secred': '萨克雷德',
                'vitor': '维托尔'
            };
              
              
             gods.forEach(god => {
             if (hasInspiration || hasGodInspiration) {
                 const godInspirations = this.cardData.god_inspirations[god];
                 code += '    var = {\n';
                if (!godInspirations || godInspirations.length === 0) return;
                  
                  
                 const godSection = document.createElement('div');
                 if (hasInspiration) {
                godSection.className = 'god-section';
                    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';
                }
                  
                  
                 const godTitle = document.createElement('div');
                 if (hasGodInspiration) {
                godTitle.className = 'god-title';
                    code += '        god_inspiration = {\n';
                godTitle.textContent = godNames[god] || god;
                    Object.entries(card.var.god_inspiration).forEach(([god, inspList]) => {
                godSection.appendChild(godTitle);
                        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';
                }
                  
                  
                 godInspirations.forEach((inspiration, index) => {
                 code += '   },\n';
                    const variantBox = document.createElement('div');
            }
                    variantBox.className = 'variant-box small';
           
                   
            code += '}\n\n';
                    const variantTitle = document.createElement('div');
        });
                    variantTitle.className = 'variant-title';
       
                    variantTitle.textContent = `${godNames[god]} 变体 ${index + 1}`;
        code += 'return card';
                    variantBox.appendChild(variantTitle);
       
                   
        return code;
                    const variantContent = document.createElement('div');
    }
                    variantContent.className = 'variant-content';
   
                   
    // 加载战斗员列表
                    if (inspiration.ap) {
    async function loadFighters() {
                        const apLine = document.createElement('div');
        try {
                        apLine.textContent = `AP: ${inspiration.ap}`;
            const api = new mw.Api();
                        variantContent.appendChild(apLine);
            const result = await api.get({
                    }
                action: 'query',
                   
                list: 'allpages',
                    if (inspiration.type) {
                apprefix: '卡牌/',
                        const typeLine = document.createElement('div');
                apnamespace: 828,
                        typeLine.textContent = `类型: ${inspiration.type}`;
                 aplimit: 500
                        variantContent.appendChild(typeLine);
                    }
                   
                    if (inspiration.dict) {
                        const dictLine = document.createElement('div');
                        dictLine.textContent = `机制: ${inspiration.dict}`;
                        variantContent.appendChild(dictLine);
                    }
                   
                    if (inspiration.desc_global) {
                        const descLine = document.createElement('div');
                        descLine.className = 'variant-desc';
                        descLine.textContent = `描述: ${inspiration.desc_global}`;
                        variantContent.appendChild(descLine);
                    }
                   
                    variantBox.appendChild(variantContent);
                    godSection.appendChild(variantBox);
                 });
               
                container.appendChild(godSection);
             });
             });
              
              
             return container;
             if (result.query && result.query.allpages) {
                state.fighters = result.query.allpages.map(page => {
                    return page.title.replace('模块:卡牌/', '');
                });
            }
        } catch (error) {
            console.error('加载战斗员列表失败:', error);
         }
         }
 
    }
        createInputField(label, field) {
   
            const group = document.createElement('div');
    // 加载战斗员卡牌数据
            group.className = 'form-group';
    async function loadFighterCards(fighter) {
           
        if (!fighter) return [];
             const labelDiv = document.createElement('div');
       
            labelDiv.className = 'form-label';
        try {
            labelDiv.textContent = label;
             const api = new mw.Api();
              
              
             const input = document.createElement('div');
             const result = await api.get({
            input.className = 'custom-input';
                action: 'query',
            input.contentEditable = true;
                prop: 'revisions',
            input.dataset.field = field;
                titles: '模块:卡牌/' + fighter,
            input.textContent = this.cardData[field] || '';
                rvprop: 'content',
            input.addEventListener('input', () => {
                 rvslots: 'main',
                 this.cardData[field] = input.textContent;
                 formatversion: 2
                 this.updatePreview();
             });
             });
              
              
             group.appendChild(labelDiv);
             if (!result.query || !result.query.pages || result.query.pages.length === 0) {
            group.appendChild(input);
                console.error('未找到页面');
           
                return [];
            return group;
             }
        }
 
        createCheckboxField(label, field) {
            const group = document.createElement('div');
             group.className = 'form-group';
              
              
             const labelDiv = document.createElement('div');
             const page = result.query.pages[0];
            labelDiv.className = 'form-label';
            labelDiv.textContent = label;
              
              
             const checkboxContainer = document.createElement('div');
             if (page.missing) {
            checkboxContainer.className = 'checkbox-group';
                console.error('页面不存在');
           
                return [];
            const checkbox = document.createElement('div');
            checkbox.className = 'custom-checkbox';
            checkbox.dataset.field = field;
            if (this.cardData[field]) {
                checkbox.classList.add('checked');
             }
             }
              
              
             const statusLabel = document.createElement('div');
             const content = page.revisions[0].slots.main.content;
            statusLabel.textContent = this.cardData[field] ? '是' : '否';
              
              
             checkbox.onclick = () => {
             const parsed = parseLuaCode(content);
                checkbox.classList.toggle('checked');
                this.cardData[field] = checkbox.classList.contains('checked');
                statusLabel.textContent = this.cardData[field] ? '是' : '否';
                this.updatePreview();
            };
              
              
             checkboxContainer.appendChild(checkbox);
             state.defaultInfo = parsed.defaultInfo;
            checkboxContainer.appendChild(statusLabel);
              
              
             group.appendChild(labelDiv);
             return parsed.cards;
            group.appendChild(checkboxContainer);
              
              
             return group;
        } catch (error) {
            console.error('加载卡牌数据失败:', error);
             return [];
        }
    }
   
    // 更新代码预览(不触发滚动)
    function updateCodePreview() {
        const codePreview = document.querySelector('.code-preview');
        if (codePreview) {
            codePreview.textContent = generateLuaCode();
         }
         }
 
    }
         createFormatButtons() {
   
             const container = document.createElement('div');
    // 渲染变体卡牌编辑表单
             container.className = 'format-buttons';
    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 buttons = [
             const variantSection = createElement('div', 'variant-edit-section');
                { label: '蓝色文本', class: 'blue', template: '{{文本|蓝|%s}}' },
            const variantTitle = createElement('div', 'section-title');
                { label: '绿色文本', class: 'green', template: '{{文本|绿|%s}}' },
            variantTitle.textContent = `灵光一闪 #${state.currentInspirationIndex + 1}`;
                { label: '绿色描边', class: 'green', template: '{{描边|绿|%s}}' },
            variantTitle.style.borderColor = '#9c27b0';
                { label: '词典', class: '', template: '{{词典|%s}}' },
             variantSection.appendChild(variantTitle);
                { label: '换行', class: '', template: '<br>' }
             ];
              
              
             buttons.forEach(btn => {
             // 返回按钮
                const button = document.createElement('div');
            const backBtn = createButton('← 返回基础信息', 'btn', () => {
                button.className = 'format-btn ' + btn.class;
                state.editMode = 'base';
                button.textContent = btn.label;
                state.currentInspirationIndex = null;
                button.onclick = () => {
                 renderWithoutScroll();
                    const textarea = document.getElementById('desc-input');
                    if (textarea) {
                        this.insertTemplate(textarea, btn.template);
                    }
                };
                 container.appendChild(button);
             });
             });
            backBtn.style.marginBottom = '15px';
            backBtn.style.width = '100%';
            variantSection.appendChild(backBtn);
              
              
             return container;
             // AP输入
        }
            const apInput = createInput('text', insp.ap, (value) => {
 
                insp.ap = value;
        insertTemplate(element, template) {
                updateCodePreview();
            element.focus();
             }, 'AP (数字、X、Ø)');
              
             variantSection.appendChild(createFormGroup('AP:', apInput));
            const selection = window.getSelection();
             let selectedText = '';
              
              
             if (selection.rangeCount > 0) {
             // 类型选择
                const range = selection.getRangeAt(0);
            const typeSelect = createSelect(
                 if (element.contains(range.commonAncestorContainer)) {
                 ['', '攻击', '技能', '强化'],
                     selectedText = range.toString();
                insp.type || '',
                (value) => {
                     insp.type = value;
                    updateCodePreview();
                 }
                 }
             }
             );
            variantSection.appendChild(createFormGroup('类型:', typeSelect.wrapper));
              
              
             let insertText;
             // 机制输入
             if (template === '<br>') {
             const dictInput = createInput('text', insp.dict, (value) => {
                 insertText = '<br>';
                 insp.dict = value;
                 document.execCommand('insertHTML', false, insertText);
                 updateCodePreview();
             } else {
             }, '多个机制使用、隔开');
                insertText = template.replace('%s', selectedText || '选择文字');
            variantSection.appendChild(createFormGroup('机制:', dictInput));
                document.execCommand('insertText', false, insertText);
            }
              
              
             this.cardData.desc_global = element.textContent;
             // 描述区域
             this.updatePreview();
             const descSection = createElement('div', 'form-group');
        }
             const descLabel = createElement('div', 'form-label');
 
             descLabel.textContent = '描述:';
        createGroupSelect() {
            descSection.appendChild(descLabel);
             const group = document.createElement('div');
             group.className = 'form-group';
              
              
             const label = document.createElement('div');
            // 描述工具栏
            label.className = 'form-label';
             const toolbar = createElement('div', 'button-group');
            label.textContent = '卡组(group)';
              
              
             const container = document.createElement('div');
             const blueTextBtn = createButton('蓝色文本', 'btn btn-blue', () => {
             container.className = 'group-options';
                insertTextAtCursor(descInput, '{{文本|蓝|选择文字}}', true);
             });
            toolbar.appendChild(blueTextBtn);
              
              
             const groups = ['自我意识技能', '起始卡牌', '独特卡牌', '灵光一闪', '神光一闪'];
             const greenTextBtn = createButton('绿色文本', 'btn btn-green', () => {
                insertTextAtCursor(descInput, '{{文本|绿|选择文字}}', true);
            });
            toolbar.appendChild(greenTextBtn);
              
              
             groups.forEach(groupName => {
             const blueUnderlineBtn = createButton('蓝色下划线', 'btn btn-blue', () => {
                const option = document.createElement('div');
                insertTextAtCursor(descInput, '{{文本|蓝|下划线|选择文字}}', true);
                option.className = 'group-option';
                option.textContent = groupName;
                if (this.cardData.group === groupName) {
                    option.classList.add('selected');
                }
                option.onclick = () => {
                    container.querySelectorAll('.group-option').forEach(o => o.classList.remove('selected'));
                    option.classList.add('selected');
                    this.cardData.group = groupName;
                    this.updatePreview();
                };
                container.appendChild(option);
             });
             });
            toolbar.appendChild(blueUnderlineBtn);
              
              
             group.appendChild(label);
             const greenUnderlineBtn = createButton('绿色下划线', 'btn btn-green', () => {
             group.appendChild(container);
                insertTextAtCursor(descInput, '{{文本|绿|下划线|选择文字}}', true);
            });
             toolbar.appendChild(greenUnderlineBtn);
              
              
             return group;
             const strokeTextBtn = createButton('绿色描边', 'btn btn-green', () => {
        }
                insertTextAtCursor(descInput, '{{描边|绿|选择文字}}', true);
 
            });
        createRaritySelect() {
             toolbar.appendChild(strokeTextBtn);
            const group = document.createElement('div');
             group.className = 'form-group';
              
              
             const label = document.createElement('div');
             const dictBtn = createButton('词典', 'btn', () => {
             label.className = 'form-label';
                insertTextAtCursor(descInput, '{{词典|选择文字}}', true);
             label.textContent = '稀有度(rarity)';
             });
             toolbar.appendChild(dictBtn);
              
              
             const container = document.createElement('div');
             const wrapBtn = createButton('换行', 'btn', () => {
            container.className = 'rarity-options';
                 insertTextAtCursor(descInput, '<br>');
           
            const rarities = ['白', '', '橙', '彩'];
           
            rarities.forEach(rarity => {
                 const option = document.createElement('div');
                option.className = 'rarity-option';
                option.textContent = rarity;
                if (this.cardData.rarity === rarity) {
                    option.classList.add('selected');
                }
                option.onclick = () => {
                    container.querySelectorAll('.rarity-option').forEach(o => o.classList.remove('selected'));
                    option.classList.add('selected');
                    this.cardData.rarity = rarity;
                    this.updatePreview();
                };
                container.appendChild(option);
             });
             });
            toolbar.appendChild(wrapBtn);
              
              
             group.appendChild(label);
             descSection.appendChild(toolbar);
            group.appendChild(container);
           
            return group;
        }
 
        createGodSelect() {
            const group = document.createElement('div');
            group.className = 'form-group';
              
              
             const label = document.createElement('div');
             const descInput = createInput('textarea', insp.desc_global, (value) => {
             label.className = 'form-label';
                insp.desc_global = value;
             label.textContent = '神明';
                updateCodePreview();
            }, '变体描述');
             descInput.style.minHeight = '150px';
             descSection.appendChild(descInput);
              
              
             const container = document.createElement('div');
             variantSection.appendChild(descSection);
            container.className = 'god-options';
              
              
             const gods = ['circen', 'diallos', 'nihilum', 'secred', 'vitor'];
            // 新增:衍生卡牌输入框
             const subInput = createInput('textarea', insp.sub || '', (value) => {
                insp.sub = value;
                updateCodePreview();
            }, '衍生卡牌');
            subInput.style.minHeight = '35px';
            variantSection.appendChild(createFormGroup('衍生卡牌:', subInput));
              
              
             gods.forEach(god => {
             // 删除按钮
                 const option = document.createElement('div');
            const deleteBtn = createButton('删除此变体', 'btn-danger', () => {
                option.className = 'god-option';
                 if (confirm('确定要删除这个灵光一闪吗?')) {
                option.textContent = god;
                    state.currentCard.var.inspiration.splice(state.currentInspirationIndex, 1);
                if (this.cardData.god === god) {
                    state.editMode = 'base';
                     option.classList.add('selected');
                    state.currentInspirationIndex = null;
                     renderWithoutScroll();
                 }
                 }
                option.onclick = () => {
                    container.querySelectorAll('.god-option').forEach(o => o.classList.remove('selected'));
                    option.classList.add('selected');
                    this.cardData.god = god;
                    this.updatePreview();
                };
                container.appendChild(option);
             });
             });
            deleteBtn.style.marginTop = '20px';
            deleteBtn.style.width = '100%';
            variantSection.appendChild(deleteBtn);
              
              
             group.appendChild(label);
             container.appendChild(variantSection);
            group.appendChild(container);
              
              
            return group;
         } else if (state.editMode === 'god_inspiration' && state.currentGodInspirationIndex !== null) {
         }
             const insp = state.currentCard.var.god_inspiration[state.currentGod][state.currentGodInspirationIndex];
 
             if (!insp) return;
        createTypeSelect() {
             const group = document.createElement('div');
             group.className = 'form-group';
              
              
             const label = document.createElement('div');
             const variantSection = createElement('div', 'variant-edit-section');
             label.className = 'form-label';
             const variantTitle = createElement('div', 'section-title');
             label.textContent = '卡牌类型(type)';
             variantTitle.textContent = `${state.currentGod} 神光 #${state.currentGodInspirationIndex + 1}`;
            variantTitle.style.borderColor = '#673ab7';
            variantSection.appendChild(variantTitle);
              
              
             const container = document.createElement('div');
            // 返回按钮
             container.className = 'type-options';
             const backBtn = createButton('← 返回基础信息', 'btn', () => {
                state.editMode = 'base';
                state.currentGodInspirationIndex = null;
                renderWithoutScroll();
            });
            backBtn.style.marginBottom = '15px';
             backBtn.style.width = '100%';
            variantSection.appendChild(backBtn);
              
              
             const types = ['攻击', '技能', '强化'];
            // AP输入
             const apInput = createInput('text', insp.ap, (value) => {
                insp.ap = value;
                updateCodePreview();
            }, 'AP (数字、X、Ø)');
            variantSection.appendChild(createFormGroup('AP:', apInput));
              
              
             types.forEach(type => {
             // 类型选择
                const option = document.createElement('div');
            const typeSelect = createSelect(
                 option.className = 'type-option';
                ['', '攻击', '技能', '强化'],
                 option.textContent = type;
                 insp.type || '',
                if (this.cardData.type === type) {
                 (value) => {
                     option.classList.add('selected');
                    insp.type = value;
                     updateCodePreview();
                 }
                 }
                option.onclick = () => {
            );
                    container.querySelectorAll('.type-option').forEach(o => o.classList.remove('selected'));
            variantSection.appendChild(createFormGroup('类型:', typeSelect.wrapper));
                    option.classList.add('selected');
                    this.cardData.type = type;
                    this.updatePreview();
                };
                container.appendChild(option);
            });
              
              
             group.appendChild(label);
             // 机制输入
             group.appendChild(container);
            const dictInput = createInput('text', insp.dict, (value) => {
                insp.dict = value;
                updateCodePreview();
             }, '多个机制使用、隔开');
            variantSection.appendChild(createFormGroup('机制:', dictInput));
              
              
             return group;
             // 描述区域
        }
            const descSection = createElement('div', 'form-group');
 
             const descLabel = createElement('div', 'form-label');
        renderCardLists() {
            descLabel.textContent = '描述:';
             const container = document.createElement('div');
            descSection.appendChild(descLabel);
              
              
             const title = document.createElement('div');
            // 描述工具栏
            title.className = 'panel-title';
             const toolbar = createElement('div', 'button-group');
            title.textContent = '卡牌列表';
            container.appendChild(title);
              
              
            // 主卡牌列表
             const blueTextBtn = createButton('蓝色文本', 'btn btn-blue', () => {
             const mainSection = document.createElement('div');
                insertTextAtCursor(descInput, '{{文本|蓝|选择文字}}', true);
             mainSection.className = 'card-list-section';
            });
             toolbar.appendChild(blueTextBtn);
              
              
             const mainTitle = document.createElement('div');
             const greenTextBtn = createButton('绿色文本', 'btn btn-green', () => {
            mainTitle.className = 'section-title';
                insertTextAtCursor(descInput, '{{文本|绿|选择文字}}', true);
             mainTitle.textContent = '主卡牌';
             });
             mainSection.appendChild(mainTitle);
             toolbar.appendChild(greenTextBtn);
              
              
             const mainList = document.createElement('div');
             const blueUnderlineBtn = createButton('蓝色下划线', 'btn btn-blue', () => {
            mainList.className = 'list-container';
                insertTextAtCursor(descInput, '{{文本|蓝|下划线|选择文字}}', true);
            mainList.id = 'main-card-list';
             });
             mainSection.appendChild(mainList);
             toolbar.appendChild(blueUnderlineBtn);
             container.appendChild(mainSection);
              
              
            // 灵光一闪列表
             const greenUnderlineBtn = createButton('绿色下划线', 'btn btn-green', () => {
             const inspirationSection = document.createElement('div');
                insertTextAtCursor(descInput, '{{文本|绿|下划线|选择文字}}', true);
             inspirationSection.className = 'card-list-section';
            });
             toolbar.appendChild(greenUnderlineBtn);
              
              
             const inspirationTitle = document.createElement('div');
             const strokeTextBtn = createButton('绿色描边', 'btn btn-green', () => {
            inspirationTitle.className = 'section-title';
                insertTextAtCursor(descInput, '{{描边|绿|选择文字}}', true);
             inspirationTitle.textContent = '灵光一闪卡牌';
             });
             inspirationSection.appendChild(inspirationTitle);
             toolbar.appendChild(strokeTextBtn);
              
              
             const inspirationList = document.createElement('div');
             const dictBtn = createButton('词典', 'btn', () => {
            inspirationList.className = 'list-container';
                insertTextAtCursor(descInput, '{{词典|选择文字}}', true);
            inspirationList.id = 'inspiration-card-list';
             });
             inspirationSection.appendChild(inspirationList);
             toolbar.appendChild(dictBtn);
             container.appendChild(inspirationSection);
              
              
            // 神之一闪列表
             const wrapBtn = createButton('换行', 'btn', () => {
             const godSection = document.createElement('div');
                insertTextAtCursor(descInput, '<br>');
             godSection.className = 'card-list-section';
             });
            toolbar.appendChild(wrapBtn);
              
              
             const godTitle = document.createElement('div');
             const circenBtn = createButton('凯尔肯', 'btn', () => {
            godTitle.className = 'section-title';
                insertTextAtCursor(descInput, '{{图标|凯尔肯}}');
             godTitle.textContent = '神之一闪卡牌';
             });
             godSection.appendChild(godTitle);
             toolbar.appendChild(circenBtn);
           
 
             const godList = document.createElement('div');
             const diallosBtn = createButton('戴奥斯', 'btn', () => {
            godList.className = 'list-container';
                insertTextAtCursor(descInput, '{{图标|戴奥斯}}');
             godList.id = 'god-card-list';
             });
             godSection.appendChild(godList);
             toolbar.appendChild(diallosBtn);
             container.appendChild(godSection);
 
              
             const nihiluBtn = createButton('尼希隆', 'btn', () => {
             this.updateCardLists();
                insertTextAtCursor(descInput, '{{图标|尼希隆}}');
           
             });
            return container;
             toolbar.appendChild(nihiluBtn);
        }


        updateCardLists() {
             const secredBtn = createButton('赛克瑞德', 'btn', () => {
            const mainList = document.getElementById('main-card-list');
                 insertTextAtCursor(descInput, '{{图标|赛克瑞德}}');
             const inspirationList = document.getElementById('inspiration-card-list');
            const godList = document.getElementById('god-card-list');
           
            if (!mainList || !inspirationList || !godList) return;
           
            const mainCards = [];
            const inspirationCards = [];
            const godCards = [];
           
            // 分类卡牌
            Object.keys(this.cards).forEach(name => {
                 const card = this.cards[name];
                if (card.isgod_inspiration) {
                    godCards.push(name);
                } else if (card.isinspiration) {
                    inspirationCards.push(name);
                } else {
                    mainCards.push(name);
                }
             });
             });
              
             toolbar.appendChild(secredBtn);
            // 更新各个列表
            this.updateCardListSection(mainList, mainCards);
            this.updateCardListSection(inspirationList, inspirationCards);
            this.updateCardListSection(godList, godCards);
        }


        updateCardListSection(container, cardNames) {
             const vitorBtn = createButton('维托', 'btn', () => {
             container.innerHTML = '';
                 insertTextAtCursor(descInput, '{{图标|维托}}');
           
            if (cardNames.length === 0) {
                const empty = document.createElement('div');
                empty.className = 'list-empty';
                empty.textContent = '暂无卡牌';
                container.appendChild(empty);
                return;
            }
           
            cardNames.forEach(name => {
                 const card = this.cards[name];
                const item = document.createElement('div');
                item.className = 'card-list-item';
               
                const info = document.createElement('div');
               
                const nameDiv = document.createElement('div');
                nameDiv.className = 'card-list-item-name';
                nameDiv.textContent = name;
               
                const detailDiv = document.createElement('div');
                detailDiv.className = 'card-list-item-info';
                detailDiv.textContent = `${card.type || '攻击'} | AP:${card.ap || 0} | ${card.rarity || ''}`;
               
                info.appendChild(nameDiv);
                info.appendChild(detailDiv);
               
                const deleteBtn = document.createElement('div');
                deleteBtn.className = 'delete-btn';
                deleteBtn.textContent = '删除';
                deleteBtn.onclick = (e) => {
                    e.stopPropagation();
                    if (confirm(`确定要删除卡牌"${name}"吗?`)) {
                        delete this.cards[name];
                        this.updateCardLists();
                        this.updatePreview();
                        if (this.currentCard === name) {
                            this.newCard();
                        }
                    }
                };
               
                item.appendChild(info);
                item.appendChild(deleteBtn);
               
                item.onclick = () => {
                    this.loadCard(name);
                    document.querySelectorAll('.card-list-item').forEach(i => i.classList.remove('active'));
                    item.classList.add('active');
                };
               
                container.appendChild(item);
             });
             });
        }
            toolbar.appendChild(vitorBtn);


        renderPreview() {
             descSection.appendChild(toolbar);
             const container = document.createElement('div');
              
              
             const title = document.createElement('div');
             const descInput = createInput('textarea', insp.desc_global, (value) => {
             title.className = 'panel-title';
                insp.desc_global = value;
             title.textContent = 'Lua代码预览';
                updateCodePreview();
             container.appendChild(title);
             }, '变体描述');
             descInput.style.minHeight = '150px';
             descSection.appendChild(descInput);
              
              
             const preview = document.createElement('div');
             variantSection.appendChild(descSection);
            preview.className = 'preview-code';
            preview.id = 'code-preview';
            container.appendChild(preview);
              
              
             const copyBtn = document.createElement('div');
            // 新增:衍生卡牌输入框
            copyBtn.className = 'btn btn-primary';
             const subInput = createInput('textarea', insp.sub || '', (value) => {
             copyBtn.textContent = '复制代码';
                insp.sub = value;
             copyBtn.style.marginTop = '10px';
                updateCodePreview();
             copyBtn.onclick = () => this.copyCode();
             }, '衍生卡牌');
            container.appendChild(copyBtn);
             subInput.style.minHeight = '35px';
             variantSection.appendChild(createFormGroup('衍生卡牌:', subInput));
              
              
             this.updatePreview();
             // 删除按钮
            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);
              
              
             return container;
             container.appendChild(variantSection);
         }
         }
 
    }
         updatePreview() {
   
             const preview = document.getElementById('code-preview');
    // 不触发滚动的渲染函数
             if (!preview) return;
    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');
              
              
             preview.textContent = this.generateLuaCode();
             if (newInputSection) newInputSection.scrollTop = scrollPositions.input;
         }
            if (newListSection) newListSection.scrollTop = scrollPositions.list;
 
            if (newPreviewSection) newPreviewSection.scrollTop = scrollPositions.preview;
         generateLuaCode() {
        });
             let code = 'local card = {}\n\n';
    }
   
    // 渲染函数
    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);
              
              
             if (this.defaultData.order.length > 0) {
             try {
                 code += `card.order = { "${this.defaultData.order.join(',')}" }\n\n`;
                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);
              
              
             code += 'card.info = {\n';
             const orderInput = createInput('text', state.defaultInfo.order, (value) => {
            if (this.defaultData.ego) {
                 state.defaultInfo.order = value;
                 code += `    ego = "${this.defaultData.ego}",\n`;
                updateCodePreview();
             }
             }, 'card.order');
             code += '}\n\n';
             defaultSection.appendChild(createFormGroup('卡牌顺序:', orderInput));
              
              
             Object.keys(this.cards).forEach(name => {
             const egoInput = createInput('text', state.defaultInfo.ego, (value) => {
                 const card = this.cards[name];
                 state.defaultInfo.ego = value;
                 code += this.generateCardCode(name, card);
                 updateCodePreview();
             });
            }, 'card.info.ego');
             defaultSection.appendChild(createFormGroup('属性:', egoInput));
              
              
             code += 'return card';
             inputSection.appendChild(defaultSection);
           
            return code;
         }
         }
 
       
         generateCardCode(name, card) {
         // 卡牌编辑区 - 根据editMode显示不同内容
            let code = `card["${name}"] = {\n`;
        if (state.currentCard) {
            code += '    base = {\n';
             if (state.editMode === 'base') {
           
                // 显示基础信息编辑
            if (card.displayname) code += `        displayname = "${card.displayname}",\n`;
                const cardSection = createElement('div', '');
             if (card.art) code += `        art = "${card.art}",\n`;
                cardSection.style.marginTop = '20px';
            if (card.group) code += `        group = "${card.group}",\n`;
               
            if (card.rarity) code += `        rarity = "${card.rarity}",\n`;
                 const cardTitle = createElement('div', 'section-title');
            if (card.ap) code += `        ap = ${isNaN(card.ap) ? `"${card.ap}"` : card.ap},\n`;
                 cardTitle.textContent = '卡牌信息';
            if (card.type) code += `        type = "${card.type}",\n`;
                 cardSection.appendChild(cardTitle);
            if (card.dict) code += `        dict = "${card.dict}",\n`;
            if (card.desc_global) {
                 const desc = card.desc_global.replace(/\n/g, '<br>').replace(/"/g, '\\"');
                 code += `        desc_global = "${desc}",\n`;
            }
            if (card.sub) code += `        sub = "${card.sub}",\n`;
            if (card.isinspiration) code += `        isinspiration = 1,\n`;
            if (card.isgod_inspiration) code += `        isgod_inspiration = 1,\n`;
           
            code += '   },\n';
           
            // 添加变体数据
            if ((card.isinspiration && card.inspirations.length > 0) ||
                 (card.isgod_inspiration && this.hasGodInspirations(card))) {
                code += '    \n    var = {\n';
                  
                  
                 // 灵光一闪变体
                 // 卡牌名称
                 if (card.isinspiration && card.inspirations.length > 0) {
                 const nameInput = createInput('text', state.currentCard.name, (value) => {
                    code += '        inspiration = {\n';
                     state.currentCard.name = value;
                     card.inspirations.forEach(inspiration => {
                    updateCodePreview();
                        code += '            {\n';
                    // 更新列表显示
                        if (inspiration.ap) code += `                ap = ${isNaN(inspiration.ap) ? `"${inspiration.ap}"` : inspiration.ap},\n`;
                    const cardItems = document.querySelectorAll('.card-item');
                        if (inspiration.type) code += `                type = "${inspiration.type}",\n`;
                    cardItems.forEach((item, idx) => {
                         if (inspiration.dict) code += `                dict = "${inspiration.dict}",\n`;
                         if (state.cards[idx] === state.currentCard) {
                        if (inspiration.desc_global) {
                             const nameEl = item.querySelector('.card-item-name');
                             const desc = inspiration.desc_global.replace(/\n/g, '<br>').replace(/"/g, '\\"');
                             if (nameEl) nameEl.textContent = value || '未命名卡牌';
                             code += `                desc_global = "${desc}",\n`;
                         }
                         }
                        code += '            },\n';
                     });
                     });
                     code += '       },\n';
                }, '卡牌名称');
                 }
                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));
                  
                  
                 // 神之一闪变体
                 // 类型
                 if (card.isgod_inspiration) {
                 const typeSelect = createSelect(
                     const gods = ['circen', 'diallos', 'nihilum', 'secred', 'vitor'];
                     ['', '攻击', '技能', '强化'],
                     const hasAnyGod = gods.some(god => card.god_inspirations[god] && card.god_inspirations[god].length > 0);
                     state.currentCard.base.type || '',
                   
                    (value) => {
                    if (hasAnyGod) {
                        state.currentCard.base.type = value;
                        code += '       god_inspiration = {\n';
                        updateCodePreview();
                       
                        gods.forEach(god => {
                            const godInspirations = card.god_inspirations[god];
                            if (godInspirations && godInspirations.length > 0) {
                                code += `            ${god} = {\n`;
                                godInspirations.forEach(inspiration => {
                                    code += '                {\n';
                                    if (inspiration.ap) code += `                    ap = ${isNaN(inspiration.ap) ? `"${inspiration.ap}"` : inspiration.ap},\n`;
                                    if (inspiration.type) code += `                    type = "${inspiration.type}",\n`;
                                    if (inspiration.dict) code += `                    dict = "${inspiration.dict}",\n`;
                                    if (inspiration.desc_global) {
                                        const desc = inspiration.desc_global.replace(/\n/g, '<br>').replace(/"/g, '\\"');
                                        code += `                    desc_global = "${desc}",\n`;
                                    }
                                    code += '                },\n';
                                });
                                code += '            },\n';
                            }
                        });
                       
                        code += '        },\n';
                     }
                     }
                 }
                );
                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));
                  
                  
                 code += '    },\n';
                 // 是否存在灵光一闪
            }
                const inspirationCheckbox = createCheckbox(state.currentCard.base.isinspiration, (value) => {
           
                    state.currentCard.base.isinspiration = value;
            code += '}\n\n';
                    if (!value) {
           
                        state.currentCard.var.inspiration = [];
            return code;
                    }
        }
                    updateCodePreview();
 
                     renderWithoutScroll();
        hasGodInspirations(card) {
                 });
            const gods = ['circen', 'diallos', 'nihilum', 'secred', 'vitor'];
                cardSection.appendChild(createFormGroup('是否存在灵光一闪:', inspirationCheckbox));
            return gods.some(god => card.god_inspirations[god] && card.god_inspirations[god].length > 0);
        }
 
        saveCard() {
            if (!this.cardData.name) {
                alert('请输入卡牌名称!');
                return;
            }
           
            this.cards[this.cardData.name] = JSON.parse(JSON.stringify(this.cardData));
            this.currentCard = this.cardData.name;
           
            if (!this.defaultData.order.includes(this.cardData.name)) {
                this.defaultData.order.push(this.cardData.name);
                const orderInput = document.getElementById('order-input');
                if (orderInput) {
                     orderInput.textContent = this.defaultData.order.join(',');
                 }
            }
           
            this.updateCardLists();
            this.updatePreview();
           
            alert('卡牌保存成功!');
        }
 
        newCard() {
            this.currentCard = null;
            this.cardData = {
                name: '',
                displayname: '',
                art: '',
                group: '',
                rarity: '',
                god: '',
                ap: '',
                type: '攻击',
                dict: '',
                desc_global: '',
                sub: '',
                isinspiration: false,
                isgod_inspiration: false,
                inspirations: [],
                god_inspirations: {
                    circen: [],
                    diallos: [],
                    nihilum: [],
                    secred: [],
                    vitor: []
                }
            };
           
            this.render();
        }
 
        loadCard(name) {
            if (!this.cards[name]) return;
           
            this.currentCard = name;
            this.cardData = JSON.parse(JSON.stringify(this.cards[name]));
            this.render();
        }
 
        async loadFighterData() {
            if (!this.currentFighter) return;
           
            try {
                const api = new mw.Api();
                const moduleName = `模块:卡牌/${this.currentFighter}`;
                  
                  
                 const response = await api.get({
                // 是否存在神光一闪
                     action: 'query',
                 const godInspirationCheckbox = createCheckbox(state.currentCard.base.isgod_inspiration, (value) => {
                    prop: 'revisions',
                     state.currentCard.base.isgod_inspiration = value;
                    titles: moduleName,
                    if (!value) {
                    rvprop: 'content',
                        state.currentCard.var.god_inspiration = {
                     rvslots: 'main'
                            凯尔肯: [],
                            戴奥斯: [],
                            尼希隆: [],
                            赛克瑞德: [],
                            维托: []
                        };
                    }
                    updateCodePreview();
                     renderWithoutScroll();
                 });
                 });
                cardSection.appendChild(createFormGroup('是否存在神光一闪:', godInspirationCheckbox));
                  
                  
                 const pages = response.query.pages;
                 inputSection.appendChild(cardSection);
                const page = Object.values(pages)[0];
                  
                  
                 if (page.revisions && page.revisions[0]) {
                 // 保存卡牌按钮
                    const content = page.revisions[0].slots.main['*'];
                const saveCardBtn = createButton('保存卡牌', 'btn-primary', () => {
                    console.log('Card Manager: 加载了战斗员数据');
                     updateCodePreview();
                   
                     alert('卡牌已保存到代码预览!');
                     // 解析Lua代码
                });
                    this.parseLuaContent(content);
                 saveCardBtn.style.marginTop = '20px';
                      
                saveCardBtn.style.width = '100%';
                    // 重新渲染界面
                inputSection.appendChild(saveCardBtn);
                    this.render();
                  
                   
             } else {
                    alert(`成功加载战斗员"${this.currentFighter}"的数据!`);
                 // 显示变体编辑
                 } else {
                 renderVariantEditor(inputSection);
                    console.log('Card Manager: 该战斗员暂无数据');
                    alert(`战斗员"${this.currentFighter}"暂无卡牌数据`);
                 }
             } catch (error) {
                 console.error('Card Manager: 加载战斗员数据失败:', error);
                 alert('加载失败: ' + error.message);
             }
             }
         }
         }
 
       
         parseLuaContent(content) {
        // 添加新卡牌按钮
             // 重置数据
         if (state.currentFighter && state.editMode === 'base') {
            this.cards = {};
             const addCardBtn = createButton('+ 新增卡牌', 'btn-success', () => {
             this.defaultData = { order: [], ego: '' };
                const newCard = createEmptyCard();
              
                newCard.name = '新卡牌' + (state.cards.length + 1);
             try {
                state.cards.push(newCard);
                // 解析 card.order
                state.currentCard = newCard;
                const orderMatch = content.match(/card\.order\s*=\s*\{\s*"([^"]+)"\s*\}/);
                state.editMode = 'base';
                if (orderMatch) {
                state.currentInspirationIndex = null;
                    this.defaultData.order = orderMatch[1].split(',').map(s => s.trim()).filter(s => s);
                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 || '未命名卡牌';
                  
                  
                 // 解析 card.info.ego
                 const cardInfo = createElement('div', 'card-item-info');
                 const infoBlockMatch = content.match(/card\.info\s*=\s*\{([^}]*)\}/);
                 const infoText = [];
                 if (infoBlockMatch) {
                if (card.base.type) infoText.push(card.base.type);
                    const egoMatch = infoBlockMatch[1].match(/ego\s*=\s*"([^"]+)"/);
                 if (card.base.ap !== '') infoText.push('AP:' + card.base.ap);
                    if (egoMatch) {
                if (card.base.rarity) infoText.push(card.base.rarity);
                        this.defaultData.ego = egoMatch[1];
                 cardInfo.textContent = infoText.join(' | ') || '暂无信息';
                    }
                 }
                  
                  
                 // 使用更复杂的解析逻辑来处理嵌套结构
                 cardItem.appendChild(cardName);
                const lines = content.split('\n');
                 cardItem.appendChild(cardInfo);
                 let currentCard = null;
                let currentSection = null; // 'base' 或 'var'
                let currentVarType = null; // 'inspiration' 或 'god_inspiration'
                let currentGodName = null; // circen, diallos 等
                let braceStack = [];
                let sectionContent = [];
                  
                  
                 for (let i = 0; i < lines.length; i++) {
                 cardItem.addEventListener('click', () => {
                     const line = lines[i];
                    state.currentCard = card;
                     const trimmedLine = line.trim();
                    state.editMode = 'base';
                   
                     state.currentInspirationIndex = null;
                    // 匹配卡牌定义开始 card["卡牌名"] = {
                     state.currentGodInspirationIndex = null;
                     const cardMatch = line.match(/^card\["([^"]+)"\]\s*=\s*\{/);
                    renderWithoutScroll();
                    if (cardMatch) {
                });
                        currentCard = cardMatch[1];
               
                        braceStack = ['{'];
                // 删除按钮
                         continue;
                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 (!currentCard) continue;
                     const inspName = createElement('div', 'inspiration-item-name');
                    inspName.textContent = `灵光 #${idx + 1}`;
                      
                      
                     // 匹配 base = {
                     const inspInfo = createElement('div', 'inspiration-item-info');
                     if (trimmedLine.match(/^base\s*=\s*\{/)) {
                    const infoText = [];
                        currentSection = 'base';
                     if (insp.type) infoText.push(insp.type);
                        sectionContent = [];
                    if (insp.ap !== '') infoText.push('AP:' + insp.ap);
                        continue;
                    inspInfo.textContent = infoText.join(' | ') || '点击编辑';
                    }
                      
                      
                     // 匹配 var = {
                     inspItem.appendChild(inspName);
                     if (trimmedLine.match(/^var\s*=\s*\{/)) {
                     inspItem.appendChild(inspInfo);
                        currentSection = 'var';
                        sectionContent = [];
                        continue;
                    }
                      
                      
                     // 如果在 base 部分
                     inspItem.addEventListener('click', () => {
                    if (currentSection === 'base') {
                         state.editMode = 'inspiration';
                         if (trimmedLine === '},') {
                        state.currentInspirationIndex = idx;
                            // base 部分结束
                        state.currentGodInspirationIndex = null;
                            this.parseCardBase(currentCard, sectionContent.join('\n'));
                         renderWithoutScroll();
                            currentSection = null;
                    });
                            sectionContent = [];
                         } else {
                            sectionContent.push(line);
                        }
                        continue;
                    }
                      
                      
                     // 如果在 var 部分
                     inspirationSection.appendChild(inspItem);
                    if (currentSection === 'var') {
                 });
                        // 匹配 inspiration = {
                        if (trimmedLine.match(/^inspiration\s*=\s*\{/)) {
                            currentVarType = 'inspiration';
                            sectionContent = [];
                            continue;
                        }
                       
                        // 匹配 god_inspiration = {
                        if (trimmedLine.match(/^god_inspiration\s*=\s*\{/)) {
                            currentVarType = 'god_inspiration';
                            sectionContent = [];
                            continue;
                        }
                       
                        // 在 inspiration 中
                        if (currentVarType === 'inspiration') {
                            if (trimmedLine === '},') {
                                // inspiration 部分结束
                                this.parseInspirations(currentCard, sectionContent.join('\n'));
                                currentVarType = null;
                                sectionContent = [];
                            } else {
                                sectionContent.push(line);
                            }
                            continue;
                        }
                       
                        // 在 god_inspiration 中
                        if (currentVarType === 'god_inspiration') {
                            // 匹配神明名称 circen = {
                            const godMatch = trimmedLine.match(/^(circen|diallos|nihilum|secred|vitor)\s*=\s*\{/);
                            if (godMatch) {
                                currentGodName = godMatch[1];
                                sectionContent = [];
                                continue;
                            }
                           
                            if (currentGodName) {
                                if (trimmedLine === '},') {
                                    // 某个神明的部分结束
                                    this.parseGodInspirations(currentCard, currentGodName, sectionContent.join('\n'));
                                    currentGodName = null;
                                    sectionContent = [];
                                } else {
                                    sectionContent.push(line);
                                }
                                continue;
                            }
                           
                            // god_inspiration 整体结束
                            if (trimmedLine === '},') {
                                currentVarType = null;
                            }
                            continue;
                        }
                       
                        // var 部分结束
                        if (trimmedLine === '},') {
                            currentSection = null;
                        }
                    }
                   
                    // 卡牌定义结束
                    if (trimmedLine === '}' && braceStack.length === 1) {
                        currentCard = null;
                        braceStack = [];
                    }
                 }
               
                console.log('Card Manager: 解析完成');
                console.log('Card Manager: order =', this.defaultData.order);
                console.log('Card Manager: ego =', this.defaultData.ego);
                console.log('Card Manager: 卡牌数量 =', Object.keys(this.cards).length);
                console.log('Card Manager: 卡牌列表 =', Object.keys(this.cards));
               
            } catch (error) {
                console.error('Card Manager: 解析Lua内容时出错:', error);
                alert('解析卡牌数据失败: ' + error.message);
             }
             }
           
            listSection.appendChild(inspirationSection);
         }
         }
 
       
         parseCardBase(cardName, baseContent) {
         // 神光一闪列表
             const card = {
        if (state.currentCard && state.currentCard.base.isgod_inspiration) {
                name: cardName,
             const godInspirationSection = createElement('div', 'inspiration-section');
                displayname: this.extractFieldValue(baseContent, 'displayname'),
            godInspirationSection.style.minHeight = '250px';
                art: this.extractFieldValue(baseContent, 'art'),
            const godInspirationHeader = createElement('div', 'list-header');
                group: this.extractFieldValue(baseContent, 'group'),
            const godInspirationTitle = createElement('div', 'list-title');
                rarity: this.extractFieldValue(baseContent, 'rarity'),
            godInspirationTitle.textContent = '神光一闪列表';
                god: this.extractFieldValue(baseContent, 'god'),
            godInspirationHeader.appendChild(godInspirationTitle);
                ap: this.extractFieldValue(baseContent, 'ap'),
            godInspirationSection.appendChild(godInspirationHeader);
                type: this.extractFieldValue(baseContent, 'type') || '攻击',
                dict: this.extractFieldValue(baseContent, 'dict'),
                desc_global: this.extractFieldValue(baseContent, 'desc_global').replace(/<br>/g, '\n'),
                sub: this.extractFieldValue(baseContent, 'sub'),
                isinspiration: baseContent.includes('isinspiration = 1'),
                isgod_inspiration: baseContent.includes('isgod_inspiration = 1'),
                inspirations: [],
                god_inspirations: {
                    circen: [],
                    diallos: [],
                    nihilum: [],
                    secred: [],
                    vitor: []
                }
            };
              
              
             this.cards[cardName] = card;
             // 神明选择标签
        }
            const godSelectGroup = createElement('div', 'god-select-group');
 
            ['凯尔肯', '戴奥斯', '尼希隆', '赛克瑞德', '维托'].forEach(god => {
        parseInspirations(cardName, content) {
                const godTab = createElement('div', 'god-tab' + (state.currentGod === god ? ' active' : ''));
             if (!this.cards[cardName]) return;
                godTab.textContent = god;
                godTab.addEventListener('click', () => {
                    state.currentGod = god;
                    renderWithoutScroll();
                });
                godSelectGroup.appendChild(godTab);
             });
            godInspirationSection.appendChild(godSelectGroup);
              
              
             // 分割成单个灵光一闪变体
             // 当前神明的神光一闪列表
             const variants = this.splitVariants(content);
             const currentGodInspirations = state.currentCard.var.god_inspiration[state.currentGod];
              
              
             variants.forEach(variantContent => {
             const addGodInspirationBtn = createButton('+ 添加 ' + state.currentGod + ' 神光', 'btn-primary', () => {
                 const variant = {
                 const newIndex = currentGodInspirations.length;
                    ap: this.extractFieldValue(variantContent, 'ap'),
                currentGodInspirations.push(createEmptyVariant());
                    type: this.extractFieldValue(variantContent, 'type'),
                state.editMode = 'god_inspiration';
                    dict: this.extractFieldValue(variantContent, 'dict'),
                state.currentGodInspirationIndex = newIndex;
                    desc_global: this.extractFieldValue(variantContent, 'desc_global').replace(/<br>/g, '\n')
                 state.currentInspirationIndex = null;
                 };
                 render();
                 this.cards[cardName].inspirations.push(variant);
             });
             });
            addGodInspirationBtn.style.marginBottom = '10px';
            addGodInspirationBtn.style.width = '100%';
            godInspirationSection.appendChild(addGodInspirationBtn);
              
              
             console.log(`Card Manager: 卡牌 "${cardName}" 有 ${this.cards[cardName].inspirations.length} 个灵光一闪变体`);
             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);
         }
         }
 
       
         parseGodInspirations(cardName, godName, content) {
        manager.appendChild(listSection);
             if (!this.cards[cardName]) return;
       
        // 右侧预览区
        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 variants = this.splitVariants(content);
             const pageName = '模块:卡牌/' + state.currentFighter;
              
              
             variants.forEach(variantContent => {
             const loading = createElement('div', 'loading-indicator');
                const variant = {
            loading.textContent = '正在保存...';
                    ap: this.extractFieldValue(variantContent, 'ap'),
            document.body.appendChild(loading);
                    type: this.extractFieldValue(variantContent, 'type'),
                    dict: this.extractFieldValue(variantContent, 'dict'),
                    desc_global: this.extractFieldValue(variantContent, 'desc_global').replace(/<br>/g, '\n')
                };
                this.cards[cardName].god_inspirations[godName].push(variant);
            });
              
              
             console.log(`Card Manager: 卡牌 "${cardName}" 的神明 "${godName}" 有 ${this.cards[cardName].god_inspirations[godName].length} 个神光一闪变体`);
             try {
        }
                const api = new mw.Api();
 
                 await api.postWithToken('csrf', {
        splitVariants(content) {
                    action: 'edit',
            const variants = [];
                     title: pageName,
            const lines = content.split('\n');
                     text: code,
            let currentVariant = [];
                    summary: '通过卡牌管理器更新卡牌数据',
            let braceCount = 0;
                     contentmodel: 'Scribunto'
           
                });
            for (let line of lines) {
                 alert('保存成功!');
                 const trimmed = line.trim();
            } catch (error) {
               
                console.error('保存失败:', error);
                if (trimmed === '{') {
                alert('保存失败:' + error);
                     braceCount++;
            } finally {
                     if (braceCount === 1) {
                 if (loading.parentNode) {
                        currentVariant = [];
                     document.body.removeChild(loading);
                     }
                 } else if (trimmed === '},' || trimmed === '}') {
                    braceCount--;
                    if (braceCount === 0 && currentVariant.length > 0) {
                        variants.push(currentVariant.join('\n'));
                        currentVariant = [];
                    }
                 } else if (braceCount === 1) {
                     currentVariant.push(line);
                 }
                 }
             }
             }
        });
        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';
              
              
             return variants;
             const content = document.getElementById('mw-content-text');
            if (content) {
                content.insertBefore(container, content.firstChild);
            } else {
                document.body.appendChild(container);
            }
         }
         }
 
       
         extractFieldValue(content, fieldName) {
         const loading = createElement('div', 'loading-indicator');
             // 匹配 fieldName = "value" 格式
        loading.textContent = '正在初始化...';
             const pattern = new RegExp(`${fieldName}\\s*=\\s*"([^"]*)"`, 'i');
        document.body.appendChild(loading);
            const match = content.match(pattern);
       
            if (match) {
        try {
                return match[1];
             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];
                }
             }
             }
              
              
             // 匹配 fieldName = value 格式(数字)
             render();
            const numPattern = new RegExp(`${fieldName}\\s*=\\s*([\\d.]+)`, 'i');
        } catch (error) {
             const numMatch = content.match(numPattern);
            console.error('初始化失败:', error);
             if (numMatch) {
             alert('初始化失败:' + error.message);
                 return numMatch[1];
        } finally {
             if (loading.parentNode) {
                 document.body.removeChild(loading);
             }
             }
           
            return '';
        }
        copyCode() {
            const code = this.generateLuaCode();
            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('代码已复制到剪贴板!');
         }
         }
     }
     }
 
      
     // 初始化函数
    function initCardManager() {
        console.log('Card Manager: 准备启动');
        const manager = new CardManager();
        manager.init();
    }
 
    // 在页面加载完成后启动
     if (document.readyState === 'loading') {
     if (document.readyState === 'loading') {
         document.addEventListener('DOMContentLoaded', () => {
         document.addEventListener('DOMContentLoaded', init);
            mw.loader.using(['mediawiki.api']).then(initCardManager);
        });
     } else {
     } else {
         mw.loader.using(['mediawiki.api']).then(initCardManager);
         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
    };
    
})();