Better Loot Tracker

计算并展示掉落记录中强化和炼金行动的部分信息

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Better Loot Tracker
// @namespace    http://tampermonkey.net/
// @version      1.1.0
// @description  计算并展示掉落记录中强化和炼金行动的部分信息
// @author       PaperCat
// @match        https://www.milkywayidle.com/*
// @match        https://test.milkywayidle.com/*
// @match        https://milkywayidle.com/*
// @match        https://milkywayidlecn.com/*
// @match        https://www.milkywayidlecn.com/*
// @match        https://test.milkywayidlecn.com/*
// @require      https://cdnjs.cloudflare.com/ajax/libs/mathjs/10.6.4/math.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/libs/lz-string.min.js
// @license      MIT
// @grant        none
// ==/UserScript==

/*
    此插件依赖 MWITools 的市场数据,请确保已安装 MWITools:
    This plugin depends on MWITools for market data. Please install MWITools:
    https://greasyfork.org/en/scripts/494467-mwitools
*/

(function() {
    'use strict';

    const userLanguage = localStorage.getItem('i18nextLng');
    const isZH = userLanguage?.startsWith("zh");

    // ======================
    // 国际化文本
    // ======================
    const i18n = {
        zh: {
            success: '成功',
            failure: '失败',
            target: '目标',
            protectLevel: '保护等级',
            preferredLevels: '偏好等级',
            superEnhanceMinLevel: '超级强化最低起始等级',
            globalSettings: '全局设置',
            alchemyPriceMode: '炼金价格选择',
            alchemyPriceAskBid: '左买右卖',
            alchemyPriceBidAsk: '右买左卖',
            alchemyPriceAskAsk: '左买左卖',
            alchemyPriceBidBid: '右买右卖',
            autoOptimal: '自动(最优)',
            treatAsSuccess: '视为成功',
            material: '材料',
            protection: '保护',
            total: '总消耗',
            superSpend: '强化消耗',
            alchemyCost: '成本',
            alchemyOutput: '产出',
            alchemyProfit: '收益',
            originalCost: '原始成本',
            finalValue: '最终价值',
            profit: '收益',
            aboveExpected: '高于期望',
            belowExpected: '低于期望',
            expected: '期望',
            noMarketData: '市场数据未加载,请确保已安装MWITools'
        },
        en: {
            success: 'Success',
            failure: 'Failure',
            target: 'Target',
            protectLevel: 'Protect Level',
            preferredLevels: 'Preferred Levels',
            superEnhanceMinLevel: 'Super Enhance Min Start',
            globalSettings: 'Global Settings',
            alchemyPriceMode: 'Alchemy Price Mode',
            alchemyPriceAskBid: 'Ask/ Bid',
            alchemyPriceBidAsk: 'Bid/ Ask',
            alchemyPriceAskAsk: 'Ask/ Ask',
            alchemyPriceBidBid: 'Bid/ Bid',
            autoOptimal: 'Auto(Optimal)',
            treatAsSuccess: 'Treat as Success',
            material: 'Material',
            protection: 'Protect',
            total: 'Total',
            superSpend: 'Enhance Spend',
            alchemyCost: 'Cost',
            alchemyOutput: 'Output',
            alchemyProfit: 'Profit',
            originalCost: 'Original Cost',
            finalValue: 'Final Value',
            profit: 'Profit',
            aboveExpected: 'Above expected',
            belowExpected: 'Below expected',
            expected: 'Expected',
            noMarketData: 'Market data not loaded, please ensure MWITools is installed'
        }
    };
    
    const t = isZH ? i18n.zh : i18n.en;
    const DEBUG = {
        init: true,
        calc: false
    };

    const logInit = (...args) => {
        if (DEBUG.init) console.log(...args);
    };

    const logCalc = (...args) => {
        if (DEBUG.calc) console.log(...args);
    };

    const LOOT_LOG_PANEL_SELECTOR = '.LootLogPanel_lootLogPanel__2013X';
    const LOOT_LOG_LIST_SELECTOR = '.LootLogPanel_actionLoots__3oTid';
    const LOOT_LOG_ITEM_SELECTOR = '.LootLogPanel_actionLoot__32gl_';
    const REFRESH_BUTTON_SELECTOR = 'button.Button_button__1Fe9z';

    const PREFERENCE_LEVELS_KEY = 'EnhancementLootTracker_preference_levels';
    const SUPER_ENHANCE_MIN_KEY = 'EnhancementLootTracker_super_min_start_level';
    const ALCHEMY_PRICE_MODE_KEY = 'EnhancementLootTracker_alchemy_price_mode';
    const ALCHEMY_PRICE_MODES = ['ask_bid', 'bid_ask', 'ask_ask', 'bid_bid'];
    let globalPreferenceText = localStorage.getItem(PREFERENCE_LEVELS_KEY) || '';
    let globalSuperEnhanceMinLevel = Number(localStorage.getItem(SUPER_ENHANCE_MIN_KEY));
    let globalAlchemyPriceMode = localStorage.getItem(ALCHEMY_PRICE_MODE_KEY) || 'ask_bid';
    if (!Number.isFinite(globalSuperEnhanceMinLevel) || globalSuperEnhanceMinLevel < 0) {
        globalSuperEnhanceMinLevel = 5;
    }
    if (!ALCHEMY_PRICE_MODES.includes(globalAlchemyPriceMode)) {
        globalAlchemyPriceMode = 'ask_bid';
    }

    function getGlobalPreferenceLevels() {
        return parsePreferenceLevels(globalPreferenceText);
    }

    function setGlobalPreferenceText(text) {
        globalPreferenceText = text || '';
        localStorage.setItem(PREFERENCE_LEVELS_KEY, globalPreferenceText);
    }

    function getSuperEnhanceMinLevel() {
        return globalSuperEnhanceMinLevel;
    }

    function setSuperEnhanceMinLevel(value) {
        const parsed = Number(value);
        if (!Number.isFinite(parsed)) return;
        const normalized = Math.min(Math.max(Math.round(parsed), 0), 20);
        globalSuperEnhanceMinLevel = normalized;
        localStorage.setItem(SUPER_ENHANCE_MIN_KEY, String(normalized));
    }

    function getAlchemyPriceMode() {
        return globalAlchemyPriceMode;
    }

    function setAlchemyPriceMode(value) {
        if (!ALCHEMY_PRICE_MODES.includes(value)) return;
        globalAlchemyPriceMode = value;
        localStorage.setItem(ALCHEMY_PRICE_MODE_KEY, value);
    }

    function getLootLogContainer() {
        return document.querySelector(LOOT_LOG_LIST_SELECTOR);
    }

    function setupRefreshButtonHook() {
        const panel = document.querySelector(LOOT_LOG_PANEL_SELECTOR);
        if (!panel) return;

        const refreshButton = panel.querySelector(REFRESH_BUTTON_SELECTOR);
        if (!refreshButton || refreshButton.dataset.eltBound === '1') return;

        refreshButton.dataset.eltBound = '1';
        refreshButton.addEventListener('click', () => {
            setTimeout(() => processLootLogs({ force: true }), 0);
        });
    }

    // ======================
    // 数据访问帮助函数
    // ======================

    function decompressInitClientData(compressedData) {
        try {
            const decompressedJson = LZString.decompressFromUTF16(compressedData);
            if (!decompressedJson) {
                throw new Error("decompressInitClientData: decompressFromUTF16() returned null");
            }
            return JSON.parse(decompressedJson);
        } catch (error) {
            console.error("[Better Loot Tracker] decompressInitClientData: ", error);
            return null;
        }
    }

    let _cachedInitClientData = null;

    function getInitClientData() {
        if (_cachedInitClientData) return _cachedInitClientData;
        
        const stored = localStorage.getItem("initClientData");
        if (!stored) return null;
        
        // 解压缩
        const decompressed = decompressInitClientData(stored);
        if (decompressed) {
            _cachedInitClientData = decompressed;
            return decompressed;
        }
        
        return null;
    }

    // 获取市场数据 (来自MWITools)
    function getMarketData() {
        try {
            const marketDataStr = localStorage.getItem('MWITools_marketAPI_json');
            if (marketDataStr) {
                return JSON.parse(marketDataStr);
            }
        } catch (e) {
            console.error('[Better Loot Tracker] Error loading market data:', e);
        }
        return null;
    }

    function getMarketPrice(itemHRID, marketData) {
        if (itemHRID === '/items/coin' || itemHRID === '/items/coins') return 1;
        if (!itemHRID || typeof itemHRID !== 'string') return 0;
        if (!marketData?.marketData) return 0;

        const marketRoot = marketData.marketData[itemHRID];
        if (!marketRoot) return 0;

        const priceObject = marketRoot["0"];
        if (!priceObject) return 0;

        return priceObject.a || priceObject.b || 0;
    }

    function getMarketPriceSide(itemHRID, marketData, side) {
        if (itemHRID === '/items/coin' || itemHRID === '/items/coins') return 1;
        if (!itemHRID || typeof itemHRID !== 'string') return 0;
        if (!marketData?.marketData) return 0;

        const marketRoot = marketData.marketData[itemHRID];
        if (!marketRoot) return 0;

        const priceObject = marketRoot["0"];
        if (!priceObject) return 0;

        if (side === 'bid') return priceObject.b || priceObject.a || 0;
        return priceObject.a || priceObject.b || 0;
    }

    /* 官方汉化 */
    const ZHItemNames = {
        "/items/coin": "金币",
        "/items/task_token": "任务代币",
        "/items/chimerical_token": "奇幻代币",
        "/items/sinister_token": "阴森代币",
        "/items/enchanted_token": "秘法代币",
        "/items/pirate_token": "海盗代币",
        "/items/cowbell": "牛铃",
        "/items/bag_of_10_cowbells": "牛铃袋 (10个)",
        "/items/purples_gift": "小紫牛的礼物",
        "/items/small_meteorite_cache": "小陨石舱",
        "/items/medium_meteorite_cache": "中陨石舱",
        "/items/large_meteorite_cache": "大陨石舱",
        "/items/small_artisans_crate": "小工匠匣",
        "/items/medium_artisans_crate": "中工匠匣",
        "/items/large_artisans_crate": "大工匠匣",
        "/items/small_treasure_chest": "小宝箱",
        "/items/medium_treasure_chest": "中宝箱",
        "/items/large_treasure_chest": "大宝箱",
        "/items/chimerical_chest": "奇幻宝箱",
        "/items/chimerical_refinement_chest": "奇幻精炼宝箱",
        "/items/sinister_chest": "阴森宝箱",
        "/items/sinister_refinement_chest": "阴森精炼宝箱",
        "/items/enchanted_chest": "秘法宝箱",
        "/items/enchanted_refinement_chest": "秘法精炼宝箱",
        "/items/pirate_chest": "海盗宝箱",
        "/items/pirate_refinement_chest": "海盗精炼宝箱",
        "/items/blue_key_fragment": "蓝色钥匙碎片",
        "/items/green_key_fragment": "绿色钥匙碎片",
        "/items/purple_key_fragment": "紫色钥匙碎片",
        "/items/white_key_fragment": "白色钥匙碎片",
        "/items/orange_key_fragment": "橙色钥匙碎片",
        "/items/brown_key_fragment": "棕色钥匙碎片",
        "/items/stone_key_fragment": "石头钥匙碎片",
        "/items/dark_key_fragment": "黑暗钥匙碎片",
        "/items/burning_key_fragment": "燃烧钥匙碎片",
        "/items/chimerical_entry_key": "奇幻钥匙",
        "/items/chimerical_chest_key": "奇幻宝箱钥匙",
        "/items/sinister_entry_key": "阴森钥匙",
        "/items/sinister_chest_key": "阴森宝箱钥匙",
        "/items/enchanted_entry_key": "秘法钥匙",
        "/items/enchanted_chest_key": "秘法宝箱钥匙",
        "/items/pirate_entry_key": "海盗钥匙",
        "/items/pirate_chest_key": "海盗宝箱钥匙",
        "/items/donut": "甜甜圈",
        "/items/blueberry_donut": "蓝莓甜甜圈",
        "/items/blackberry_donut": "黑莓甜甜圈",
        "/items/strawberry_donut": "草莓甜甜圈",
        "/items/mooberry_donut": "哞莓甜甜圈",
        "/items/marsberry_donut": "火星莓甜甜圈",
        "/items/spaceberry_donut": "太空莓甜甜圈",
        "/items/cupcake": "纸杯蛋糕",
        "/items/blueberry_cake": "蓝莓蛋糕",
        "/items/blackberry_cake": "黑莓蛋糕",
        "/items/strawberry_cake": "草莓蛋糕",
        "/items/mooberry_cake": "哞莓蛋糕",
        "/items/marsberry_cake": "火星莓蛋糕",
        "/items/spaceberry_cake": "太空莓蛋糕",
        "/items/gummy": "软糖",
        "/items/apple_gummy": "苹果软糖",
        "/items/orange_gummy": "橙子软糖",
        "/items/plum_gummy": "李子软糖",
        "/items/peach_gummy": "桃子软糖",
        "/items/dragon_fruit_gummy": "火龙果软糖",
        "/items/star_fruit_gummy": "杨桃软糖",
        "/items/yogurt": "酸奶",
        "/items/apple_yogurt": "苹果酸奶",
        "/items/orange_yogurt": "橙子酸奶",
        "/items/plum_yogurt": "李子酸奶",
        "/items/peach_yogurt": "桃子酸奶",
        "/items/dragon_fruit_yogurt": "火龙果酸奶",
        "/items/star_fruit_yogurt": "杨桃酸奶",
        "/items/milking_tea": "挤奶茶",
        "/items/foraging_tea": "采摘茶",
        "/items/woodcutting_tea": "伐木茶",
        "/items/cooking_tea": "烹饪茶",
        "/items/brewing_tea": "冲泡茶",
        "/items/alchemy_tea": "炼金茶",
        "/items/enhancing_tea": "强化茶",
        "/items/cheesesmithing_tea": "奶酪锻造茶",
        "/items/crafting_tea": "制作茶",
        "/items/tailoring_tea": "缝纫茶",
        "/items/super_milking_tea": "超级挤奶茶",
        "/items/super_foraging_tea": "超级采摘茶",
        "/items/super_woodcutting_tea": "超级伐木茶",
        "/items/super_cooking_tea": "超级烹饪茶",
        "/items/super_brewing_tea": "超级冲泡茶",
        "/items/super_alchemy_tea": "超级炼金茶",
        "/items/super_enhancing_tea": "超级强化茶",
        "/items/super_cheesesmithing_tea": "超级奶酪锻造茶",
        "/items/super_crafting_tea": "超级制作茶",
        "/items/super_tailoring_tea": "超级缝纫茶",
        "/items/ultra_milking_tea": "究极挤奶茶",
        "/items/ultra_foraging_tea": "究极采摘茶",
        "/items/ultra_woodcutting_tea": "究极伐木茶",
        "/items/ultra_cooking_tea": "究极烹饪茶",
        "/items/ultra_brewing_tea": "究极冲泡茶",
        "/items/ultra_alchemy_tea": "究极炼金茶",
        "/items/ultra_enhancing_tea": "究极强化茶",
        "/items/ultra_cheesesmithing_tea": "究极奶酪锻造茶",
        "/items/ultra_crafting_tea": "究极制作茶",
        "/items/ultra_tailoring_tea": "究极缝纫茶",
        "/items/gathering_tea": "采集茶",
        "/items/gourmet_tea": "美食茶",
        "/items/wisdom_tea": "经验茶",
        "/items/processing_tea": "加工茶",
        "/items/efficiency_tea": "效率茶",
        "/items/artisan_tea": "工匠茶",
        "/items/catalytic_tea": "催化茶",
        "/items/blessed_tea": "福气茶",
        "/items/stamina_coffee": "耐力咖啡",
        "/items/intelligence_coffee": "智力咖啡",
        "/items/defense_coffee": "防御咖啡",
        "/items/attack_coffee": "攻击咖啡",
        "/items/melee_coffee": "近战咖啡",
        "/items/ranged_coffee": "远程咖啡",
        "/items/magic_coffee": "魔法咖啡",
        "/items/super_stamina_coffee": "超级耐力咖啡",
        "/items/super_intelligence_coffee": "超级智力咖啡",
        "/items/super_defense_coffee": "超级防御咖啡",
        "/items/super_attack_coffee": "超级攻击咖啡",
        "/items/super_melee_coffee": "超级近战咖啡",
        "/items/super_ranged_coffee": "超级远程咖啡",
        "/items/super_magic_coffee": "超级魔法咖啡",
        "/items/ultra_stamina_coffee": "究极耐力咖啡",
        "/items/ultra_intelligence_coffee": "究极智力咖啡",
        "/items/ultra_defense_coffee": "究极防御咖啡",
        "/items/ultra_attack_coffee": "究极攻击咖啡",
        "/items/ultra_melee_coffee": "究极近战咖啡",
        "/items/ultra_ranged_coffee": "究极远程咖啡",
        "/items/ultra_magic_coffee": "究极魔法咖啡",
        "/items/wisdom_coffee": "经验咖啡",
        "/items/lucky_coffee": "幸运咖啡",
        "/items/swiftness_coffee": "迅捷咖啡",
        "/items/channeling_coffee": "吟唱咖啡",
        "/items/critical_coffee": "暴击咖啡",
        "/items/poke": "破胆之刺",
        "/items/impale": "透骨之刺",
        "/items/puncture": "破甲之刺",
        "/items/penetrating_strike": "贯心之刺",
        "/items/scratch": "爪影斩",
        "/items/cleave": "分裂斩",
        "/items/maim": "血刃斩",
        "/items/crippling_slash": "致残斩",
        "/items/smack": "重碾",
        "/items/sweep": "重扫",
        "/items/stunning_blow": "重锤",
        "/items/fracturing_impact": "碎裂冲击",
        "/items/shield_bash": "盾击",
        "/items/quick_shot": "快速射击",
        "/items/aqua_arrow": "流水箭",
        "/items/flame_arrow": "烈焰箭",
        "/items/rain_of_arrows": "箭雨",
        "/items/silencing_shot": "沉默之箭",
        "/items/steady_shot": "稳定射击",
        "/items/pestilent_shot": "疫病射击",
        "/items/penetrating_shot": "贯穿射击",
        "/items/water_strike": "流水冲击",
        "/items/ice_spear": "冰枪术",
        "/items/frost_surge": "冰霜爆裂",
        "/items/mana_spring": "法力喷泉",
        "/items/entangle": "缠绕",
        "/items/toxic_pollen": "剧毒粉尘",
        "/items/natures_veil": "自然菌幕",
        "/items/life_drain": "生命吸取",
        "/items/fireball": "火球",
        "/items/flame_blast": "熔岩爆裂",
        "/items/firestorm": "火焰风暴",
        "/items/smoke_burst": "烟爆灭影",
        "/items/minor_heal": "初级自愈术",
        "/items/heal": "自愈术",
        "/items/quick_aid": "快速治疗术",
        "/items/rejuvenate": "群体治疗术",
        "/items/taunt": "嘲讽",
        "/items/provoke": "挑衅",
        "/items/toughness": "坚韧",
        "/items/elusiveness": "闪避",
        "/items/precision": "精确",
        "/items/berserk": "狂暴",
        "/items/elemental_affinity": "元素增幅",
        "/items/frenzy": "狂速",
        "/items/spike_shell": "尖刺防护",
        "/items/retribution": "惩戒",
        "/items/vampirism": "吸血",
        "/items/revive": "复活",
        "/items/insanity": "疯狂",
        "/items/invincible": "无敌",
        "/items/speed_aura": "速度光环",
        "/items/guardian_aura": "守护光环",
        "/items/fierce_aura": "物理光环",
        "/items/critical_aura": "暴击光环",
        "/items/mystic_aura": "元素光环",
        "/items/gobo_stabber": "哥布林长剑",
        "/items/gobo_slasher": "哥布林关刀",
        "/items/gobo_smasher": "哥布林狼牙棒",
        "/items/spiked_bulwark": "尖刺重盾",
        "/items/werewolf_slasher": "狼人关刀",
        "/items/griffin_bulwark": "狮鹫重盾",
        "/items/griffin_bulwark_refined": "狮鹫重盾(精)",
        "/items/gobo_shooter": "哥布林弹弓",
        "/items/vampiric_bow": "吸血弓",
        "/items/cursed_bow": "咒怨之弓",
        "/items/cursed_bow_refined": "咒怨之弓(精)",
        "/items/gobo_boomstick": "哥布林火棍",
        "/items/cheese_bulwark": "奶酪重盾",
        "/items/verdant_bulwark": "翠绿重盾",
        "/items/azure_bulwark": "蔚蓝重盾",
        "/items/burble_bulwark": "深紫重盾",
        "/items/crimson_bulwark": "绛红重盾",
        "/items/rainbow_bulwark": "彩虹重盾",
        "/items/holy_bulwark": "神圣重盾",
        "/items/wooden_bow": "木弓",
        "/items/birch_bow": "桦木弓",
        "/items/cedar_bow": "雪松弓",
        "/items/purpleheart_bow": "紫心弓",
        "/items/ginkgo_bow": "银杏弓",
        "/items/redwood_bow": "红杉弓",
        "/items/arcane_bow": "神秘弓",
        "/items/stalactite_spear": "石钟长枪",
        "/items/granite_bludgeon": "花岗岩大棒",
        "/items/furious_spear": "狂怒长枪",
        "/items/furious_spear_refined": "狂怒长枪(精)",
        "/items/regal_sword": "君王之剑",
        "/items/regal_sword_refined": "君王之剑(精)",
        "/items/chaotic_flail": "混沌连枷",
        "/items/chaotic_flail_refined": "混沌连枷(精)",
        "/items/soul_hunter_crossbow": "灵魂猎手弩",
        "/items/sundering_crossbow": "裂空之弩",
        "/items/sundering_crossbow_refined": "裂空之弩(精)",
        "/items/frost_staff": "冰霜法杖",
        "/items/infernal_battlestaff": "炼狱法杖",
        "/items/jackalope_staff": "鹿角兔之杖",
        "/items/rippling_trident": "涟漪三叉戟",
        "/items/rippling_trident_refined": "涟漪三叉戟(精)",
        "/items/blooming_trident": "绽放三叉戟",
        "/items/blooming_trident_refined": "绽放三叉戟(精)",
        "/items/blazing_trident": "炽焰三叉戟",
        "/items/blazing_trident_refined": "炽焰三叉戟(精)",
        "/items/cheese_sword": "奶酪剑",
        "/items/verdant_sword": "翠绿剑",
        "/items/azure_sword": "蔚蓝剑",
        "/items/burble_sword": "深紫剑",
        "/items/crimson_sword": "绛红剑",
        "/items/rainbow_sword": "彩虹剑",
        "/items/holy_sword": "神圣剑",
        "/items/cheese_spear": "奶酪长枪",
        "/items/verdant_spear": "翠绿长枪",
        "/items/azure_spear": "蔚蓝长枪",
        "/items/burble_spear": "深紫长枪",
        "/items/crimson_spear": "绛红长枪",
        "/items/rainbow_spear": "彩虹长枪",
        "/items/holy_spear": "神圣长枪",
        "/items/cheese_mace": "奶酪钉头锤",
        "/items/verdant_mace": "翠绿钉头锤",
        "/items/azure_mace": "蔚蓝钉头锤",
        "/items/burble_mace": "深紫钉头锤",
        "/items/crimson_mace": "绛红钉头锤",
        "/items/rainbow_mace": "彩虹钉头锤",
        "/items/holy_mace": "神圣钉头锤",
        "/items/wooden_crossbow": "木弩",
        "/items/birch_crossbow": "桦木弩",
        "/items/cedar_crossbow": "雪松弩",
        "/items/purpleheart_crossbow": "紫心弩",
        "/items/ginkgo_crossbow": "银杏弩",
        "/items/redwood_crossbow": "红杉弩",
        "/items/arcane_crossbow": "神秘弩",
        "/items/wooden_water_staff": "木制水法杖",
        "/items/birch_water_staff": "桦木水法杖",
        "/items/cedar_water_staff": "雪松水法杖",
        "/items/purpleheart_water_staff": "紫心水法杖",
        "/items/ginkgo_water_staff": "银杏水法杖",
        "/items/redwood_water_staff": "红杉水法杖",
        "/items/arcane_water_staff": "神秘水法杖",
        "/items/wooden_nature_staff": "木制自然法杖",
        "/items/birch_nature_staff": "桦木自然法杖",
        "/items/cedar_nature_staff": "雪松自然法杖",
        "/items/purpleheart_nature_staff": "紫心自然法杖",
        "/items/ginkgo_nature_staff": "银杏自然法杖",
        "/items/redwood_nature_staff": "红杉自然法杖",
        "/items/arcane_nature_staff": "神秘自然法杖",
        "/items/wooden_fire_staff": "木制火法杖",
        "/items/birch_fire_staff": "桦木火法杖",
        "/items/cedar_fire_staff": "雪松火法杖",
        "/items/purpleheart_fire_staff": "紫心火法杖",
        "/items/ginkgo_fire_staff": "银杏火法杖",
        "/items/redwood_fire_staff": "红杉火法杖",
        "/items/arcane_fire_staff": "神秘火法杖",
        "/items/eye_watch": "掌上监工",
        "/items/snake_fang_dirk": "蛇牙短剑",
        "/items/vision_shield": "视觉盾",
        "/items/gobo_defender": "哥布林防御者",
        "/items/vampire_fang_dirk": "吸血鬼短剑",
        "/items/knights_aegis": "骑士盾",
        "/items/knights_aegis_refined": "骑士盾(精)",
        "/items/treant_shield": "树人盾",
        "/items/manticore_shield": "蝎狮盾",
        "/items/tome_of_healing": "治疗之书",
        "/items/tome_of_the_elements": "元素之书",
        "/items/watchful_relic": "警戒遗物",
        "/items/bishops_codex": "主教法典",
        "/items/bishops_codex_refined": "主教法典(精)",
        "/items/cheese_buckler": "奶酪圆盾",
        "/items/verdant_buckler": "翠绿圆盾",
        "/items/azure_buckler": "蔚蓝圆盾",
        "/items/burble_buckler": "深紫圆盾",
        "/items/crimson_buckler": "绛红圆盾",
        "/items/rainbow_buckler": "彩虹圆盾",
        "/items/holy_buckler": "神圣圆盾",
        "/items/wooden_shield": "木盾",
        "/items/birch_shield": "桦木盾",
        "/items/cedar_shield": "雪松盾",
        "/items/purpleheart_shield": "紫心盾",
        "/items/ginkgo_shield": "银杏盾",
        "/items/redwood_shield": "红杉盾",
        "/items/arcane_shield": "神秘盾",
        "/items/sinister_cape": "阴森斗篷",
        "/items/sinister_cape_refined": "阴森斗篷(精)",
        "/items/chimerical_quiver": "奇幻箭袋",
        "/items/chimerical_quiver_refined": "奇幻箭袋(精)",
        "/items/enchanted_cloak": "秘法披风",
        "/items/enchanted_cloak_refined": "秘法披风(精)",
        "/items/red_culinary_hat": "红色厨师帽",
        "/items/snail_shell_helmet": "蜗牛壳头盔",
        "/items/vision_helmet": "视觉头盔",
        "/items/fluffy_red_hat": "蓬松红帽子",
        "/items/corsair_helmet": "掠夺者头盔",
        "/items/corsair_helmet_refined": "掠夺者头盔(精)",
        "/items/acrobatic_hood": "杂技师兜帽",
        "/items/acrobatic_hood_refined": "杂技师兜帽(精)",
        "/items/magicians_hat": "魔术师帽",
        "/items/magicians_hat_refined": "魔术师帽(精)",
        "/items/cheese_helmet": "奶酪头盔",
        "/items/verdant_helmet": "翠绿头盔",
        "/items/azure_helmet": "蔚蓝头盔",
        "/items/burble_helmet": "深紫头盔",
        "/items/crimson_helmet": "绛红头盔",
        "/items/rainbow_helmet": "彩虹头盔",
        "/items/holy_helmet": "神圣头盔",
        "/items/rough_hood": "粗糙兜帽",
        "/items/reptile_hood": "爬行动物兜帽",
        "/items/gobo_hood": "哥布林兜帽",
        "/items/beast_hood": "野兽兜帽",
        "/items/umbral_hood": "暗影兜帽",
        "/items/cotton_hat": "棉帽",
        "/items/linen_hat": "亚麻帽",
        "/items/bamboo_hat": "竹帽",
        "/items/silk_hat": "丝帽",
        "/items/radiant_hat": "光辉帽",
        "/items/dairyhands_top": "挤奶工上衣",
        "/items/foragers_top": "采摘者上衣",
        "/items/lumberjacks_top": "伐木工上衣",
        "/items/cheesemakers_top": "奶酪师上衣",
        "/items/crafters_top": "工匠上衣",
        "/items/tailors_top": "裁缝上衣",
        "/items/chefs_top": "厨师上衣",
        "/items/brewers_top": "饮品师上衣",
        "/items/alchemists_top": "炼金师上衣",
        "/items/enhancers_top": "强化师上衣",
        "/items/gator_vest": "鳄鱼马甲",
        "/items/turtle_shell_body": "龟壳胸甲",
        "/items/colossus_plate_body": "巨像胸甲",
        "/items/demonic_plate_body": "恶魔胸甲",
        "/items/anchorbound_plate_body": "锚定胸甲",
        "/items/anchorbound_plate_body_refined": "锚定胸甲(精)",
        "/items/maelstrom_plate_body": "怒涛胸甲",
        "/items/maelstrom_plate_body_refined": "怒涛胸甲(精)",
        "/items/marine_tunic": "海洋皮衣",
        "/items/revenant_tunic": "亡灵皮衣",
        "/items/griffin_tunic": "狮鹫皮衣",
        "/items/kraken_tunic": "克拉肯皮衣",
        "/items/kraken_tunic_refined": "克拉肯皮衣(精)",
        "/items/icy_robe_top": "冰霜袍服",
        "/items/flaming_robe_top": "烈焰袍服",
        "/items/luna_robe_top": "月神袍服",
        "/items/royal_water_robe_top": "皇家水系袍服",
        "/items/royal_water_robe_top_refined": "皇家水系袍服(精)",
        "/items/royal_nature_robe_top": "皇家自然系袍服",
        "/items/royal_nature_robe_top_refined": "皇家自然系袍服(精)",
        "/items/royal_fire_robe_top": "皇家火系袍服",
        "/items/royal_fire_robe_top_refined": "皇家火系袍服(精)",
        "/items/cheese_plate_body": "奶酪胸甲",
        "/items/verdant_plate_body": "翠绿胸甲",
        "/items/azure_plate_body": "蔚蓝胸甲",
        "/items/burble_plate_body": "深紫胸甲",
        "/items/crimson_plate_body": "绛红胸甲",
        "/items/rainbow_plate_body": "彩虹胸甲",
        "/items/holy_plate_body": "神圣胸甲",
        "/items/rough_tunic": "粗糙皮衣",
        "/items/reptile_tunic": "爬行动物皮衣",
        "/items/gobo_tunic": "哥布林皮衣",
        "/items/beast_tunic": "野兽皮衣",
        "/items/umbral_tunic": "暗影皮衣",
        "/items/cotton_robe_top": "棉袍服",
        "/items/linen_robe_top": "亚麻袍服",
        "/items/bamboo_robe_top": "竹袍服",
        "/items/silk_robe_top": "丝绸袍服",
        "/items/radiant_robe_top": "光辉袍服",
        "/items/dairyhands_bottoms": "挤奶工下装",
        "/items/foragers_bottoms": "采摘者下装",
        "/items/lumberjacks_bottoms": "伐木工下装",
        "/items/cheesemakers_bottoms": "奶酪师下装",
        "/items/crafters_bottoms": "工匠下装",
        "/items/tailors_bottoms": "裁缝下装",
        "/items/chefs_bottoms": "厨师下装",
        "/items/brewers_bottoms": "饮品师下装",
        "/items/alchemists_bottoms": "炼金师下装",
        "/items/enhancers_bottoms": "强化师下装",
        "/items/turtle_shell_legs": "龟壳腿甲",
        "/items/colossus_plate_legs": "巨像腿甲",
        "/items/demonic_plate_legs": "恶魔腿甲",
        "/items/anchorbound_plate_legs": "锚定腿甲",
        "/items/anchorbound_plate_legs_refined": "锚定腿甲(精)",
        "/items/maelstrom_plate_legs": "怒涛腿甲",
        "/items/maelstrom_plate_legs_refined": "怒涛腿甲(精)",
        "/items/marine_chaps": "航海皮裤",
        "/items/revenant_chaps": "亡灵皮裤",
        "/items/griffin_chaps": "狮鹫皮裤",
        "/items/kraken_chaps": "克拉肯皮裤",
        "/items/kraken_chaps_refined": "克拉肯皮裤(精)",
        "/items/icy_robe_bottoms": "冰霜袍裙",
        "/items/flaming_robe_bottoms": "烈焰袍裙",
        "/items/luna_robe_bottoms": "月神袍裙",
        "/items/royal_water_robe_bottoms": "皇家水系袍裙",
        "/items/royal_water_robe_bottoms_refined": "皇家水系袍裙(精)",
        "/items/royal_nature_robe_bottoms": "皇家自然系袍裙",
        "/items/royal_nature_robe_bottoms_refined": "皇家自然系袍裙(精)",
        "/items/royal_fire_robe_bottoms": "皇家火系袍裙",
        "/items/royal_fire_robe_bottoms_refined": "皇家火系袍裙(精)",
        "/items/cheese_plate_legs": "奶酪腿甲",
        "/items/verdant_plate_legs": "翠绿腿甲",
        "/items/azure_plate_legs": "蔚蓝腿甲",
        "/items/burble_plate_legs": "深紫腿甲",
        "/items/crimson_plate_legs": "绛红腿甲",
        "/items/rainbow_plate_legs": "彩虹腿甲",
        "/items/holy_plate_legs": "神圣腿甲",
        "/items/rough_chaps": "粗糙皮裤",
        "/items/reptile_chaps": "爬行动物皮裤",
        "/items/gobo_chaps": "哥布林皮裤",
        "/items/beast_chaps": "野兽皮裤",
        "/items/umbral_chaps": "暗影皮裤",
        "/items/cotton_robe_bottoms": "棉袍裙",
        "/items/linen_robe_bottoms": "亚麻袍裙",
        "/items/bamboo_robe_bottoms": "竹袍裙",
        "/items/silk_robe_bottoms": "丝绸袍裙",
        "/items/radiant_robe_bottoms": "光辉袍裙",
        "/items/enchanted_gloves": "附魔手套",
        "/items/pincer_gloves": "蟹钳手套",
        "/items/panda_gloves": "熊猫手套",
        "/items/magnetic_gloves": "磁力手套",
        "/items/dodocamel_gauntlets": "渡渡驼护手",
        "/items/dodocamel_gauntlets_refined": "渡渡驼护手(精)",
        "/items/sighted_bracers": "瞄准护腕",
        "/items/marksman_bracers": "神射护腕",
        "/items/marksman_bracers_refined": "神射护腕(精)",
        "/items/chrono_gloves": "时空手套",
        "/items/cheese_gauntlets": "奶酪护手",
        "/items/verdant_gauntlets": "翠绿护手",
        "/items/azure_gauntlets": "蔚蓝护手",
        "/items/burble_gauntlets": "深紫护手",
        "/items/crimson_gauntlets": "绛红护手",
        "/items/rainbow_gauntlets": "彩虹护手",
        "/items/holy_gauntlets": "神圣护手",
        "/items/rough_bracers": "粗糙护腕",
        "/items/reptile_bracers": "爬行动物护腕",
        "/items/gobo_bracers": "哥布林护腕",
        "/items/beast_bracers": "野兽护腕",
        "/items/umbral_bracers": "暗影护腕",
        "/items/cotton_gloves": "棉手套",
        "/items/linen_gloves": "亚麻手套",
        "/items/bamboo_gloves": "竹手套",
        "/items/silk_gloves": "丝手套",
        "/items/radiant_gloves": "光辉手套",
        "/items/collectors_boots": "收藏家靴",
        "/items/shoebill_shoes": "鲸头鹳鞋",
        "/items/black_bear_shoes": "黑熊鞋",
        "/items/grizzly_bear_shoes": "棕熊鞋",
        "/items/polar_bear_shoes": "北极熊鞋",
        "/items/centaur_boots": "半人马靴",
        "/items/sorcerer_boots": "巫师靴",
        "/items/cheese_boots": "奶酪靴",
        "/items/verdant_boots": "翠绿靴",
        "/items/azure_boots": "蔚蓝靴",
        "/items/burble_boots": "深紫靴",
        "/items/crimson_boots": "绛红靴",
        "/items/rainbow_boots": "彩虹靴",
        "/items/holy_boots": "神圣靴",
        "/items/rough_boots": "粗糙靴",
        "/items/reptile_boots": "爬行动物靴",
        "/items/gobo_boots": "哥布林靴",
        "/items/beast_boots": "野兽靴",
        "/items/umbral_boots": "暗影靴",
        "/items/cotton_boots": "棉靴",
        "/items/linen_boots": "亚麻靴",
        "/items/bamboo_boots": "竹靴",
        "/items/silk_boots": "丝靴",
        "/items/radiant_boots": "光辉靴",
        "/items/small_pouch": "小袋子",
        "/items/medium_pouch": "中袋子",
        "/items/large_pouch": "大袋子",
        "/items/giant_pouch": "巨大袋子",
        "/items/gluttonous_pouch": "贪食之袋",
        "/items/guzzling_pouch": "暴饮之囊",
        "/items/necklace_of_efficiency": "效率项链",
        "/items/fighter_necklace": "战士项链",
        "/items/ranger_necklace": "射手项链",
        "/items/wizard_necklace": "巫师项链",
        "/items/necklace_of_wisdom": "经验项链",
        "/items/necklace_of_speed": "速度项链",
        "/items/philosophers_necklace": "贤者项链",
        "/items/earrings_of_gathering": "采集耳环",
        "/items/earrings_of_essence_find": "精华发现耳环",
        "/items/earrings_of_armor": "护甲耳环",
        "/items/earrings_of_regeneration": "恢复耳环",
        "/items/earrings_of_resistance": "抗性耳环",
        "/items/earrings_of_rare_find": "稀有发现耳环",
        "/items/earrings_of_critical_strike": "暴击耳环",
        "/items/philosophers_earrings": "贤者耳环",
        "/items/ring_of_gathering": "采集戒指",
        "/items/ring_of_essence_find": "精华发现戒指",
        "/items/ring_of_armor": "护甲戒指",
        "/items/ring_of_regeneration": "恢复戒指",
        "/items/ring_of_resistance": "抗性戒指",
        "/items/ring_of_rare_find": "稀有发现戒指",
        "/items/ring_of_critical_strike": "暴击戒指",
        "/items/philosophers_ring": "贤者戒指",
        "/items/trainee_milking_charm": "实习挤奶护符",
        "/items/basic_milking_charm": "基础挤奶护符",
        "/items/advanced_milking_charm": "高级挤奶护符",
        "/items/expert_milking_charm": "专家挤奶护符",
        "/items/master_milking_charm": "大师挤奶护符",
        "/items/grandmaster_milking_charm": "宗师挤奶护符",
        "/items/trainee_foraging_charm": "实习采摘护符",
        "/items/basic_foraging_charm": "基础采摘护符",
        "/items/advanced_foraging_charm": "高级采摘护符",
        "/items/expert_foraging_charm": "专家采摘护符",
        "/items/master_foraging_charm": "大师采摘护符",
        "/items/grandmaster_foraging_charm": "宗师采摘护符",
        "/items/trainee_woodcutting_charm": "实习伐木护符",
        "/items/basic_woodcutting_charm": "基础伐木护符",
        "/items/advanced_woodcutting_charm": "高级伐木护符",
        "/items/expert_woodcutting_charm": "专家伐木护符",
        "/items/master_woodcutting_charm": "大师伐木护符",
        "/items/grandmaster_woodcutting_charm": "宗师伐木护符",
        "/items/trainee_cheesesmithing_charm": "实习奶酪锻造护符",
        "/items/basic_cheesesmithing_charm": "基础奶酪锻造护符",
        "/items/advanced_cheesesmithing_charm": "高级奶酪锻造护符",
        "/items/expert_cheesesmithing_charm": "专家奶酪锻造护符",
        "/items/master_cheesesmithing_charm": "大师奶酪锻造护符",
        "/items/grandmaster_cheesesmithing_charm": "宗师奶酪锻造护符",
        "/items/trainee_crafting_charm": "实习制作护符",
        "/items/basic_crafting_charm": "基础制作护符",
        "/items/advanced_crafting_charm": "高级制作护符",
        "/items/expert_crafting_charm": "专家制作护符",
        "/items/master_crafting_charm": "大师制作护符",
        "/items/grandmaster_crafting_charm": "宗师制作护符",
        "/items/trainee_tailoring_charm": "实习缝纫护符",
        "/items/basic_tailoring_charm": "基础缝纫护符",
        "/items/advanced_tailoring_charm": "高级缝纫护符",
        "/items/expert_tailoring_charm": "专家缝纫护符",
        "/items/master_tailoring_charm": "大师缝纫护符",
        "/items/grandmaster_tailoring_charm": "宗师缝纫护符",
        "/items/trainee_cooking_charm": "实习烹饪护符",
        "/items/basic_cooking_charm": "基础烹饪护符",
        "/items/advanced_cooking_charm": "高级烹饪护符",
        "/items/expert_cooking_charm": "专家烹饪护符",
        "/items/master_cooking_charm": "大师烹饪护符",
        "/items/grandmaster_cooking_charm": "宗师烹饪护符",
        "/items/trainee_brewing_charm": "实习冲泡护符",
        "/items/basic_brewing_charm": "基础冲泡护符",
        "/items/advanced_brewing_charm": "高级冲泡护符",
        "/items/expert_brewing_charm": "专家冲泡护符",
        "/items/master_brewing_charm": "大师冲泡护符",
        "/items/grandmaster_brewing_charm": "宗师冲泡护符",
        "/items/trainee_alchemy_charm": "实习炼金护符",
        "/items/basic_alchemy_charm": "基础炼金护符",
        "/items/advanced_alchemy_charm": "高级炼金护符",
        "/items/expert_alchemy_charm": "专家炼金护符",
        "/items/master_alchemy_charm": "大师炼金护符",
        "/items/grandmaster_alchemy_charm": "宗师炼金护符",
        "/items/trainee_enhancing_charm": "实习强化护符",
        "/items/basic_enhancing_charm": "基础强化护符",
        "/items/advanced_enhancing_charm": "高级强化护符",
        "/items/expert_enhancing_charm": "专家强化护符",
        "/items/master_enhancing_charm": "大师强化护符",
        "/items/grandmaster_enhancing_charm": "宗师强化护符",
        "/items/trainee_stamina_charm": "实习耐力护符",
        "/items/basic_stamina_charm": "基础耐力护符",
        "/items/advanced_stamina_charm": "高级耐力护符",
        "/items/expert_stamina_charm": "专家耐力护符",
        "/items/master_stamina_charm": "大师耐力护符",
        "/items/grandmaster_stamina_charm": "宗师耐力护符",
        "/items/trainee_intelligence_charm": "实习智力护符",
        "/items/basic_intelligence_charm": "基础智力护符",
        "/items/advanced_intelligence_charm": "高级智力护符",
        "/items/expert_intelligence_charm": "专家智力护符",
        "/items/master_intelligence_charm": "大师智力护符",
        "/items/grandmaster_intelligence_charm": "宗师智力护符",
        "/items/trainee_attack_charm": "实习攻击护符",
        "/items/basic_attack_charm": "基础攻击护符",
        "/items/advanced_attack_charm": "高级攻击护符",
        "/items/expert_attack_charm": "专家攻击护符",
        "/items/master_attack_charm": "大师攻击护符",
        "/items/grandmaster_attack_charm": "宗师攻击护符",
        "/items/trainee_defense_charm": "实习防御护符",
        "/items/basic_defense_charm": "基础防御护符",
        "/items/advanced_defense_charm": "高级防御护符",
        "/items/expert_defense_charm": "专家防御护符",
        "/items/master_defense_charm": "大师防御护符",
        "/items/grandmaster_defense_charm": "宗师防御护符",
        "/items/trainee_melee_charm": "实习近战护符",
        "/items/basic_melee_charm": "基础近战护符",
        "/items/advanced_melee_charm": "高级近战护符",
        "/items/expert_melee_charm": "专家近战护符",
        "/items/master_melee_charm": "大师近战护符",
        "/items/grandmaster_melee_charm": "宗师近战护符",
        "/items/trainee_ranged_charm": "实习远程护符",
        "/items/basic_ranged_charm": "基础远程护符",
        "/items/advanced_ranged_charm": "高级远程护符",
        "/items/expert_ranged_charm": "专家远程护符",
        "/items/master_ranged_charm": "大师远程护符",
        "/items/grandmaster_ranged_charm": "宗师远程护符",
        "/items/trainee_magic_charm": "实习魔法护符",
        "/items/basic_magic_charm": "基础魔法护符",
        "/items/advanced_magic_charm": "高级魔法护符",
        "/items/expert_magic_charm": "专家魔法护符",
        "/items/master_magic_charm": "大师魔法护符",
        "/items/grandmaster_magic_charm": "宗师魔法护符",
        "/items/basic_task_badge": "基础任务徽章",
        "/items/advanced_task_badge": "高级任务徽章",
        "/items/expert_task_badge": "专家任务徽章",
        "/items/celestial_brush": "星空刷子",
        "/items/cheese_brush": "奶酪刷子",
        "/items/verdant_brush": "翠绿刷子",
        "/items/azure_brush": "蔚蓝刷子",
        "/items/burble_brush": "深紫刷子",
        "/items/crimson_brush": "绛红刷子",
        "/items/rainbow_brush": "彩虹刷子",
        "/items/holy_brush": "神圣刷子",
        "/items/celestial_shears": "星空剪刀",
        "/items/cheese_shears": "奶酪剪刀",
        "/items/verdant_shears": "翠绿剪刀",
        "/items/azure_shears": "蔚蓝剪刀",
        "/items/burble_shears": "深紫剪刀",
        "/items/crimson_shears": "绛红剪刀",
        "/items/rainbow_shears": "彩虹剪刀",
        "/items/holy_shears": "神圣剪刀",
        "/items/celestial_hatchet": "星空斧头",
        "/items/cheese_hatchet": "奶酪斧头",
        "/items/verdant_hatchet": "翠绿斧头",
        "/items/azure_hatchet": "蔚蓝斧头",
        "/items/burble_hatchet": "深紫斧头",
        "/items/crimson_hatchet": "绛红斧头",
        "/items/rainbow_hatchet": "彩虹斧头",
        "/items/holy_hatchet": "神圣斧头",
        "/items/celestial_hammer": "星空锤子",
        "/items/cheese_hammer": "奶酪锤子",
        "/items/verdant_hammer": "翠绿锤子",
        "/items/azure_hammer": "蔚蓝锤子",
        "/items/burble_hammer": "深紫锤子",
        "/items/crimson_hammer": "绛红锤子",
        "/items/rainbow_hammer": "彩虹锤子",
        "/items/holy_hammer": "神圣锤子",
        "/items/celestial_chisel": "星空凿子",
        "/items/cheese_chisel": "奶酪凿子",
        "/items/verdant_chisel": "翠绿凿子",
        "/items/azure_chisel": "蔚蓝凿子",
        "/items/burble_chisel": "深紫凿子",
        "/items/crimson_chisel": "绛红凿子",
        "/items/rainbow_chisel": "彩虹凿子",
        "/items/holy_chisel": "神圣凿子",
        "/items/celestial_needle": "星空针",
        "/items/cheese_needle": "奶酪针",
        "/items/verdant_needle": "翠绿针",
        "/items/azure_needle": "蔚蓝针",
        "/items/burble_needle": "深紫针",
        "/items/crimson_needle": "绛红针",
        "/items/rainbow_needle": "彩虹针",
        "/items/holy_needle": "神圣针",
        "/items/celestial_spatula": "星空锅铲",
        "/items/cheese_spatula": "奶酪锅铲",
        "/items/verdant_spatula": "翠绿锅铲",
        "/items/azure_spatula": "蔚蓝锅铲",
        "/items/burble_spatula": "深紫锅铲",
        "/items/crimson_spatula": "绛红锅铲",
        "/items/rainbow_spatula": "彩虹锅铲",
        "/items/holy_spatula": "神圣锅铲",
        "/items/celestial_pot": "星空壶",
        "/items/cheese_pot": "奶酪壶",
        "/items/verdant_pot": "翠绿壶",
        "/items/azure_pot": "蔚蓝壶",
        "/items/burble_pot": "深紫壶",
        "/items/crimson_pot": "绛红壶",
        "/items/rainbow_pot": "彩虹壶",
        "/items/holy_pot": "神圣壶",
        "/items/celestial_alembic": "星空蒸馏器",
        "/items/cheese_alembic": "奶酪蒸馏器",
        "/items/verdant_alembic": "翠绿蒸馏器",
        "/items/azure_alembic": "蔚蓝蒸馏器",
        "/items/burble_alembic": "深紫蒸馏器",
        "/items/crimson_alembic": "绛红蒸馏器",
        "/items/rainbow_alembic": "彩虹蒸馏器",
        "/items/holy_alembic": "神圣蒸馏器",
        "/items/celestial_enhancer": "星空强化器",
        "/items/cheese_enhancer": "奶酪强化器",
        "/items/verdant_enhancer": "翠绿强化器",
        "/items/azure_enhancer": "蔚蓝强化器",
        "/items/burble_enhancer": "深紫强化器",
        "/items/crimson_enhancer": "绛红强化器",
        "/items/rainbow_enhancer": "彩虹强化器",
        "/items/holy_enhancer": "神圣强化器",
        "/items/milk": "牛奶",
        "/items/verdant_milk": "翠绿牛奶",
        "/items/azure_milk": "蔚蓝牛奶",
        "/items/burble_milk": "深紫牛奶",
        "/items/crimson_milk": "绛红牛奶",
        "/items/rainbow_milk": "彩虹牛奶",
        "/items/holy_milk": "神圣牛奶",
        "/items/cheese": "奶酪",
        "/items/verdant_cheese": "翠绿奶酪",
        "/items/azure_cheese": "蔚蓝奶酪",
        "/items/burble_cheese": "深紫奶酪",
        "/items/crimson_cheese": "绛红奶酪",
        "/items/rainbow_cheese": "彩虹奶酪",
        "/items/holy_cheese": "神圣奶酪",
        "/items/log": "原木",
        "/items/birch_log": "白桦原木",
        "/items/cedar_log": "雪松原木",
        "/items/purpleheart_log": "紫心原木",
        "/items/ginkgo_log": "银杏原木",
        "/items/redwood_log": "红杉原木",
        "/items/arcane_log": "神秘原木",
        "/items/lumber": "木板",
        "/items/birch_lumber": "白桦木板",
        "/items/cedar_lumber": "雪松木板",
        "/items/purpleheart_lumber": "紫心木板",
        "/items/ginkgo_lumber": "银杏木板",
        "/items/redwood_lumber": "红杉木板",
        "/items/arcane_lumber": "神秘木板",
        "/items/rough_hide": "粗糙兽皮",
        "/items/reptile_hide": "爬行动物皮",
        "/items/gobo_hide": "哥布林皮",
        "/items/beast_hide": "野兽皮",
        "/items/umbral_hide": "暗影皮",
        "/items/rough_leather": "粗糙皮革",
        "/items/reptile_leather": "爬行动物皮革",
        "/items/gobo_leather": "哥布林皮革",
        "/items/beast_leather": "野兽皮革",
        "/items/umbral_leather": "暗影皮革",
        "/items/cotton": "棉花",
        "/items/flax": "亚麻",
        "/items/bamboo_branch": "竹子",
        "/items/cocoon": "蚕茧",
        "/items/radiant_fiber": "光辉纤维",
        "/items/cotton_fabric": "棉花布料",
        "/items/linen_fabric": "亚麻布料",
        "/items/bamboo_fabric": "竹子布料",
        "/items/silk_fabric": "丝绸",
        "/items/radiant_fabric": "光辉布料",
        "/items/egg": "鸡蛋",
        "/items/wheat": "小麦",
        "/items/sugar": "糖",
        "/items/blueberry": "蓝莓",
        "/items/blackberry": "黑莓",
        "/items/strawberry": "草莓",
        "/items/mooberry": "哞莓",
        "/items/marsberry": "火星莓",
        "/items/spaceberry": "太空莓",
        "/items/apple": "苹果",
        "/items/orange": "橙子",
        "/items/plum": "李子",
        "/items/peach": "桃子",
        "/items/dragon_fruit": "火龙果",
        "/items/star_fruit": "杨桃",
        "/items/arabica_coffee_bean": "低级咖啡豆",
        "/items/robusta_coffee_bean": "中级咖啡豆",
        "/items/liberica_coffee_bean": "高级咖啡豆",
        "/items/excelsa_coffee_bean": "特级咖啡豆",
        "/items/fieriosa_coffee_bean": "火山咖啡豆",
        "/items/spacia_coffee_bean": "太空咖啡豆",
        "/items/green_tea_leaf": "绿茶叶",
        "/items/black_tea_leaf": "黑茶叶",
        "/items/burble_tea_leaf": "紫茶叶",
        "/items/moolong_tea_leaf": "哞龙茶叶",
        "/items/red_tea_leaf": "红茶叶",
        "/items/emp_tea_leaf": "虚空茶叶",
        "/items/catalyst_of_coinification": "点金催化剂",
        "/items/catalyst_of_decomposition": "分解催化剂",
        "/items/catalyst_of_transmutation": "转化催化剂",
        "/items/prime_catalyst": "至高催化剂",
        "/items/snake_fang": "蛇牙",
        "/items/shoebill_feather": "鲸头鹳羽毛",
        "/items/snail_shell": "蜗牛壳",
        "/items/crab_pincer": "蟹钳",
        "/items/turtle_shell": "乌龟壳",
        "/items/marine_scale": "海洋鳞片",
        "/items/treant_bark": "树皮",
        "/items/centaur_hoof": "半人马蹄",
        "/items/luna_wing": "月神翼",
        "/items/gobo_rag": "哥布林抹布",
        "/items/goggles": "护目镜",
        "/items/magnifying_glass": "放大镜",
        "/items/eye_of_the_watcher": "观察者之眼",
        "/items/icy_cloth": "冰霜织物",
        "/items/flaming_cloth": "烈焰织物",
        "/items/sorcerers_sole": "魔法师鞋底",
        "/items/chrono_sphere": "时空球",
        "/items/frost_sphere": "冰霜球",
        "/items/panda_fluff": "熊猫绒",
        "/items/black_bear_fluff": "黑熊绒",
        "/items/grizzly_bear_fluff": "棕熊绒",
        "/items/polar_bear_fluff": "北极熊绒",
        "/items/red_panda_fluff": "小熊猫绒",
        "/items/magnet": "磁铁",
        "/items/stalactite_shard": "钟乳石碎片",
        "/items/living_granite": "花岗岩",
        "/items/colossus_core": "巨像核心",
        "/items/vampire_fang": "吸血鬼之牙",
        "/items/werewolf_claw": "狼人之爪",
        "/items/revenant_anima": "亡者之魂",
        "/items/soul_fragment": "灵魂碎片",
        "/items/infernal_ember": "地狱余烬",
        "/items/demonic_core": "恶魔核心",
        "/items/griffin_leather": "狮鹫之皮",
        "/items/manticore_sting": "蝎狮之刺",
        "/items/jackalope_antler": "鹿角兔之角",
        "/items/dodocamel_plume": "渡渡驼之翎",
        "/items/griffin_talon": "狮鹫之爪",
        "/items/chimerical_refinement_shard": "奇幻精炼碎片",
        "/items/acrobats_ribbon": "杂技师彩带",
        "/items/magicians_cloth": "魔术师织物",
        "/items/chaotic_chain": "混沌锁链",
        "/items/cursed_ball": "诅咒之球",
        "/items/sinister_refinement_shard": "阴森精炼碎片",
        "/items/royal_cloth": "皇家织物",
        "/items/knights_ingot": "骑士之锭",
        "/items/bishops_scroll": "主教卷轴",
        "/items/regal_jewel": "君王宝石",
        "/items/sundering_jewel": "裂空宝石",
        "/items/enchanted_refinement_shard": "秘法精炼碎片",
        "/items/marksman_brooch": "神射胸针",
        "/items/corsair_crest": "掠夺者徽章",
        "/items/damaged_anchor": "破损船锚",
        "/items/maelstrom_plating": "怒涛甲片",
        "/items/kraken_leather": "克拉肯皮革",
        "/items/kraken_fang": "克拉肯之牙",
        "/items/pirate_refinement_shard": "海盗精炼碎片",
        "/items/butter_of_proficiency": "精通之油",
        "/items/thread_of_expertise": "专精之线",
        "/items/branch_of_insight": "洞察之枝",
        "/items/gluttonous_energy": "贪食能量",
        "/items/guzzling_energy": "暴饮能量",
        "/items/milking_essence": "挤奶精华",
        "/items/foraging_essence": "采摘精华",
        "/items/woodcutting_essence": "伐木精华",
        "/items/cheesesmithing_essence": "奶酪锻造精华",
        "/items/crafting_essence": "制作精华",
        "/items/tailoring_essence": "缝纫精华",
        "/items/cooking_essence": "烹饪精华",
        "/items/brewing_essence": "冲泡精华",
        "/items/alchemy_essence": "炼金精华",
        "/items/enhancing_essence": "强化精华",
        "/items/swamp_essence": "沼泽精华",
        "/items/aqua_essence": "海洋精华",
        "/items/jungle_essence": "丛林精华",
        "/items/gobo_essence": "哥布林精华",
        "/items/eyessence": "眼精华",
        "/items/sorcerer_essence": "法师精华",
        "/items/bear_essence": "熊熊精华",
        "/items/golem_essence": "魔像精华",
        "/items/twilight_essence": "暮光精华",
        "/items/abyssal_essence": "地狱精华",
        "/items/chimerical_essence": "奇幻精华",
        "/items/sinister_essence": "阴森精华",
        "/items/enchanted_essence": "秘法精华",
        "/items/pirate_essence": "海盗精华",
        "/items/task_crystal": "任务水晶",
        "/items/star_fragment": "星光碎片",
        "/items/pearl": "珍珠",
        "/items/amber": "琥珀",
        "/items/garnet": "石榴石",
        "/items/jade": "翡翠",
        "/items/amethyst": "紫水晶",
        "/items/moonstone": "月亮石",
        "/items/sunstone": "太阳石",
        "/items/philosophers_stone": "贤者之石",
        "/items/crushed_pearl": "珍珠碎片",
        "/items/crushed_amber": "琥珀碎片",
        "/items/crushed_garnet": "石榴石碎片",
        "/items/crushed_jade": "翡翠碎片",
        "/items/crushed_amethyst": "紫水晶碎片",
        "/items/crushed_moonstone": "月亮石碎片",
        "/items/crushed_sunstone": "太阳石碎片",
        "/items/crushed_philosophers_stone": "贤者之石碎片",
        "/items/shard_of_protection": "保护碎片",
        "/items/mirror_of_protection": "保护之镜",
        "/items/philosophers_mirror": "贤者之镜",
    };
    // ======================
    // 物品名称映射
    // ======================

    let itemNameToHrid = {};
    let itemHridToName = {};
    let zhNameToHrid = {};

    function buildItemMaps() {
        if (!itemDetailMap) {
            const initData = getInitClientData();
            if (initData?.itemDetailMap) {
                itemDetailMap = initData.itemDetailMap;
            } else {
                logInit('[Better Loot Tracker] No itemDetailMap available for building item maps');
                return;
            }
        }

        // 由 itemDetailMap 构建英文名映射
        for (const [hrid, item] of Object.entries(itemDetailMap)) {
            if (item.name) {
                itemNameToHrid[item.name] = hrid;
                itemHridToName[hrid] = item.name;
            }
        }
        
        // 由 ZHItemNames 构建中文名映射(反转映射)
        for (const [hrid, zhName] of Object.entries(ZHItemNames)) {
            zhNameToHrid[zhName] = hrid;
        }
        
        logInit('[Better Loot Tracker] 物品映射构建完成,英文', Object.keys(itemNameToHrid).length, '中文:', Object.keys(zhNameToHrid).length);
    }
    
    // 根据物品名称获取HRID(支持中英文)
    function getItemHrid(itemName) {
        // 先去掉末尾的强化等级标记(如 "+1" 或 "+5")
        const cleanName = itemName.replace(/\s*\+\d+$/, '').trim();
        
        // 先尝试英文名
        if (itemNameToHrid[cleanName]) {
            return itemNameToHrid[cleanName];
        }
        
        // 再尝试中文名
        if (zhNameToHrid[cleanName]) {
            return zhNameToHrid[cleanName];
        }
        
        // 尝试用 itemDetailMap 动态查找(遍历所有物品)
        if (itemDetailMap) {
            for (const [hrid, item] of Object.entries(itemDetailMap)) {
                // 检查英文名
                if (item.name === cleanName) {
                    itemNameToHrid[cleanName] = hrid;
                    return hrid;
                }
            }
        }
        
        // 通过 ZHItemNames 查找
        for (const [hrid, zhName] of Object.entries(ZHItemNames)) {
            if (zhName === cleanName) {
                zhNameToHrid[cleanName] = hrid;
                return hrid;
            }
        }
        
        return null;
    }

    // ======================
    // 强化计算
    // ======================

    const SUCCESS_RATE = [
        50, 45, 45, 40, 40, 40, 35, 35, 35, 35,
        30, 30, 30, 30, 30, 30, 30, 30, 30, 30
    ];
    const ITEM_ENHANCE_LEVEL_TO_BUFF_BONUS_MAP = {
        0: 0, 1: 2, 2: 4.2, 3: 6.6, 4: 9.2, 5: 12, 6: 15, 7: 18.2, 8: 21.6, 9: 25.2, 10: 29,
        11: 33.4, 12: 38.4, 13: 44, 14: 50.2, 15: 57, 16: 64.4, 17: 72.4, 18: 81, 19: 90.2, 20: 100
    };
    const ENHANCE_DEFAULT_PARAMS = {
        enhancing_level: 125,
        laboratory_level: 6,
        enhancer_bonus: 5.42,
        glove_bonus: 12.9,
        tea_enhancing: false,
        tea_super_enhancing: false,
        tea_ultra_enhancing: true,
        tea_blessed: true
    };

    function getBaseItemLevel(itemHRID) {
        if (!itemDetailMap) {
            const initData = getInitClientData();
            if (initData?.itemDetailMap) {
                itemDetailMap = initData.itemDetailMap;
            } else {
                return 0;
            }
        }
        const itemDetails = itemDetailMap[itemHRID];
        return itemDetails?.itemLevel || 0;
    }

    function getEnhancementCosts(itemHRID) {
        if (!itemDetailMap) {
            const initData = getInitClientData();
            if (initData?.itemDetailMap) {
                itemDetailMap = initData.itemDetailMap;
            } else {
                return null;
            }
        }
        
        const itemData = itemDetailMap[itemHRID];
        if (!itemData?.enhancementCosts) return null;

        return itemData.enhancementCosts;
    }

    function getProtectionItems(itemHRID) {
        if (!itemDetailMap) {
            const initData = getInitClientData();
            if (initData?.itemDetailMap) {
                itemDetailMap = initData.itemDetailMap;
            } else {
                return [itemHRID, "/items/mirror_of_protection"];
            }
        }
        
        const itemData = itemDetailMap[itemHRID];
        let protectHrids = [itemHRID, "/items/mirror_of_protection"];
        
        if (itemData?.protectionItemHrids) {
            protectHrids = protectHrids.concat(itemData.protectionItemHrids);
        }
        
        return protectHrids;
    }

    // ======================
    // 数据获取和管理
    // ======================

    // 存储角色数据
    let characterItems = null;
    let characterBuffs = null;
    let characterSkills = null;
    let characterHouseRoomMap = null;
    let itemDetailMap = null;

    // Hook WebSocket消息获取数据
    function hookWebSocket() {
        logInit('[Better Loot Tracker] Starting WebSocket hook installation...');
        
        try {
            const dataProperty = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data");
            if (!dataProperty) {
                console.error('[Better Loot Tracker] Failed to get MessageEvent.prototype.data property');
                return;
            }
            
            const oriGet = dataProperty.get;
            if (!oriGet) {
                console.error('[Better Loot Tracker] Failed to get original data getter');
                return;
            }

            dataProperty.get = function hookedGet() {
                const socket = this.currentTarget;
                if (!(socket instanceof WebSocket)) {
                    return oriGet.call(this);
                }
                
                const url = socket.url;
                logCalc('[Better Loot Tracker] WebSocket message from:', url);
                
                if (url.indexOf("api.milkywayidle.com/ws") <= -1 && url.indexOf("api-test.milkywayidle.com/ws") <= -1) {
                    return oriGet.call(this);
                }

                const message = oriGet.call(this);
                Object.defineProperty(this, "data", { value: message }); // Anti-loop

                try {
                    const obj = JSON.parse(message);
                    logCalc('[Better Loot Tracker] WebSocket message type:', obj.type);
                    
                    if (obj && obj.type === "init_character_data") {
                        logInit('[Better Loot Tracker] Received init_character_data');
                        characterItems = obj.characterItems;
                        characterBuffs = obj.characterBuffs;
                        characterSkills = obj.characterSkills;
                        characterHouseRoomMap = obj.characterHouseRoomMap;
                        logInit('[Better Loot Tracker] Updated characterItems:', !!characterItems, characterItems?.length);
                        logInit('[Better Loot Tracker] Updated characterBuffs:', !!characterBuffs, characterBuffs?.length);
                        logInit('[Better Loot Tracker] Updated characterSkills:', !!characterSkills, Object.keys(characterSkills || {}).length);
                        logInit('[Better Loot Tracker] Updated characterHouseRoomMap:', !!characterHouseRoomMap, Object.keys(characterHouseRoomMap || {}).length);
                        
                        // 延迟调用调试函数,确保所有数据都已更新
                        setTimeout(() => {
                            debugShowAllData();
                        }, 1000);
                    } else if (obj && obj.type === "init_client_data") {
                        logInit('[Better Loot Tracker] Received init_client_data');
                        itemDetailMap = obj.itemDetailMap;
                        logInit('[Better Loot Tracker] Updated itemDetailMap:', !!itemDetailMap, Object.keys(itemDetailMap || {}).length);
                    }
                } catch (e) {
                    console.error('[Better Loot Tracker] Error parsing WebSocket message:', e);
                }

                return message;
            };

            Object.defineProperty(MessageEvent.prototype, "data", dataProperty);
            logInit('[Better Loot Tracker] WebSocket hook installed successfully');
        } catch (error) {
            console.error('[Better Loot Tracker] Error installing WebSocket hook:', error);
        }
    }

    // 获取暴饮之囊的饮料浓度加成
    function getDrinkConcentrationBonus() {
        logCalc('[Better Loot Tracker] getDrinkConcentrationBonus - characterItems:', !!characterItems);
        if (!characterItems || !itemDetailMap) return 0;


        logCalc('[Better Loot Tracker] characterItems length:', characterItems.length);

        for (const item of characterItems) {
            if (item.itemLocationHrid === "/item_locations/pouch" && item.itemHrid === "/items/guzzling_pouch") {
                logCalc('[Better Loot Tracker] Found guzzling pouch:', item);
                const itemDetail = itemDetailMap[item.itemHrid];
                logCalc('[Better Loot Tracker] Guzzling pouch detail:', itemDetail);
                
                if (itemDetail?.equipmentDetail?.noncombatStats?.drinkConcentration) {
                    const enhanceBonus = 1 + (ITEM_ENHANCE_LEVEL_TO_BUFF_BONUS_MAP[item.enhancementLevel || 0] || 0) / 100;
                    const result = itemDetail.equipmentDetail.noncombatStats.drinkConcentration * enhanceBonus * 100;
                    logCalc('[Better Loot Tracker] Drink concentration bonus:', result);
                    return result;
                }
            }
        }
        logCalc('[Better Loot Tracker] No guzzling pouch found');
        return 0;
    }

    // 获取强化等级
    function getPlayerEnhanceParams() {
        const res = {
            ...ENHANCE_DEFAULT_PARAMS,
            drink_concentration_bonus: getDrinkConcentrationBonus(),
            enhancers_top_speed: 0,
            enhancers_bottom_speed: 0,
            necklace_speed: 0
        };

        if (characterSkills && Array.isArray(characterSkills)) {
            for (const s of characterSkills) {
                if (s.skillHrid && s.skillHrid.includes("enhancing")) {
                    res.enhancing_level = s.level;
                    break;
                }
            }
        }

        let foundObservatory = false;
        if (characterHouseRoomMap) {
            for (const key in characterHouseRoomMap) {
                const hrid = characterHouseRoomMap[key].houseRoomHrid || "";
                if (hrid.includes("observatory")) {
                    const observatoryLevel = characterHouseRoomMap[key].level;
                    if (observatoryLevel !== undefined && observatoryLevel !== null) {
                        res.laboratory_level = observatoryLevel;
                        foundObservatory = true;
                        break;
                    }
                }
            }
            if (!foundObservatory) {
                for (const key in characterHouseRoomMap) {
                    const hrid = characterHouseRoomMap[key].houseRoomHrid || "";
                    if (hrid.includes("laboratory")) {
                        const laboratoryLevel = characterHouseRoomMap[key].level;
                        if (laboratoryLevel !== undefined && laboratoryLevel !== null) {
                            res.laboratory_level = laboratoryLevel;
                            break;
                        }
                    }
                }
            }
        }

        let foundEnhancer = false;
        if (characterItems && Array.isArray(characterItems)) {
            for (const it of characterItems) {
                if (!it.itemLocationHrid || it.itemLocationHrid === "/item_locations/inventory") continue;
                const hrid = it.itemHrid;
                const detail = itemDetailMap?.[hrid];
                if (!detail) continue;
                const noncombat = detail.equipmentDetail && detail.equipmentDetail.noncombatStats;
                if (noncombat && noncombat.enhancingSuccess && !foundEnhancer) {
                    const ENHANCER_LEVEL_BONUS = [
                        0.0, 2.0, 4.2, 6.6, 9.2, 12.0, 15.0, 18.2, 21.6, 25.2, 29.0,
                        33.4, 38.4, 44.0, 50.2, 57.0, 64.4, 72.4, 81.0, 90.2, 100.0
                    ];
                    const instanceLevel = Math.min(Math.max(Number(it.enhancementLevel ?? 0), 0), 20);
                    const baseFraction = noncombat.enhancingSuccess || 0.0;
                    if (instanceLevel >= 1) {
                        const multiplier = 1 + ENHANCER_LEVEL_BONUS[instanceLevel] / 100.0;
                        const finalFraction = baseFraction * multiplier;
                        res.enhancer_bonus = Number((finalFraction * 100).toFixed(4));
                    } else {
                        res.enhancer_bonus = Number((baseFraction * 100).toFixed(4));
                    }
                    foundEnhancer = true;
                }
                if (hrid && (hrid.includes("glove") || hrid.includes("gloves") || hrid.includes("gauntlets"))) {
                    if (it.enhancementLevel !== undefined && it.enhancementLevel !== null) {
                        const lvl = Number(it.enhancementLevel);
                        if (lvl >= 10) res.glove_bonus = 12.9;
                        else if (lvl >= 5) res.glove_bonus = 11.2;
                        else res.glove_bonus = 10.0;
                    } else {
                        res.glove_bonus = ENHANCE_DEFAULT_PARAMS.glove_bonus;
                    }
                }
                if (hrid === "/items/enhancers_top") {
                    const enhancingSpeed = detail?.equipmentDetail?.noncombatStats?.enhancingSpeed;
                    if (enhancingSpeed) {
                        const enhanceBonus = 1 + (ITEM_ENHANCE_LEVEL_TO_BUFF_BONUS_MAP[it.enhancementLevel || 0] || 0) / 100;
                        res.enhancers_top_speed = enhancingSpeed * enhanceBonus * 100;
                    }
                }
                if (hrid === "/items/enhancers_bottoms") {
                    const enhancingSpeed = detail?.equipmentDetail?.noncombatStats?.enhancingSpeed;
                    if (enhancingSpeed) {
                        const enhanceBonus = 1 + (ITEM_ENHANCE_LEVEL_TO_BUFF_BONUS_MAP[it.enhancementLevel || 0] || 0) / 100;
                        res.enhancers_bottom_speed = enhancingSpeed * enhanceBonus * 100;
                    }
                }
                if (hrid === "/items/necklace_of_speed" || hrid === "/items/philosophers_necklace") {
                    const enhancingSpeed = detail?.equipmentDetail?.noncombatStats?.enhancingSpeed;
                    if (enhancingSpeed) {
                        const enhanceBonus = 1 + (ITEM_ENHANCE_LEVEL_TO_BUFF_BONUS_MAP[it.enhancementLevel || 0] || 0) * 5 / 100;
                        res.necklace_speed = enhancingSpeed * enhanceBonus * 100;
                    }
                }
            }
        }

        return res;
    }

    // ======================
    // 调试函数 - 显示所有获取到的数据
    // ======================
    
    function debugShowAllData() {
        if (!DEBUG.calc) return;
        logCalc('=== [Better Loot Tracker] 调试信息 - 所有数据===');
        
        // 基础数据
        logCalc('1. 基础数据状态');
        logCalc('   - itemDetailMap available:', !!itemDetailMap);
        logCalc('   - characterItems available:', !!characterItems);
        logCalc('   - characterBuffs available:', !!characterBuffs);
        logCalc('   - characterSkills available:', !!characterSkills);
        
        if (itemDetailMap) {
            logCalc('   - itemDetailMap size:', Object.keys(itemDetailMap).length);
        }
        
        if (characterSkills) {
            logCalc('   - characterSkills length:', characterSkills.length);
            const enhancingSkill = characterSkills.find(skill => skill.skillHrid === '/skills/enhancing');
            const observatorySkill = characterSkills.find(skill => skill.skillHrid === '/skills/observatory');
            logCalc('   - 强化技能等级', enhancingSkill?.level || '未找到');
            logCalc('   - 天文台技能等级', observatorySkill?.level || '未找到');
        }
        
        if (characterItems) {
            logCalc('   - characterItems length:', characterItems.length);
            logCalc('   - characterItems sample:', characterItems.slice(0, 3));
            
            // 查找暴饮之囊
            const guzzlingPouch = characterItems.find(item => 
                item.itemLocationHrid === "/item_locations/pouch" && 
                item.itemHrid === "/items/guzzling_pouch"
            );
            logCalc('   - 暴饮之囊:', guzzlingPouch);
            
            // 查找强化器
            const enhancers = characterItems.filter(item => 
                item.itemLocationHrid && 
                item.itemLocationHrid !== "/item_locations/inventory" &&
                itemDetailMap[item.itemHrid]?.equipmentDetail?.noncombatStats?.enhancingSuccess
            );
            logCalc('   - 强化器数量', enhancers.length);
            logCalc('   - 强化器列表', enhancers);
        }
        
        if (characterBuffs) {
            logCalc('   - characterBuffs length:', characterBuffs.length);
            logCalc('   - characterBuffs sample:', characterBuffs.slice(0, 3));
            
            // 查找茶类buff
            const teaBuffs = characterBuffs.filter(buff => 
                buff.itemHrid && (
                    buff.itemHrid.includes('tea') || 
                    buff.itemHrid.includes('enhancing') ||
                    buff.itemHrid.includes('blessed')
                )
            );
            logCalc('   - 茶类buff数量:', teaBuffs.length);
            logCalc('   - 茶类buff列表:', teaBuffs);
        }
        
        // 计算结果
        logCalc('2. 计算结果:');
        const playerParams = getPlayerEnhanceParams();
        const drinkMultiplier = playerParams.drink_concentration_bonus ? (1 + playerParams.drink_concentration_bonus / 100) : 1;
        const effectiveLevel = playerParams.enhancing_level +
            (playerParams.tea_enhancing ? 3 * drinkMultiplier : 0) +
            (playerParams.tea_super_enhancing ? 6 * drinkMultiplier : 0) +
            (playerParams.tea_ultra_enhancing ? 8 * drinkMultiplier : 0);
        const enhancingLevel = playerParams.enhancing_level;
        const observatoryLevel = playerParams.laboratory_level;
        const drinkBonus = playerParams.drink_concentration_bonus;
        const enhancerBonus = playerParams.enhancer_bonus;
        const teaEffects = {
            enhancing: playerParams.tea_enhancing,
            superEnhancing: playerParams.tea_super_enhancing,
            ultraEnhancing: playerParams.tea_ultra_enhancing,
            blessed: playerParams.tea_blessed
        };
        
        logCalc('   - 强化技能等级', enhancingLevel);
        logCalc('   - 天文台技能等级', observatoryLevel);
        logCalc('   - 暴饮之囊加成:', drinkBonus);
        logCalc('   - 强化器加成', enhancerBonus);
        logCalc('   - 茶效果', teaEffects);
        
        // 测试强化计算
        logCalc('3. 测试强化计算 (以星空针+5为例):');
        const testItemHrid = '/items/celestial_needle';
        if (itemDetailMap && itemDetailMap[testItemHrid]) {
            const testResult = Enhancelate(testItemHrid, 5, 2);
            logCalc('   - 测试物品:', testItemHrid);
            logCalc('   - 物品等级:', getBaseItemLevel(testItemHrid));
            logCalc('   - 期望强化次数:', testResult.actions);
            logCalc('   - 期望保护次数:', testResult.protectCount);
        } else {
            logCalc('   - 测试物品不存在于itemDetailMap')
        }
        
        logCalc('=== 调试信息结束 ===');
    }

    // 计算期望强化次数和保护次数
    function Enhancelate(itemHrid, stopAt, protectAt, overrideParams = null) {
        logCalc('[Better Loot Tracker] Enhancelate called with:', { itemHrid, stopAt, protectAt, overrideParams });
        
        const itemLevel = getBaseItemLevel(itemHrid);
        logCalc('[Better Loot Tracker] Item level:', itemLevel);
        const playerParams = { ...getPlayerEnhanceParams(), ...(overrideParams || {}) };
        
        // 获取实际的强化等级和天文台等级
        const actualEnhancingLevel = playerParams.enhancing_level;
        const actualObservatoryLevel = playerParams.laboratory_level;
        
        logCalc('[Better Loot Tracker] Using enhancing level:', actualEnhancingLevel);
        logCalc('[Better Loot Tracker] Using observatory level:', actualObservatoryLevel);
        
        // 获取暴饮之囊加成
        const drinkConcentrationBonus = playerParams.drink_concentration_bonus;
        const drinkConcentrationMultiplier = drinkConcentrationBonus ? (1 + drinkConcentrationBonus / 100) : 1;
        logCalc('[Better Loot Tracker] Drink concentration multiplier:', drinkConcentrationMultiplier);
        
        // 获取茶效果
        const teaEffects = {
            enhancing: playerParams.tea_enhancing,
            superEnhancing: playerParams.tea_super_enhancing,
            ultraEnhancing: playerParams.tea_ultra_enhancing,
            blessed: playerParams.tea_blessed
        };
        
        // 计算有效强化等级(包含茶的加成和暴饮之囊加成影响)
        const effectiveLevel = actualEnhancingLevel +
            (teaEffects.enhancing ? 3 * drinkConcentrationMultiplier : 0) +
            (teaEffects.superEnhancing ? 6 * drinkConcentrationMultiplier : 0) +
            (teaEffects.ultraEnhancing ? 8 * drinkConcentrationMultiplier : 0);
        logCalc('[Better Loot Tracker] Effective level:', effectiveLevel, 'base:', actualEnhancingLevel);
        
        // 获取强化器加成
        const enhancerBonus = playerParams.enhancer_bonus;
        
        // 计算总加成
        let totalBonus;
        if (effectiveLevel >= itemLevel) {
            totalBonus = 1 + (0.05 * (effectiveLevel + actualObservatoryLevel - itemLevel) + enhancerBonus) / 100;
        } else {
            totalBonus = 1 - 0.5 * (1 - effectiveLevel / itemLevel) + (0.05 * actualObservatoryLevel + enhancerBonus) / 100;
        }
        logCalc('[Better Loot Tracker] Total bonus:', totalBonus);

        // 建立马尔可夫矩阵
        let markov = math.zeros(21, 21);
        for (let i = 0; i < stopAt; i++) {
            const successChance = (SUCCESS_RATE[i] / 100.0) * totalBonus;
            const destination = i >= protectAt ? i - 1 : 0;
            
            if (teaEffects.blessed) {
                // 祝福茶效果也受暴饮之囊加成影响
                const blessedEffect = 0.01 * drinkConcentrationMultiplier;
                markov.set([i, Math.min(i + 2, 20)], successChance * blessedEffect);
                markov.set([i, i + 1], successChance * (1 - blessedEffect));
                markov.set([i, destination], 1 - successChance);
            } else {
                markov.set([i, i + 1], successChance);
                markov.set([i, destination], 1.0 - successChance);
            }
        }
        markov.set([stopAt, stopAt], 1.0);

        // 计算期望强化次数
        let Q = markov.subset(math.index(math.range(0, stopAt), math.range(0, stopAt)));
        const M = math.inv(math.subtract(math.identity(stopAt), Q));
        const attemptsArray = M.subset(math.index(math.range(0, 1), math.range(0, stopAt)));
        const attempts = typeof attemptsArray === "number" 
            ? attemptsArray 
            : math.flatten(math.row(attemptsArray, 0).valueOf()).reduce((a, b) => a + b, 0);

        // 计算期望保护次数
        let protects = 0;
        if (protectAt >= 1 && protectAt < stopAt) {
            const protectAttempts = M.subset(math.index(math.range(0, 1), math.range(protectAt, stopAt)));
            const protectAttemptsArray = typeof protectAttempts === "number" 
                ? [protectAttempts] 
                : math.flatten(math.row(protectAttempts, 0).valueOf());
            protects = protectAttemptsArray.map((a, i) => 
                a * markov.get([i + protectAt, i + protectAt - 1])
            ).reduce((a, b) => a + b, 0);
        }

        const result = {
            actions: attempts,
            protectCount: protects
        };
        logCalc('[Better Loot Tracker] Enhancelate result:', result);
        return result;
    }

    // 找到最佳保护等级
    function findBestProtectLevel(itemHrid, targetLevel, marketData) {
        const enhancementCosts = getEnhancementCosts(itemHrid);
        if (!enhancementCosts) return { protectAt: 2, materialCost: 0, protectCost: 0 };

        // 计算每次强化的材料成本
        let perActionCost = 0;
        for (const cost of enhancementCosts) {
            const price = getMarketPrice(cost.itemHrid, marketData);
            perActionCost += price * cost.count;
        }

        // 计算保护成本
        const protectionItems = getProtectionItems(itemHrid);
        let minProtectCost = Infinity;
        for (const protectHrid of protectionItems) {
            const price = getMarketPrice(protectHrid, marketData);
            if (price > 0 && price < minProtectCost) {
                minProtectCost = price;
            }
        }
        if (minProtectCost === Infinity) minProtectCost = 0;

        // 遍历所有可能的保护等级找到最优
        let bestResult = null;
        const startProtect = targetLevel === 1 ? 1 : 2;
        
        for (let protectAt = startProtect; protectAt <= targetLevel; protectAt++) {
            const sim = Enhancelate(itemHrid, targetLevel, protectAt);
            const totalCost = perActionCost * sim.actions + minProtectCost * sim.protectCount;
            
            if (!bestResult || totalCost < bestResult.totalCost) {
                bestResult = {
                    protectAt: protectAt,
                    expectedActions: sim.actions,
                    expectedProtects: sim.protectCount,
                    perActionCost: perActionCost,
                    minProtectCost: minProtectCost,
                    totalCost: totalCost
                };
            }
        }

        return bestResult;
    }

    // ======================
    // 解析掉落记录
    // ======================

    function parseEnhancementLoot(lootElement) {
        // 获取标题信息
        const titleSpan = lootElement.querySelector('div > span:not(.loot-log-index)');
        if (!titleSpan) return null;

        const titleText = titleSpan.textContent;
        
        // 检查是否是强化行动
        if (!titleText.includes('强化') && !titleText.toLowerCase().includes('enhancing')) {
            return null;
        }

        // 解析强化次数:格式如 "强化 - 星空针(104)" 或 "Enhancing - Celestial Needle (104)"
        const countMatch = titleText.match(/\((\d+)\)/);
        if (!countMatch) return null;
        const enhanceCount = parseInt(countMatch[1]);
        const startLevelMatch = titleText.match(/\+(\d+)\s*\(\d+\)\s*$/);
        const startLevel = startLevelMatch ? parseInt(startLevelMatch[1]) : 0;

        // 解析物品名称 - 同时尝试中英文格式
        let itemName = null;
        
        // 尝试中文格式
        const zhMatch = titleText.match(/强化\s*-\s*(.+?)\s*\(/);
        if (zhMatch) {
            itemName = zhMatch[1].trim();
        }
        
        // 如果中文没匹配到,尝试英文格式
        if (!itemName) {
            const enMatch = titleText.match(/Enhancing\s*-\s*(.+?)\s*\(/i);
            if (enMatch) {
                itemName = enMatch[1].trim();
            }
        }
        
        if (!itemName) return null;

        // 获取物品HRID(支持中英文,自动去掉强化等级)
        const itemHrid = getItemHrid(itemName);
        if (!itemHrid) {
            logCalc('[Better Loot Tracker] 未找到物品HRID:', itemName);
            return null;
        }

        // 解析各等级掉落
        const drops = {};
        const itemContainers = lootElement.querySelectorAll('.Item_itemContainer__x7kH1');
        
        for (const container of itemContainers) {
            const countDiv = container.querySelector('.Item_count__1HVvv');
            const levelDiv = container.querySelector('.Item_enhancementLevel__19g-e');
            
            if (countDiv) {
                const count = parseInt(countDiv.textContent) || 0;
                let level = 0;
                
                if (levelDiv) {
                    const levelMatch = levelDiv.textContent.match(/\+(\d+)/);
                    level = levelMatch ? parseInt(levelMatch[1]) : 0;
                }
                
                // 检查是否是强化精华(排除它)
                const itemIcon = container.querySelector('svg use');
                if (itemIcon) {
                    const href = itemIcon.getAttribute('href') || '';
                    if (href.includes('enhancing_essence')) {
                        continue; // 跳过强化精华
                    }
                }
                
                drops[level] = (drops[level] || 0) + count;
            }
        }

        return {
            itemName,
            itemHrid,
            enhanceCount,
            startLevel,
            drops
        };
    }

    function parseAlchemyLoot(lootElement) {
        const titleSpan = lootElement.querySelector('div > span:not(.loot-log-index)');
        if (!titleSpan) return null;

        const titleText = titleSpan.textContent;
        if (!titleText.includes('炼金') && !titleText.toLowerCase().includes('alchemy')) {
            return null;
        }

        const costMatch = titleText.match(/:\s*(.+?)\s*\((\d+)\)\s*$/);
        if (!costMatch) return null;

        const costItemName = costMatch[1].trim();
        const costCount = parseInt(costMatch[2], 10);
        if (!costItemName || !Number.isFinite(costCount)) return null;

        const costItemHrid = getItemHrid(costItemName);
        if (!costItemHrid) {
            logCalc('[Better Loot Tracker] 未找到炼金消耗物品HRID:', costItemName);
            return null;
        }

        const outputs = {};
        const itemContainers = lootElement.querySelectorAll('.Item_itemContainer__x7kH1');
        for (const container of itemContainers) {
            const countDiv = container.querySelector('.Item_count__1HVvv');
            if (!countDiv) continue;
            const count = parseInt(countDiv.textContent, 10) || 0;
            if (count <= 0) continue;

            const itemIcon = container.querySelector('svg use');
            const href = itemIcon?.getAttribute('href') || '';
            const idMatch = href.match(/#(.+)$/);
            if (!idMatch) continue;

            const itemId = idMatch[1].trim();
            if (!itemId) continue;

            const itemHrid = `/items/${itemId}`;
            outputs[itemHrid] = (outputs[itemHrid] || 0) + count;
        }

        return {
            costItemHrid,
            costCount,
            outputs
        };
    }

    function analyzeEnhancementResult(parsedData) {
        const { drops } = parsedData;
        
        // 找到最高等级和其数量
        let maxLevel = 0;
        let maxLevelCount = 0;
        
        for (const [levelStr, count] of Object.entries(drops)) {
            const level = parseInt(levelStr);
            if (level > maxLevel) {
                maxLevel = level;
                maxLevelCount = count;
            }
        }

        // 判断目标等级和是否成功
        let targetLevel, success;
        if (maxLevelCount === 1) {
            targetLevel = maxLevel;
            success = true;
        } else {
            targetLevel = maxLevel + 1;
            success = false;
        }

        return {
            targetLevel,
            success,
            maxLevel,
            maxLevelCount
        };
    }

    function parsePreferenceLevels(text) {
        if (!text) return [];
        const matches = text.match(/\d+/g) || [];
        const levels = matches
            .map((value) => parseInt(value, 10))
            .filter((level) => Number.isFinite(level) && level >= 1 && level <= 20);
        return Array.from(new Set(levels)).sort((a, b) => a - b);
    }

    function applyPreferredTarget(analysisResult, preferenceLevels) {
        if (!preferenceLevels || preferenceLevels.length === 0) return analysisResult;
        const { maxLevel } = analysisResult;
        if (preferenceLevels.includes(maxLevel)) return analysisResult;

        const nextPreferred = preferenceLevels.find((level) => level > maxLevel);
        if (!nextPreferred) return analysisResult;

        return {
            ...analysisResult,
            targetLevel: nextPreferred,
            success: false
        };
    }

    function getAlchemyPriceSides(mode) {
        switch (mode) {
            case 'bid_ask':
                return { costSide: 'bid', outputSide: 'ask' };
            case 'ask_ask':
                return { costSide: 'ask', outputSide: 'ask' };
            case 'bid_bid':
                return { costSide: 'bid', outputSide: 'bid' };
            case 'ask_bid':
            default:
                return { costSide: 'ask', outputSide: 'bid' };
        }
    }

    function hasSuperEnhanceGap(drops, protectAt) {
        if (!protectAt || protectAt < 2) return false;
        let missingStreak = 0;
        for (let level = 1; level < protectAt; level++) {
            if ((drops[level] || 0) > 0) {
                missingStreak = 0;
                continue;
            }
            missingStreak += 1;
            if (missingStreak >= 2) return true;
        }
        return false;
    }

    function getExpectedTotalCostToLevel(itemHrid, level, marketData) {
        if (!level || level <= 0) return 0;
        const strategy = findBestProtectLevel(itemHrid, level, marketData);
        return strategy ? strategy.totalCost : 0;
    }

    function applySuperEnhanceFailurePadding(drops, startLevel) {
        const padded = { ...drops };
        const cap = Math.max(0, Math.min(Math.floor(startLevel), 20));
        for (let level = 0; level <= cap; level++) {
            padded[level] = (padded[level] || 0) + 1;
        }
        return padded;
    }

    function displayAlchemyInfo(lootElement, alchemyData, marketData) {
        const { costItemHrid, costCount, outputs } = alchemyData;
        const priceSides = getAlchemyPriceSides(globalAlchemyPriceMode);
        const costPrice = getMarketPriceSide(costItemHrid, marketData, priceSides.costSide);
        const totalCost = costPrice * costCount;

        let totalOutput = 0;
        for (const [itemHrid, count] of Object.entries(outputs)) {
            const outputPrice = getMarketPriceSide(itemHrid, marketData, priceSides.outputSide);
            totalOutput += outputPrice * count;
        }
        totalOutput *= 0.98;

        const profit = totalOutput - totalCost;
        const profitColor = profit >= 0 ? 'rgb(100, 255, 100)' : 'rgb(255, 100, 100)';

        const titleSpan = lootElement.querySelector('div > span:not(.loot-log-index)');
        if (!titleSpan) return;

        const existingTitleInfo = titleSpan.parentElement.querySelector('.alchemy-title-info');
        if (existingTitleInfo) {
            existingTitleInfo.remove();
        }

        const titleInfo = document.createElement('span');
        titleInfo.className = 'alchemy-title-info';
        titleInfo.style.cssText = 'margin-left: 8px;';
        titleInfo.innerHTML = `
            <span style="margin-left: 8px; color: #e0e0e0;">${t.alchemyCost}: ${formatNumber(totalCost)}</span>
            <span style="margin-left: 8px; color: #e0e0e0;">${t.alchemyOutput}: ${formatNumber(totalOutput)}</span>
            <span style="margin-left: 8px; color: ${profitColor};">${t.alchemyProfit}: ${formatNumber(profit)}</span>
        `;

        titleSpan.after(titleInfo);
    }

    function renderGlobalSettingsPanel(container) {
        if (!container) return;

        let wrapper = container.querySelector('.enhancement-loot-tracker-global-settings-wrapper');
        if (!wrapper) {
            wrapper = document.createElement('div');
            wrapper.className = 'enhancement-loot-tracker-global-settings-wrapper';
            wrapper.style.cssText = `
                margin: 6px 0 10px 0;
                display: flex;
                align-items: center;
                gap: 8px;
                flex-wrap: wrap;
            `;

            wrapper.innerHTML = `
                <button class="elt-global-settings-toggle" style="background: rgba(100,100,100,0.5); border: 1px solid #666; border-radius: 6px; color: #ddd; cursor: pointer; padding: 4px 10px; font-size: 12px;">
                    ${t.globalSettings}
                </button>
                <div class="enhancement-loot-tracker-global-settings" style="
                    padding: 8px 12px;
                    background: rgba(0, 0, 0, 0.35);
                    border-radius: 8px;
                    font-size: 12px;
                    color: #e0e0e0;
                    display: none;
                    align-items: center;
                    flex-wrap: wrap;
                    gap: 8px;
                ">
                    <label style="display: flex; align-items: center; gap: 6px;">
                        ${t.preferredLevels}:
                        <input class="elt-global-preference" placeholder="使用空格分隔,如‘7 8 10’" style="width: 140px; background: rgba(50,50,50,0.8); color: #e0e0e0; border: 1px solid #555; border-radius: 4px; padding: 2px 6px; font-size: 11px;">
                    </label>
                    <label style="display: flex; align-items: center; gap: 6px;">
                        ${t.superEnhanceMinLevel}:
                        <input class="elt-global-super-min" type="number" min="0" max="20" style="width: 64px; background: rgba(50,50,50,0.8); color: #e0e0e0; border: 1px solid #555; border-radius: 4px; padding: 2px 6px; font-size: 11px;">
                    </label>
                    <label style="display: flex; align-items: center; gap: 6px;">
                        ${t.alchemyPriceMode}:
                        <select class="elt-global-alchemy-price" style="background: rgba(50,50,50,0.8); color: #e0e0e0; border: 1px solid #555; border-radius: 4px; padding: 2px 6px; font-size: 11px;">
                            <option value="ask_bid">${t.alchemyPriceAskBid}</option>
                            <option value="bid_ask">${t.alchemyPriceBidAsk}</option>
                            <option value="ask_ask">${t.alchemyPriceAskAsk}</option>
                            <option value="bid_bid">${t.alchemyPriceBidBid}</option>
                        </select>
                    </label>
                    <span style="font-size: 11px; color: #888;">用于所有掉落记录</span>
                </div>
            `;

            container.prepend(wrapper);

            const toggle = wrapper.querySelector('.elt-global-settings-toggle');
            const panel = wrapper.querySelector('.enhancement-loot-tracker-global-settings');
            toggle.addEventListener('click', () => {
                if (panel) {
                    panel.style.display = panel.style.display === 'none' ? 'flex' : 'none';
                }
            });
        }

        const input = wrapper.querySelector('.elt-global-preference');
        if (input && input.value !== globalPreferenceText) {
            input.value = globalPreferenceText;
        }
        if (input && !input.dataset.bound) {
            input.dataset.bound = '1';
            input.addEventListener('change', () => {
                setGlobalPreferenceText(input.value);
                processLootLogs({ force: true });
            });
        }

        const superInput = wrapper.querySelector('.elt-global-super-min');
        if (superInput && superInput.value !== String(globalSuperEnhanceMinLevel)) {
            superInput.value = String(globalSuperEnhanceMinLevel);
        }
        if (superInput && !superInput.dataset.bound) {
            superInput.dataset.bound = '1';
            superInput.addEventListener('change', () => {
                setSuperEnhanceMinLevel(superInput.value);
                processLootLogs({ force: true });
            });
        }

        const alchemySelect = wrapper.querySelector('.elt-global-alchemy-price');
        if (alchemySelect && alchemySelect.value !== globalAlchemyPriceMode) {
            alchemySelect.value = globalAlchemyPriceMode;
        }
        if (alchemySelect && !alchemySelect.dataset.bound) {
            alchemySelect.dataset.bound = '1';
            alchemySelect.addEventListener('change', () => {
                setAlchemyPriceMode(alchemySelect.value);
                processLootLogs({ force: true });
            });
        }
    }

    /**
     * 计算实际保护次数
     * 
     * 算法说明
     * 1. 从保护等级x开始,累加x, x+2, x+4...的掉落次数
     * 2. 如果成功,再减去保护等级和目标等级之间包含的"奇数位置"等级数量
     *    这里“奇数位置”是指:从protectAt开始数,第1个、第2个..等级
     *    例如 protectAt=5, targetLevel=7: 
     *    需要累加 +5 和 +7 的次数
     *    成功时减去(因为成功到达+7需要经过+5和+7这两个保护点各一次成功)
     * 
     * @param {Object} drops - 各等级掉落数据{0: 46, 1: 27, 2: 12, ...}
     * @param {number} protectAt - 保护起始等级
     * @param {number} targetLevel - 目标等级
     * @param {boolean} success - 是否成功到达目标
     * @returns {number} 实际保护次数
     */
    function calculateActualProtections(drops, protectAt, targetLevel, success) {
        if (!protectAt || protectAt < 1) return 0;
        // 按保护等级的奇偶性统计保护位掉落
        let protectCount = 0;
        const parity = protectAt % 2;
        for (let level = protectAt; level <= targetLevel; level++) {
            if (level % 2 !== parity) continue;
            protectCount += (drops[level] || 0);
        }
        
        // 成功时扣掉一路通过的保护位次数
        if (success) {
            let successPassCount = 0;
            for (let level = protectAt; level <= targetLevel; level++) {
                if (level % 2 !== parity) continue;
                successPassCount++;
            }
            protectCount -= successPassCount;
        }
        
        return Math.max(0, protectCount);
    }

    // ======================
    // 格式化数据
    // ======================

    function formatNumber(num) {
        if (num === undefined || num === null || isNaN(num)) return '0';
        
        const absNum = Math.abs(num);
        let formatted;
        
        if (absNum >= 1e9) {
            formatted = (num / 1e9).toFixed(2) + 'B';
        } else if (absNum >= 1e6) {
            formatted = (num / 1e6).toFixed(2) + 'M';
        } else if (absNum >= 1e3) {
            formatted = (num / 1e3).toFixed(2) + 'K';
        } else {
            formatted = Math.round(num).toString();
        }
        
        return formatted;
    }

    // ======================
    // 显示增强信息
    // ======================

    // 存储每个掉落记录的配置
    const lootConfigs = new WeakMap();

    function displayEnhancementInfo(lootElement, parsedData, analysisResult, marketData, customConfig = null) {
        logCalc('[Better Loot Tracker] displayEnhancementInfo called with:', parsedData);
        
        const { itemHrid, enhanceCount, drops, startLevel } = parsedData;
        const defaultTargetLevel = analysisResult.targetLevel;
        const defaultSuccess = analysisResult.success;
        const baseItemPrice = getMarketPrice(itemHrid, marketData);
        
        // 获取或初始化配置
        let config = customConfig || lootConfigs.get(lootElement);
        if (!config) {
            const preferenceLevels = getGlobalPreferenceLevels();
            const preferredAnalysis = applyPreferredTarget(analysisResult, preferenceLevels);
            config = {
                targetLevel: preferredAnalysis.targetLevel,
                success: preferredAnalysis.success,
                protectAt: null,
                hasCustomTarget: false,
                hasCustomSuccess: false
            };
            lootConfigs.set(lootElement, config);
        }

        const preferredAnalysis = applyPreferredTarget(analysisResult, getGlobalPreferenceLevels());
        const targetLevel = config.hasCustomTarget ? config.targetLevel : preferredAnalysis.targetLevel;
        const success = config.hasCustomSuccess ? config.success : preferredAnalysis.success;
        if (!config.hasCustomTarget) config.targetLevel = targetLevel;
        if (!config.hasCustomSuccess) config.success = success;
        
        logCalc('[Better Loot Tracker] Config:', config);
        
        // 获取最佳强化策略
        const bestStrategy = findBestProtectLevel(itemHrid, targetLevel, marketData);
        if (!bestStrategy) {
            logCalc('[Better Loot Tracker] No best strategy found');
            return;
        }
        
        logCalc('[Better Loot Tracker] Best strategy:', bestStrategy);
        
        // 使用用户自定义保护等级或最佳保护等级
        const protectAt = config.protectAt !== null
            ? Math.min(config.protectAt, targetLevel)
            : bestStrategy.protectAt;

        const maxLevel = analysisResult.maxLevel;
        const hasZeroDrop = (drops[0] || 0) > 0;
        const superMinLevel = getSuperEnhanceMinLevel();
        let isSuperEnhance = false;
        let superSuccess = false;
        let superTargetLevel = targetLevel;
        if (startLevel > 0 && startLevel >= superMinLevel) {
            if (!hasZeroDrop) {
                isSuperEnhance = true;
                superSuccess = true;
                superTargetLevel = maxLevel;
            } else if (hasSuperEnhanceGap(drops, protectAt)) {
                isSuperEnhance = true;
                superSuccess = false;
                superTargetLevel = 0;
            }
        }
        
        // 重新计算使用用户选择的保护等级的期望值
        const sim = Enhancelate(itemHrid, targetLevel, protectAt);
        const expectedMaterialCost = bestStrategy.perActionCost * sim.actions;
        const expectedProtectCost = bestStrategy.minProtectCost * sim.protectCount;
        const expectedTotalCost = expectedMaterialCost + expectedProtectCost;
        
        logCalc('[Better Loot Tracker] Expected costs:', {
            materialCost: expectedMaterialCost,
            protectCost: expectedProtectCost,
            totalCost: expectedTotalCost
        });
        
        // 计算实际消耗
        const actualMaterialCost = bestStrategy.perActionCost * enhanceCount;
        const actualProtectTargetLevel = isSuperEnhance ? maxLevel : targetLevel;
        const actualProtectSuccess = isSuperEnhance ? superSuccess : success;
        const dropsForProtect = isSuperEnhance && startLevel > 0
            ? applySuperEnhanceFailurePadding(drops, startLevel)
            : drops;
        const actualProtectCount = calculateActualProtections(dropsForProtect, protectAt, actualProtectTargetLevel, actualProtectSuccess);
        const actualProtectCost = bestStrategy.minProtectCost * actualProtectCount;
        const actualTotalCost = actualMaterialCost + actualProtectCost;
        
        logCalc('[Better Loot Tracker] Actual costs:', {
            materialCost: actualMaterialCost,
            protectCost: actualProtectCost,
            totalCost: actualTotalCost,
            protectCount: actualProtectCount
        });
        
        // 计算比例
        const materialRatioNum = expectedMaterialCost > 0 ? actualMaterialCost / expectedMaterialCost : 0;
        const protectRatioNum = expectedProtectCost > 0 ? actualProtectCost / expectedProtectCost : 0;
        const totalRatioNum = expectedTotalCost > 0 ? actualTotalCost / expectedTotalCost : 0;
        
        const materialRatio = materialRatioNum.toFixed(2);
        const protectRatio = protectRatioNum.toFixed(2);
        const totalRatio = totalRatioNum.toFixed(2);
        
        // 根据比例决定颜色:>1红色、<1绿色、=1白色
        const getRatioColor = (ratio) => {
            if (ratio > 1) return 'rgb(255, 100, 100)';
            if (ratio < 1) return 'rgb(100, 255, 100)';
            return '#e0e0e0';
        };
        const materialColor = getRatioColor(materialRatioNum);
        const protectColor = getRatioColor(protectRatioNum);
        const totalColor = getRatioColor(totalRatioNum);
        
        // 计算差值
        const diff = actualTotalCost - expectedTotalCost;
        const diffText = diff >= 0 ? `${t.aboveExpected}: ${formatNumber(diff)}` : `${t.belowExpected}: ${formatNumber(Math.abs(diff))}`;
        const diffColor = diff >= 0 ? 'rgb(255, 100, 100)' : 'rgb(100, 255, 100)';
        
        // 成功/失败状态
        const statusText = isSuperEnhance ? (superSuccess ? t.success : t.failure) : (success ? t.success : t.failure);
        const statusColor = isSuperEnhance
            ? (superSuccess ? 'rgb(100, 255, 100)' : 'rgb(255, 100, 100)')
            : (success ? 'rgb(100, 255, 100)' : 'rgb(255, 100, 100)');
        
        // 生成唯一ID
        const uniqueId = `elt-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
        
        // ========== 标题行信息(显示在标题后面) ==========
        const titleSpan = lootElement.querySelector('div > span:not(.loot-log-index)');
        if (titleSpan) {
            // 移除旧的标题行信息
            const existingTitleInfo = titleSpan.parentElement.querySelector('.enhancement-title-info');
            if (existingTitleInfo) {
                existingTitleInfo.remove();
            }
            
            // 创建标题行信息
            const titleInfo = document.createElement('span');
            titleInfo.className = 'enhancement-title-info';
            titleInfo.style.cssText = 'margin-left: 8px;';
            
            // 只有成功时才显示差值信息
            const diffHtml = success ? `<span style="margin-left: 8px; color: ${diffColor}; font-weight: bold;">${diffText}</span>` : '';
            const superOriginalCost = baseItemPrice + getExpectedTotalCostToLevel(itemHrid, startLevel, marketData);
            const superFinalValue = superSuccess
                ? baseItemPrice + getExpectedTotalCostToLevel(itemHrid, superTargetLevel, marketData)
                : baseItemPrice;
            const superProfit = superFinalValue - superOriginalCost - actualTotalCost;
            const superProfitColor = superProfit >= 0 ? 'rgb(100, 255, 100)' : 'rgb(255, 100, 100)';

            const normalHtml = `
                <span style="color: ${statusColor}; font-weight: bold;">[${statusText}]</span>
                <span style="margin-left: 8px; color: ${materialColor};">${t.material}: ${formatNumber(actualMaterialCost)} (${materialRatio}x ${formatNumber(expectedMaterialCost)})</span>
                <span style="margin-left: 8px; color: ${protectColor};">${t.protection}: ${formatNumber(actualProtectCost)} (${protectRatio}x ${formatNumber(expectedProtectCost)})</span>
                <span style="margin-left: 8px; color: ${totalColor};">${t.total}: ${formatNumber(actualTotalCost)} (${totalRatio}x ${formatNumber(expectedTotalCost)})</span>
                ${diffHtml}
            `;

            const superHtml = `
                <span style="color: ${statusColor}; font-weight: bold;">[${statusText}]</span>
                <span style="margin-left: 8px; color: #e0e0e0;">${t.superSpend}: ${formatNumber(actualTotalCost)}</span>
                <span style="margin-left: 8px; color: #e0e0e0;">${t.originalCost}: ${formatNumber(superOriginalCost)}</span>
                <span style="margin-left: 8px; color: #e0e0e0;">${t.finalValue}: ${formatNumber(superFinalValue)}</span>
                <span style="margin-left: 8px; color: ${superProfitColor};">${t.profit}: ${formatNumber(superProfit)}</span>
            `;

            titleInfo.innerHTML = `
                ${isSuperEnhance ? superHtml : normalHtml}
                <button class="enhancement-toggle-settings" style="margin-left: 8px; background: rgba(100,100,100,0.5); border: 1px solid #666; border-radius: 4px; color: #ccc; cursor: pointer; padding: 1px 6px; font-size: 12px;">⚙</button>
            `;
            
            // 插入到标题后面
            titleSpan.after(titleInfo);
            
            // 添加设置按钮点击事件
            const toggleBtn = titleInfo.querySelector('.enhancement-toggle-settings');
            toggleBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                const settingsPanel = lootElement.querySelector('.enhancement-loot-tracker-info');
                if (settingsPanel) {
                    settingsPanel.style.display = settingsPanel.style.display === 'none' ? 'block' : 'none';
                }
            });
        }
        
        // ========== 底部配置区域(默认隐藏) ==========
        // 创建显示元素
        const infoSpan = document.createElement('div');
        infoSpan.className = 'enhancement-loot-tracker-info';
        infoSpan.style.cssText = `
            margin-top: 8px;
            padding: 6px 10px;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 6px;
            font-size: 12px;
            color: #e0e0e0;
            display: none;
        `;
        
        // 生成目标等级选项
        let targetOptions = '';
        for (let i = 1; i <= 20; i++) {
            const selected = i === targetLevel ? 'selected' : '';
            targetOptions += `<option value="${i}" ${selected}>+${i}</option>`;
        }
        
        // 生成保护等级选项
        const autoProtectLabel = isZH ? `自动(+${bestStrategy.protectAt})` : `Auto(+${bestStrategy.protectAt})`;
        let protectOptions = `<option value="auto">${autoProtectLabel}</option>`;
        for (let i = 2; i <= targetLevel; i++) {
            const selected = (config.protectAt !== null && i === protectAt) ? 'selected' : '';
            protectOptions += `<option value="${i}" ${selected}>+${i}</option>`;
        }
        if (config.protectAt === null) {
            protectOptions = protectOptions.replace('value="auto"', 'value="auto" selected');
        }
        
        infoSpan.innerHTML = `
            <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 8px;">
                <label style="display: flex; align-items: center; gap: 4px;">
                    ${t.target}:
                    <select id="${uniqueId}-target" style="background: rgba(50,50,50,0.8); color: #e0e0e0; border: 1px solid #555; border-radius: 4px; padding: 2px 4px; font-size: 11px;">
                        ${targetOptions}
                    </select>
                </label>
                <label style="display: flex; align-items: center; gap: 4px;">
                    ${t.protectLevel}:
                    <select id="${uniqueId}-protect" style="background: rgba(50,50,50,0.8); color: #e0e0e0; border: 1px solid #555; border-radius: 4px; padding: 2px 4px; font-size: 11px;">
                        ${protectOptions}
                    </select>
                </label>
                <label style="display: flex; align-items: center; gap: 4px;">
                    <input type="checkbox" id="${uniqueId}-success" ${success ? 'checked' : ''} style="margin: 0;">
                    ${t.treatAsSuccess}
                </label>
                <span style="margin-left: 8px; font-size: 11px; color: #888;">
                    ${t.expected}: ${formatNumber(expectedTotalCost)}
                </span>
            </div>
        `;
        
        // 检查是否已经添加过
        const existingInfo = lootElement.querySelector('.enhancement-loot-tracker-info');
        if (existingInfo) {
            existingInfo.remove();
        }
        
        // 添加到掉落记录底部
        const dropsContainer = lootElement.querySelector('.LootLogPanel_itemDrops__2h0ov');
        if (dropsContainer) {
            dropsContainer.before(infoSpan);
        } else {
            lootElement.prepend(infoSpan);
        }
        
        // 添加事件监听器
        const targetSelect = infoSpan.querySelector(`#${uniqueId}-target`);
        const protectSelect = infoSpan.querySelector(`#${uniqueId}-protect`);
        const successCheckbox = infoSpan.querySelector(`#${uniqueId}-success`);
        
        const updateDisplay = (options = {}) => {
            // 记住当前设置面板的显示状态
            const currentPanel = lootElement.querySelector('.enhancement-loot-tracker-info');
            const wasVisible = currentPanel && currentPanel.style.display !== 'none';

            const hasCustomTarget = options.targetChanged ? true : config.hasCustomTarget;
            const hasCustomSuccess = options.successChanged ? true : config.hasCustomSuccess;
            const preferredAnalysis = applyPreferredTarget(analysisResult, getGlobalPreferenceLevels());
            const resolvedTargetLevel = hasCustomTarget ? parseInt(targetSelect.value) : preferredAnalysis.targetLevel;
            const resolvedSuccess = hasCustomSuccess ? successCheckbox.checked : preferredAnalysis.success;

            const newConfig = {
                targetLevel: resolvedTargetLevel,
                success: resolvedSuccess,
                protectAt: protectSelect.value === 'auto' ? null : parseInt(protectSelect.value),
                hasCustomTarget,
                hasCustomSuccess
            };
            
            // 如果目标等级改变,更新保护等级选项
            if (newConfig.targetLevel !== config.targetLevel) {
                const refreshedBest = findBestProtectLevel(parsedData.itemHrid, newConfig.targetLevel, marketData) || { protectAt: 2 };
                const refreshedAutoLabel = isZH ? `自动(+${refreshedBest.protectAt})` : `Auto(+${refreshedBest.protectAt})`;
                let newProtectOptions = `<option value="auto" selected>${refreshedAutoLabel}</option>`;
                for (let i = 2; i <= newConfig.targetLevel; i++) {
                    newProtectOptions += `<option value="${i}">+${i}</option>`;
                }
                protectSelect.innerHTML = newProtectOptions;
                newConfig.protectAt = null;
            }
            
            lootConfigs.set(lootElement, newConfig);
            displayEnhancementInfo(lootElement, parsedData, analysisResult, marketData, newConfig);
            
            // 恢复设置面板的显示状态
            if (wasVisible) {
                const newPanel = lootElement.querySelector('.enhancement-loot-tracker-info');
                if (newPanel) {
                    newPanel.style.display = 'block';
                }
            }
        };
        
        targetSelect.addEventListener('change', () => updateDisplay({ targetChanged: true }));
        protectSelect.addEventListener('change', () => updateDisplay());
        successCheckbox.addEventListener('change', () => updateDisplay({ successChanged: true }));
    }

    // ======================
    // 主处理函数
    // ======================

    function processLootLogs(options = {}) {
        logCalc('[Better Loot Tracker] processLootLogs 开始执行..');
        const force = !!options.force;
        
        const marketData = getMarketData();
        if (!marketData) {
            logCalc(`[Better Loot Tracker] ${t.noMarketData}`);
            return;
        }
        logCalc('[Better Loot Tracker] 市场数据已加载');

        const container = getLootLogContainer();
        if (!container) {
            logCalc('[Better Loot Tracker] 没有找到掉落记录容器');
            return;
        }

        renderGlobalSettingsPanel(container);
        setupRefreshButtonHook();

        const lootLogList = container.querySelectorAll(LOOT_LOG_ITEM_SELECTOR);
        logCalc('[Better Loot Tracker] 找到掉落记录数量:', lootLogList.length);
        
        if (!lootLogList.length) {
            logCalc('[Better Loot Tracker] 没有找到掉落记录元素');
            return;
        }

        let processedCount = 0;
        lootLogList.forEach((lootElement, index) => {
            logCalc(`[Better Loot Tracker] 处理第${index + 1}个掉落记录..`);

            if (!force && lootElement.dataset.eltProcessed === '1') {
                return;
            }
            
            // 解析掉落数据
            const parsedData = parseEnhancementLoot(lootElement);
            if (parsedData) {
                logCalc(`[Better Loot Tracker] 第${index + 1}个记录是强化记录:`, parsedData);
                
                // 分析强化结果
                const analysisResult = analyzeEnhancementResult(parsedData);
                logCalc(`[Better Loot Tracker] 分析结果:`, analysisResult);
                
                // 显示信息
                displayEnhancementInfo(lootElement, parsedData, analysisResult, marketData);
                lootElement.dataset.eltProcessed = '1';
                processedCount++;
                return;
            }

            const alchemyData = parseAlchemyLoot(lootElement);
            if (alchemyData) {
                logCalc(`[Better Loot Tracker] 第${index + 1}个记录是炼金记录:`, alchemyData);
                displayAlchemyInfo(lootElement, alchemyData, marketData);
                lootElement.dataset.eltProcessed = '1';
                processedCount++;
                return;
            }

            logCalc(`[Better Loot Tracker] 第${index + 1}个记录不是强化或炼金记录`);
        });
        
        logCalc(`[Better Loot Tracker] 处理完成,共处理${processedCount}个强化记录`);
    }

    // ======================
    // 观察DOM变化
    // ======================

    function setupObserver() {
        logInit('[Better Loot Tracker] 设置DOM观察器..');
        
        const observer = new MutationObserver((mutations) => {
            let shouldProcess = false;
            
            for (const mutation of mutations) {
                if (mutation.type === 'childList') {
                    for (const node of mutation.addedNodes) {
                        if (node.nodeType === 1) {
                            if (node.classList?.contains('LootLogPanel_actionLoot__32gl_') ||
                                node.querySelector?.('.LootLogPanel_actionLoot__32gl_') ||
                                node.classList?.contains('LootLogPanel_actionLoots__3oTid')) {
                                shouldProcess = true;
                                logCalc('[Better Loot Tracker] 检测到新的掉落记录');
                                break;
                            }
                        }
                    }
                }
                if (shouldProcess) break;
            }
            
            if (shouldProcess) {
                logCalc('[Better Loot Tracker] 延迟处理新的掉落记录...');
                setTimeout(processLootLogs, 200);
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
        
        logInit('[Better Loot Tracker] DOM观察器已设置');
    }

    // ======================
    // 初始化
    // ======================

    function init() {
        logInit('[Better Loot Tracker] 初始化开始..');
        logInit('[Better Loot Tracker] 当前URL:', window.location.href);
        logInit('[Better Loot Tracker] 用户代理:', navigator.userAgent);
        
        // 安装WebSocket hook
        hookWebSocket();
        
        // 等待initClientData加载
        let checkCount = 0;
        const checkData = setInterval(() => {
            checkCount++;
            const initData = getInitClientData();
            logCalc(`[Better Loot Tracker] 检查数据(${checkCount}/60):`, !!initData, !!initData?.itemDetailMap);
            
            if (initData?.itemDetailMap) {
                clearInterval(checkData);
                
                // 初始化itemDetailMap
                itemDetailMap = initData.itemDetailMap;
                
                logInit('[Better Loot Tracker] InitData loaded, itemDetailMap size:', Object.keys(itemDetailMap).length);
                logInit('[Better Loot Tracker] CharacterItems from WebSocket:', !!characterItems);
                logInit('[Better Loot Tracker] CharacterBuffs from WebSocket:', !!characterBuffs);
                logInit('[Better Loot Tracker] CharacterSkills from WebSocket:', !!characterSkills);
                
                buildItemMaps();
                setupObserver();
                
                // 首次处理
                setTimeout(() => {
                    logCalc('[Better Loot Tracker] 开始首次处理掉落记录..');
                    processLootLogs();
                }, 1000);
                
                // 显示调试信息
                setTimeout(() => {
                    logCalc('[Better Loot Tracker] 显示调试信息...');
                    debugShowAllData();
                }, 2000);
                
                logInit('[Better Loot Tracker] 初始化完毕..');
            }
            
            if (checkCount >= 60) {
                clearInterval(checkData);
                logInit('[Better Loot Tracker] 初始化超时,但继续尝试..');
                
                // 即使超时也尝试安装observer
                setupObserver();
                setTimeout(() => {
                    debugShowAllData();
                }, 1000);
            }
        }, 500);
    }

    // 等待页面加载完成
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
        logInit('[Better Loot Tracker] Waiting for DOMContentLoaded');
    } else {
        logInit('[Better Loot Tracker] DOM already loaded, initializing immediately');
        init();
    }

    // 添加一个全局标识,确认插件已加载
    window.EnhancementLootTrackerLoaded = true;
    logInit('[Better Loot Tracker] Plugin loaded successfully');

    // 添加全局测试函数
    window.testEnhancementLootTracker = function() {
        logCalc('[Better Loot Tracker] 手动测试开始..');
        debugShowAllData();
        processLootLogs({ force: true });
    };

})();