您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
原神规划助手扩展
// ==UserScript== // @name genshinSeelieEx // @name:zh 原神、崩坏:星穹铁道、绝区零规划助手扩展 // @namespace https://github.com/KeyPJ/seelieEx // @version 6.0.2 // @author KeyPJ // @description:zh 个人想偷懒,不想手动在仙灵 - 规划助手 手动录入角色及其天赋,于是简单整理一个脚本,利用米游社养成计算器api获取角色信息,直接导入至seelie // @license MIT // @homepage https://github.com/KeyPJ // @homepageURL https://github.com/KeyPJ/seelieEx // @include https://seelie.me/* // @include https://hsr.seelie.me/* // @include https://zzz.seelie.me/* // @require https://unpkg.com/[email protected]/umd/react.production.min.js // @require https://unpkg.com/[email protected]/umd/react-dom.production.min.js // @require https://unpkg.com/[email protected]/dist/localforage.min.js // @resource character https://cdn.jsdelivr.net/gh/KeyPJ/seelieEx@main/src/data/character.json // @resource hsr_character https://cdn.jsdelivr.net/gh/KeyPJ/seelieEx@main/src/data/hsr_character.json // @resource hsr_weapon https://cdn.jsdelivr.net/gh/KeyPJ/seelieEx@main/src/data/hsr_weapon.json // @resource weapon https://cdn.jsdelivr.net/gh/KeyPJ/seelieEx@main/src/data/weapon.json // @resource zzz_character https://cdn.jsdelivr.net/gh/KeyPJ/seelieEx@main/src/data/zzz_character.json // @resource zzz_weapon https://cdn.jsdelivr.net/gh/KeyPJ/seelieEx@main/src/data/zzz_weapon.json // @connect api-takumi.mihoyo.com // @connect public-data-api.mihoyo.com // @grant GM.xmlHttpRequest // @grant GM_getResourceText // @grant GM_openInTab // @grant GM_registerMenuCommand // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-end // @contributionURL https://github.com/KeyPJ/seelieEx // @copyright 2021, KeyPJ https://github.com/KeyPJ // @description 原神规划助手扩展 // ==/UserScript== (r=>{const t=document.createElement("style");t.dataset.source="vite-plugin-monkey",t.innerText=r,document.head.appendChild(t)})(' *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-x-\\[20\\%\\]{left:20%;right:20%}.inset-y-0{top:0;bottom:0}.left-0{left:0}.right-0{right:0}.top-10{top:2.5rem}.z-10{z-index:10}.z-\\[1200\\]{z-index:1200}.mb-4{margin-bottom:1rem}.mt-1{margin-top:.25rem}.mt-10{margin-top:2.5rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.max-h-60{max-height:15rem}.min-h-min{min-height:-moz-min-content;min-height:min-content}.w-1\\/2{width:50%}.w-1\\/4{width:25%}.w-11{width:2.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-full{width:100%}.min-w-\\[50\\%\\]{min-width:50%}.max-w-md{max-width:28rem}.translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-6{--tw-translate-x: 1.5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-default{cursor:default}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-flow-col{grid-auto-flow:column}.grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.flex-row{flex-direction:row}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-blue-400{--tw-border-opacity: 1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.border-gray-600{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))}.border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.border-purple-700\\/50{border-color:#7e22ce80}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-600{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.bg-purple-800\\/70{background-color:#6b21a8b3}.bg-purple-900\\/30{background-color:#581c874d}.bg-slate-700\\/50{background-color:#33415580}.bg-slate-800\\/90{background-color:#1e293be6}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-2{padding:.5rem}.p-4{padding:1rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.pb-2{padding-bottom:.5rem}.pl-10{padding-left:2.5rem}.pl-3{padding-left:.75rem}.pr-10{padding-right:2.5rem}.pr-2{padding-right:.5rem}.pr-4{padding-right:1rem}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-blue-300{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-purple-300{--tw-text-opacity: 1;color:rgb(216 180 254 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.underline{-webkit-text-decoration-line:underline;text-decoration-line:underline}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-black{--tw-ring-opacity: 1;--tw-ring-color: rgb(0 0 0 / var(--tw-ring-opacity, 1))}.ring-opacity-5{--tw-ring-opacity: .05}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,fill,stroke,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ex-flex-col{flex-direction:column}.ex-mx-auto{margin-left:auto;margin-right:auto}.hover\\:bg-amber-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.hover\\:bg-blue-500:hover{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.hover\\:bg-purple-700:hover{--tw-bg-opacity: 1;background-color:rgb(126 34 206 / var(--tw-bg-opacity, 1))}.hover\\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus-visible\\:border-indigo-500:focus-visible{--tw-border-opacity: 1;border-color:rgb(99 102 241 / var(--tw-border-opacity, 1))}.focus-visible\\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\\:ring-white:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity, 1))}.focus-visible\\:ring-opacity-75:focus-visible{--tw-ring-opacity: .75}.focus-visible\\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\\:ring-offset-orange-300:focus-visible{--tw-ring-offset-color: #fdba74}@media (min-width: 640px){.sm\\:text-sm{font-size:.875rem;line-height:1.25rem}} '); var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; (function(require$$1, ReactDOM2, localforage2) { var _a, _b; "use strict"; const App$1 = ""; function getDefaultExportFromCjs(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; } var jsxRuntime = { exports: {} }; var reactJsxRuntime_production_min = {}; /* object-assign (c) Sindre Sorhus @license MIT */ var getOwnPropertySymbols = Object.getOwnPropertySymbols; var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; function toObject(val) { if (val === null || val === void 0) { throw new TypeError("Object.assign cannot be called with null or undefined"); } return Object(val); } function shouldUseNative() { try { if (!Object.assign) { return false; } var test1 = new String("abc"); test1[5] = "de"; if (Object.getOwnPropertyNames(test1)[0] === "5") { return false; } var test2 = {}; for (var i = 0; i < 10; i++) { test2["_" + String.fromCharCode(i)] = i; } var order2 = Object.getOwnPropertyNames(test2).map(function(n2) { return test2[n2]; }); if (order2.join("") !== "0123456789") { return false; } var test3 = {}; "abcdefghijklmnopqrst".split("").forEach(function(letter) { test3[letter] = letter; }); if (Object.keys(Object.assign({}, test3)).join("") !== "abcdefghijklmnopqrst") { return false; } return true; } catch (err) { return false; } } shouldUseNative() ? Object.assign : function(target, source) { var from; var to2 = toObject(target); var symbols; for (var s = 1; s < arguments.length; s++) { from = Object(arguments[s]); for (var key in from) { if (hasOwnProperty.call(from, key)) { to2[key] = from[key]; } } if (getOwnPropertySymbols) { symbols = getOwnPropertySymbols(from); for (var i = 0; i < symbols.length; i++) { if (propIsEnumerable.call(from, symbols[i])) { to2[symbols[i]] = from[symbols[i]]; } } } } return to2; }; /** @license React v17.0.2 * react-jsx-runtime.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var f = require$$1, g = 60103; reactJsxRuntime_production_min.Fragment = 60107; if ("function" === typeof Symbol && Symbol.for) { var h = Symbol.for; g = h("react.element"); reactJsxRuntime_production_min.Fragment = h("react.fragment"); } var m = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, n = Object.prototype.hasOwnProperty, p = { key: true, ref: true, __self: true, __source: true }; function q(c, a, k) { var b, d = {}, e = null, l = null; void 0 !== k && (e = "" + k); void 0 !== a.key && (e = "" + a.key); void 0 !== a.ref && (l = a.ref); for (b in a) n.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]); if (c && c.defaultProps) for (b in a = c.defaultProps, a) void 0 === d[b] && (d[b] = a[b]); return { $$typeof: g, type: c, key: e, ref: l, props: d, _owner: m.current }; } reactJsxRuntime_production_min.jsx = q; reactJsxRuntime_production_min.jsxs = q; { jsxRuntime.exports = reactJsxRuntime_production_min; } var jsxRuntimeExports = jsxRuntime.exports; const jsx = jsxRuntimeExports.jsx; const jsxs = jsxRuntimeExports.jsxs; function classNames(...classes) { return classes.filter(Boolean).join(" "); } function ListboxSelect(props) { const { selected, setSelected, optionList, show, className = "" } = props; const [isOpen, setIsOpen] = require$$1.useState(false); const containerRef = require$$1.useRef(null); require$$1.useEffect(() => { const handleClickOutside = (event) => { if (containerRef.current && !containerRef.current.contains(event.target)) { setIsOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); const toggleDropdown = (e) => { e.stopPropagation(); setIsOpen(!isOpen); }; const handleSelect = (item, e) => { e.stopPropagation(); setSelected(item); setIsOpen(false); }; return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: classNames("relative mt-1 w-full", className), children: [/* @__PURE__ */ jsxs("button", { type: "button", className: "relative w-full py-2 pl-3 pr-10 text-left bg-white rounded-lg shadow-md cursor-default focus:outline-none focus-visible:ring-2 focus-visible:ring-opacity-75 focus-visible:ring-white focus-visible:ring-offset-orange-300 focus-visible:ring-offset-2 focus-visible:border-indigo-500 sm:text-sm", onClick: toggleDropdown, children: [/* @__PURE__ */ jsx("span", { className: "block truncate text-gray-900", children: show(selected) }), /* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none", children: /* @__PURE__ */ jsx("svg", { className: `w-5 h-5 text-gray-400 transition-transform ${isOpen ? "transform rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) }) })] }), isOpen && /* @__PURE__ */ jsx("div", { className: "absolute z-10 w-full py-1 mt-1 overflow-auto text-base bg-white rounded-md shadow-lg max-h-60 ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm", onClick: (e) => e.stopPropagation(), children: optionList.map((item, index) => /* @__PURE__ */ jsxs("div", { className: `cursor-default select-none relative py-2 pl-10 pr-4 ${selected === item ? "text-amber-900 bg-amber-100" : "text-gray-900 hover:bg-amber-100"}`, onClick: (e) => handleSelect(item, e), children: [/* @__PURE__ */ jsx("span", { className: `block truncate ${selected === item ? "font-medium" : "font-normal"}`, children: show(item) }), selected === item && /* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 left-0 flex items-center pl-3 text-amber-600", children: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) })] }, index)) })] }); } function ToggleSwitch(props) { const { className, checked, onChange, labelLeft, labelRight } = props; return /* @__PURE__ */ jsxs("div", { className: `${className} flex flex-row items-center`, children: [/* @__PURE__ */ jsx("div", { className: "w-1/4 text-gray-200", children: labelLeft }), /* @__PURE__ */ jsx("div", { className: "w-1/2", children: /* @__PURE__ */ jsx("button", { type: "button", className: `relative inline-flex items-center h-6 rounded-full w-11 transition-colors ${checked ? "bg-blue-600" : "bg-gray-600"}`, onClick: () => onChange(!checked), "aria-pressed": checked, children: /* @__PURE__ */ jsx("span", { className: `inline-block w-4 h-4 transform bg-white rounded-full transition-transform ${checked ? "translate-x-6" : "translate-x-1"}` }) }) }), /* @__PURE__ */ jsx("div", { className: "w-1/4 text-gray-200", children: labelRight })] }); } var GameType = /* @__PURE__ */ ((GameType2) => { GameType2["GENSHIN"] = "genshin"; GameType2["HSR"] = "hsr"; GameType2["ZZZ"] = "zzz"; return GameType2; })(GameType || {}); const GameDomainMap = { "hsr.seelie.me": "hsr", "zzz.seelie.me": "zzz" /* ZZZ */ }; var axios$3 = { exports: {} }; var bind$2 = function bind2(fn, thisArg) { return function wrap() { var args = new Array(arguments.length); for (var i = 0; i < args.length; i++) { args[i] = arguments[i]; } return fn.apply(thisArg, args); }; }; var bind$1 = bind$2; var toString = Object.prototype.toString; var kindOf = function(cache) { return function(thing) { var str = toString.call(thing); return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); }; }(/* @__PURE__ */ Object.create(null)); function kindOfTest(type) { type = type.toLowerCase(); return function isKindOf(thing) { return kindOf(thing) === type; }; } function isArray(val) { return Array.isArray(val); } function isUndefined(val) { return typeof val === "undefined"; } function isBuffer(val) { return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && typeof val.constructor.isBuffer === "function" && val.constructor.isBuffer(val); } var isArrayBuffer = kindOfTest("ArrayBuffer"); function isArrayBufferView(val) { var result; if (typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView) { result = ArrayBuffer.isView(val); } else { result = val && val.buffer && isArrayBuffer(val.buffer); } return result; } function isString(val) { return typeof val === "string"; } function isNumber(val) { return typeof val === "number"; } function isObject(val) { return val !== null && typeof val === "object"; } function isPlainObject(val) { if (kindOf(val) !== "object") { return false; } var prototype2 = Object.getPrototypeOf(val); return prototype2 === null || prototype2 === Object.prototype; } var isDate = kindOfTest("Date"); var isFile = kindOfTest("File"); var isBlob = kindOfTest("Blob"); var isFileList = kindOfTest("FileList"); function isFunction(val) { return toString.call(val) === "[object Function]"; } function isStream(val) { return isObject(val) && isFunction(val.pipe); } function isFormData(thing) { var pattern = "[object FormData]"; return thing && (typeof FormData === "function" && thing instanceof FormData || toString.call(thing) === pattern || isFunction(thing.toString) && thing.toString() === pattern); } var isURLSearchParams = kindOfTest("URLSearchParams"); function trim(str) { return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ""); } function isStandardBrowserEnv() { if (typeof navigator !== "undefined" && (navigator.product === "ReactNative" || navigator.product === "NativeScript" || navigator.product === "NS")) { return false; } return typeof window !== "undefined" && typeof document !== "undefined"; } function forEach(obj, fn) { if (obj === null || typeof obj === "undefined") { return; } if (typeof obj !== "object") { obj = [obj]; } if (isArray(obj)) { for (var i = 0, l = obj.length; i < l; i++) { fn.call(null, obj[i], i, obj); } } else { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { fn.call(null, obj[key], key, obj); } } } } function merge() { var result = {}; function assignValue(val, key) { if (isPlainObject(result[key]) && isPlainObject(val)) { result[key] = merge(result[key], val); } else if (isPlainObject(val)) { result[key] = merge({}, val); } else if (isArray(val)) { result[key] = val.slice(); } else { result[key] = val; } } for (var i = 0, l = arguments.length; i < l; i++) { forEach(arguments[i], assignValue); } return result; } function extend(a, b, thisArg) { forEach(b, function assignValue(val, key) { if (thisArg && typeof val === "function") { a[key] = bind$1(val, thisArg); } else { a[key] = val; } }); return a; } function stripBOM(content) { if (content.charCodeAt(0) === 65279) { content = content.slice(1); } return content; } function inherits(constructor, superConstructor, props, descriptors2) { constructor.prototype = Object.create(superConstructor.prototype, descriptors2); constructor.prototype.constructor = constructor; props && Object.assign(constructor.prototype, props); } function toFlatObject(sourceObj, destObj, filter) { var props; var i; var prop; var merged = {}; destObj = destObj || {}; do { props = Object.getOwnPropertyNames(sourceObj); i = props.length; while (i-- > 0) { prop = props[i]; if (!merged[prop]) { destObj[prop] = sourceObj[prop]; merged[prop] = true; } } sourceObj = Object.getPrototypeOf(sourceObj); } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); return destObj; } function endsWith(str, searchString, position) { str = String(str); if (position === void 0 || position > str.length) { position = str.length; } position -= searchString.length; var lastIndex = str.indexOf(searchString, position); return lastIndex !== -1 && lastIndex === position; } function toArray(thing) { if (!thing) return null; var i = thing.length; if (isUndefined(i)) return null; var arr = new Array(i); while (i-- > 0) { arr[i] = thing[i]; } return arr; } var isTypedArray = function(TypedArray) { return function(thing) { return TypedArray && thing instanceof TypedArray; }; }(typeof Uint8Array !== "undefined" && Object.getPrototypeOf(Uint8Array)); var utils$c = { isArray, isArrayBuffer, isBuffer, isFormData, isArrayBufferView, isString, isNumber, isObject, isPlainObject, isUndefined, isDate, isFile, isBlob, isFunction, isStream, isURLSearchParams, isStandardBrowserEnv, forEach, merge, extend, trim, stripBOM, inherits, toFlatObject, kindOf, kindOfTest, endsWith, toArray, isTypedArray, isFileList }; const utils$d = /* @__PURE__ */ getDefaultExportFromCjs(utils$c); var utils$b = utils$c; function encode(val) { return encodeURIComponent(val).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+").replace(/%5B/gi, "[").replace(/%5D/gi, "]"); } var buildURL$1 = function buildURL2(url, params, paramsSerializer) { if (!params) { return url; } var serializedParams; if (paramsSerializer) { serializedParams = paramsSerializer(params); } else if (utils$b.isURLSearchParams(params)) { serializedParams = params.toString(); } else { var parts = []; utils$b.forEach(params, function serialize(val, key) { if (val === null || typeof val === "undefined") { return; } if (utils$b.isArray(val)) { key = key + "[]"; } else { val = [val]; } utils$b.forEach(val, function parseValue(v) { if (utils$b.isDate(v)) { v = v.toISOString(); } else if (utils$b.isObject(v)) { v = JSON.stringify(v); } parts.push(encode(key) + "=" + encode(v)); }); }); serializedParams = parts.join("&"); } if (serializedParams) { var hashmarkIndex = url.indexOf("#"); if (hashmarkIndex !== -1) { url = url.slice(0, hashmarkIndex); } url += (url.indexOf("?") === -1 ? "?" : "&") + serializedParams; } return url; }; const buildURL$2 = /* @__PURE__ */ getDefaultExportFromCjs(buildURL$1); var utils$a = utils$c; function InterceptorManager$1() { this.handlers = []; } InterceptorManager$1.prototype.use = function use(fulfilled, rejected, options) { this.handlers.push({ fulfilled, rejected, synchronous: options ? options.synchronous : false, runWhen: options ? options.runWhen : null }); return this.handlers.length - 1; }; InterceptorManager$1.prototype.eject = function eject(id) { if (this.handlers[id]) { this.handlers[id] = null; } }; InterceptorManager$1.prototype.forEach = function forEach2(fn) { utils$a.forEach(this.handlers, function forEachHandler(h2) { if (h2 !== null) { fn(h2); } }); }; var InterceptorManager_1 = InterceptorManager$1; var utils$9 = utils$c; var normalizeHeaderName$1 = function normalizeHeaderName2(headers2, normalizedName) { utils$9.forEach(headers2, function processHeader(value, name) { if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { headers2[normalizedName] = value; delete headers2[name]; } }); }; var utils$8 = utils$c; function AxiosError$3(message, code, config, request, response) { Error.call(this); this.message = message; this.name = "AxiosError"; code && (this.code = code); config && (this.config = config); request && (this.request = request); response && (this.response = response); } utils$8.inherits(AxiosError$3, Error, { toJSON: function toJSON() { return { // Standard message: this.message, name: this.name, // Microsoft description: this.description, number: this.number, // Mozilla fileName: this.fileName, lineNumber: this.lineNumber, columnNumber: this.columnNumber, stack: this.stack, // Axios config: this.config, code: this.code, status: this.response && this.response.status ? this.response.status : null }; } }); var prototype = AxiosError$3.prototype; var descriptors = {}; [ "ERR_BAD_OPTION_VALUE", "ERR_BAD_OPTION", "ECONNABORTED", "ETIMEDOUT", "ERR_NETWORK", "ERR_FR_TOO_MANY_REDIRECTS", "ERR_DEPRECATED", "ERR_BAD_RESPONSE", "ERR_BAD_REQUEST", "ERR_CANCELED" // eslint-disable-next-line func-names ].forEach(function(code) { descriptors[code] = { value: code }; }); Object.defineProperties(AxiosError$3, descriptors); Object.defineProperty(prototype, "isAxiosError", { value: true }); AxiosError$3.from = function(error, code, config, request, response, customProps) { var axiosError = Object.create(prototype); utils$8.toFlatObject(error, axiosError, function filter(obj) { return obj !== Error.prototype; }); AxiosError$3.call(axiosError, error.message, code, config, request, response); axiosError.name = error.name; customProps && Object.assign(axiosError, customProps); return axiosError; }; var AxiosError_1 = AxiosError$3; var transitional = { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false }; var utils$7 = utils$c; function toFormData$1(obj, formData) { formData = formData || new FormData(); var stack = []; function convertValue(value) { if (value === null) return ""; if (utils$7.isDate(value)) { return value.toISOString(); } if (utils$7.isArrayBuffer(value) || utils$7.isTypedArray(value)) { return typeof Blob === "function" ? new Blob([value]) : Buffer.from(value); } return value; } function build(data2, parentKey) { if (utils$7.isPlainObject(data2) || utils$7.isArray(data2)) { if (stack.indexOf(data2) !== -1) { throw Error("Circular reference detected in " + parentKey); } stack.push(data2); utils$7.forEach(data2, function each(value, key) { if (utils$7.isUndefined(value)) return; var fullKey = parentKey ? parentKey + "." + key : key; var arr; if (value && !parentKey && typeof value === "object") { if (utils$7.endsWith(key, "{}")) { value = JSON.stringify(value); } else if (utils$7.endsWith(key, "[]") && (arr = utils$7.toArray(value))) { arr.forEach(function(el) { !utils$7.isUndefined(el) && formData.append(fullKey, convertValue(el)); }); return; } } build(value, fullKey); }); stack.pop(); } else { formData.append(parentKey, convertValue(data2)); } } build(obj); return formData; } var toFormData_1 = toFormData$1; var AxiosError$2 = AxiosError_1; var settle = function settle2(resolve, reject, response) { var validateStatus = response.config.validateStatus; if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response); } else { reject(new AxiosError$2( "Request failed with status code " + response.status, [AxiosError$2.ERR_BAD_REQUEST, AxiosError$2.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], response.config, response.request, response )); } }; const settle$1 = /* @__PURE__ */ getDefaultExportFromCjs(settle); var cookies; var hasRequiredCookies; function requireCookies() { if (hasRequiredCookies) return cookies; hasRequiredCookies = 1; var utils2 = utils$c; cookies = utils2.isStandardBrowserEnv() ? ( // Standard browser envs support document.cookie function standardBrowserEnv() { return { write: function write(name, value, expires, path, domain, secure) { var cookie = []; cookie.push(name + "=" + encodeURIComponent(value)); if (utils2.isNumber(expires)) { cookie.push("expires=" + new Date(expires).toGMTString()); } if (utils2.isString(path)) { cookie.push("path=" + path); } if (utils2.isString(domain)) { cookie.push("domain=" + domain); } if (secure === true) { cookie.push("secure"); } document.cookie = cookie.join("; "); }, read: function read(name) { var match = document.cookie.match(new RegExp("(^|;\\s*)(" + name + ")=([^;]*)")); return match ? decodeURIComponent(match[3]) : null; }, remove: function remove(name) { this.write(name, "", Date.now() - 864e5); } }; }() ) : ( // Non standard browser env (web workers, react-native) lack needed support. function nonStandardBrowserEnv() { return { write: function write() { }, read: function read() { return null; }, remove: function remove() { } }; }() ); return cookies; } var isAbsoluteURL$1 = function isAbsoluteURL2(url) { return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); }; var combineURLs$1 = function combineURLs2(baseURL, relativeURL) { return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL; }; var isAbsoluteURL = isAbsoluteURL$1; var combineURLs = combineURLs$1; var buildFullPath$1 = function buildFullPath2(baseURL, requestedURL) { if (baseURL && !isAbsoluteURL(requestedURL)) { return combineURLs(baseURL, requestedURL); } return requestedURL; }; const buildFullPath$2 = /* @__PURE__ */ getDefaultExportFromCjs(buildFullPath$1); var utils$6 = utils$c; var ignoreDuplicateOf = [ "age", "authorization", "content-length", "content-type", "etag", "expires", "from", "host", "if-modified-since", "if-unmodified-since", "last-modified", "location", "max-forwards", "proxy-authorization", "referer", "retry-after", "user-agent" ]; var parseHeaders = function parseHeaders2(headers2) { var parsed = {}; var key; var val; var i; if (!headers2) { return parsed; } utils$6.forEach(headers2.split("\n"), function parser(line) { i = line.indexOf(":"); key = utils$6.trim(line.substr(0, i)).toLowerCase(); val = utils$6.trim(line.substr(i + 1)); if (key) { if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) { return; } if (key === "set-cookie") { parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]); } else { parsed[key] = parsed[key] ? parsed[key] + ", " + val : val; } } }); return parsed; }; const parseHeaders$1 = /* @__PURE__ */ getDefaultExportFromCjs(parseHeaders); var isURLSameOrigin; var hasRequiredIsURLSameOrigin; function requireIsURLSameOrigin() { if (hasRequiredIsURLSameOrigin) return isURLSameOrigin; hasRequiredIsURLSameOrigin = 1; var utils2 = utils$c; isURLSameOrigin = utils2.isStandardBrowserEnv() ? ( // Standard browser envs have full support of the APIs needed to test // whether the request URL is of the same origin as current location. function standardBrowserEnv() { var msie = /(msie|trident)/i.test(navigator.userAgent); var urlParsingNode = document.createElement("a"); var originURL; function resolveURL(url) { var href = url; if (msie) { urlParsingNode.setAttribute("href", href); href = urlParsingNode.href; } urlParsingNode.setAttribute("href", href); return { href: urlParsingNode.href, protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, "") : "", host: urlParsingNode.host, search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, "") : "", hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, "") : "", hostname: urlParsingNode.hostname, port: urlParsingNode.port, pathname: urlParsingNode.pathname.charAt(0) === "/" ? urlParsingNode.pathname : "/" + urlParsingNode.pathname }; } originURL = resolveURL(window.location.href); return function isURLSameOrigin2(requestURL) { var parsed = utils2.isString(requestURL) ? resolveURL(requestURL) : requestURL; return parsed.protocol === originURL.protocol && parsed.host === originURL.host; }; }() ) : ( // Non standard browser envs (web workers, react-native) lack needed support. function nonStandardBrowserEnv() { return function isURLSameOrigin2() { return true; }; }() ); return isURLSameOrigin; } var CanceledError_1; var hasRequiredCanceledError; function requireCanceledError() { if (hasRequiredCanceledError) return CanceledError_1; hasRequiredCanceledError = 1; var AxiosError2 = AxiosError_1; var utils2 = utils$c; function CanceledError2(message) { AxiosError2.call(this, message == null ? "canceled" : message, AxiosError2.ERR_CANCELED); this.name = "CanceledError"; } utils2.inherits(CanceledError2, AxiosError2, { __CANCEL__: true }); CanceledError_1 = CanceledError2; return CanceledError_1; } var parseProtocol; var hasRequiredParseProtocol; function requireParseProtocol() { if (hasRequiredParseProtocol) return parseProtocol; hasRequiredParseProtocol = 1; parseProtocol = function parseProtocol2(url) { var match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); return match && match[1] || ""; }; return parseProtocol; } var xhr; var hasRequiredXhr; function requireXhr() { if (hasRequiredXhr) return xhr; hasRequiredXhr = 1; var utils2 = utils$c; var settle$12 = settle; var cookies2 = requireCookies(); var buildURL2 = buildURL$1; var buildFullPath2 = buildFullPath$1; var parseHeaders$12 = parseHeaders; var isURLSameOrigin2 = requireIsURLSameOrigin(); var transitionalDefaults2 = transitional; var AxiosError2 = AxiosError_1; var CanceledError2 = requireCanceledError(); var parseProtocol2 = requireParseProtocol(); xhr = function xhrAdapter2(config) { return new Promise(function dispatchXhrRequest(resolve, reject) { var requestData = config.data; var requestHeaders = config.headers; var responseType = config.responseType; var onCanceled; function done() { if (config.cancelToken) { config.cancelToken.unsubscribe(onCanceled); } if (config.signal) { config.signal.removeEventListener("abort", onCanceled); } } if (utils2.isFormData(requestData) && utils2.isStandardBrowserEnv()) { delete requestHeaders["Content-Type"]; } var request = new XMLHttpRequest(); if (config.auth) { var username = config.auth.username || ""; var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : ""; requestHeaders.Authorization = "Basic " + btoa(username + ":" + password); } var fullPath = buildFullPath2(config.baseURL, config.url); request.open(config.method.toUpperCase(), buildURL2(fullPath, config.params, config.paramsSerializer), true); request.timeout = config.timeout; function onloadend() { if (!request) { return; } var responseHeaders = "getAllResponseHeaders" in request ? parseHeaders$12(request.getAllResponseHeaders()) : null; var responseData = !responseType || responseType === "text" || responseType === "json" ? request.responseText : request.response; var response = { data: responseData, status: request.status, statusText: request.statusText, headers: responseHeaders, config, request }; settle$12(function _resolve(value) { resolve(value); done(); }, function _reject(err) { reject(err); done(); }, response); request = null; } if ("onloadend" in request) { request.onloadend = onloadend; } else { request.onreadystatechange = function handleLoad() { if (!request || request.readyState !== 4) { return; } if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf("file:") === 0)) { return; } setTimeout(onloadend); }; } request.onabort = function handleAbort() { if (!request) { return; } reject(new AxiosError2("Request aborted", AxiosError2.ECONNABORTED, config, request)); request = null; }; request.onerror = function handleError() { reject(new AxiosError2("Network Error", AxiosError2.ERR_NETWORK, config, request, request)); request = null; }; request.ontimeout = function handleTimeout() { var timeoutErrorMessage = config.timeout ? "timeout of " + config.timeout + "ms exceeded" : "timeout exceeded"; var transitional2 = config.transitional || transitionalDefaults2; if (config.timeoutErrorMessage) { timeoutErrorMessage = config.timeoutErrorMessage; } reject(new AxiosError2( timeoutErrorMessage, transitional2.clarifyTimeoutError ? AxiosError2.ETIMEDOUT : AxiosError2.ECONNABORTED, config, request )); request = null; }; if (utils2.isStandardBrowserEnv()) { var xsrfValue = (config.withCredentials || isURLSameOrigin2(fullPath)) && config.xsrfCookieName ? cookies2.read(config.xsrfCookieName) : void 0; if (xsrfValue) { requestHeaders[config.xsrfHeaderName] = xsrfValue; } } if ("setRequestHeader" in request) { utils2.forEach(requestHeaders, function setRequestHeader(val, key) { if (typeof requestData === "undefined" && key.toLowerCase() === "content-type") { delete requestHeaders[key]; } else { request.setRequestHeader(key, val); } }); } if (!utils2.isUndefined(config.withCredentials)) { request.withCredentials = !!config.withCredentials; } if (responseType && responseType !== "json") { request.responseType = config.responseType; } if (typeof config.onDownloadProgress === "function") { request.addEventListener("progress", config.onDownloadProgress); } if (typeof config.onUploadProgress === "function" && request.upload) { request.upload.addEventListener("progress", config.onUploadProgress); } if (config.cancelToken || config.signal) { onCanceled = function(cancel) { if (!request) { return; } reject(!cancel || cancel && cancel.type ? new CanceledError2() : cancel); request.abort(); request = null; }; config.cancelToken && config.cancelToken.subscribe(onCanceled); if (config.signal) { config.signal.aborted ? onCanceled() : config.signal.addEventListener("abort", onCanceled); } } if (!requestData) { requestData = null; } var protocol = parseProtocol2(fullPath); if (protocol && ["http", "https", "file"].indexOf(protocol) === -1) { reject(new AxiosError2("Unsupported protocol " + protocol + ":", AxiosError2.ERR_BAD_REQUEST, config)); return; } request.send(requestData); }); }; return xhr; } var _null; var hasRequired_null; function require_null() { if (hasRequired_null) return _null; hasRequired_null = 1; _null = null; return _null; } var utils$5 = utils$c; var normalizeHeaderName = normalizeHeaderName$1; var AxiosError$1 = AxiosError_1; var transitionalDefaults = transitional; var toFormData = toFormData_1; var DEFAULT_CONTENT_TYPE = { "Content-Type": "application/x-www-form-urlencoded" }; function setContentTypeIfUnset(headers2, value) { if (!utils$5.isUndefined(headers2) && utils$5.isUndefined(headers2["Content-Type"])) { headers2["Content-Type"] = value; } } function getDefaultAdapter() { var adapter; if (typeof XMLHttpRequest !== "undefined") { adapter = requireXhr(); } else if (typeof process !== "undefined" && Object.prototype.toString.call(process) === "[object process]") { adapter = requireXhr(); } return adapter; } function stringifySafely(rawValue, parser, encoder) { if (utils$5.isString(rawValue)) { try { (parser || JSON.parse)(rawValue); return utils$5.trim(rawValue); } catch (e) { if (e.name !== "SyntaxError") { throw e; } } } return (encoder || JSON.stringify)(rawValue); } var defaults$3 = { transitional: transitionalDefaults, adapter: getDefaultAdapter(), transformRequest: [function transformRequest(data2, headers2) { normalizeHeaderName(headers2, "Accept"); normalizeHeaderName(headers2, "Content-Type"); if (utils$5.isFormData(data2) || utils$5.isArrayBuffer(data2) || utils$5.isBuffer(data2) || utils$5.isStream(data2) || utils$5.isFile(data2) || utils$5.isBlob(data2)) { return data2; } if (utils$5.isArrayBufferView(data2)) { return data2.buffer; } if (utils$5.isURLSearchParams(data2)) { setContentTypeIfUnset(headers2, "application/x-www-form-urlencoded;charset=utf-8"); return data2.toString(); } var isObjectPayload = utils$5.isObject(data2); var contentType = headers2 && headers2["Content-Type"]; var isFileList2; if ((isFileList2 = utils$5.isFileList(data2)) || isObjectPayload && contentType === "multipart/form-data") { var _FormData = this.env && this.env.FormData; return toFormData(isFileList2 ? { "files[]": data2 } : data2, _FormData && new _FormData()); } else if (isObjectPayload || contentType === "application/json") { setContentTypeIfUnset(headers2, "application/json"); return stringifySafely(data2); } return data2; }], transformResponse: [function transformResponse(data2) { var transitional2 = this.transitional || defaults$3.transitional; var silentJSONParsing = transitional2 && transitional2.silentJSONParsing; var forcedJSONParsing = transitional2 && transitional2.forcedJSONParsing; var strictJSONParsing = !silentJSONParsing && this.responseType === "json"; if (strictJSONParsing || forcedJSONParsing && utils$5.isString(data2) && data2.length) { try { return JSON.parse(data2); } catch (e) { if (strictJSONParsing) { if (e.name === "SyntaxError") { throw AxiosError$1.from(e, AxiosError$1.ERR_BAD_RESPONSE, this, null, this.response); } throw e; } } } return data2; }], /** * A timeout in milliseconds to abort a request. If set to 0 (default) a * timeout is not created. */ timeout: 0, xsrfCookieName: "XSRF-TOKEN", xsrfHeaderName: "X-XSRF-TOKEN", maxContentLength: -1, maxBodyLength: -1, env: { FormData: require_null() }, validateStatus: function validateStatus(status) { return status >= 200 && status < 300; }, headers: { common: { "Accept": "application/json, text/plain, */*" } } }; utils$5.forEach(["delete", "get", "head"], function forEachMethodNoData(method) { defaults$3.headers[method] = {}; }); utils$5.forEach(["post", "put", "patch"], function forEachMethodWithData(method) { defaults$3.headers[method] = utils$5.merge(DEFAULT_CONTENT_TYPE); }); var defaults_1 = defaults$3; var utils$4 = utils$c; var defaults$2 = defaults_1; var transformData$1 = function transformData2(data2, headers2, fns) { var context = this || defaults$2; utils$4.forEach(fns, function transform(fn) { data2 = fn.call(context, data2, headers2); }); return data2; }; var isCancel$1; var hasRequiredIsCancel; function requireIsCancel() { if (hasRequiredIsCancel) return isCancel$1; hasRequiredIsCancel = 1; isCancel$1 = function isCancel2(value) { return !!(value && value.__CANCEL__); }; return isCancel$1; } var utils$3 = utils$c; var transformData = transformData$1; var isCancel = requireIsCancel(); var defaults$1 = defaults_1; var CanceledError = requireCanceledError(); function throwIfCancellationRequested(config) { if (config.cancelToken) { config.cancelToken.throwIfRequested(); } if (config.signal && config.signal.aborted) { throw new CanceledError(); } } var dispatchRequest$1 = function dispatchRequest2(config) { throwIfCancellationRequested(config); config.headers = config.headers || {}; config.data = transformData.call( config, config.data, config.headers, config.transformRequest ); config.headers = utils$3.merge( config.headers.common || {}, config.headers[config.method] || {}, config.headers ); utils$3.forEach( ["delete", "get", "head", "post", "put", "patch", "common"], function cleanHeaderConfig(method) { delete config.headers[method]; } ); var adapter = config.adapter || defaults$1.adapter; return adapter(config).then(function onAdapterResolution(response) { throwIfCancellationRequested(config); response.data = transformData.call( config, response.data, response.headers, config.transformResponse ); return response; }, function onAdapterRejection(reason) { if (!isCancel(reason)) { throwIfCancellationRequested(config); if (reason && reason.response) { reason.response.data = transformData.call( config, reason.response.data, reason.response.headers, config.transformResponse ); } } return Promise.reject(reason); }); }; var utils$2 = utils$c; var mergeConfig$2 = function mergeConfig2(config1, config2) { config2 = config2 || {}; var config = {}; function getMergedValue(target, source) { if (utils$2.isPlainObject(target) && utils$2.isPlainObject(source)) { return utils$2.merge(target, source); } else if (utils$2.isPlainObject(source)) { return utils$2.merge({}, source); } else if (utils$2.isArray(source)) { return source.slice(); } return source; } function mergeDeepProperties(prop) { if (!utils$2.isUndefined(config2[prop])) { return getMergedValue(config1[prop], config2[prop]); } else if (!utils$2.isUndefined(config1[prop])) { return getMergedValue(void 0, config1[prop]); } } function valueFromConfig2(prop) { if (!utils$2.isUndefined(config2[prop])) { return getMergedValue(void 0, config2[prop]); } } function defaultToConfig2(prop) { if (!utils$2.isUndefined(config2[prop])) { return getMergedValue(void 0, config2[prop]); } else if (!utils$2.isUndefined(config1[prop])) { return getMergedValue(void 0, config1[prop]); } } function mergeDirectKeys(prop) { if (prop in config2) { return getMergedValue(config1[prop], config2[prop]); } else if (prop in config1) { return getMergedValue(void 0, config1[prop]); } } var mergeMap = { "url": valueFromConfig2, "method": valueFromConfig2, "data": valueFromConfig2, "baseURL": defaultToConfig2, "transformRequest": defaultToConfig2, "transformResponse": defaultToConfig2, "paramsSerializer": defaultToConfig2, "timeout": defaultToConfig2, "timeoutMessage": defaultToConfig2, "withCredentials": defaultToConfig2, "adapter": defaultToConfig2, "responseType": defaultToConfig2, "xsrfCookieName": defaultToConfig2, "xsrfHeaderName": defaultToConfig2, "onUploadProgress": defaultToConfig2, "onDownloadProgress": defaultToConfig2, "decompress": defaultToConfig2, "maxContentLength": defaultToConfig2, "maxBodyLength": defaultToConfig2, "beforeRedirect": defaultToConfig2, "transport": defaultToConfig2, "httpAgent": defaultToConfig2, "httpsAgent": defaultToConfig2, "cancelToken": defaultToConfig2, "socketPath": defaultToConfig2, "responseEncoding": defaultToConfig2, "validateStatus": mergeDirectKeys }; utils$2.forEach(Object.keys(config1).concat(Object.keys(config2)), function computeConfigValue(prop) { var merge2 = mergeMap[prop] || mergeDeepProperties; var configValue = merge2(prop); utils$2.isUndefined(configValue) && merge2 !== mergeDirectKeys || (config[prop] = configValue); }); return config; }; var data; var hasRequiredData; function requireData() { if (hasRequiredData) return data; hasRequiredData = 1; data = { "version": "0.27.2" }; return data; } var VERSION = requireData().version; var AxiosError = AxiosError_1; var validators$1 = {}; ["object", "boolean", "number", "function", "string", "symbol"].forEach(function(type, i) { validators$1[type] = function validator2(thing) { return typeof thing === type || "a" + (i < 1 ? "n " : " ") + type; }; }); var deprecatedWarnings = {}; validators$1.transitional = function transitional2(validator2, version, message) { function formatMessage(opt, desc) { return "[Axios v" + VERSION + "] Transitional option '" + opt + "'" + desc + (message ? ". " + message : ""); } return function(value, opt, opts) { if (validator2 === false) { throw new AxiosError( formatMessage(opt, " has been removed" + (version ? " in " + version : "")), AxiosError.ERR_DEPRECATED ); } if (version && !deprecatedWarnings[opt]) { deprecatedWarnings[opt] = true; console.warn( formatMessage( opt, " has been deprecated since v" + version + " and will be removed in the near future" ) ); } return validator2 ? validator2(value, opt, opts) : true; }; }; function assertOptions(options, schema, allowUnknown) { if (typeof options !== "object") { throw new AxiosError("options must be an object", AxiosError.ERR_BAD_OPTION_VALUE); } var keys = Object.keys(options); var i = keys.length; while (i-- > 0) { var opt = keys[i]; var validator2 = schema[opt]; if (validator2) { var value = options[opt]; var result = value === void 0 || validator2(value, opt, options); if (result !== true) { throw new AxiosError("option " + opt + " must be " + result, AxiosError.ERR_BAD_OPTION_VALUE); } continue; } if (allowUnknown !== true) { throw new AxiosError("Unknown option " + opt, AxiosError.ERR_BAD_OPTION); } } } var validator$1 = { assertOptions, validators: validators$1 }; var utils$1 = utils$c; var buildURL = buildURL$1; var InterceptorManager = InterceptorManager_1; var dispatchRequest = dispatchRequest$1; var mergeConfig$1 = mergeConfig$2; var buildFullPath = buildFullPath$1; var validator = validator$1; var validators = validator.validators; function Axios$1(instanceConfig) { this.defaults = instanceConfig; this.interceptors = { request: new InterceptorManager(), response: new InterceptorManager() }; } Axios$1.prototype.request = function request(configOrUrl, config) { if (typeof configOrUrl === "string") { config = config || {}; config.url = configOrUrl; } else { config = configOrUrl || {}; } config = mergeConfig$1(this.defaults, config); if (config.method) { config.method = config.method.toLowerCase(); } else if (this.defaults.method) { config.method = this.defaults.method.toLowerCase(); } else { config.method = "get"; } var transitional2 = config.transitional; if (transitional2 !== void 0) { validator.assertOptions(transitional2, { silentJSONParsing: validators.transitional(validators.boolean), forcedJSONParsing: validators.transitional(validators.boolean), clarifyTimeoutError: validators.transitional(validators.boolean) }, false); } var requestInterceptorChain = []; var synchronousRequestInterceptors = true; this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { if (typeof interceptor.runWhen === "function" && interceptor.runWhen(config) === false) { return; } synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); }); var responseInterceptorChain = []; this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); }); var promise; if (!synchronousRequestInterceptors) { var chain = [dispatchRequest, void 0]; Array.prototype.unshift.apply(chain, requestInterceptorChain); chain = chain.concat(responseInterceptorChain); promise = Promise.resolve(config); while (chain.length) { promise = promise.then(chain.shift(), chain.shift()); } return promise; } var newConfig = config; while (requestInterceptorChain.length) { var onFulfilled = requestInterceptorChain.shift(); var onRejected = requestInterceptorChain.shift(); try { newConfig = onFulfilled(newConfig); } catch (error) { onRejected(error); break; } } try { promise = dispatchRequest(newConfig); } catch (error) { return Promise.reject(error); } while (responseInterceptorChain.length) { promise = promise.then(responseInterceptorChain.shift(), responseInterceptorChain.shift()); } return promise; }; Axios$1.prototype.getUri = function getUri(config) { config = mergeConfig$1(this.defaults, config); var fullPath = buildFullPath(config.baseURL, config.url); return buildURL(fullPath, config.params, config.paramsSerializer); }; utils$1.forEach(["delete", "get", "head", "options"], function forEachMethodNoData(method) { Axios$1.prototype[method] = function(url, config) { return this.request(mergeConfig$1(config || {}, { method, url, data: (config || {}).data })); }; }); utils$1.forEach(["post", "put", "patch"], function forEachMethodWithData(method) { function generateHTTPMethod(isForm) { return function httpMethod(url, data2, config) { return this.request(mergeConfig$1(config || {}, { method, headers: isForm ? { "Content-Type": "multipart/form-data" } : {}, url, data: data2 })); }; } Axios$1.prototype[method] = generateHTTPMethod(); Axios$1.prototype[method + "Form"] = generateHTTPMethod(true); }); var Axios_1 = Axios$1; var CancelToken_1; var hasRequiredCancelToken; function requireCancelToken() { if (hasRequiredCancelToken) return CancelToken_1; hasRequiredCancelToken = 1; var CanceledError2 = requireCanceledError(); function CancelToken(executor) { if (typeof executor !== "function") { throw new TypeError("executor must be a function."); } var resolvePromise; this.promise = new Promise(function promiseExecutor(resolve) { resolvePromise = resolve; }); var token = this; this.promise.then(function(cancel) { if (!token._listeners) return; var i; var l = token._listeners.length; for (i = 0; i < l; i++) { token._listeners[i](cancel); } token._listeners = null; }); this.promise.then = function(onfulfilled) { var _resolve; var promise = new Promise(function(resolve) { token.subscribe(resolve); _resolve = resolve; }).then(onfulfilled); promise.cancel = function reject() { token.unsubscribe(_resolve); }; return promise; }; executor(function cancel(message) { if (token.reason) { return; } token.reason = new CanceledError2(message); resolvePromise(token.reason); }); } CancelToken.prototype.throwIfRequested = function throwIfRequested() { if (this.reason) { throw this.reason; } }; CancelToken.prototype.subscribe = function subscribe(listener) { if (this.reason) { listener(this.reason); return; } if (this._listeners) { this._listeners.push(listener); } else { this._listeners = [listener]; } }; CancelToken.prototype.unsubscribe = function unsubscribe(listener) { if (!this._listeners) { return; } var index = this._listeners.indexOf(listener); if (index !== -1) { this._listeners.splice(index, 1); } }; CancelToken.source = function source() { var cancel; var token = new CancelToken(function executor(c) { cancel = c; }); return { token, cancel }; }; CancelToken_1 = CancelToken; return CancelToken_1; } var spread; var hasRequiredSpread; function requireSpread() { if (hasRequiredSpread) return spread; hasRequiredSpread = 1; spread = function spread2(callback) { return function wrap(arr) { return callback.apply(null, arr); }; }; return spread; } var isAxiosError; var hasRequiredIsAxiosError; function requireIsAxiosError() { if (hasRequiredIsAxiosError) return isAxiosError; hasRequiredIsAxiosError = 1; var utils2 = utils$c; isAxiosError = function isAxiosError2(payload) { return utils2.isObject(payload) && payload.isAxiosError === true; }; return isAxiosError; } var utils = utils$c; var bind = bind$2; var Axios = Axios_1; var mergeConfig = mergeConfig$2; var defaults = defaults_1; function createInstance(defaultConfig) { var context = new Axios(defaultConfig); var instance = bind(Axios.prototype.request, context); utils.extend(instance, Axios.prototype, context); utils.extend(instance, context); instance.create = function create(instanceConfig) { return createInstance(mergeConfig(defaultConfig, instanceConfig)); }; return instance; } var axios$2 = createInstance(defaults); axios$2.Axios = Axios; axios$2.CanceledError = requireCanceledError(); axios$2.CancelToken = requireCancelToken(); axios$2.isCancel = requireIsCancel(); axios$2.VERSION = requireData().version; axios$2.toFormData = toFormData_1; axios$2.AxiosError = AxiosError_1; axios$2.Cancel = axios$2.CanceledError; axios$2.all = function all(promises) { return Promise.all(promises); }; axios$2.spread = requireSpread(); axios$2.isAxiosError = requireIsAxiosError(); axios$3.exports = axios$2; axios$3.exports.default = axios$2; var axiosExports = axios$3.exports; var axios = axiosExports; const axios$1 = /* @__PURE__ */ getDefaultExportFromCjs(axios); function xhrAdapter(config) { return new Promise((resolve, reject) => { let requestData = config.data; const requestHeaders = config.headers ?? {}; if (utils$d.isFormData(requestData)) { delete requestHeaders["Content-Type"]; } if (config.auth) { const username = config.auth.username || ""; const password = config.auth.password || ""; requestHeaders.Authorization = "Basic " + Buffer.from(username + ":" + password).toString("base64"); } const onerror = function handleError() { reject(new axios.AxiosError("Network Error", axios.AxiosError.ERR_NETWORK, config)); }; const ontimeout = function handleTimeout() { reject(new axios.AxiosError("timeout of " + config.timeout + "ms exceeded", axios.AxiosError.ECONNABORTED, config)); }; utils$d.forEach(requestHeaders, function setRequestHeader(val, key) { if (typeof requestData === "undefined" && key.toLowerCase() === "content-type") { delete requestHeaders[key]; } }); if (requestData === void 0) { requestData = null; } const onload = function handleLoad(resp) { const responseHeaders = "responseHeaders" in resp ? parseHeaders$1(resp.responseHeaders) : {}; const responseData = !config.responseType || config.responseType === "text" ? resp.responseText : resp.response; const response = { data: responseData, status: resp.status, statusText: resp.statusText, headers: responseHeaders, config, request: { // can't got real XMLHttpRequest object, only some property is available responseURL: resp.finalUrl, status: resp.status, statusText: resp.statusText, responseXML: null } }; settle$1(resolve, reject, response); }; if (config.cancelToken) { config.cancelToken.promise.then(function onCanceled(cancel) { reject(cancel); }); } let responseType; if (config.responseType && config.responseType !== "json") { responseType = config.responseType; } const method = config.method.toUpperCase(); if (method === "UNLINK" || method === "PURGE" || method === "LINK") { reject(new axios.AxiosError(`${method} is not a supported method by GM.xmlHttpRequest`)); } else { GM.xmlHttpRequest({ method, url: buildURL$2(buildFullPath$2(config.baseURL, config.url), config.params, config.paramsSerializer), headers: Object.fromEntries(Object.entries(requestHeaders).map(([key, val]) => [key, val.toString()])), responseType, data: requestData, timeout: config.timeout, ontimeout, onload, onerror }); } }); } const characters$2 = JSON.parse(GM_getResourceText("character")); const weapons$2 = JSON.parse(GM_getResourceText("weapon")); const charactersNum$1 = characters$2.length; const getCharacterId$2 = (queryName) => { for (let e of characters$2) { const { id, name } = e; if (queryName == name) { return id; } } console.error(`getCharacterId ${queryName} 查询失败`); return ""; }; const getWeaponId$2 = (queryName) => { for (let e of weapons$2) { const { id, name } = e; if (queryName == name) { return id; } } console.error(`getWeaponrId ${queryName} 查询失败`); return ""; }; const elementAttrIds = [ { element_attr_id: 1, name: "pyro" }, { element_attr_id: 2, name: "anemo" }, { element_attr_id: 3, name: "geo" }, { element_attr_id: 4, name: "electro" }, { element_attr_id: 5, name: "hydro" }, { element_attr_id: 6, name: "cryo" }, { element_attr_id: 7, name: "dendro" } ]; const getElementAttrName = (queryName) => { for (let e of elementAttrIds) { const { element_attr_id, name } = e; if (queryName == element_attr_id) { return name; } } console.error(`getElementAttrName: ${queryName} 查询失败`); return ""; }; axios$1.defaults.adapter = xhrAdapter; axios$1.defaults.withCredentials = true; async function refreshPage() { console.log("刷新页面?"); const confirmed = confirm("确定要刷新页面吗?刷新后将重新加载所有数据。"); if (confirmed) { window.location.reload(); } } function getGuid() { function S4() { return ((1 + Math.random()) * 65536 | 0).toString(16).substring(1); } return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4(); } function generateCharString(number = 16) { const characters2 = "abcdef0123456789"; let result = ""; for (let i = 0; i < number; i++) { const randomIndex = Math.floor(Math.random() * characters2.length); result += characters2[randomIndex]; } return result; } const headers = { Referer: "https://act.mihoyo.com/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" }; const to = (promise) => promise.then((data2) => { return [null, data2]; }).catch((err) => { console.error(err); return [err]; }); const getFp = async () => { let fp = localStorage.getItem("fp"); let deviceId = localStorage.getItem("mysDeviceId"); if (!deviceId) { deviceId = getGuid(); localStorage.setItem("mysDeviceId", deviceId); } if (!fp) { let url = "https://public-data-api.mihoyo.com/device-fp/api/getFp"; const [err, res] = await to(axios$1.post( url, JSON.stringify({ seed_id: generateCharString(), device_id: deviceId.toUpperCase(), platform: "1", seed_time: (/* @__PURE__ */ new Date()).getTime() + "", ext_fields: `{"proxyStatus":"0","accelerometer":"-0.159515x-0.830887x-0.682495","ramCapacity":"3746","IDFV":"${deviceId.toUpperCase()}","gyroscope":"-0.191951x-0.112927x0.632637","isJailBreak":"0","model":"iPhone12,5","ramRemain":"115","chargeStatus":"1","networkType":"WIFI","vendor":"--","osVersion":"17.0.2","batteryStatus":"50","screenSize":"414×896","cpuCores":"6","appMemory":"55","romCapacity":"488153","romRemain":"157348","cpuType":"CPU_TYPE_ARM64","magnetometer":"-84.426331x-89.708435x-37.117889"}`, app_name: "bbs_cn", device_fp: "38d7ee834d1e9" }), { timeout: 5e3, headers } )); if (!err) { const { status, data: resData } = await res; if (status == 200) { const { retcode, data: data2 } = resData; if (retcode === 0) { let resFp = data2["device_fp"]; localStorage.setItem("fp", resFp); return resFp; } } } } else { return fp; } }; const getAccount = async (roleUrl, openUrl, gameType) => { const [err, res] = await to(axios$1.get(roleUrl, { headers })); if (!err) { const { status, data: resData } = await res; if (status == 200) { const { retcode, data: data2 } = resData; if (retcode === 0) { const { list: accountList } = await data2; return accountList; } } } alert(`请确认已登录活动页面且绑定${gameType}账户!`); GM_openInTab(openUrl); throw err ? err : new Error("账户信息获取失败"); }; const getStorageAccount = () => localStorage.account || "main"; const getTotalGoal = async () => { const currentAdapter = AdapterManager.getCurrentAdapter(); const key = `${getStorageAccount()}-goals`; const text = await currentAdapter.getItem(key) || "[]"; return typeof text === "string" ? JSON.parse(text) : text; }; const getGoalInactive = async () => { const currentAdapter = AdapterManager.getCurrentAdapter(); const key = `${getStorageAccount()}-inactive`; const text = await currentAdapter.getItem(key) || "[]"; return Object.keys(typeof text === "string" ? JSON.parse(text) : text); }; const setGoalInactive = async (ids = /* @__PURE__ */ new Set()) => { const inactiveObject = Object.fromEntries( [...ids].map((id) => [id, true]) ); const currentAdapter = AdapterManager.getCurrentAdapter(); const key = `${getStorageAccount()}-inactive`; await currentAdapter.setItem(key, inactiveObject); await refreshPage(); }; const setGoals = async (goals) => { const key = `${getStorageAccount()}-goals`; const currentAdapter = AdapterManager.getCurrentAdapter(); await currentAdapter.setItem(key, goals); await currentAdapter.setItem("last_update", (/* @__PURE__ */ new Date()).toISOString()); }; const getNextId = async () => { const goals = await getTotalGoal(); const ids = goals.map((g2) => g2.id).filter((id) => true); return ids.length > 0 ? Math.max(...ids) + 1 : 1; }; const batchUpdateGoals = async (type, identifierKey, updateFn, all, ...updateArgs) => { const totalGoal = await getTotalGoal(); const goalInactive = await getGoalInactive(); const goals = totalGoal.filter((a) => a.type === type).filter((a) => all || !goalInactive.includes(a[identifierKey])); for (let goal of goals) { await updateFn(goal, ...updateArgs); } await refreshPage(); }; const computeInactive = (goals, config) => { var _a2, _b2, _c; const isGoalCompleted = (goal) => goal.goal.level <= goal.current.level; const goalTypeIdentifiers = /* @__PURE__ */ new Map(); config.forEach(({ type, identifierKey, isTalent, talentKeys }) => { const filteredGoals = goals.filter((g2) => g2.type === type); if (isTalent && talentKeys) { const completedTalents = filteredGoals.filter( (talent) => talentKeys.every( (key) => talent[key].goal <= talent[key].current ) ); goalTypeIdentifiers.set(type, new Set(completedTalents.map((g2) => g2[identifierKey].toString()))); } else { const goals1 = filteredGoals; const completedGoals = goals1.filter(isGoalCompleted); goalTypeIdentifiers.set(type, new Set(completedGoals.map((g2) => g2[identifierKey].toString()))); } }); const characterType = (_a2 = config.find((c) => c.type === "character")) == null ? void 0 : _a2.type; const talentType = (_b2 = config.find((c) => c.isTalent)) == null ? void 0 : _b2.type; const weaponType = (_c = config.find((c) => !c.isTalent && c.type !== "character")) == null ? void 0 : _c.type; const characterIds = goalTypeIdentifiers.get(characterType) || /* @__PURE__ */ new Set(); const talentIds = goalTypeIdentifiers.get(talentType) || /* @__PURE__ */ new Set(); const weaponIds = goalTypeIdentifiers.get(weaponType) || /* @__PURE__ */ new Set(); const characterNames = new Set([...talentIds].filter((id) => characterIds.has(id))); return /* @__PURE__ */ new Set([...characterNames, ...weaponIds]); }; const setInactive = async (config) => { const goals = await getTotalGoal(); const inactive = computeInactive(goals, config); await setGoalInactive(inactive); }; axios$1.defaults.adapter = xhrAdapter; axios$1.defaults.withCredentials = true; const CHARACTERS_URL$2 = "https://api-takumi.mihoyo.com/event/e20200928calculate/v1/sync/avatar/list"; const requestPageSize$1 = 200; const getCharacters$2 = async (uid, region, page = 1) => { let fp = await getFp(); const genshinHeaders = { "x-rpc-device_fp": fp, ...headers }; const [err, res] = await to(axios$1.post(CHARACTERS_URL$2, JSON.stringify({ "element_attr_ids": [], "weapon_cat_ids": [], "page": page, "size": requestPageSize$1, "uid": uid, "region": region, "lang": "zh-cn" }), { timeout: 5e3, headers: genshinHeaders })); if (!err) { const { status, data: resData } = await res; if (status == 200) { const { retcode, data: data2 } = resData; if (retcode === 0) { const { list: characterList } = await data2; return characterList; } } } localStorage.removeItem("fp"); throw err ? err : new Error("角色列表获取失败"); }; const getCharacterDetail$2 = async (character, uid, region) => { return { character, ...character }; }; const getDetailList$2 = async (game_uid, region) => { let maxPageSize = Math.ceil(charactersNum$1 / requestPageSize$1); let idxs = Array.from(new Array(maxPageSize).keys()); const characters2 = []; for await (let i of idxs) { characters2.push.apply(characters2, await getCharacters$2(game_uid, region, i + 1)); } const details = characters2.map((c) => getCharacterDetail$2(c)); const detailList = []; for await (let d of details) { if (!!d) { detailList.push(d); } } return detailList; }; const addGoal$2 = async (data2) => { var _a2, _b2; let index = -1; const goals = await getTotalGoal(); if (data2.character) { index = goals.findIndex( (g2) => g2.character === data2.character && g2.type === data2.type ); } else if (data2.id) { index = goals.findIndex((g2) => g2.id === data2.id); } if (index >= 0) { goals[index] = { ...goals[index], ...data2 }; } else { const lastId = (_b2 = (_a2 = goals == null ? void 0 : goals.map((g2) => g2.id)) == null ? void 0 : _a2.filter((id) => typeof id == "number")) == null ? void 0 : _b2.sort((a, b) => a < b ? 1 : -1)[0]; data2.id = (lastId || 0) + 1; goals.push(data2); } await setGoals(goals); }; const addTalentGoal = async (talentCharacter, skill_list) => { const totalGoal = await getTotalGoal(); const talentIdx = totalGoal.findIndex((g2) => g2.type == "talent" && g2.character == talentCharacter); const [normalCurrent, skillCurrent, burstCurrent] = skill_list.filter((a) => a.max_level == 10).sort().map((a) => a.level_current); let talentGoal; if (talentIdx < 0) { const id = await getNextId(); talentGoal = { type: "talent", character: talentCharacter, c3: false, c5: false, normal: { current: normalCurrent, goal: normalCurrent }, skill: { current: skillCurrent, goal: skillCurrent }, burst: { current: burstCurrent, goal: burstCurrent }, id }; } else { const seelieGoal = totalGoal[talentIdx]; const { normal, skill, burst } = seelieGoal; const { goal: normalGoal } = normal; const { goal: skillGoal } = skill; const { goal: burstGoal } = burst; talentGoal = { ...seelieGoal, normal: { current: normalCurrent, goal: normalCurrent > normalGoal ? normalCurrent : normalGoal }, skill: { current: skillCurrent, goal: skillCurrent > skillGoal ? skillCurrent : skillGoal }, burst: { current: burstCurrent, goal: burstCurrent > burstGoal ? burstCurrent : burstGoal } }; } await addGoal$2(talentGoal); }; const addCharacterGoal$2 = async (level_current, nameEn, name, type) => { let totalGoal = await getTotalGoal(); let characterPredicate = (g2) => g2.type == type && g2.character == nameEn; let weaponPredicate = (g2) => g2.type == type && g2.weapon == nameEn; const characterIdx = totalGoal.findIndex(type == "character" ? characterPredicate : weaponPredicate); const characterStatus = initCharacterStatus$2(level_current); let characterGoal; function initCharacterGoal(id) { return { type, character: nameEn, current: characterStatus, goal: characterStatus, id }; } function initWeaponGoal(id) { return { type, character: "", weapon: nameEn, current: characterStatus, goal: characterStatus, id }; } if (characterIdx < 0) { const id = await getNextId(); characterGoal = type == "character" ? initCharacterGoal(id) : initWeaponGoal(id); } else { const seelieGoal = type == "character" ? totalGoal[characterIdx] : totalGoal[characterIdx]; const { goal, current } = seelieGoal; const { level: levelCurrent, asc: ascCurrent } = current; const { level: levelGoal, asc: ascGoal } = goal; const { level, asc } = characterStatus; characterGoal = { ...seelieGoal, current: level >= levelCurrent && asc >= ascCurrent ? characterStatus : current, goal: level >= levelGoal && asc >= ascGoal ? characterStatus : goal }; } await addGoal$2(characterGoal); }; async function addCharacter$2(characterDataEx) { const { character, skill_list, weapon } = characterDataEx; const { name, element_attr_id } = character; if (weapon) { const { name: name2, level_current: weaponLeveL } = weapon; const weaponId = getWeaponId$2(name2); if (weaponId) { await addCharacterGoal$2(weaponLeveL, weaponId, name2, "weapon"); } } const { level_current: characterLevel } = character; const characterId = getCharacterId$2(name); if (!characterId) { return; } await addCharacterGoal$2(characterLevel, characterId, name, "character"); let talentCharacter = characterId; if (characterId == "traveler") { const elementAttrName = getElementAttrName(element_attr_id); talentCharacter = `traveler_${elementAttrName}`; } await addTalentGoal(talentCharacter, skill_list); } const characterStatusList$2 = [ { level: 1, asc: 0, text: "1" }, { level: 20, asc: 0, text: "20" }, { level: 20, asc: 1, text: "20 A" }, { level: 40, asc: 1, text: "40" }, { level: 40, asc: 2, text: "40 A" }, { level: 50, asc: 2, text: "50" }, { level: 50, asc: 3, text: "50 A" }, { level: 60, asc: 3, text: "60" }, { level: 60, asc: 4, text: "60 A" }, { level: 70, asc: 4, text: "70" }, { level: 70, asc: 5, text: "70 A" }, { level: 80, asc: 5, text: "80" }, { level: 80, asc: 6, text: "80 A" }, { level: 90, asc: 6, text: "90" } ]; const initCharacterStatus$2 = (level_current) => { let initCharacterStatus2 = characterStatusList$2[0]; if (level_current < 20) { return initCharacterStatus2; } for (let characterStatus of characterStatusList$2) { const { level } = characterStatus; if (level_current < level) { return initCharacterStatus2; } else if (level_current == level) { return characterStatus; } else if (level_current > level) { initCharacterStatus2 = characterStatus; } } return initCharacterStatus2; }; const updateTalent = async (talent, normalGoal = 9, skillGoal = 9, burstGoal = 9) => { const { normal: { current: normalCurrent }, skill: { current: skillCurrent }, burst: { current: burstCurrent } } = talent; const talentNew = { ...talent, normal: { current: normalCurrent, goal: normalCurrent > normalGoal ? normalCurrent : normalGoal }, skill: { current: skillCurrent, goal: skillCurrent > skillGoal ? skillCurrent : skillGoal }, burst: { current: burstCurrent, goal: burstCurrent > burstGoal ? burstCurrent : burstGoal } }; await addGoal$2(talentNew); }; const batchUpdateTalent = async (all, normal, skill, burst) => { await batchUpdateGoals( "talent", "character", // 天赋目标用character字段标识 (talent) => updateTalent(talent, normal, skill, burst), all ); }; const updateCharacter$2 = async (character, characterStatusGoal) => { const { current } = character; const { level: levelCurrent, asc: ascCurrent } = current; const { level, asc } = characterStatusGoal; const characterGoalNew = { ...character, goal: level >= levelCurrent && asc >= ascCurrent ? characterStatusGoal : current }; await addGoal$2(characterGoalNew); }; const batchUpdateCharacter$2 = async (all, characterStatusGoal) => { batchUpdateGoals( "character", "character", // 角色目标用character字段标识 updateCharacter$2, all, characterStatusGoal ).then(() => { console.log("角色更新完成"); }); }; const batchUpdateWeapon$2 = async (all, characterStatusGoal) => { batchUpdateGoals( "weapon", "weapon", // 武器目标用weapon字段标识 (weapon) => updateCharacter$2(weapon, characterStatusGoal), all, characterStatusGoal ).then(() => { console.log("武器更新完成"); }); }; class BaseAdapter { constructor() { // 公共实现:批量更新角色 __publicField(this, "batchUpdateCharacter", (all, status) => { const { batchUpdateCharacter: batchUpdateCharacter2 } = this.importSeelieMethods(); batchUpdateCharacter2(all, status); }); // 公共实现:批量更新武器 __publicField(this, "batchUpdateWeapon", (all, status) => { const { batchUpdateWeapon: batchUpdateWeapon2 } = this.importSeelieMethods(); batchUpdateWeapon2(all, status); }); } // 公共实现:获取账户列表 async getAccounts() { const { BBS_URL, ROLE_URL } = this.getApiConfig(); return await getAccount(ROLE_URL, BBS_URL, this.getGameName()); } async getItem(key) { return Promise.resolve(localStorage.getItem(key)); } async setItem(key, value) { localStorage.setItem(key, typeof value === "string" ? value : JSON.stringify(value)); return Promise.resolve(); } } class GenshinAdapter extends BaseAdapter { constructor() { super(...arguments); __publicField(this, "batchUpdateTalent", (all, normal, skill, burst) => { batchUpdateTalent(all, normal, skill, burst).then(() => { console.log("天赋更新完成"); }); }); __publicField(this, "getInactiveConfig", () => { const GENSHIN_INACTIVE_CONFIG = [ { type: "character", identifierKey: "character" }, // 角色目标(标识字段:character) { type: "talent", identifierKey: "character", isTalent: true, talentKeys: ["normal", "skill", "burst"] // 原神天赋类型:普通攻击/元素战技/元素爆发 }, // 天赋目标(标识字段:character) { type: "weapon", identifierKey: "id" } // 武器目标(标识字段:weapon) ]; return GENSHIN_INACTIVE_CONFIG; }); } getGameName() { return GameType.GENSHIN; } getApiConfig() { return { BBS_URL: "https://act.mihoyo.com/ys/event/calculator/index.html", ROLE_URL: "https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=hk4e_cn" }; } async getCharacterDetails(uid, region) { return getDetailList$2(uid, region); } async syncCharacters(res) { console.group("返回数据"); console.groupCollapsed("角色"); console.table(res.map((a) => a.character)); console.groupEnd(); console.groupCollapsed("武器"); console.table(res.map((a) => a.weapon)); console.groupEnd(); console.groupCollapsed("角色天赋"); res.forEach((c) => { const name = c.character.name; console.groupCollapsed(name); console.table(c.skill_list); console.groupEnd(); }); console.groupEnd(); console.groupEnd(); for (let v of res) { await addCharacter$2(v); } } importSeelieMethods() { return { batchUpdateCharacter: batchUpdateCharacter$2, batchUpdateWeapon: batchUpdateWeapon$2 }; } getCharacterStatusList() { return characterStatusList$2; } } const characters$1 = JSON.parse(GM_getResourceText("hsr_character")); const weapons$1 = JSON.parse(GM_getResourceText("hsr_weapon")); const charactersNum = characters$1.length; const getCharacterId$1 = (queryName) => { for (let e of characters$1) { const { id, name } = e; if (queryName == name) { return id; } } console.error(`getCharacterId ${queryName} 查询失败`); return ""; }; const getWeaponId$1 = (queryName) => { for (let e of weapons$1) { const { id, name } = e; if (queryName == name) { return id; } } console.error(`getWeaponrId ${queryName} 查询失败`); return ""; }; axios$1.defaults.adapter = xhrAdapter; axios$1.defaults.withCredentials = true; const CHARACTERS_URL$1 = "https://api-takumi.mihoyo.com/event/rpgcalc/avatar/list"; const CHARACTERS_DETAIL_URL$1 = "https://api-takumi.mihoyo.com/event/rpgcalc/avatar/detail"; const requestPageSize = 50; const getCharacters$1 = async (uid, region, page = 1) => { let url = CHARACTERS_URL$1; let game = "hkrpg"; let params = `?game=${game}&uid=${uid}®ion=${region}&lang=zh-cn&tab_from=TabOwned&page=${page}&size=100`; const [err, res] = await to(axios$1.get(url + params, { headers })); if (!err) { const { status, data: resData } = await res; if (status == 200) { const { retcode, data: data2 } = resData; if (retcode === 0) { const { list: characterList } = await data2; return characterList; } } } throw err ? err : new Error("角色列表获取失败"); }; const getCharacterDetail$1 = async (character, uid, region) => { const { item_id: id } = character; let game = "hkrpg"; const params = `?game=${game}&lang=zh-cn&item_id=${id}&tab_from=TabOwned&change_target_level=0&uid=${uid}®ion=${region}`; let URL = CHARACTERS_DETAIL_URL$1; const [err, res] = await to(axios$1.get(URL + params, { headers })); if (!err) { const { status, data: resData } = await res; if (status == 200) { const { retcode, data: data2 } = resData; if (retcode === 0) { const characterData = await data2; return characterData; } } } else { console.error(err); } }; const getDetailList$1 = async (game_uid, region) => { let maxPageSize = Math.ceil(charactersNum / requestPageSize); let idxs = Array.from(new Array(maxPageSize).keys()); const characters2 = []; for await (let i of idxs) { characters2.push.apply(characters2, await getCharacters$1(game_uid, region, i + 1)); } const details = characters2.map((c) => getCharacterDetail$1(c, game_uid, region)); const detailList = []; for await (let d of details) { if (!!d) { detailList.push(d); } } return detailList; }; const addGoal$1 = async (data2) => { var _a2, _b2; let index = -1; const goals = await getTotalGoal(); if (data2.character) { index = goals.findIndex( (g2) => g2.character === data2.character && g2.type === data2.type ); } else if (data2.id) { index = goals.findIndex((g2) => g2.id === data2.id); } if (index >= 0) { goals[index] = { ...goals[index], ...data2 }; } else { const lastId = (_b2 = (_a2 = goals == null ? void 0 : goals.map((g2) => g2.id)) == null ? void 0 : _a2.filter((id) => typeof id == "number")) == null ? void 0 : _b2.sort((a, b) => a < b ? 1 : -1)[0]; data2.id = (lastId || 0) + 1; goals.push(data2); } await setGoals(goals); }; let initBonus = {}; const addTraceGoal$1 = async (talentCharacter, skill_list, skills_servant) => { const totalGoal = await getTotalGoal(); const talentIdx = totalGoal.findIndex((g2) => g2.type == "trace" && g2.character == talentCharacter); skill_list.sort((a, b) => a.point_id > b.point_id ? 1 : 0); const [baseCurrent, skillCurrent, ultimateCurrent, talentCurrent] = skill_list.map((a) => a.cur_level); let [petSkillCurrent, petTalentCurrent] = [1, 1]; let hasServant = skills_servant && skills_servant.length > 0; if (hasServant) { [petSkillCurrent, petTalentCurrent] = skills_servant.map((a) => a.cur_level); } let talentGoal; if (talentIdx < 0) { const id = await getNextId(); talentGoal = { type: "trace", character: talentCharacter, basic: { current: baseCurrent, goal: baseCurrent }, skill: { current: skillCurrent, goal: skillCurrent }, ultimate: { current: ultimateCurrent, goal: ultimateCurrent }, talent: { current: talentCurrent, goal: talentCurrent }, pet_skill: { current: petSkillCurrent, goal: petSkillCurrent }, pet_talent: { current: petSkillCurrent, goal: petSkillCurrent }, bonus: initBonus, id }; } else { const seelieGoal = totalGoal[talentIdx]; const { basic, skill, ultimate, talent, pet_skill, pet_talent } = seelieGoal; const { goal: basicGoal } = basic; const { goal: skillGoal } = skill; const { goal: ultimateGoal } = ultimate; const { goal: talentGoal2 } = talent; const { goal: petSkillGoal } = pet_skill; const { goal: petTalentGoal } = pet_talent; talentGoal = { ...seelieGoal, basic: { current: baseCurrent, goal: baseCurrent > basicGoal ? Math.min(petSkillCurrent, 6) : basicGoal }, skill: { current: skillCurrent, goal: skillCurrent > skillGoal ? skillCurrent : skillGoal }, ultimate: { current: ultimateCurrent, goal: ultimateCurrent > ultimateGoal ? ultimateCurrent : ultimateGoal }, talent: { current: talentCurrent, goal: talentCurrent > talentGoal2 ? talentCurrent : talentGoal2 }, pet_skill: { current: petSkillCurrent, goal: petSkillCurrent > petSkillGoal ? Math.min(petSkillCurrent, 6) : petSkillGoal }, pet_talent: { current: petTalentCurrent, goal: petTalentCurrent > petTalentGoal ? Math.min(petTalentCurrent, 6) : petTalentGoal } }; } await addGoal$1(talentGoal); }; const addCharacterGoal$1 = async (level_current, nameEn, name, type) => { const totalGoal = await getTotalGoal(); let characterPredicate = (g2) => g2.type == type && g2.character == nameEn; let weaponPredicate = (g2) => g2.type == type && g2.cone == nameEn; const characterIdx = totalGoal.findIndex(type == "character" ? characterPredicate : weaponPredicate); const characterStatus = initCharacterStatus$1(level_current); let characterGoal; function initCharacterGoal(id) { return { type, character: nameEn, current: characterStatus, goal: characterStatus, id, eidolon: 0 }; } function initWeaponGoal(id) { return { type, character: "", cone: nameEn, current: characterStatus, goal: characterStatus, id }; } if (characterIdx < 0) { const id = await getNextId(); characterGoal = type == "character" ? initCharacterGoal(id) : initWeaponGoal(id); } else { const seelieGoal = type == "character" ? totalGoal[characterIdx] : totalGoal[characterIdx]; const { goal, current } = seelieGoal; const { level: levelCurrent, asc: ascCurrent } = current; const { level: levelGoal, asc: ascGoal } = goal; const { level, asc } = characterStatus; characterGoal = { ...seelieGoal, current: level >= levelCurrent && asc >= ascCurrent ? characterStatus : current, goal: level >= levelGoal && asc >= ascGoal ? characterStatus : goal }; } await addGoal$1(characterGoal); }; async function addCharacter$1(characterDataEx) { const { avatar: character, skills: skill_list, skills_servant, equipment: weapon } = characterDataEx; const { item_name: name } = character; if (weapon) { const { item_name: name2, cur_level: weaponLeveL } = weapon; const weaponId = getWeaponId$1(name2); if (weaponId) { await addCharacterGoal$1(weaponLeveL, weaponId, name2, "cone"); } } const { cur_level: characterLevel } = character; const characterId = getCharacterId$1(name); if (!characterId || characterId.includes("trailblazer")) { return; } await addCharacterGoal$1(characterLevel, characterId, name, "character"); await addTraceGoal$1(characterId, skill_list, skills_servant); } const characterStatusList$1 = [ { level: 1, asc: 0, text: "1" }, { level: 20, asc: 0, text: "20" }, { level: 20, asc: 1, text: "20 A" }, { level: 30, asc: 1, text: "30" }, { level: 30, asc: 2, text: "30 A" }, { level: 40, asc: 2, text: "40" }, { level: 40, asc: 3, text: "40 A" }, { level: 50, asc: 3, text: "50" }, { level: 50, asc: 4, text: "50 A" }, { level: 60, asc: 5, text: "60" }, { level: 60, asc: 5, text: "60 A" }, { level: 70, asc: 5, text: "70" }, { level: 70, asc: 6, text: "70 A" }, { level: 80, asc: 6, text: "80" } ]; const initCharacterStatus$1 = (level_current) => { let initCharacterStatus2 = characterStatusList$1[0]; if (level_current < 20) { return initCharacterStatus2; } for (let characterStatus of characterStatusList$1) { const { level } = characterStatus; if (level_current < level) { return initCharacterStatus2; } else if (level_current == level) { return characterStatus; } else if (level_current > level) { initCharacterStatus2 = characterStatus; } } return initCharacterStatus2; }; const updateTrace$1 = async (talent, normalGoal = 6, skillGoal = 9, burstGoal = 9, talentGoal2 = 9) => { const { basic: { current: basicCurrent }, skill: { current: skillCurrent }, ultimate: { current: ultimateCurrent }, talent: { current: talentCurrent } } = talent; const talentNew = { ...talent, basic: { current: basicCurrent, goal: basicCurrent > normalGoal ? basicCurrent : normalGoal }, skill: { current: skillCurrent, goal: skillCurrent > skillGoal ? skillCurrent : skillGoal }, ultimate: { current: ultimateCurrent, goal: ultimateCurrent > burstGoal ? ultimateCurrent : burstGoal }, talent: { current: talentCurrent, goal: talentCurrent > talentGoal2 ? talentCurrent : talentGoal2 } }; await addGoal$1(talentNew); }; const batchUpdateTrace$1 = async (all, normal, skill, burst, t) => { if (normal > 6) { normal = 6; } await batchUpdateGoals( "trace", "character", // 天赋目标用character字段标识 (trace) => updateTrace$1(trace, normal, skill, burst, t), all ); }; const updateCharacter$1 = async (character, characterStatusGoal) => { const { current } = character; const { level: levelCurrent, asc: ascCurrent } = current; const { level, asc } = characterStatusGoal; const characterGoalNew = { ...character, goal: level >= levelCurrent && asc >= ascCurrent ? characterStatusGoal : current }; await addGoal$1(characterGoalNew); }; const batchUpdateCharacter$1 = async (all, characterStatusGoal) => { batchUpdateGoals( "character", "character", updateCharacter$1, all, characterStatusGoal ).then(() => { console.log("角色更新完成"); }); }; const batchUpdateWeapon$1 = async (all, characterStatusGoal) => { batchUpdateGoals( "cone", "cone", (weapon) => updateCharacter$1(weapon, characterStatusGoal), all, characterStatusGoal ).then(() => { console.log("武器更新完成"); }); }; class HsrAdapter extends BaseAdapter { constructor() { super(...arguments); __publicField(this, "batchUpdateTalent", (all, normal, skill, burst, t) => { batchUpdateTrace$1(all, normal, skill, burst, t); }); __publicField(this, "getInactiveConfig", () => { const HSR_INACTIVE_CONFIG = [ { type: "character", identifierKey: "character" }, // 角色目标 { type: "trace", identifierKey: "character", isTalent: true, talentKeys: ["basic", "skill", "ultimate", "talent", "pet_talent", "pet_skill"] }, // 行迹目标 { type: "cone", identifierKey: "id" } // 光锥目标(标识键为 id) ]; return HSR_INACTIVE_CONFIG; }); } getGameName() { return GameType.HSR; } getApiConfig() { return { BBS_URL: "https://act.mihoyo.com/sr/event/cultivation-tool/index.html", ROLE_URL: "https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=hkrpg_cn" }; } async getCharacterDetails(uid, region) { return getDetailList$1(uid, region); } async syncCharacters(res) { console.group("返回数据"); console.groupCollapsed("角色"); console.table(res.map((a) => a.avatar)); console.groupEnd(); console.groupCollapsed("光锥"); console.table(res.map((a) => a.equipment)); console.groupEnd(); console.groupCollapsed("角色天赋"); res.forEach((c) => { const name = c.avatar.item_name; console.groupCollapsed(name); console.table(c.skills); console.groupEnd(); }); console.groupEnd(); console.groupCollapsed("角色额外天赋(仅展示不做处理)"); res.forEach((c) => { const name = c.avatar.item_name; console.groupCollapsed(name); console.table(c.skills_other); console.groupEnd(); }); console.groupEnd(); console.groupEnd(); for (let v of res) { await addCharacter$1(v); } } importSeelieMethods() { return { batchUpdateCharacter: batchUpdateCharacter$1, batchUpdateWeapon: batchUpdateWeapon$1 }; } getCharacterStatusList() { return characterStatusList$1; } async getItem(key) { return localforage2.getItem(key); } async setItem(key, value) { return localforage2.setItem(key, value); } } axios$1.defaults.adapter = xhrAdapter; axios$1.defaults.withCredentials = true; const CHARACTERS_URL = "https://api-takumi.mihoyo.com/event/nap_cultivate_tool/user/avatar_basic_list"; const CHARACTERS_DETAIL_URL = "https://api-takumi.mihoyo.com/event/nap_cultivate_tool/user/batch_avatar_detail_v2"; const getCharacters = async (uid, region, page = 1) => { let url = CHARACTERS_URL; let params = `?uid=${uid}®ion=${region}`; let fp = await getFp(); const [err, res] = await to(axios$1.get(url + params, { headers: { ...headers, "x-rpc-device_fp": fp }, timeout: 1e4 })); if (!err) { const { status, data: resData } = await res; if (status == 200) { const { retcode, data: data2 } = resData; if (retcode === 0) { const { list: characterList } = await data2; return characterList; } } } alert("请确认已登录活动页面且绑定账户!"); throw err ? err : new Error("角色列表获取失败"); }; const getCharacterDetail = async (ids, uid, region) => { const params = `?uid=${uid}®ion=${region}`; let URL = CHARACTERS_DETAIL_URL; let fp = await getFp(); let avatarList = ids.map((id) => ({ avatar_id: id, is_teaser: false, teaser_need_weapon: false, teaser_sp_skill: false })); const [err, res] = await to(axios$1.post( URL + params, { avatar_list: avatarList }, { headers: { ...headers, "x-rpc-device_fp": fp }, timeout: 1e4 } )); if (!err) { const { status, data: resData } = await res; if (status == 200) { const { retcode, data: data2 } = resData; if (retcode === 0) { const { list: characterList } = await data2; return characterList; } } } else { console.error(err); } return []; }; const getDetailList = async (game_uid, region) => { let maxPageSize = 1; let idxs = Array.from(new Array(maxPageSize).keys()); const characters2 = []; for await (let i of idxs) { let characterData = await getCharacters(game_uid, region, i + 1); characters2.push.apply(characters2, characterData.filter((a) => a.unlocked).map((a) => a.avatar)); } let ids = characters2.map((a) => a.id); const batchSize = 10; const allResults = []; for (let i = 0; i < ids.length; i += batchSize) { const batchIds = ids.slice(i, i + batchSize); const batchResults = await getCharacterDetail(batchIds, game_uid, region); allResults.push(...batchResults); } return allResults; }; const characters = JSON.parse(GM_getResourceText("zzz_character")); const weapons = JSON.parse(GM_getResourceText("zzz_weapon")); characters.length; const getCharacterId = (queryName) => { for (let e of characters) { const { id, name } = e; if (queryName == name) { return id; } } console.error(`getCharacterId ${queryName} 查询失败`); return ""; }; const getWeaponId = (queryName) => { for (let e of weapons) { const { id, name } = e; if (queryName == name) { return id; } } console.error(`getWeaponrId ${queryName} 查询失败`); return ""; }; const addGoal = async (data2) => { var _a2, _b2; let index = -1; const goals = await getTotalGoal(); if (data2.character) { index = goals.findIndex( (g2) => g2.character === data2.character && g2.type === data2.type ); } else if (data2.id) { index = goals.findIndex((g2) => g2.id === data2.id); } if (index >= 0) { goals[index] = { ...goals[index], ...data2 }; } else { const lastId = (_b2 = (_a2 = goals == null ? void 0 : goals.map((g2) => g2.id)) == null ? void 0 : _a2.filter((id) => typeof id == "number")) == null ? void 0 : _b2.sort((a, b) => a < b ? 1 : -1)[0]; data2.id = (lastId || 0) + 1; goals.push(data2); } await setGoals(goals); }; const addTraceGoal = async (talentCharacter, skill_list) => { const totalGoal = await getTotalGoal(); const talentIdx = totalGoal.findIndex((g2) => g2.type == "talent" && g2.character == talentCharacter); const typeOrder = [0, 2, 6, 1, 3, 5]; skill_list.sort((a, b) => { const aIndex = typeOrder.indexOf(a.skill_type); const bIndex = typeOrder.indexOf(b.skill_type); return aIndex - bIndex; }); const [baseCurrent, dodgeCurrent, assistCurrent, specialCurrent, chainCurrent, coreCurrent] = skill_list.map((a) => a.level); let talentGoal; let coreValue = coreCurrent - 1; if (talentIdx < 0) { const id = await getNextId(); talentGoal = { type: "talent", character: talentCharacter, basic: { current: baseCurrent, goal: baseCurrent }, dodge: { current: dodgeCurrent, goal: dodgeCurrent }, assist: { current: assistCurrent, goal: assistCurrent }, special: { current: specialCurrent, goal: specialCurrent }, chain: { current: chainCurrent, goal: chainCurrent }, core: { current: Math.max(1, coreValue), goal: Math.max(1, coreValue) }, id }; } else { const seelieGoal = totalGoal[talentIdx]; const { basic, dodge, assist, special, chain, core } = seelieGoal; const { goal: basicGoal } = basic; const { goal: dodgeGoal } = dodge; const { goal: assistGoal } = assist; const { goal: specialGoal } = special; const { goal: chainGoal } = chain; const { goal: coreGoal } = core; talentGoal = { ...seelieGoal, basic: { current: baseCurrent, goal: baseCurrent > basicGoal ? baseCurrent : basicGoal }, dodge: { current: dodgeCurrent, goal: dodgeCurrent > dodgeGoal ? dodgeCurrent : dodgeGoal }, assist: { current: assistCurrent, goal: assistCurrent > assistGoal ? assistCurrent : assistGoal }, special: { current: specialCurrent, goal: specialCurrent > specialGoal ? specialCurrent : specialGoal }, chain: { current: chainCurrent, goal: chainCurrent > chainGoal ? chainCurrent : chainGoal }, core: { current: coreValue, goal: coreValue > coreGoal ? coreValue : coreGoal } }; } await addGoal(talentGoal); }; const addCharacterGoal = async (level_current, nameEn, name, type) => { let totalGoal = await getTotalGoal(); let characterPredicate = (g2) => g2.type == type && g2.character == nameEn; let weaponPredicate = (g2) => g2.type == type && g2.weapon == nameEn; const characterIdx = totalGoal.findIndex(type == "character" ? characterPredicate : weaponPredicate); const characterStatus = initCharacterStatus(level_current); let characterGoal; function initCharacterGoal(id) { return { type: "character", character: nameEn, current: characterStatus, goal: characterStatus, id, cons: 0 }; } function initWeaponGoal(id) { return { type: "weapon", character: "", weapon: nameEn, current: characterStatus, goal: characterStatus, id }; } if (characterIdx < 0) { const id = await getNextId(); characterGoal = type == "character" ? initCharacterGoal(id) : initWeaponGoal(id); } else { const seelieGoal = type == "character" ? totalGoal[characterIdx] : totalGoal[characterIdx]; const { goal, current } = seelieGoal; const { level: levelCurrent, asc: ascCurrent } = current; const { level: levelGoal, asc: ascGoal } = goal; const { level, asc } = characterStatus; characterGoal = { ...seelieGoal, current: level >= levelCurrent && asc >= ascCurrent ? characterStatus : current, goal: level >= levelGoal && asc >= ascGoal ? characterStatus : goal }; } await addGoal(characterGoal); }; async function addCharacter(characterDataEx) { const { avatar: character, weapon } = characterDataEx; const { name_mi18n: name, skills: skill_list } = character; if (weapon) { const { name: name2, level: weaponLeveL } = weapon; const weaponId = getWeaponId(name2); if (weaponId) { await addCharacterGoal(weaponLeveL, weaponId, name2, "weapon"); } } const { level: characterLevel } = character; const characterId = getCharacterId(name); if (!characterId || characterId.includes("trailblazer")) { return; } await addCharacterGoal(characterLevel, characterId, name, "character"); await addTraceGoal(characterId, skill_list); } const characterStatusList = [ { level: 1, asc: 0, text: "1" }, { level: 20, asc: 0, text: "20" }, { level: 20, asc: 1, text: "20 A" }, { level: 30, asc: 1, text: "30" }, { level: 30, asc: 2, text: "30 A" }, { level: 40, asc: 2, text: "40" }, { level: 40, asc: 3, text: "40 A" }, { level: 50, asc: 3, text: "50" }, { level: 50, asc: 4, text: "50 A" }, { level: 60, asc: 5, text: "60" } ]; const initCharacterStatus = (level_current) => { let initCharacterStatus2 = characterStatusList[0]; if (level_current < 20) { return initCharacterStatus2; } for (let characterStatus of characterStatusList) { const { level } = characterStatus; if (level_current < level) { return initCharacterStatus2; } else if (level_current == level) { return characterStatus; } else if (level_current > level) { initCharacterStatus2 = characterStatus; } } return initCharacterStatus2; }; const updateTrace = async (talent, basicGoal = 11, dodgeGoal = 11, assistGoal = 11, specialGoal = 11, chainGoal = 11, coreGoal = 6) => { const { basic: { current: baseCurrent }, dodge: { current: dodgeCurrent }, assist: { current: assistCurrent }, special: { current: specialCurrent }, chain: { current: chainCurrent }, core: { current: coreCurrent } } = talent; const talentNew = { ...talent, basic: { current: baseCurrent, goal: baseCurrent > basicGoal ? baseCurrent : basicGoal }, dodge: { current: dodgeCurrent, goal: dodgeCurrent > dodgeGoal ? dodgeCurrent : dodgeGoal }, assist: { current: assistCurrent, goal: assistCurrent > assistGoal ? assistCurrent : assistGoal }, special: { current: specialCurrent, goal: specialCurrent > specialGoal ? specialCurrent : specialGoal }, chain: { current: chainCurrent, goal: chainCurrent > chainGoal ? chainCurrent : chainGoal }, core: { current: coreCurrent, goal: coreCurrent > coreGoal ? coreCurrent : coreGoal } }; await addGoal(talentNew); }; const batchUpdateTrace = async (all, basicGoal = 11, dodgeGoal = 11, assistGoal = 11, specialGoal = 11, chainGoal = 11, coreGoal = 6) => { if (coreGoal > 6) { coreGoal = 6; } await batchUpdateGoals( "talent", "character", // 天赋目标用character字段标识 (trace) => updateTrace(trace, basicGoal, dodgeGoal, assistGoal, specialGoal, chainGoal, coreGoal), all ); }; const updateCharacter = async (character, characterStatusGoal) => { const { current } = character; const { level: levelCurrent, asc: ascCurrent } = current; const { level, asc } = characterStatusGoal; const characterGoalNew = { ...character, goal: level >= levelCurrent && asc >= ascCurrent ? characterStatusGoal : current }; await addGoal(characterGoalNew); }; const batchUpdateCharacter = async (all, characterStatusGoal) => { batchUpdateGoals( "character", "character", // 角色目标用character字段标识 updateCharacter, all, characterStatusGoal ).then(() => { console.log("角色更新完成"); }); }; const batchUpdateWeapon = async (all, characterStatusGoal) => { batchUpdateGoals( "weapon", "weapon", // 武器目标用weapon字段标识 (weapon) => updateCharacter(weapon, characterStatusGoal), all, characterStatusGoal ).then(() => { console.log("武器更新完成"); }); }; class ZzzAdapter extends BaseAdapter { constructor() { super(...arguments); __publicField(this, "batchUpdateTalent", (all, basicGoal, dodgeGoal, assistGoal, specialGoal, chainGoal, coreGoal) => { batchUpdateTrace(all, basicGoal, dodgeGoal, assistGoal, specialGoal, chainGoal, coreGoal); }); __publicField(this, "getInactiveConfig", () => { const ZZZ_INACTIVE_CONFIG = [ { type: "character", identifierKey: "character" }, // 角色目标 { type: "talent", identifierKey: "character", isTalent: true, talentKeys: ["basic", "dodge", "assist", "special", "chain", "core"] }, // 天赋目标 { type: "weapon", identifierKey: "id" } // 武器目标(标识键为 id) ]; return ZZZ_INACTIVE_CONFIG; }); } getGameName() { return GameType.ZZZ; } getApiConfig() { return { BBS_URL: "https://act.mihoyo.com/zzz/gt/character-builder-h/index.html", ROLE_URL: "https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookieToken?game_biz=nap_cn" }; } async getCharacterDetails(uid, region) { return getDetailList(uid, region); } async syncCharacters(res) { console.group("返回数据"); console.groupCollapsed("角色"); console.table(res.map((a) => a.avatar)); console.groupEnd(); console.groupCollapsed("光锥"); console.table(res.map((a) => a.weapon)); console.groupEnd(); console.groupCollapsed("角色天赋"); res.forEach((c) => { const name = c.avatar.name_mi18n; console.groupCollapsed(name); console.table(c.avatar.skills); console.groupEnd(); }); console.groupEnd(); console.groupEnd(); for (let v of res) { await addCharacter(v); } } importSeelieMethods() { return { batchUpdateCharacter, batchUpdateWeapon }; } getCharacterStatusList() { return characterStatusList; } } class AdapterManager { static init() { this.adapters.set(GameType.GENSHIN, new GenshinAdapter()); this.adapters.set(GameType.HSR, new HsrAdapter()); this.adapters.set(GameType.ZZZ, new ZzzAdapter()); this.detectCurrentGame(); } // 新增:根据域名检测当前游戏 static detectCurrentGame() { const hostname = window.location.hostname; console.log("当前域名: %s", hostname); for (const [domain, gameType] of Object.entries(GameDomainMap)) { if (hostname.includes(domain)) { this.currentGame = gameType; return; } } this.currentGame = GameType.GENSHIN; } // 获取当前域名对应的适配器 static getCurrentAdapter() { return this.getAdapter(this.currentGame); } // 获取当前游戏类型 static getCurrentGameType() { return this.currentGame; } static getAdapter(gameType) { const adapter = this.adapters.get(gameType); if (!adapter) { throw new Error(`未找到游戏 ${gameType} 的适配器`); } return adapter; } static getSupportedGames() { return Array.from(this.adapters.entries()).map(([type, adapter]) => ({ type, name: adapter.getGameName() })); } } __publicField(AdapterManager, "adapters", /* @__PURE__ */ new Map()); __publicField(AdapterManager, "currentGame"); AdapterManager.init(); function CharacterGoalTab(props) { const { showText, batchUpdateCharacter: batchUpdateCharacter2 } = props; const [selectAllRoles, setSelectAllRoles] = require$$1.useState(() => true); const characterStatusList2 = AdapterManager.getCurrentAdapter().getCharacterStatusList(); const optionList = characterStatusList2.slice(0).reverse(); const [characterLevelGoal, setCharacterLevelGoal] = require$$1.useState(() => optionList[0]); const batchSetCharacterGoalLevel = () => { batchUpdateCharacter2(!selectAllRoles, characterLevelGoal); }; return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", { className: "flex pt-4", children: /* @__PURE__ */ jsx(ToggleSwitch, { className: "w-full", checked: selectAllRoles, onChange: setSelectAllRoles, labelLeft: `全部${showText}`, labelRight: `仅激活${showText}` }) }), /* @__PURE__ */ jsxs("div", { className: "flex pt-4", children: [/* @__PURE__ */ jsxs("div", { className: "w-1/2 text-white-900", children: [showText, "目标等级:"] }), /* @__PURE__ */ jsx("div", { className: "w-1/2", children: /* @__PURE__ */ jsx(ListboxSelect, { selected: characterLevelGoal, setSelected: setCharacterLevelGoal, optionList, show: (characterStatus) => `${characterStatus.text.replace("A", "破")}` }) })] }), /* @__PURE__ */ jsx("div", { className: "flex pt-2", children: /* @__PURE__ */ jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxs("button", { className: "text-white bg-blue-500 px-4 py-2", onClick: batchSetCharacterGoalLevel, children: ["批量设置", showText, "目标等级"] }) }) })] }); } const TALENT_CONFIG = { [GameType.GENSHIN]: { talentTypes: ["normal", "skill", "burst"], // 原神天赋类型 labels: ["普通攻击", "元素战技", "元素爆发"], // 对应标签 maxLevel: 10 // 原神天赋最大等级 }, [GameType.HSR]: { talentTypes: ["normal", "skill", "burst", "t"], // HSR行迹类型 labels: ["普通攻击", "战技", "终结技", "天赋"], // HSR标签 maxLevel: 10 // HSR行迹最大等级 }, [GameType.ZZZ]: { talentTypes: ["basic", "dodge", "assist", "special", "chain", "core"], // ZZZ技能类型 labels: ["普通攻击", "闪避技", "支援技", "特殊技", "连携技", "核心被动"], // ZZZ标签 maxLevel: 12 // ZZZ技能最大等级 } }; function TalentGoalTab() { const currentGame = AdapterManager.getCurrentGameType(); const { talentTypes, labels, maxLevel } = TALENT_CONFIG[currentGame] || TALENT_CONFIG[GameType.GENSHIN]; const [talentGoalLevel, setTalentGoalLevel] = require$$1.useState(Object.fromEntries(talentTypes.map((type) => [type, maxLevel - 1]))); const [selectAllRoles, setSelectAllRoles] = require$$1.useState(true); const talentLevels = Array.from({ length: maxLevel }, (_, i) => i + 1).reverse(); const handleBatchUpdate = () => { const levels = talentTypes.map((type) => talentGoalLevel[type]); AdapterManager.getCurrentAdapter().batchUpdateTalent(!selectAllRoles, ...levels); }; return /* @__PURE__ */ jsxs("div", { children: [" ", /* @__PURE__ */ jsxs("div", { className: "flex pt-4", children: [" ", /* @__PURE__ */ jsx(ToggleSwitch, { className: "w-full", checked: selectAllRoles, onChange: setSelectAllRoles, labelLeft: "全部角色", labelRight: "仅激活角色" })] }), /* @__PURE__ */ jsxs("div", { className: "grid grid-rows-2 grid-flow-col gap-2", children: [" ", talentTypes.map((type, index) => /* @__PURE__ */ jsxs("div", { className: "flex ex-flex-col items-center", children: [/* @__PURE__ */ jsx("label", { className: "mt-10", children: labels[index] }), " ", /* @__PURE__ */ jsx(ListboxSelect, { selected: talentGoalLevel[type], setSelected: (num) => setTalentGoalLevel({ ...talentGoalLevel, [type]: num }), optionList: talentLevels, show: (num) => `${num}` })] }, type))] }), /* @__PURE__ */ jsxs("div", { className: "flex pt-2", children: [" ", /* @__PURE__ */ jsxs("div", { className: "w-full", children: [" ", /* @__PURE__ */ jsx("button", { onClick: handleBatchUpdate, className: "text-white bg-blue-500 px-4 py-2", children: "批量设置角色目标技能" })] })] })] }); } function ExDialog(props) { const { onClose } = props; const currentAdapter = AdapterManager.getCurrentAdapter(); require$$1.useEffect(() => { console.log(`当前游戏:${currentAdapter.getGameName()}`); }, [currentAdapter]); const [accountList, setAccountList] = require$$1.useState([]); const [currentAccount, setCurrentAccount] = require$$1.useState(); const [isFirstPanelOpen, setIsFirstPanelOpen] = require$$1.useState(false); const [isSecondPanelOpen, setIsSecondPanelOpen] = require$$1.useState(false); const [activeTab, setActiveTab] = require$$1.useState(0); const [isSyncing, setIsSyncing] = require$$1.useState(false); const panelRefs = [require$$1.useRef(null), require$$1.useRef(null)]; require$$1.useEffect(() => { const handleClickOutside = (e) => { if (panelRefs[0].current && !panelRefs[0].current.contains(e.target) && isFirstPanelOpen) { setIsFirstPanelOpen(false); } if (panelRefs[1].current && !panelRefs[1].current.contains(e.target) && isSecondPanelOpen) { setIsSecondPanelOpen(false); } }; document.addEventListener("click", handleClickOutside); return () => document.removeEventListener("click", handleClickOutside); }, [isFirstPanelOpen, isSecondPanelOpen]); const handleRoleSelectChange = (idx) => { setCurrentAccount(accountList[idx]); }; const accountShow = (idx) => { if (!accountList || !accountList[idx]) { return ""; } const role = accountList[idx]; return `${role.game_uid}(${role.region})`; }; const getAccountList = () => { currentAdapter.getAccounts().then((res) => { const roles = res; setAccountList(roles); roles.length > 0 && setCurrentAccount(roles[0]); }).catch((err) => { console.error(err); console.error("账户信息获取失败"); alert("账户信息获取失败"); }); }; const syncCharacterInfo = () => { if (!currentAccount) { console.error("账户信息获取失败"); alert("账户信息获取失败"); return; } console.log("开始同步角色信息"); setIsSyncing(true); const { game_uid, region } = currentAccount; currentAdapter.getCharacterDetails(game_uid, region).then(async (res) => { await currentAdapter.syncCharacters(res); console.log("米游社数据无法判断是否突破,请自行比较整数等级是否已突破"); console.log("角色信息同步完毕"); await refreshPage(); }).catch((err) => { console.error("同步失败:", err); GM_openInTab(currentAdapter.getApiConfig().BBS_URL); }).finally(() => { setIsSyncing(false); }); }; function classNames2(...classes) { return classes.filter(Boolean).join(" "); } const handleMouseLeave = () => { setIsFirstPanelOpen(false); setIsSecondPanelOpen(false); onClose(); }; const batchInActive = () => { setInactive(currentAdapter.getInactiveConfig()); }; return /* @__PURE__ */ jsxs("div", { className: "fixed top-10 inset-x-[20%] ex-mx-auto min-w-[50%] min-h-min rounded-md bg-slate-800/90 text-white text-center z-[1200] shadow-2xl", onMouseLeave: handleMouseLeave, children: [/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold underline pt-4 text-white", children: "SeelieEX" }), /* @__PURE__ */ jsx("div", { className: "w-full p-4", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-md p-2 ex-mx-auto bg-purple-900/30 rounded-2xl border border-purple-700/50", children: [/* @__PURE__ */ jsxs("div", { ref: panelRefs[0], className: "mt-2 border border-gray-700 rounded-lg bg-slate-700/50", children: [/* @__PURE__ */ jsxs("button", { className: "flex justify-between w-full px-4 py-2 text-sm font-medium text-left text-white bg-purple-800/70 rounded-lg hover:bg-purple-700 focus:outline-none transition-colors", onClick: () => setIsFirstPanelOpen(!isFirstPanelOpen), children: [/* @__PURE__ */ jsx("span", { children: "角色信息同步" }), /* @__PURE__ */ jsx("svg", { className: `w-5 h-5 text-purple-300 transition-transform ${isFirstPanelOpen ? "transform rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }), isFirstPanelOpen && /* @__PURE__ */ jsxs("div", { className: "px-4 pt-4 pb-2 text-sm text-gray-100", children: [/* @__PURE__ */ jsx("div", { className: "flex pt-2", children: /* @__PURE__ */ jsx("div", { className: "w-full", children: /* @__PURE__ */ jsx("button", { className: "text-white bg-blue-600 hover:bg-blue-500 px-4 py-2 rounded transition-colors", onClick: getAccountList, children: "获取账户信息" }) }) }), /* @__PURE__ */ jsxs("div", { className: "flex pt-4", children: [/* @__PURE__ */ jsx("div", { className: "w-1/2 text-gray-200", children: "账户选择:" }), /* @__PURE__ */ jsx("div", { className: "w-1/2", children: /* @__PURE__ */ jsx(ListboxSelect, { selected: currentAccount ? accountList.indexOf(currentAccount) : 0, setSelected: handleRoleSelectChange, optionList: accountList.map((_, idx) => idx), show: accountShow }) })] }), /* @__PURE__ */ jsx("div", { className: "flex pt-2", children: /* @__PURE__ */ jsxs("div", { className: "w-full", children: [/* @__PURE__ */ jsx("button", { className: "text-white bg-blue-600 hover:bg-blue-500 px-4 py-2 rounded transition-colors", onClick: syncCharacterInfo, disabled: isSyncing, children: isSyncing ? "同步中..." : "同步mihoyo角色信息" }), isSyncing && /* @__PURE__ */ jsx("div", { className: "mt-2 text-blue-300", children: "正在同步角色信息,请稍候..." })] }) })] })] }), /* @__PURE__ */ jsxs("div", { ref: panelRefs[1], className: "mt-2 border border-gray-700 rounded-lg bg-slate-700/50", children: [/* @__PURE__ */ jsxs("button", { className: "flex justify-between w-full px-4 py-2 text-sm font-medium text-left text-white bg-purple-800/70 rounded-lg hover:bg-purple-700 focus:outline-none transition-colors", onClick: () => setIsSecondPanelOpen(!isSecondPanelOpen), children: [/* @__PURE__ */ jsx("span", { children: "规划批量操作" }), /* @__PURE__ */ jsx("svg", { className: `w-5 h-5 text-purple-300 transition-transform ${isSecondPanelOpen ? "transform rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }), isSecondPanelOpen && /* @__PURE__ */ jsxs("div", { className: "px-4 pt-4 pb-2 text-sm text-gray-100", children: [/* @__PURE__ */ jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsx("button", { className: "w-full text-white bg-blue-500 py-2 px-4 rounded transition-colors", onClick: batchInActive, children: "一键激活/取消未达标目标" }) }), /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [/* @__PURE__ */ jsx("div", { className: "flex border-b border-gray-600", children: ["角色目标等级", "天赋目标等级", "武器目标等级"].map((title, idx) => /* @__PURE__ */ jsx("button", { className: classNames2("px-4 py-2 focus:outline-none transition-colors", activeTab === idx ? "border-b-2 border-blue-400 text-blue-300 font-medium" : "text-gray-300 hover:text-white"), onClick: () => setActiveTab(idx), children: title }, idx)) }), /* @__PURE__ */ jsxs("div", { className: "p-4", children: [activeTab === 0 && /* @__PURE__ */ jsx(CharacterGoalTab, { showText: "角色", batchUpdateCharacter: currentAdapter.batchUpdateCharacter }), activeTab === 1 && /* @__PURE__ */ jsx(TalentGoalTab, {}), activeTab === 2 && /* @__PURE__ */ jsx(CharacterGoalTab, { showText: "武器", batchUpdateCharacter: currentAdapter.batchUpdateWeapon })] })] })] })] })] }) })] }); } function App() { const [showExDialog, setShowExDialog] = require$$1.useState(() => false); require$$1.useEffect(() => { GM_registerMenuCommand("打开SeelieEx", () => setShowExDialog(true)); GM_registerMenuCommand("原神祈愿历史一览", () => GM_openInTab("https://genshin-gacha-banners.52v6.com")); GM_registerMenuCommand("意见反馈", () => GM_openInTab("https://github.com/KeyPJ/seelieEx/issues")); }); return /* @__PURE__ */ jsx("div", { className: "App", style: { display: showExDialog ? "" : "none" }, children: /* @__PURE__ */ jsx(ExDialog, { onClose: () => setShowExDialog(false) }) }); } let seelieEx = document.createElement("div"); seelieEx.id = "seelieEx"; seelieEx.className = "flex"; (_b = (_a = document.getElementById("app")) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.append(seelieEx); ReactDOM2.render(/* @__PURE__ */ jsx(require$$1.StrictMode, { children: /* @__PURE__ */ jsx(App, {}) }), document.getElementById("seelieEx")); })(React, ReactDOM, localforage);