// ==UserScript==
// @name Vue生产环境(production) Devtools 调试
// @namespace https://github.com/xcr1234/vue-devtools-production
// @version 2.0.0
// @description 使用本脚本支持直接调试生产环境的Vue项目 完美支持Vue2、Vue3!
// @homepage https://github.com/xcr1234/vue-devtools-production
// @icon data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAbpJREFUOE+lkz9IG2EYxp/3Eo1GHWzFDqFKLQ6CIGpLS9GSQzGniw5OLTg6CCLO5kT86FpolnR3kFYXJ+9o2u9EcPEPEdqp4qKlbbaihpxw98n3JUqMqYp+03s87/P7/jzvEe656J5+KIC+ymwQBmR99OGnYgoh1rethdeyfjY4tg6gR9Z1U615HfTFMeIDCtC38u6RH/L/yPo0/S/lrmX6VRfRKAEBIcQn+Vn5on4j9LLhlQL43mNnaO7w4grR1XlGRHEpHn/c3xWu1wHgBwANQBtVaPu1E09bCuAEj8Wn1B7Fb6Bb7ARA2Pud28l+Pugq1sIjke+B5nA7gBw3zOpz7RIgarNREliSYnb5IOX9yqmraA2hzZq3Tc/Vjj4mvg2ZybIA9aAW4wCivutnjpN7NUSk1Y4/yVJ18CGANDfMzuKTXYlRt+e7IWhLNrk8w4WPYFVfY28+GejOoOlcCyjEmgBhsmRGFrlhvimdm7KDFLPmHpwikAEQyBvI01yKfB2e+XsrgDqFzaYh8L5gmOWGyUrNV2IsbdAtlgYQ5IYp4yu7rv0XojYbkQAnZi7fCfA/040p3MZ43nMG7TKHEfrJ20kAAAAASUVORK5CYII=
// @include *
// @run-at document-end
// @grant none
// ==/UserScript==
const v = (e, n) => {
let o = Object.getPrototypeOf(n).constructor;
for (; o.super; )
o = o.super;
if (!o.config.devtools && (o.config.devtools = !0, e.emit("init", o), console.log(`vue devtools for [${o.version}] already open !!!`), n.$store)) {
const t = n.$store;
t._devtoolHook = e, e.emit("vuex:init", t), e.on("vuex:travel-to-state", (s) => {
t.replaceState(s);
}), t.subscribe((s, a) => {
e.emit("vuex:mutation", s, a);
});
}
};
/**
* @vue/shared v3.4.33
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/
const N = (e) => typeof e == "symbol";
/**
* @vue/reactivity v3.4.33
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/
new Set(
/* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((e) => e !== "arguments" && e !== "caller").map((e) => Symbol[e]).filter(N)
);
function E(e) {
const n = e && e.__v_raw;
return n ? E(n) : e;
}
function R() {
return I().__VUE_DEVTOOLS_GLOBAL_HOOK__;
}
function I() {
return typeof navigator < "u" && typeof window < "u" ? window : typeof globalThis < "u" ? globalThis : {};
}
const C = typeof Proxy == "function", U = "devtools-plugin:setup", D = "plugin:settings:set";
let _, m;
function G() {
var e;
return _ !== void 0 || (typeof window < "u" && window.performance ? (_ = !0, m = window.performance) : typeof globalThis < "u" && (!((e = globalThis.perf_hooks) === null || e === void 0) && e.performance) ? (_ = !0, m = globalThis.perf_hooks.performance) : _ = !1), _;
}
function M() {
return G() ? m.now() : Date.now();
}
class F {
constructor(n, o) {
this.target = null, this.targetQueue = [], this.onQueue = [], this.plugin = n, this.hook = o;
const t = {};
if (n.settings)
for (const i in n.settings) {
const r = n.settings[i];
t[i] = r.defaultValue;
}
const s = `__vue-devtools-plugin-settings__${n.id}`;
let a = Object.assign({}, t);
try {
const i = localStorage.getItem(s), r = JSON.parse(i);
Object.assign(a, r);
} catch {
}
this.fallbacks = {
getSettings() {
return a;
},
setSettings(i) {
try {
localStorage.setItem(s, JSON.stringify(i));
} catch {
}
a = i;
},
now() {
return M();
}
}, o && o.on(D, (i, r) => {
i === this.plugin.id && this.fallbacks.setSettings(r);
}), this.proxiedOn = new Proxy({}, {
get: (i, r) => this.target ? this.target.on[r] : (...c) => {
this.onQueue.push({
method: r,
args: c
});
}
}), this.proxiedTarget = new Proxy({}, {
get: (i, r) => this.target ? this.target[r] : r === "on" ? this.proxiedOn : Object.keys(this.fallbacks).includes(r) ? (...c) => (this.targetQueue.push({
method: r,
args: c,
resolve: () => {
}
}), this.fallbacks[r](...c)) : (...c) => new Promise((f) => {
this.targetQueue.push({
method: r,
args: c,
resolve: f
});
})
});
}
async setRealTarget(n) {
this.target = n;
for (const o of this.onQueue)
this.target.on[o.method](...o.args);
for (const o of this.targetQueue)
o.resolve(await this.target[o.method](...o.args));
}
}
function H(e, n) {
const o = e, t = I(), s = R(), a = C && o.enableEarlyProxy;
if (s && (t.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !a))
s.emit(U, e, n);
else {
const i = a ? new F(o, s) : null;
(t.__VUE_DEVTOOLS_PLUGINS__ = t.__VUE_DEVTOOLS_PLUGINS__ || []).push({
pluginDescriptor: o,
setupFn: n,
proxy: i
}), i && n(i.proxiedTarget);
}
}
/*!
* pinia v2.1.7
* (c) 2023 Eduardo San Martin Morote
* @license MIT
*/
var b;
(function(e) {
e.direct = "direct", e.patchObject = "patch object", e.patchFunction = "patch function";
})(b || (b = {}));
const J = typeof window < "u";
const O = typeof window == "object" && window.window === window ? window : typeof self == "object" && self.self === self ? self : typeof global == "object" && global.global === global ? global : typeof globalThis == "object" ? globalThis : { HTMLElement: null };
function B(e, { autoBom: n = !1 } = {}) {
return n && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type) ? new Blob(["\uFEFF", e], { type: e.type }) : e;
}
function S(e, n, o) {
const t = new XMLHttpRequest();
t.open("GET", e), t.responseType = "blob", t.onload = function() {
A(t.response, n, o);
}, t.onerror = function() {
console.error("could not download file");
}, t.send();
}
function L(e) {
const n = new XMLHttpRequest();
n.open("HEAD", e, !1);
try {
n.send();
} catch {
}
return n.status >= 200 && n.status <= 299;
}
function g(e) {
try {
e.dispatchEvent(new MouseEvent("click"));
} catch {
const o = document.createEvent("MouseEvents");
o.initMouseEvent("click", !0, !0, window, 0, 0, 0, 80, 20, !1, !1, !1, !1, 0, null), e.dispatchEvent(o);
}
}
const h = typeof navigator == "object" ? navigator : { userAgent: "" }, P = /Macintosh/.test(h.userAgent) && /AppleWebKit/.test(h.userAgent) && !/Safari/.test(h.userAgent), A = J ? (
// Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program
typeof HTMLAnchorElement < "u" && "download" in HTMLAnchorElement.prototype && !P ? Q : (
// Use msSaveOrOpenBlob as a second approach
"msSaveOrOpenBlob" in h ? K : (
// Fallback to using FileReader and a popup
Y
)
)
) : () => {
};
function Q(e, n = "download", o) {
const t = document.createElement("a");
t.download = n, t.rel = "noopener", typeof e == "string" ? (t.href = e, t.origin !== location.origin ? L(t.href) ? S(e, n, o) : (t.target = "_blank", g(t)) : g(t)) : (t.href = URL.createObjectURL(e), setTimeout(function() {
URL.revokeObjectURL(t.href);
}, 4e4), setTimeout(function() {
g(t);
}, 0));
}
function K(e, n = "download", o) {
if (typeof e == "string")
if (L(e))
S(e, n, o);
else {
const t = document.createElement("a");
t.href = e, t.target = "_blank", setTimeout(function() {
g(t);
});
}
else
navigator.msSaveOrOpenBlob(B(e, o), n);
}
function Y(e, n, o, t) {
if (t = t || open("", "_blank"), t && (t.document.title = t.document.body.innerText = "downloading..."), typeof e == "string")
return S(e, n, o);
const s = e.type === "application/octet-stream", a = /constructor/i.test(String(O.HTMLElement)) || "safari" in O, i = /CriOS\/[\d]+/.test(navigator.userAgent);
if ((i || s && a || P) && typeof FileReader < "u") {
const r = new FileReader();
r.onloadend = function() {
let c = r.result;
if (typeof c != "string")
throw t = null, new Error("Wrong reader.result type");
c = i ? c : c.replace(/^data:[^;]*;/, "data:attachment/file;"), t ? t.location.href = c : location.assign(c), t = null;
}, r.readAsDataURL(e);
} else {
const r = URL.createObjectURL(e);
t ? t.location.assign(r) : location.href = r, t = null, setTimeout(function() {
URL.revokeObjectURL(r);
}, 4e4);
}
}
function l(e, n) {
const o = "🍍 " + e;
typeof __VUE_DEVTOOLS_TOAST__ == "function" ? __VUE_DEVTOOLS_TOAST__(o, n) : n === "error" ? console.error(o) : n === "warn" ? console.warn(o) : console.log(o);
}
function w(e) {
return "_a" in e && "install" in e;
}
function x() {
if (!("clipboard" in navigator))
return l("Your browser doesn't support the Clipboard API", "error"), !0;
}
function $(e) {
return e instanceof Error && e.message.toLowerCase().includes("document is not focused") ? (l('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', "warn"), !0) : !1;
}
async function z(e) {
if (!x())
try {
await navigator.clipboard.writeText(JSON.stringify(e.state.value)), l("Global state copied to clipboard.");
} catch (n) {
if ($(n))
return;
l("Failed to serialize the state. Check the console for more details.", "error"), console.error(n);
}
}
async function W(e) {
if (!x())
try {
k(e, JSON.parse(await navigator.clipboard.readText())), l("Global state pasted from clipboard.");
} catch (n) {
if ($(n))
return;
l("Failed to deserialize the state from clipboard. Check the console for more details.", "error"), console.error(n);
}
}
async function q(e) {
try {
A(new Blob([JSON.stringify(e.state.value)], {
type: "text/plain;charset=utf-8"
}), "pinia-state.json");
} catch (n) {
l("Failed to export the state as JSON. Check the console for more details.", "error"), console.error(n);
}
}
let u;
function X() {
u || (u = document.createElement("input"), u.type = "file", u.accept = ".json");
function e() {
return new Promise((n, o) => {
u.onchange = async () => {
const t = u.files;
if (!t)
return n(null);
const s = t.item(0);
return n(s ? { text: await s.text(), file: s } : null);
}, u.oncancel = () => n(null), u.onerror = o, u.click();
});
}
return e;
}
async function Z(e) {
try {
const o = await X()();
if (!o)
return;
const { text: t, file: s } = o;
k(e, JSON.parse(t)), l(`Global state imported from "${s.name}".`);
} catch (n) {
l("Failed to import the state from JSON. Check the console for more details.", "error"), console.error(n);
}
}
function k(e, n) {
for (const o in n) {
const t = e.state.value[o];
t ? Object.assign(t, n[o]) : e.state.value[o] = n[o];
}
}
const j = "🍍 Pinia (root)", p = "_root";
function ee(e) {
return w(e) ? {
id: p,
label: j
} : {
id: e.$id,
label: e.$id
};
}
function te(e) {
if (w(e)) {
const o = Array.from(e._s.keys()), t = e._s;
return {
state: o.map((a) => ({
editable: !0,
key: a,
value: e.state.value[a]
})),
getters: o.filter((a) => t.get(a)._getters).map((a) => {
const i = t.get(a);
return {
editable: !1,
key: a,
value: i._getters.reduce((r, c) => (r[c] = i[c], r), {})
};
})
};
}
const n = {
state: Object.keys(e.$state).map((o) => ({
editable: !0,
key: o,
value: e.$state[o]
}))
};
return e._getters && e._getters.length && (n.getters = e._getters.map((o) => ({
editable: !1,
key: o,
value: e[o]
}))), e._customProperties.size && (n.customProperties = Array.from(e._customProperties).map((o) => ({
editable: !0,
key: o,
value: e[o]
}))), n;
}
const ne = [], oe = "pinia:mutations", d = "pinia", y = (e) => "🍍 " + e;
function re(e, n) {
H({
id: "dev.esm.pinia",
label: "Pinia 🍍",
logo: "https://pinia.vuejs.org/logo.svg",
packageName: "pinia",
homepage: "https://pinia.vuejs.org",
componentStateTypes: ne,
app: e
}, (o) => {
typeof o.now != "function" && l("You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html."), o.addTimelineLayer({
id: oe,
label: "Pinia 🍍",
color: 15064968
}), o.addInspector({
id: d,
label: "Pinia 🍍",
icon: "storage",
treeFilterPlaceholder: "Search stores",
actions: [
{
icon: "content_copy",
action: () => {
z(n);
},
tooltip: "Serialize and copy the state"
},
{
icon: "content_paste",
action: async () => {
await W(n), o.sendInspectorTree(d), o.sendInspectorState(d);
},
tooltip: "Replace the state with the content of your clipboard"
},
{
icon: "save",
action: () => {
q(n);
},
tooltip: "Save the state as a JSON file"
},
{
icon: "folder_open",
action: async () => {
await Z(n), o.sendInspectorTree(d), o.sendInspectorState(d);
},
tooltip: "Import the state from a JSON file"
}
],
nodeActions: [
{
icon: "restore",
tooltip: 'Reset the state (with "$reset")',
action: (t) => {
const s = n._s.get(t);
s ? typeof s.$reset != "function" ? l(`Cannot reset "${t}" store because it doesn't have a "$reset" method implemented.`, "warn") : (s.$reset(), l(`Store "${t}" reset.`)) : l(`Cannot reset "${t}" store because it wasn't found.`, "warn");
}
}
]
}), o.on.inspectComponent((t, s) => {
const a = t.componentInstance && t.componentInstance.proxy;
if (a && a._pStores) {
const i = t.componentInstance.proxy._pStores;
Object.values(i).forEach((r) => {
t.instanceData.state.push({
type: y(r.$id),
key: "state",
editable: !0,
value: r._isOptionsAPI ? {
_custom: {
value: E(r.$state),
actions: [
{
icon: "restore",
tooltip: "Reset the state of this store",
action: () => r.$reset()
}
]
}
} : (
// NOTE: workaround to unwrap transferred refs
Object.keys(r.$state).reduce((c, f) => (c[f] = r.$state[f], c), {})
)
}), r._getters && r._getters.length && t.instanceData.state.push({
type: y(r.$id),
key: "getters",
editable: !1,
value: r._getters.reduce((c, f) => {
try {
c[f] = r[f];
} catch (V) {
c[f] = V;
}
return c;
}, {})
});
});
}
}), o.on.getInspectorTree((t) => {
if (t.app === e && t.inspectorId === d) {
let s = [n];
s = s.concat(Array.from(n._s.values())), t.rootNodes = (t.filter ? s.filter((a) => "$id" in a ? a.$id.toLowerCase().includes(t.filter.toLowerCase()) : j.toLowerCase().includes(t.filter.toLowerCase())) : s).map(ee);
}
}), o.on.getInspectorState((t) => {
if (t.app === e && t.inspectorId === d) {
const s = t.nodeId === p ? n : n._s.get(t.nodeId);
if (!s)
return;
s && (t.state = te(s));
}
}), o.on.editInspectorState((t, s) => {
if (t.app === e && t.inspectorId === d) {
const a = t.nodeId === p ? n : n._s.get(t.nodeId);
if (!a)
return l(`store "${t.nodeId}" not found`, "error");
const { path: i } = t;
w(a) ? i.unshift("state") : (i.length !== 1 || !a._customProperties.has(i[0]) || i[0] in a.$state) && i.unshift("$state"), t.set(a, i, t.state.value);
}
}), o.on.editComponentState((t) => {
if (t.type.startsWith("🍍")) {
const s = t.type.replace(/^🍍\s*/, ""), a = n._s.get(s);
if (!a)
return l(`store "${s}" not found`, "error");
const { path: i } = t;
if (i[0] !== "state")
return l(`Invalid path for store "${s}":
${i}
Only state can be modified.`);
i[0] = "$state", t.set(a, i, t.state.value);
}
});
});
}
const T = (e, n) => {
if (n.config.devtools)
return;
n.config.devtools = !0, e.emit("app:init", n, n.version, {
Fragment: Symbol.for("Fragment"),
Text: Symbol.for("Text"),
Comment: Symbol.for("Comment"),
Static: Symbol.for("Static")
}), console.log(`vue devtools for [${n.version}] already open !!!`);
const o = n.unmount.bind(n);
n.unmount = () => {
e.emit("app:unmount", n), o();
}, n.config.globalProperties.$store && console.warn("vuex for vue3 not support. please use pinia");
const t = n.config.globalProperties.$pinia;
t && re(n, t);
}, se = () => {
if (self != top)
return;
const e = window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
if (!e) {
console.warn("No Vue devtools found , Please install it first: "), console.warn("see https://github.com/vuejs/vue-devtools");
return;
}
const n = window.app;
if (!n)
return;
if (n.__vue__) {
v(e, n.__vue__);
return;
}
if (n.__vue_app__) {
T(e, n.__vue_app__);
return;
}
new MutationObserver((t, s) => {
const a = s.disconnect.bind(s);
for (const i of t) {
const r = i.target;
r.__vue__ ? (v(e, r.__vue__), a()) : r.__vue_app__ && (T(e, r.__vue_app__), a());
}
}).observe(document.documentElement, {
attributes: !0,
subtree: !0,
childList: !0
});
};
se();