var Zt = Object.defineProperty;
var er = (c, o, e) => o in c ? Zt(c, o, {enumerable: !0, configurable: !0, writable: !0, value: e}) : c[o] = e;
var g = (c, o, e) => er(c, typeof o != "symbol" ? o + "" : o, e);
import {c as N, R as Mt, m as tr, j as rr, J as sr, a as ar, b as nr} from "./jszip.min-DpCewD43.js";
import {c as Te} from "./logger-CvfM-6aa.js";
import {
    m as or,
    n as De,
    o as ir,
    p as cr,
    q as ur,
    r as lr,
    u as dr,
    s as hr,
    v as jt,
    e as mt,
    w as et,
    x as pr,
    y as gt,
    z as mr,
    A as gr,
    B as ft,
    C as fr,
    D as wr,
    E as Nt,
    F as yr,
    G as br
} from "./version-check-C8vm5ItJ.js";
import {f as Ft, a as _r} from "./remote-config-BEX-YVxx.js";
import "./_commonjsHelpers-BosuxZz1.js";

const Ir = {
    outputFormat: "html",
    removeIframes: !0,
    removeComments: !0,
    removeSpecialTags: !0,
    removeSvgImages: !0,
    processCodeBlocks: !0,
    processLazyImages: !0,
    removeEmptyElements: !0,
    removeDataAttributes: !0,
    removeSrcset: !0,
    removeSizes: !0
};

function xe(c) {
    const o = [], e = c.length;
    let t = 0;
    const r = s => {
        for (let n = s; n < e; n++) {
            const i = c[n];
            if (i === "\\") {
                n++;
                continue
            }
            if (i === "]") return n
        }
        return -1
    };
    for (; t < e;) {
        const s = c.indexOf("![", t);
        if (s === -1) break;
        const n = s + 2, i = r(n);
        if (i === -1 || c[i + 1] !== "(") {
            t = n;
            continue
        }
        let a = i + 2;
        for (; a < e && /\s/.test(c[a]);) a++;
        let u = "";
        if (c[a] === "<") {
            const d = c.indexOf(">", a + 1);
            if (d === -1) {
                t = i + 1;
                continue
            }
            u = c.slice(a + 1, d), a = d + 1
        } else {
            const d = a;
            let m = 0;
            for (; a < e;) {
                const f = c[a];
                if (f === "\\") {
                    a += 2;
                    continue
                }
                if (f === "(") m++; else if (f === ")") {
                    if (m === 0) break;
                    m--
                } else if (/\s/.test(f) && m === 0) break;
                a++
            }
            u = c.slice(d, a)
        }
        if (!u) {
            t = i + 1;
            continue
        }
        for (; a < e && /\s/.test(c[a]);) a++;
        if (a < e && (c[a] === '"' || c[a] === "'")) {
            const d = c[a];
            for (a++; a < e;) {
                const m = c[a];
                if (m === "\\") {
                    a += 2;
                    continue
                }
                if (m === d) {
                    a++;
                    break
                }
                a++
            }
            for (; a < e && /\s/.test(c[a]);) a++
        } else if (a < e && c[a] === "(") {
            for (a++; a < e;) {
                const d = c[a];
                if (d === "\\") {
                    a += 2;
                    continue
                }
                if (d === ")") {
                    a++;
                    break
                }
                a++
            }
            for (; a < e && /\s/.test(c[a]);) a++
        }
        if (c[a] !== ")") {
            t = i + 1;
            continue
        }
        const l = c.slice(s, a + 1), h = c.slice(n, i);
        o.push({full: l, alt: h, src: u}), t = a + 1
    }
    return o
}

const ce = N("CodeAdapter");

class D {
    constructor() {
        g(this, "runtime");
        g(this, "headerRuleIds", [])
    }

    async init(o) {
        this.runtime = o
    }

    async addHeaderRule(o) {
        if (!this.runtime.headerRules) return null;
        const e = await this.runtime.headerRules.add(o);
        return this.headerRuleIds.push(e), e
    }

    async addHeaderRules(o) {
        for (const e of o) await this.addHeaderRule(e);
        this.headerRuleIds.length > 0 && ce.debug(`[${this.meta.id}] Header rules added:`, this.headerRuleIds)
    }

    async clearHeaderRules() {
        if (!(!this.runtime.headerRules || this.headerRuleIds.length === 0)) {
            for (const o of this.headerRuleIds) await this.runtime.headerRules.remove(o);
            ce.debug(`[${this.meta.id}] Header rules cleared:`, this.headerRuleIds), this.headerRuleIds = []
        }
    }

    async withHeaderRules(o, e) {
        await this.addHeaderRules(o);
        try {
            return await e()
        } finally {
            await this.clearHeaderRules()
        }
    }

    async get(o, e) {
        const t = await this.runtime.fetch(o, {method: "GET", credentials: "include", headers: e});
        return this.parseResponse(t)
    }

    async postJson(o, e, t) {
        const r = await this.runtime.fetch(o, {
            method: "POST",
            credentials: "include",
            headers: {"Content-Type": "application/json", ...t},
            body: JSON.stringify(e)
        });
        return this.parseResponse(r)
    }

    async postForm(o, e, t) {
        const r = await this.runtime.fetch(o, {
            method: "POST",
            credentials: "include",
            headers: {"Content-Type": "application/x-www-form-urlencoded", ...t},
            body: new URLSearchParams(e)
        });
        return this.parseResponse(r)
    }

    async postMultipart(o, e, t) {
        const r = await this.runtime.fetch(o, {method: "POST", credentials: "include", headers: t, body: e});
        return this.parseResponse(r)
    }

    async parseResponse(o) {
        if (!o.ok) throw new Error(`HTTP ${o.status}: ${o.statusText}`);
        const e = await o.text();
        try {
            return JSON.parse(e)
        } catch {
            return e
        }
    }

    async processImages(o, e, t) {
        const {skipPatterns: r = [], onProgress: s} = t || {}, n = [], i = /<img[^>]+src="([^"]+)"[^>]*>/gi;
        let a;
        for (; (a = i.exec(o)) !== null;) n.push({full: a[0], src: a[1], type: "html"});
        for (const d of xe(o)) n.push({full: d.full, src: d.src, alt: d.alt, type: "markdown"});
        if (n.length === 0) return o;
        ce.debug(`Found ${n.length} images to process (HTML + Markdown)`);
        let u = o;
        const l = new Map;
        let h = 0;
        for (const {full: d, src: m, alt: f, type: p} of n) if (m) {
            if (!m.startsWith("data:") && r.some(_ => m.includes(_))) {
                ce.debug(`Skipping matched pattern: ${m}`);
                continue
            }
            h++, s == null || s(h, n.length);
            try {
                let w = l.get(m);
                w || (ce.debug(`Uploading image ${h}/${n.length}: ${m.startsWith("data:") ? "data URI" : m}`), w = await e(m), l.set(m, w));
                let _;
                if (p === "html") {
                    if (_ = `<img src="${w.url}"`, w.attrs) for (const [y, T] of Object.entries(w.attrs)) _ += ` ${y}="${T}"`;
                    _ += " />"
                } else _ = `![${f || ""}](${w.url})`;
                u = u.replace(d, _), ce.debug(`Image uploaded: ${w.url}`)
            } catch (w) {
                ce.error(`Failed to upload image: ${m}`, w)
            }
            await this.delay(300)
        }
        return u
    }

    async uploadImageByUrl(o) {
        throw new Error("uploadImageByUrl not implemented")
    }

    async uploadImage(o, e) {
        const t = await this.blobToDataUri(o);
        return (await this.uploadImageByUrl(t)).url
    }

    async blobToDataUri(o) {
        return new Promise((e, t) => {
            const r = new FileReader;
            r.onload = () => {
                const s = r.result;
                typeof s == "string" ? e(s) : t(new Error("Failed to read blob as data URI"))
            }, r.onerror = () => t(new Error("FileReader error")), r.readAsDataURL(o)
        })
    }

    async dataUriToBlob(o) {
        return (await fetch(o)).blob()
    }

    delay(o) {
        return new Promise(e => setTimeout(e, o))
    }

    createResult(o, e) {
        return {platform: this.meta.id, success: o, timestamp: Date.now(), ...e}
    }
}

class Sr {
    constructor() {
        g(this, "adapters", new Map);
        g(this, "instances", new Map);
        g(this, "runtime")
    }

    setRuntime(o) {
        this.runtime = o, this.instances.clear()
    }

    register(o) {
        this.adapters.set(o.meta.id, o)
    }

    registerAll(o) {
        o.forEach(e => this.register(e))
    }

    async get(o) {
        if (this.instances.has(o)) return this.instances.get(o);
        const e = this.adapters.get(o);
        if (!e) return null;
        if (!this.runtime) throw new Error("Runtime not set. Call setRuntime() first.");
        const t = e.factory(this.runtime);
        return await t.init(this.runtime), this.instances.set(o, t), t
    }

    getAllMeta() {
        return Array.from(this.adapters.values()).map(o => o.meta)
    }

    has(o) {
        return this.adapters.has(o)
    }

    getRegisteredIds() {
        return Array.from(this.adapters.keys())
    }

    clear() {
        this.adapters.clear(), this.instances.clear()
    }

    getPreprocessConfig(o) {
        const e = this.adapters.get(o);
        return {...Ir, ...(e == null ? void 0 : e.preprocessConfig) || {}}
    }

    getPreprocessConfigs(o) {
        const e = {};
        for (const t of o) e[t] = this.getPreprocessConfig(t);
        return e
    }
}

const fe = new Sr;

function wt(c, o) {
    return Rr(c) || xr(c, o) || Tr()
}

function Tr() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance")
}

function xr(c, o) {
    if (Symbol.iterator in Object(c) || Object.prototype.toString.call(c) === "[object Arguments]") {
        var e = [], t = !0, r = !1, s = void 0;
        try {
            for (var n = c[Symbol.iterator](), i; !(t = (i = n.next()).done) && (e.push(i.value), !(o && e.length === o)); t = !0) ;
        } catch (a) {
            r = !0, s = a
        } finally {
            try {
                !t && n.return != null && n.return()
            } finally {
                if (r) throw s
            }
        }
        return e
    }
}

function Rr(c) {
    if (Array.isArray(c)) return c
}

function Xe(c) {
    return typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? Xe = function (e) {
        return typeof e
    } : Xe = function (e) {
        return e && typeof Symbol == "function" && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e
    }, Xe(c)
}

var kr = /\n$/;

function ke(c) {
    return Array.from(c).length
}

var tt = {
    paragraph_open: function (o) {
        return {type: "unstyled", text: "", entityRanges: [], inlineStyleRanges: []}
    }, blockquote_open: function (o) {
        return {type: "blockquote", text: ""}
    }, ordered_list_item_open: function () {
        return {type: "ordered-list-item", text: ""}
    }, unordered_list_item_open: function () {
        return {type: "unordered-list-item", text: ""}
    }, fence: function (o) {
        return {
            type: "code-block",
            data: {language: o.params || ""},
            text: (o.content || "").replace(kr, ""),
            entityRanges: [],
            inlineStyleRanges: []
        }
    }, heading_open: function (o) {
        var e = "header-" + {1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six"}[o.hLevel];
        return {type: e, text: ""}
    }
}, Ar = {
    link_open: function (o) {
        return {type: "LINK", mutability: "MUTABLE", data: {url: o.href, href: o.href}}
    }
}, Er = {strong_open: "BOLD", em_open: "ITALIC", code: "CODE", del_open: "STRIKETHROUGH"}, yt = -1;

function bt() {
    return yt++, yt
}

function vr(c, o, e) {
    var t = "", r = {}, s = [], n = [];
    return c.children.forEach(function (i) {
        if (i.type === "text") t += i.content; else if (i.type === "softbreak") t += `
`; else if (i.type === "hardbreak") t += `
`; else if (e[i.type]) {
            var a = bt(), u = {offset: ke(t) || 0, length: 0, style: e[i.type]};
            (i.type === "code" || i.type === "sub" || i.type === "sup") && (u.length = ke(i.content), t += i.content), n.push(u)
        } else if (o[i.type]) {
            var a = bt();
            r[a] = o[i.type](i), s.push({offset: ke(t) || 0, length: 0, key: a})
        } else if (i.type.indexOf("_close") !== -1 && o[i.type.replace("_close", "_open")]) s[s.length - 1].length = ke(t) - s[s.length - 1].offset; else if (i.type.indexOf("_close") !== -1 && e[i.type.replace("_close", "_open")]) {
            var l = e[i.type.replace("_close", "_open")];
            n = n.map(function (h) {
                return h.length === 0 && h.style === l && (h.length = ke(t) - h.offset), h
            })
        }
    }), {content: t, blockEntities: r, blockEntityRanges: s, blockInlineStyleRanges: n}
}

function Lt(c) {
    var o = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {},
        e = o.remarkablePreset || o.remarkableOptions,
        t = Xe(o.remarkableOptions) === "object" ? o.remarkableOptions : null, r = new Mt(e, t);
    if ((!t || !t.enable || !t.enable.block || t.enable.block !== "table" || t.enable.block.includes("table") === !1) && r.block.ruler.disable("table"), t && t.disable) for (var s = 0, n = Object.entries(t.disable); s < n.length; s++) {
        var i = wt(n[s], 2), a = i[0], u = i[1];
        r[a].ruler.disable(u)
    }
    if (t && t.enable) for (var l = 0, h = Object.entries(t.enable); l < h.length; l++) {
        var d = wt(h[l], 2), m = d[0], f = d[1];
        r[m].ruler.enable(f)
    }
    o.remarkablePlugins && o.remarkablePlugins.forEach(function (v) {
        r.use(v, {})
    });
    var p = [], w = {}, _ = r.parse(c, {}), y = null, T = 0, O = Object.assign({}, tt, o.blockTypes || {}),
        A = Object.assign({}, Ar, o.blockEntities || {}), S = Object.assign({}, Er, o.blockStyles || {});
    return _.forEach(function (v) {
        v.type === "bullet_list_open" ? y = "unordered_list_item_open" : v.type === "ordered_list_open" && (y = "ordered_list_item_open");
        var C = v.type;
        if (C === "list_item_open" && (C = y), C === "inline") {
            var k = vr(v, A, S), P = k.content, b = k.blockEntities, I = k.blockEntityRanges,
                U = k.blockInlineStyleRanges, F = p[p.length - 1];
            F.text = P, F.inlineStyleRanges = U, F.entityRanges = I, Object.assign(w, b)
        } else if ((C.indexOf("_open") !== -1 || C === "fence" || C === "hr" || C === "htmlblock") && O[C]) {
            var J = 0, $;
            if (v.level > 0 && (J = Math.floor(v.level / 2)), v.level === 0 || v.type === "list_item_open" ? $ = Object.assign({depth: J}, O[C](v)) : v.level > 0 && p[p.length - 1].text && ($ = Object.assign({}, p[p.length - 1])), $ && o.preserveNewlines) for (var x = v.lines[0] - T, E = 0; E < x; E++) p.push(tt.paragraph_open());
            $ && (T = v.lines[1], ($.type === "unordered-list-item" || $.type === "ordered-list-item") && (T += 1), p.push($))
        }
    }), p.length || p.push(tt.paragraph_open()), {entityMap: w, blocks: p}
}

const Cr = /^!\[([^\]]*)]\s*\(([^)"]+)( "([^)"]+)")?\)/, Ur = c => {
    c.block.ruler.before("paragraph", "image", (o, e, t, r) => {
        const s = o.bMarks[e] + o.tShift[e], n = o.eMarks[e];
        if (s >= n || !o.src || o.src[s] !== "!") return !1;
        const i = Cr.exec(o.src.slice(s));
        return i ? (r || (o.tokens.push({
            type: "image_open",
            src: i[2],
            alt: i[1],
            lines: [e, o.line],
            level: o.level
        }), o.tokens.push({type: "image_close", level: o.level})), o.line = e + 1, !0) : !1
    })
};

function $r(c, o = new Map) {
    const e = c.split(`
`).map(n => {
        const i = n.split("![]");
        return i.length > 1 ? i.join(`
![]`) : n
    }).join(`
`);
    let t = 0;
    const r = () => t++, s = Lt(e, {
        remarkablePlugins: [Ur], blockTypes: {
            image_open: function (n) {
                const i = r(), a = {}, u = n.src ? n.src.split("?#") : ["", ""], l = u[0], h = u[1] || "",
                    d = o.get(n.src) || o.get(l), m = d ? {
                        id: d.id,
                        src: d.url,
                        thumb: d.thumb,
                        url: d.url,
                        width: d.width,
                        height: d.height,
                        file_name: d.file_name,
                        file_size: d.file_size
                    } : {id: h, src: l, thumb: l, url: l};
                return a[i] = {type: "IMAGE", mutability: "IMMUTABLE", data: m}, {
                    type: "atomic",
                    blockEntities: a,
                    inlineStyleRanges: [],
                    entityRanges: [{offset: 0, length: 1, key: i}],
                    text: " "
                }
            }
        }, blockEntities: {
            image: function (n) {
                const i = n.src ? n.src.split("?#") : ["", ""], a = i[0], u = i[1] || "", l = o.get(n.src) || o.get(a);
                return l ? {
                    type: "IMAGE",
                    mutability: "IMMUTABLE",
                    data: {id: l.id, src: l.url, thumb: l.thumb, url: l.url, width: l.width, height: l.height}
                } : {type: "IMAGE", mutability: "IMMUTABLE", data: {id: u, src: a, thumb: a, url: a}}
            }
        }
    });
    if (s.blocks) for (const n of s.blocks) n.blockEntities && (Object.assign(s.entityMap, n.blockEntities), delete n.blockEntities);
    return JSON.stringify(s)
}

async function Ae(c, o) {
    const e = c instanceof Uint8Array ? c : new Uint8Array(c), t = new Uint8Array(e).buffer,
        r = await crypto.subtle.importKey("raw", t, {name: "HMAC", hash: "SHA-256"}, !1, ["sign"]);
    return crypto.subtle.sign("HMAC", r, new TextEncoder().encode(o))
}

async function _t(c) {
    const o = new TextEncoder().encode(c), e = await crypto.subtle.digest("SHA-256", o);
    return Ht(e)
}

function Ht(c) {
    return Array.from(new Uint8Array(c)).map(o => o.toString(16).padStart(2, "0")).join("")
}

function Pr(c) {
    return c.toISOString().replace(/[:-]|\.\d{3}/g, "")
}

function Or(c) {
    return c.toISOString().slice(0, 10).replace(/-/g, "")
}

async function Ve(c) {
    const {
            method: o,
            url: e,
            accessKeyId: t,
            secretAccessKey: r,
            securityToken: s,
            region: n = "cn-north-1",
            service: i = "imagex",
            headers: a = {},
            body: u = ""
        } = c, l = new URL(e), h = l.pathname, d = l.search.slice(1), m = new Date, f = Pr(m), p = Or(m),
        w = new URLSearchParams(d),
        y = Array.from(w.entries()).sort((M, re) => M[0].localeCompare(re[0])).map(([M, re]) => `${encodeURIComponent(M)}=${encodeURIComponent(re)}`).join("&"),
        T = {"x-amz-date": f};
    s && (T["x-amz-security-token"] = s), Object.assign(T, a);
    const O = Object.keys(T).map(M => M.toLowerCase()).sort().join(";"),
        A = Object.entries(T).map(([M, re]) => `${M.toLowerCase()}:${re.trim()}`).sort().join(`
`) + `
`, S = await _t(u), v = [o.toUpperCase(), h || "/", y, A, O, S].join(`
`), C = "AWS4-HMAC-SHA256", k = `${p}/${n}/${i}/aws4_request`, P = await _t(v), b = [C, f, k, P].join(`
`), I = await Ae(new TextEncoder().encode("AWS4" + r), p), U = await Ae(I, n), F = await Ae(U, i),
        J = await Ae(F, "aws4_request"), $ = await Ae(J, b), x = Ht($),
        E = `${C} Credential=${t}/${k}, SignedHeaders=${O}, Signature=${x}`, q = {authorization: E, "x-amz-date": f};
    return s && (q["x-amz-security-token"] = s), {authorization: E, amzDate: f, headers: q}
}

function qt(c) {
    let o = 4294967295;
    const e = Dr();
    for (let t = 0; t < c.length; t++) o = o >>> 8 ^ e[(o ^ c[t]) & 255];
    return ((o ^ 4294967295) >>> 0).toString(16).padStart(8, "0")
}

let Ee = null;

function Dr() {
    if (Ee) return Ee;
    Ee = new Uint32Array(256);
    for (let c = 0; c < 256; c++) {
        let o = c;
        for (let e = 0; e < 8; e++) o = o & 1 ? 3988292384 ^ o >>> 1 : o >>> 1;
        Ee[c] = o
    }
    return Ee
}

const we = N("Douban");

class Mr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "douban",
            name: "豆瓣",
            icon: "https://www.douban.com/favicon.ico",
            homepage: "https://www.douban.com/note/create",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "username", "");
        g(this, "avatar", "");
        g(this, "formData", null);
        g(this, "postParams", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://www.douban.com/*",
            headers: {Origin: "https://www.douban.com", Referer: "https://www.douban.com"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        try {
            const t = await (await this.runtime.fetch("https://www.douban.com/note/create", {
                    method: "GET",
                    credentials: "include"
                })).text(), r = t.match(/_USER_NAME\s*=\s*['"]([^'"]+)['"]/),
                s = t.match(/_USER_AVATAR\s*=\s*['"]([^'"]+)['"]/), n = t.match(/name="note_id"\s+value="(\d+)"/),
                i = t.match(/name="ck"\s+value="([^"]+)"/), a = t.match(/_POST_PARAMS\s*=\s*(\{[\s\S]*?\});/);
            if (!r || !n || !i) return {isAuthenticated: !1};
            if (this.username = r[1], this.avatar = s ? s[1] : "", this.formData = {note_id: n[1], ck: i[1]}, a) try {
                const u = a[1].match(/siteCookie[^}]*value\s*:\s*['"]([^'"]+)['"]/);
                u && (this.postParams = {siteCookie: {value: u[1]}})
            } catch (u) {
                we.warn("Failed to parse _POST_PARAMS:", u)
            }
            return we.debug("Auth info:", {
                username: this.username,
                noteId: this.formData.note_id,
                hasPostParams: !!this.postParams
            }), {isAuthenticated: !0, userId: this.username, username: this.username, avatar: this.avatar}
        } catch (e) {
            return we.debug("checkAuth: not logged in -", e), {isAuthenticated: !1, error: e.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            if (we.info("Starting publish..."), !this.formData && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录豆瓣");
            let r = e.markdown || "";
            const s = new Map;
            r = await this.processImages(r, async l => {
                const h = await this.uploadImageWithFullData(l);
                return s.set(h.url, h.imageData), h
            }, {skipPatterns: ["doubanio.com", "douban.com"], onProgress: t == null ? void 0 : t.onImageProgress});
            const n = $r(r, s), a = await (await this.runtime.fetch("https://www.douban.com/j/note/autosave", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/x-www-form-urlencoded"},
                body: new URLSearchParams({
                    is_rich: "1",
                    note_id: this.formData.note_id,
                    note_title: e.title,
                    note_text: n,
                    introduction: "",
                    note_privacy: "P",
                    cannot_reply: "",
                    author_tags: "",
                    accept_donation: "",
                    donation_notice: "",
                    is_original: "",
                    ck: this.formData.ck
                })
            })).json();
            return we.debug("Save response:", a), this.createResult(!0, {
                postId: this.formData.note_id,
                postUrl: "https://www.douban.com/note/create",
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageWithFullData(e) {
        var u;
        if (!this.formData || !this.postParams) throw new Error("未获取上传凭证");
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData;
        s.append("note_id", this.formData.note_id), s.append("image_file", r, "image.jpg"), s.append("ck", this.formData.ck), s.append("upload_auth_token", this.postParams.siteCookie.value);
        const i = await (await this.runtime.fetch("https://www.douban.com/j/note/add_photo", {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (we.debug("Image upload response:", i), !((u = i.photo) != null && u.url)) throw new Error("图片上传失败");
        const a = i.photo;
        return {
            url: a.url,
            imageData: {
                id: a.id,
                url: a.url,
                thumb: a.thumb,
                width: a.width,
                height: a.height,
                file_name: a.file_name,
                file_size: a.file_size
            }
        }
    }
}

const ve = N("Xueqiu");

class jr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "xueqiu",
            name: "雪球",
            icon: "https://xqdoc.imedao.com/17aebcfb84a145d33fc18679.ico",
            homepage: "https://mp.xueqiu.com/writeV2",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {
            outputFormat: "markdown",
            removeSpecialTags: !0,
            removeSpecialTagsWithParent: !0,
            processCodeBlocks: !0
        });
        g(this, "currentUser", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://mp.xueqiu.com/xq/*",
            headers: {Origin: "https://mp.xueqiu.com", Referer: "https://mp.xueqiu.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        try {
            const r = (await (await this.runtime.fetch("https://mp.xueqiu.com/writeV2", {
                method: "GET",
                credentials: "include"
            })).text()).match(/window\.UOM_CURRENTUSER\s*=\s*(\{[\s\S]*?\})\s*<\/script>/);
            if (!r) return {isAuthenticated: !1};
            try {
                const s = JSON.parse(r[1]), {currentUser: n} = s;
                if (!(n != null && n.id)) return {isAuthenticated: !1};
                this.currentUser = n;
                const i = n.photo_domain && n.profile_image_url ? `https:${n.photo_domain}${n.profile_image_url.split(",")[0]}` : "";
                return {isAuthenticated: !0, userId: String(n.id), username: n.screen_name, avatar: i}
            } catch (s) {
                return ve.error(" Failed to parse user data:", s), {isAuthenticated: !1}
            }
        } catch (e) {
            return ve.debug("checkAuth: not logged in -", e), {isAuthenticated: !1, error: e.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            if (ve.info("Starting publish..."), !this.currentUser && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录雪球");
            let r = e.markdown || "";
            r = await this.processImages(r, m => this.uploadImageByUrl(m), {
                skipPatterns: ["xueqiu.com", "imedao.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const s = new Mt({html: !0, breaks: !0});
            s.renderer.rules.heading_open = () => "<h4>", s.renderer.rules.heading_close = () => "</h4>", s.renderer.rules.strong_open = () => "<b>", s.renderer.rules.strong_close = () => "</b>", s.renderer.rules.em_open = () => "<i>", s.renderer.rules.em_close = () => "</i>", s.renderer.rules.bullet_list_open = () => "", s.renderer.rules.bullet_list_close = () => "", s.renderer.rules.ordered_list_open = () => "", s.renderer.rules.ordered_list_close = () => "", s.renderer.rules.list_item_open = () => "", s.renderer.rules.list_item_close = () => "", s.renderer.rules.hr = () => "", s.renderer.rules.image = (m, f) => {
                const p = m[f].src || "", w = m[f].alt || "";
                return `<img src="${p}" alt="${w}" class="ke_img">`
            };
            let n = s.render(r);
            n = n.replace(/<p>\s*<\/p>/g, "").replace(/\n{3,}/g, `

`).trim();
            const i = n, a = new URLSearchParams({
                text: i,
                title: e.title,
                cover_pic: "",
                flags: "false",
                original_event: "",
                status_id: "",
                legal_user_visible: "false",
                is_private: "false"
            }), l = await (await this.runtime.fetch("https://mp.xueqiu.com/xq/statuses/draft/save.json", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/x-www-form-urlencoded"},
                body: a
            })).json();
            if (ve.debug(" Save response:", l), !l.id) throw new Error(l.error_description || "保存失败");
            const h = l.id, d = `https://mp.xueqiu.com/write/draft/${h}`;
            return this.createResult(!0, {
                postId: String(h),
                postUrl: d,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageByUrl(e) {
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData;
        s.append("file", r, "image.jpg");
        const i = await (await this.runtime.fetch("https://mp.xueqiu.com/xq/photo/upload.json", {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (ve.debug(" Image upload response:", i), !i.url || !i.filename) throw new Error("图片上传失败");
        return {url: i.url.startsWith("//") ? `https:${i.url}/${i.filename}` : `${i.url}/${i.filename}`}
    }
}

const ae = N("Sohu");

function rt() {
    const c = "0123456789abcdef";
    let o = "";
    for (let e = 0; e < 32; e++) o += c[Math.floor(Math.random() * c.length)];
    return o
}

class Nr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "sohu",
            name: "搜狐号",
            icon: "https://mp.sohu.com/favicon.ico",
            homepage: "https://mp.sohu.com/mpfe/v3/main/first/page?newsType=1",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html"});
        g(this, "accountInfo", null);
        g(this, "deviceId", rt());
        g(this, "spCm", "");
        g(this, "HEADER_RULES", [{
            urlFilter: "*://mp.sohu.com/*",
            headers: {Origin: "https://mp.sohu.com", Referer: "https://mp.sohu.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e, t, r, s;
        try {
            const i = await (await this.runtime.fetch(`https://mp.sohu.com/mpbp/bp/account/list?_=${Date.now()}`, {
                method: "GET",
                credentials: "include"
            })).json();
            if (ae.debug("checkAuth response:", i), i.code !== 2e6 || !((s = (r = (t = (e = i.data) == null ? void 0 : e.data) == null ? void 0 : t[0]) == null ? void 0 : r.accounts) != null && s.length)) return {isAuthenticated: !1};
            const a = [];
            for (const l of i.data.data) l.accounts && a.push(...l.accounts);
            if (a.length === 0) return {isAuthenticated: !1};
            this.accountInfo = a[0], ae.info(`Using account: ${this.accountInfo.nickName} (id: ${this.accountInfo.id})` + (a.length > 1 ? `, ${a.length} sub-accounts available` : "")), await this.fetchSpCm();
            const u = a.length > 1 ? `${this.accountInfo.nickName} (共${a.length}个子账号)` : this.accountInfo.nickName;
            return {
                isAuthenticated: !0,
                userId: String(this.accountInfo.id),
                username: u,
                avatar: this.accountInfo.avatar
            }
        } catch (n) {
            return ae.debug("checkAuth: not logged in -", n), {isAuthenticated: !1, error: n.message}
        }
    }

    async fetchSpCm() {
        try {
            if (this.runtime.getCookie) {
                const e = await this.runtime.getCookie(".sohu.com", "mp-cv");
                if (e) {
                    this.spCm = e, ae.debug("Got sp-cm from cookie:", this.spCm);
                    return
                }
            }
            this.spCm = `100-${Date.now()}-${rt()}`, ae.debug("Generated sp-cm:", this.spCm)
        } catch {
            this.spCm = `100-${Date.now()}-${rt()}`, ae.debug("Fallback sp-cm:", this.spCm)
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            if (ae.info("Starting publish..."), !this.accountInfo && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录搜狐号");
            let r = e.html || "";
            r = await this.processImages(r, l => this.uploadImageByUrl(l), {
                skipPatterns: ["sohu.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const s = {
                    title: e.title,
                    brief: "",
                    content: r,
                    channelId: 24,
                    categoryId: -1,
                    id: 0,
                    userColumnId: 0,
                    columnNewsIds: [],
                    businessCode: 0,
                    declareOriginal: !1,
                    cover: "",
                    topicIds: [],
                    isAd: 0,
                    userLabels: "[]",
                    reprint: !1,
                    customTags: "",
                    infoResource: 0,
                    sourceUrl: "",
                    visibleToLoginedUsers: 0,
                    attrIds: [],
                    auto: !0,
                    accountId: Number(this.accountInfo.id)
                },
                i = await (await this.runtime.fetch(`https://mp.sohu.com/mpbp/bp/news/v4/news/draft/v2?accountId=${this.accountInfo.id}`, {
                    method: "POST",
                    credentials: "include",
                    headers: {
                        "Content-Type": "application/json",
                        "X-Requested-With": "XMLHttpRequest",
                        "dv-id": this.deviceId,
                        "sp-cm": this.spCm
                    },
                    body: JSON.stringify(s)
                })).json();
            if (ae.debug(" Save response:", i), !i.success) throw new Error(i.msg || "保存失败");
            const a = i.data,
                u = `https://mp.sohu.com/mpfe/v4/contentManagement/news/addarticle?spm=smmp.articlelist.0.0&contentStatus=2&id=${a}`;
            return this.createResult(!0, {
                postId: String(a),
                postUrl: u,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageByUrl(e) {
        if (!this.accountInfo) throw new Error("未登录");
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData;
        s.append("file", r, "image.jpg"), s.append("accountId", this.accountInfo.id);
        const i = await (await this.runtime.fetch("https://mp.sohu.com/commons/front/outerUpload/image/file?accountId=" + this.accountInfo.id, {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (ae.debug(" Image upload response:", i), !i.url) throw new Error("图片上传失败:" + i.msg);
        return {url: i.url}
    }
}

const ue = N("Woshipm");

class Fr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "woshipm",
            name: "人人都是产品经理",
            icon: "https://www.woshipm.com/favicon.ico",
            homepage: "https://www.woshipm.com",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html", removeEmptyLines: !0});
        g(this, "jltoken", "");
        g(this, "HEADER_RULES", [{
            urlFilter: "*://woshipm.com/wp-admin/admin-ajax.php*",
            headers: {"X-Requested-With": "XMLHttpRequest"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://woshipm.com/api2/*",
            headers: {"X-Requested-With": "XMLHttpRequest"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://woshipm.com/tensorflow/upyun/upload*",
            headers: {"X-Requested-With": "XMLHttpRequest"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e, t;
        try {
            const s = await (await this.runtime.fetch("https://www.woshipm.com/writing", {
                method: "GET",
                credentials: "include"
            })).text(), n = s.match(/"jltoken"\s*:\s*"([^"]+)"/);
            n && (this.jltoken = n[1], ue.debug("Found jltoken"));
            const i = s.match(/var\s+userSettings\s*=\s*\{[^}]*"uid"\s*:\s*"(\d+)"/);
            if (!i) return {isAuthenticated: !1};
            const a = i[1], l = await (await this.runtime.fetch(`https://www.woshipm.com/api2/user/profile?uid=${a}`, {
                method: "GET",
                credentials: "include",
                headers: {"X-Requested-With": "XMLHttpRequest"}
            })).json();
            return l.CODE === 200 && ((t = (e = l.RESULT) == null ? void 0 : e.userInfoVo) != null && t.uid) ? {
                isAuthenticated: !0,
                userId: String(l.RESULT.userInfoVo.uid),
                username: l.RESULT.userInfoVo.nickName,
                avatar: l.RESULT.userInfoVo.avartar
            } : {isAuthenticated: !1}
        } catch (r) {
            return ue.debug("checkAuth: not logged in -", r), {isAuthenticated: !1, error: r.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            ue.info("Starting publish...");
            let r = e.html || "";
            r = await this.processImages(r, l => this.uploadImageByUrl(l), {
                skipPatterns: ["woshipm.com", "image.woshipm.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const s = await this.runtime.fetch("https://www.woshipm.com/wp-admin/admin-ajax.php", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/x-www-form-urlencoded", "X-Requested-With": "XMLHttpRequest"},
                body: new URLSearchParams({action: "add_draft", post_title: e.title, post_content: r})
            }), n = await s.text();
            if (ue.debug("Create draft response:", s.status, n.substring(0, 300)), !s.ok) throw new Error(`创建草稿失败: ${s.status} - ${n}`);
            let i;
            try {
                i = JSON.parse(n)
            } catch {
                throw new Error(`创建草稿失败: 响应不是有效 JSON - ${n.substring(0, 100)}`)
            }
            if (!i.post_id) throw new Error(i.error || "创建草稿失败: 无效响应");
            const a = String(i.post_id), u = i.url || `https://www.woshipm.com/writing?pid=${a}`;
            return ue.debug("Draft created:", a), this.createResult(!0, {
                postId: a,
                postUrl: u,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImage(e, t) {
        return this.uploadImageBinaryInternal(e, t || "image.png")
    }

    async uploadImageByUrl(e) {
        try {
            const t = await this.runtime.fetch(e, {credentials: "omit"});
            if (!t.ok) throw new Error(`Failed to fetch image: ${t.status}`);
            const r = await t.blob();
            return {url: await this.uploadImageBinaryInternal(r, this.getFilenameFromUrl(e))}
        } catch (t) {
            return ue.warn("Failed to upload image by URL:", e, t), {url: e}
        }
    }

    async uploadImageBinaryInternal(e, t) {
        const r = new FormData;
        r.append("action", "wpuf_insert_image"), r.append("name", t), r.append("files", e, t);
        const s = {Origin: "https://www.woshipm.com", Referer: "https://www.woshipm.com/writing"};
        this.jltoken && (s.jlstar = `Bearer ${this.jltoken}`);
        const i = await (await this.runtime.fetch("https://www.woshipm.com/tensorflow/upyun/upload", {
            method: "POST",
            credentials: "include",
            headers: s,
            body: r
        })).json();
        if (i.data && i.data.length > 0 && i.data[0].url) return ue.debug("Uploaded image:", t, "->", i.data[0].url), i.data[0].url;
        throw new Error(i.error || "Failed to upload image")
    }

    getFilenameFromUrl(e) {
        try {
            return new URL(e).pathname.split("/").pop() || "image.png"
        } catch {
            return "image.png"
        }
    }
}

const Q = N("Zhihu"), Lr = tr;

class Hr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "zhihu",
            name: "知乎",
            icon: "https://static.zhihu.com/static/favicon.ico",
            homepage: "https://www.zhihu.com",
            capabilities: ["article", "draft", "image_upload", "tags", "cover"]
        });
        g(this, "preprocessConfig", {
            outputFormat: "html",
            removeSpecialTags: !0,
            removeSpecialTagsWithParent: !0,
            processCodeBlocks: !0,
            convertSectionToDiv: !0,
            removeTrailingBr: !0,
            unwrapSingleChildContainers: !0,
            unwrapNestedFigures: !0,
            compactHtml: !0,
            removeEmptyLines: !0,
            removeEmptyDivs: !0,
            removeNestedEmptyContainers: !0
        });
        g(this, "HEADER_RULES", [{
            urlFilter: "*://www.zhihu.com/api/*",
            headers: {"x-requested-with": "fetch"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://zhuanlan.zhihu.com/api/*",
            headers: {"x-requested-with": "fetch"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://api.zhihu.com/*",
            headers: {"x-requested-with": "fetch"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        try {
            const t = await (await this.runtime.fetch("https://www.zhihu.com/api/v4/me", {
                method: "GET",
                credentials: "include",
                headers: {"x-requested-with": "fetch"}
            })).json();
            return t.id ? {
                isAuthenticated: !0,
                userId: t.id,
                username: t.name,
                avatar: t.avatar_url
            } : {isAuthenticated: !1}
        } catch (e) {
            return Q.debug("checkAuth: not logged in -", e), {isAuthenticated: !1, error: e.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            Q.info("Starting publish...");
            const r = await this.runtime.fetch("https://zhuanlan.zhihu.com/api/articles/drafts", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/json", "x-requested-with": "fetch"},
                body: JSON.stringify({title: e.title, content: "", delta_time: 0})
            }), s = await r.text();
            if (Q.debug("Create draft response:", r.status, s.substring(0, 200)), !r.ok) throw new Error(`创建草稿失败: ${r.status} - ${s}`);
            let n;
            try {
                n = JSON.parse(s)
            } catch {
                throw new Error(`创建草稿失败: 响应不是有效 JSON - ${s.substring(0, 100)}`)
            }
            if (!n.id) throw new Error("创建草稿失败: 无效响应");
            const i = n.id;
            Q.debug("Draft created:", i);
            let a = e.html || "";
            a = await this.processImages(a, h => this.uploadImageByUrl(h), {
                skipPatterns: ["zhimg.com", "pic1.zhimg.com", "pic2.zhimg.com", "pic3.zhimg.com", "pic4.zhimg.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            }), a = this.transformContent(a);
            const u = await this.runtime.fetch(`https://zhuanlan.zhihu.com/api/articles/${i}/draft`, {
                method: "PATCH",
                credentials: "include",
                headers: {"Content-Type": "application/json", "x-requested-with": "fetch"},
                body: JSON.stringify({title: e.title, content: a})
            });
            if (!u.ok) {
                const h = await u.text();
                throw Q.error("Update draft failed:", u.status, h), new Error(`更新草稿失败: ${u.status}`)
            }
            Q.debug("Draft updated, status:", u.status);
            const l = `https://zhuanlan.zhihu.com/p/${i}/edit`;
            return this.createResult(!0, {postId: i, postUrl: l, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    transformContent(e) {
        let t = e;
        return t = this.transformTables(t), t = t.replace(/<img([^>]+)src="([^"]+)"([^>]*)>/gi, '<figure><img$1src="$2"$3></figure>'), t = t.replace(/<pre><code class="language-(\w+)">/gi, '<pre lang="$1"><code>'), t = t.replace(/\s*data-(?!draft)[a-z-]+="[^"]*"/gi, ""), t = t.replace(/\s*style="[^"]*"/gi, ""), t
    }

    transformTables(e) {
        let t = e.replace(/<figure[^>]*>\s*(<table[\s\S]*?<\/table>)\s*<\/figure>/gi, "$1");
        return t = t.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (r, s) => {
            const n = s.match(/<thead[^>]*>([\s\S]*?)<\/thead>/i), i = s.match(/<tbody[^>]*>([\s\S]*?)<\/tbody>/i);
            let a = "", u = "";
            if (n && (a = n[1].replace(/<td([^>]*)>/gi, "<th$1>").replace(/<\/td>/gi, "</th>")), i ? u = i[1] : u = s.replace(/<thead[^>]*>[\s\S]*?<\/thead>/gi, "").replace(/<\/?tbody[^>]*>/gi, ""), !n) {
                const l = u.match(/<tr[^>]*>([\s\S]*?)<\/tr>/i);
                if (l) {
                    const h = l[1];
                    /<th[^>]*>/i.test(h) && !/<td[^>]*>/i.test(h) && (a = l[0], u = u.replace(l[0], ""))
                }
            }
            return `<table data-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal"><tbody>${a}${u}</tbody></table>`
        }), t
    }

    async uploadImage(e, t) {
        return this.uploadImageBinaryInternal(e)
    }

    async uploadImageByUrl(e) {
        if (e.startsWith("data:")) {
            Q.debug("Detected data URI, using binary upload");
            const s = await fetch(e).then(i => i.blob());
            return {url: await this.uploadImageBinaryInternal(s)}
        }
        const r = await (await this.runtime.fetch("https://zhuanlan.zhihu.com/api/uploaded_images", {
            method: "POST",
            credentials: "include",
            headers: {"x-requested-with": "fetch", "Content-Type": "application/x-www-form-urlencoded"},
            body: new URLSearchParams({url: e, source: "article"})
        })).json();
        if (r.src) return {url: r.src};
        throw new Error("图片上传失败")
    }

    async uploadImageBinaryInternal(e) {
        const t = await e.arrayBuffer(), r = Lr(t),
            n = await (await this.runtime.fetch("https://api.zhihu.com/images", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/json"},
                body: JSON.stringify({image_hash: r, source: "article"})
            })).json(), i = n.upload_file;
        if (i.state === 1) return `https://pic4.zhimg.com/${(await this.waitForImageReady(i.image_id)).original_hash}`;
        const a = n.upload_token;
        await this.ossUpload("https://zhihu-pics-upload.zhimg.com", i.object_key, e, a);
        let u = i.object_key;
        return e.type === "image/gif" && (u = u + ".gif"), `https://pic4.zhimg.com/${u}`
    }

    async waitForImageReady(e) {
        for (let r = 0; r < 10; r++) {
            const n = await (await this.runtime.fetch(`https://api.zhihu.com/images/${e}`, {credentials: "include"})).json();
            if (n.status === "completed" || n.original_hash) return n;
            await new Promise(i => setTimeout(i, 1e3))
        }
        throw new Error("Image processing timeout")
    }

    async ossUpload(e, t, r, s) {
        const n = r.type || "application/octet-stream", i = `${e}/${t}`, a = new Date().toUTCString(),
            l = {"x-oss-date": a, "x-oss-security-token": s.access_token, "x-oss-user-agent": "aliyun-sdk-js/6.8.0"},
            h = Object.keys(l).sort().map(y => `${y}:${l[y]}`).join(`
`), m = `/zhihu-pics/${t}`, f = `PUT

` + n + `
` + a + `
` + h + `
` + m, p = await this.hmacSha1Base64(s.access_key, f), w = `OSS ${s.access_id}:${p}`;
        Q.debug("OSS stringToSign:", JSON.stringify(f)), Q.debug("OSS authorization:", w);
        let _;
        try {
            this.runtime.headerRules && (_ = await this.runtime.headerRules.add({
                urlFilter: "*://zhihu-pics-upload.zhimg.com/*",
                headers: {Origin: "https://zhuanlan.zhihu.com", Referer: "https://zhuanlan.zhihu.com/"},
                resourceTypes: ["xmlhttprequest"]
            }), Q.debug("Added header rule for OSS upload:", _));
            const y = await this.runtime.fetch(i, {
                method: "PUT",
                headers: {
                    "Content-Type": n,
                    Authorization: w,
                    "x-oss-date": a,
                    "x-oss-security-token": s.access_token,
                    "x-oss-user-agent": "aliyun-sdk-js/6.8.0"
                },
                body: r
            });
            if (!y.ok) {
                const T = await y.text();
                throw Q.error("OSS upload failed:", y.status, T), new Error(`OSS upload failed: ${y.status}`)
            }
            Q.debug("OSS upload success")
        } finally {
            _ && this.runtime.headerRules && (await this.runtime.headerRules.remove(_), Q.debug("Removed header rule:", _))
        }
    }

    async hmacSha1Base64(e, t) {
        const r = new TextEncoder, s = r.encode(e), n = r.encode(t),
            i = await crypto.subtle.importKey("raw", s, {name: "HMAC", hash: "SHA-1"}, !1, ["sign"]),
            a = await crypto.subtle.sign("HMAC", i, n);
        return btoa(String.fromCharCode(...new Uint8Array(a)))
    }
}

const B = N("Juejin"), It = "2608", St = "73owjymdk6";

function qr() {
    return "xxxxxxxxxxxxxxxx".replace(/x/g, () => Math.floor(Math.random() * 16).toString(16)) + Date.now().toString()
}

class Br extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "juejin",
            name: "掘金",
            icon: "https://lf-web-assets.juejin.cn/obj/juejin-web/xitu_juejin_web/static/favicons/favicon-32x32.png",
            homepage: "https://juejin.cn",
            capabilities: ["article", "draft", "image_upload", "categories", "tags", "cover"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "cachedCsrfToken", null);
        g(this, "cachedImageXToken", null);
        g(this, "imageXTokenExpiry", 0);
        g(this, "uuid", qr());
        g(this, "HEADER_RULES", [{
            urlFilter: "*://api.juejin.cn/*",
            headers: {Origin: "https://juejin.cn", Referer: "https://juejin.cn/"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://imagex.bytedanceapi.com/*",
            headers: {Origin: "https://juejin.cn", Referer: "https://juejin.cn/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e;
        try {
            const r = await (await this.runtime.fetch("https://api.juejin.cn/user_api/v1/user/get", {
                method: "GET",
                credentials: "include"
            })).json();
            return (e = r.data) != null && e.user_id ? {
                isAuthenticated: !0,
                userId: r.data.user_id,
                username: r.data.user_name,
                avatar: r.data.avatar_large
            } : {isAuthenticated: !1}
        } catch (t) {
            return B.debug("checkAuth: not logged in -", t), {isAuthenticated: !1, error: t.message}
        }
    }

    async getCsrfToken() {
        if (this.cachedCsrfToken) return this.cachedCsrfToken;
        const t = (await this.runtime.fetch("https://api.juejin.cn/user_api/v1/sys/token", {
            method: "HEAD",
            headers: {"x-secsdk-csrf-request": "1", "x-secsdk-csrf-version": "1.2.10"},
            credentials: "include"
        })).headers.get("x-ware-csrf-token");
        if (!t) throw B.warn("CSRF token not found in response headers"), new Error("Failed to get CSRF token");
        const r = t.split(",");
        if (r.length < 2) throw new Error("Invalid CSRF token format");
        return this.cachedCsrfToken = r[1], B.debug("Got CSRF token:", this.cachedCsrfToken.substring(0, 10) + "..."), this.cachedCsrfToken
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var h;
            B.info("Starting publish...");
            const r = await this.getCsrfToken();
            let s = e.markdown || "";
            s = await this.processImages(s, d => this.uploadImageByUrl(d), {
                skipPatterns: ["juejin.cn", "p1-juejin", "p3-juejin", "p6-juejin", "p9-juejin", "byteimg.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const n = await this.runtime.fetch("https://api.juejin.cn/content_api/v1/article_draft/create", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/json", "x-secsdk-csrf-token": r},
                body: JSON.stringify({
                    brief_content: "",
                    category_id: "0",
                    cover_image: "",
                    edit_type: 10,
                    html_content: "deprecated",
                    link_url: "",
                    mark_content: s,
                    tag_ids: [],
                    title: e.title
                })
            }), i = await n.text();
            if (B.debug("Create draft response:", n.status, i.substring(0, 300)), !n.ok) throw new Error(`创建草稿失败: ${n.status} - ${i}`);
            let a;
            try {
                a = JSON.parse(i)
            } catch {
                throw new Error(`创建草稿失败: 响应不是有效 JSON - ${i.substring(0, 100)}`)
            }
            if (a.err_no && a.err_no !== 0) throw new Error(a.err_msg || `创建草稿失败: 错误码 ${a.err_no}`);
            if (!((h = a.data) != null && h.id)) throw new Error(a.err_msg || "创建草稿失败: 无效响应");
            const u = a.data.id;
            B.debug("Draft created:", u);
            const l = `https://juejin.cn/editor/drafts/${u}`;
            return this.createResult(!0, {postId: u, postUrl: l, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImage(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, () => this.uploadImageBinaryInternal(e))
    }

    async uploadImageByUrl(e) {
        try {
            let t;
            if (e.startsWith("data:")) B.debug("Detected data URI, converting to blob"), t = await fetch(e).then(s => s.blob()); else {
                B.debug("Downloading remote image:", e.substring(0, 80));
                const s = await this.runtime.fetch(e, {method: "GET"});
                if (!s.ok) return B.warn("Failed to download image:", s.status), {url: e};
                t = await s.blob()
            }
            const r = await this.uploadImageBinaryInternal(t);
            return B.debug("Uploaded image:", e.substring(0, 50), "->", r), {url: r}
        } catch (t) {
            return B.warn("Failed to upload image by URL:", e, t), {url: e}
        }
    }

    async getImageXToken() {
        var a;
        if (this.cachedImageXToken && Date.now() < this.imageXTokenExpiry - 6e4) return this.cachedImageXToken;
        const e = `https://api.juejin.cn/imagex/v2/gen_token?aid=${It}&uuid=${this.uuid}&client=web`,
            r = await (await this.runtime.fetch(e, {
                method: "GET",
                credentials: "include",
                headers: {"Content-Type": "application/json"}
            })).text();
        B.debug("gen_token response:", r.substring(0, 500));
        let s;
        try {
            s = JSON.parse(r)
        } catch {
            throw new Error(`Invalid JSON response from gen_token: ${r.substring(0, 200)}`)
        }
        if (s.err_no && s.err_no !== 0) throw new Error(s.err_msg || `Failed to get ImageX token: err_no=${s.err_no}`);
        const n = (a = s.data) == null ? void 0 : a.token;
        if (!n || !n.AccessKeyId || !n.SecretAccessKey) throw new Error(`Invalid ImageX token response: ${r.substring(0, 200)}`);
        const i = new Date(n.ExpiredTime).getTime();
        return this.cachedImageXToken = {
            AccessKeyId: n.AccessKeyId,
            SecretAccessKey: n.SecretAccessKey,
            SessionToken: n.SessionToken,
            ExpiredTime: i
        }, this.imageXTokenExpiry = i, B.debug("Got ImageX token, expires at:", n.ExpiredTime), this.cachedImageXToken
    }

    async applyImageUpload(e) {
        var i;
        const t = `https://imagex.bytedanceapi.com/?Action=ApplyImageUpload&Version=2018-08-01&ServiceId=${St}`,
            r = await Ve({
                method: "GET",
                url: t,
                accessKeyId: e.AccessKeyId,
                secretAccessKey: e.SecretAccessKey,
                securityToken: e.SessionToken,
                region: "cn-north-1",
                service: "imagex"
            }), n = await (await this.runtime.fetch(t, {method: "GET", headers: {...r.headers}})).json();
        if (!((i = n.Result) != null && i.UploadAddress)) throw new Error("Failed to apply image upload");
        return n.Result.UploadAddress
    }

    async uploadToTOS(e, t) {
        const r = e.StoreInfos[0], s = e.UploadHosts[0];
        if (!r || !s) throw new Error("Invalid upload address");
        const n = `https://${s}/${r.StoreUri}`, i = await t.arrayBuffer(), a = new Uint8Array(i), u = qt(a);
        B.debug("Uploading to TOS:", n, "size:", t.size, "crc32:", u);
        const l = await this.runtime.fetch(n, {
            method: "PUT",
            headers: {Authorization: r.Auth, "Content-Type": t.type || "application/octet-stream", "Content-CRC32": u},
            body: t
        });
        if (!l.ok) {
            const h = await l.text();
            throw new Error(`TOS upload failed: ${l.status} ${h}`)
        }
        B.debug("TOS upload success")
    }

    async commitImageUpload(e, t) {
        const r = `https://imagex.bytedanceapi.com/?Action=CommitImageUpload&Version=2018-08-01&SessionKey=${encodeURIComponent(t)}&ServiceId=${St}`,
            s = await Ve({
                method: "POST",
                url: r,
                accessKeyId: e.AccessKeyId,
                secretAccessKey: e.SecretAccessKey,
                securityToken: e.SessionToken,
                region: "cn-north-1",
                service: "imagex"
            }), i = await (await this.runtime.fetch(r, {
                method: "POST",
                headers: {...s.headers, "Content-Length": "0"}
            })).json();
        if (!i.Result) throw new Error("Failed to commit image upload");
        return i.Result
    }

    async getImageUrl(e) {
        var i, a;
        const t = `https://api.juejin.cn/imagex/v2/get_img_url?aid=${It}&uuid=${this.uuid}&uri=${encodeURIComponent(e)}&img_type=private`,
            s = await (await this.runtime.fetch(t, {
                method: "GET",
                credentials: "include",
                headers: {"Content-Type": "application/json"}
            })).json();
        if (s.err_no && s.err_no !== 0) throw new Error(s.err_msg || "Failed to get image URL");
        const n = ((i = s.data) == null ? void 0 : i.main_url) || ((a = s.data) == null ? void 0 : a.backup_url);
        if (!n) throw new Error("Invalid image URL response");
        return n
    }

    async uploadImageBinaryInternal(e) {
        var a, u, l;
        const t = await this.getImageXToken(), r = await this.applyImageUpload(t);
        B.debug("Apply upload success, session:", r.SessionKey.substring(0, 50) + "..."), await this.uploadToTOS(r, e);
        const s = await this.commitImageUpload(t, r.SessionKey);
        B.debug("Commit upload success:", (u = (a = s.Results) == null ? void 0 : a[0]) == null ? void 0 : u.Uri);
        const n = (l = r.StoreInfos[0]) == null ? void 0 : l.StoreUri;
        if (!n) throw new Error("No store URI in upload address");
        const i = await this.getImageUrl(n);
        return B.debug("Got image URL:", i), i
    }

    async getCategories() {
        return ((await (await this.runtime.fetch("https://api.juejin.cn/tag_api/v1/query_category_briefs", {
            method: "GET",
            credentials: "include"
        })).json()).data || []).map(r => ({id: r.category_id, name: r.category_name}))
    }
}

const ne = N("CSDN");

class zr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "csdn",
            name: "CSDN",
            icon: "https://g.csdnimg.cn/static/logo/favicon32.ico",
            homepage: "https://editor.csdn.net/md/",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "userInfo", null);
        g(this, "API_KEY", "203803574");
        g(this, "API_SECRET", "9znpamsyl2c7cdrr9sas0le9vbc3r6ba");
        g(this, "HEADER_RULES", [{
            urlFilter: "*://bizapi.csdn.net/*",
            headers: {Origin: "https://editor.csdn.net", Referer: "https://editor.csdn.net/"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://imgservice.csdn.net/*",
            headers: {Origin: "https://editor.csdn.net", Referer: "https://editor.csdn.net/"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://csdn-img-blog.obs.cn-north-4.myhuaweicloud.com/*",
            headers: {Origin: "https://editor.csdn.net", Referer: "https://editor.csdn.net/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e;
        try {
            const t = "/blog-console-api/v3/editor/getBaseInfo", r = await this.signRequest(t, "GET"),
                n = await (await this.runtime.fetch(`https://bizapi.csdn.net${t}`, {
                    method: "GET",
                    credentials: "include",
                    headers: r
                })).json();
            return ne.debug("checkAuth response:", n), n.code === 200 && ((e = n.data) != null && e.name) ? (this.userInfo = {
                csdnid: n.data.name,
                username: n.data.nickname || n.data.name,
                avatarurl: n.data.avatar
            }, {
                isAuthenticated: !0,
                userId: n.data.name,
                username: n.data.nickname || n.data.name,
                avatar: n.data.avatar
            }) : {isAuthenticated: !1}
        } catch (t) {
            return ne.debug("checkAuth: not logged in -", t), {isAuthenticated: !1, error: t.message}
        }
    }

    createUuid() {
        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, e => {
            const t = Math.random() * 16 | 0;
            return (e === "x" ? t : t & 3 | 8).toString(16)
        })
    }

    async hmacSha256(e, t) {
        const r = new TextEncoder, s = r.encode(t), n = r.encode(e),
            i = await crypto.subtle.importKey("raw", s, {name: "HMAC", hash: "SHA-256"}, !1, ["sign"]),
            a = await crypto.subtle.sign("HMAC", i, n), u = new Uint8Array(a);
        let l = "";
        for (let h = 0; h < u.byteLength; h++) l += String.fromCharCode(u[h]);
        return btoa(l)
    }

    async signRequest(e, t = "POST") {
        const r = this.createUuid(), s = t === "GET" ? `GET
*/*



x-ca-key:${this.API_KEY}
x-ca-nonce:${r}
${e}` : `POST
*/*

application/json

x-ca-key:${this.API_KEY}
x-ca-nonce:${r}
${e}`;
        ne.debug("Sign string:", JSON.stringify(s));
        const n = await this.hmacSha256(s, this.API_SECRET), i = {
            accept: "*/*",
            "x-ca-key": this.API_KEY,
            "x-ca-nonce": r,
            "x-ca-signature": n,
            "x-ca-signature-headers": "x-ca-key,x-ca-nonce"
        };
        return t === "POST" && (i["content-type"] = "application/json"), i
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var d;
            if (ne.info("Starting publish..."), !this.userInfo && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录 CSDN");
            let r = e.markdown || "";
            r = await this.processImages(r, m => this.uploadImageByUrl(m), {
                skipPatterns: ["csdnimg.cn", "csdn.net"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const s = e.html || "", n = "/blog-console-api/v3/mdeditor/saveArticle", i = await this.signRequest(n),
                u = await (await this.runtime.fetch(`https://bizapi.csdn.net${n}`, {
                    method: "POST",
                    credentials: "include",
                    headers: i,
                    body: JSON.stringify({
                        title: e.title,
                        markdowncontent: r,
                        content: s,
                        readType: "public",
                        level: 0,
                        tags: "",
                        status: 2,
                        categories: "",
                        type: "original",
                        original_link: "",
                        authorized_status: !1,
                        not_auto_saved: "1",
                        source: "pc_mdeditor",
                        cover_images: [],
                        cover_type: 1,
                        is_new: 1,
                        vote_id: 0,
                        resource_id: "",
                        pubStatus: "draft",
                        creator_activity_id: ""
                    })
                })).json();
            if (ne.debug("Save response:", u), u.code !== 200 || !((d = u.data) != null && d.id)) throw new Error(u.msg || u.message || "保存草稿失败");
            const l = u.data.id, h = `https://editor.csdn.net/md?articleId=${l}`;
            return this.createResult(!0, {postId: l, postUrl: h, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImage(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            const r = await new Promise((n, i) => {
                const a = new FileReader;
                a.onload = () => n(a.result), a.onerror = i, a.readAsDataURL(e)
            });
            return (await this.uploadImageByUrl(r)).url
        })
    }

    async uploadImageByUrl(e) {
        var w, _, y;
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(),
            s = ((_ = (w = e.split(".").pop()) == null ? void 0 : w.toLowerCase()) == null ? void 0 : _.split("?")[0]) || "jpg",
            n = ["jpg", "jpeg", "png", "gif", "webp"].includes(s) ? s : "jpg",
            i = "/resource-api/v1/image/direct/upload/signature", a = await this.signRequest(i, "POST"),
            l = await (await this.runtime.fetch(`https://bizapi.csdn.net${i}`, {
                method: "POST",
                credentials: "include",
                headers: a,
                body: JSON.stringify({imageTemplate: "", appName: "direct_blog_markdown", imageSuffix: n})
            })).json();
        if (ne.debug("Upload signature response:", l), l.code !== 200 || !l.data) return ne.warn("Failed to get upload signature, using original URL"), {url: e};
        const h = l.data, d = h.customParam, m = new FormData;
        m.append("key", h.filePath), m.append("policy", h.policy), m.append("signature", h.signature), m.append("callbackBody", h.callbackBody), m.append("callbackBodyType", h.callbackBodyType), m.append("callbackUrl", h.callbackUrl), m.append("AccessKeyId", h.accessId), m.append("x:rtype", d.rtype), m.append("x:filePath", d.filePath), m.append("x:isAudit", String(d.isAudit)), m.append("x:x-image-app", d["x-image-app"]), m.append("x:type", d.type), m.append("x:x-image-suffix", d["x-image-suffix"]), m.append("x:username", d.username), m.append("file", r, `image.${n}`);
        const p = await (await this.runtime.fetch(h.host, {method: "POST", body: m})).json();
        return ne.debug("OBS upload response:", p), p.code !== 200 || !((y = p.data) != null && y.imageUrl) ? (ne.warn("OBS upload failed, using original URL"), {url: e}) : {url: p.data.imageUrl}
    }
}

const L = N("Weibo");

class Wr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "weibo",
            name: "微博",
            icon: "https://weibo.com/favicon.ico",
            homepage: "https://card.weibo.com/article/v5/editor",
            capabilities: ["article", "draft", "image_upload", "cover"]
        });
        g(this, "preprocessConfig", {outputFormat: "html"});
        g(this, "userConfig", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://card.weibo.com/*",
            headers: {Origin: "https://card.weibo.com", Referer: "https://card.weibo.com/article/v5/editor"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://picupload.weibo.com/*",
            headers: {Origin: "https://weibo.com", Referer: "https://weibo.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        try {
            const e = await this.getUserConfig();
            return e != null && e.uid ? {
                isAuthenticated: !0,
                userId: e.uid,
                username: e.nick,
                avatar: e.avatar_large
            } : {isAuthenticated: !1}
        } catch (e) {
            return L.debug("checkAuth: not logged in -", e), {isAuthenticated: !1, error: e.message}
        }
    }

    async getUserConfig() {
        if (this.userConfig) return this.userConfig;
        const r = (await (await this.runtime.fetch("https://card.weibo.com/article/v5/editor", {credentials: "include"})).text()).match(/config:\s*JSON\.parse\('(.+?)'\)/);
        if (!r) return L.error("Failed to find config in HTML"), null;
        try {
            const s = r[1].replace(/\\'/g, "'").replace(/\\\\/g, "\\"), n = JSON.parse(s);
            return n.uid ? (this.userConfig = {
                uid: String(n.uid),
                nick: n.nick || "",
                avatar_large: n.avatar_large || ""
            }, L.debug("User config:", this.userConfig), this.userConfig) : null
        } catch (s) {
            return L.error("Failed to parse config:", s), null
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var w;
            L.info("Starting publish...");
            const r = await this.getUserConfig();
            if (!(r != null && r.uid)) throw new Error("请先登录微博");
            let s = e.html || "";
            s = s.replace(/>\s+</g, "><"), s = await this.processWeiboImages(s, t == null ? void 0 : t.onImageProgress);
            const n = this.generateReqId(),
                a = await (await this.runtime.fetch(`https://card.weibo.com/article/v5/aj/editor/draft/create?uid=${r.uid}&_rid=${n}`, {
                    method: "POST",
                    credentials: "include",
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                        accept: "application/json, text/plain, */*",
                        "SN-REQID": n
                    },
                    body: new URLSearchParams({})
                })).json();
            if (a.code !== 1e5 || !((w = a.data) != null && w.id)) throw new Error(a.msg || "创建草稿失败");
            const u = a.data.id;
            L.debug("Created draft:", u);
            let l = "";
            if (e.cover) try {
                l = (await this.uploadImageByUrl(e.cover)).url
            } catch (_) {
                L.warn("Failed to upload cover:", _)
            }
            const h = this.generateReqId(),
                m = await (await this.runtime.fetch(`https://card.weibo.com/article/v5/aj/editor/draft/save?uid=${r.uid}&id=${u}&_rid=${h}`, {
                    method: "POST",
                    credentials: "include",
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                        accept: "application/json, text/plain, */*",
                        "SN-REQID": h
                    },
                    body: new URLSearchParams({
                        id: u,
                        title: e.title,
                        subtitle: "",
                        type: "",
                        status: "0",
                        publish_at: "",
                        error_msg: "",
                        error_code: "0",
                        collection: "[]",
                        free_content: "",
                        content: s,
                        cover: l,
                        summary: "",
                        writer: "",
                        extra: "null",
                        is_word: "0",
                        article_recommend: "[]",
                        follow_to_read: "1",
                        isreward: "1",
                        pay_setting: '{"ispay":0,"isvclub":0}',
                        source: "0",
                        action: "1",
                        content_type: "0",
                        save: "1"
                    })
                })).json();
            L.debug("Save response:", m);
            const f = String(m.code);
            if (f !== "100000") throw new Error(m.msg || `保存失败 (错误码: ${f})`);
            const p = `https://card.weibo.com/article/v5/editor#/draft/${u}`;
            return this.createResult(!0, {postId: u, postUrl: p, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    generateReqId() {
        var n;
        const e = `${(n = this.userConfig) == null ? void 0 : n.uid}&${Date.now()}`,
            t = btoa(e).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""),
            r = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
        let s = t;
        for (; s.length < 43;) s += r.charAt(Math.floor(Math.random() * r.length));
        return s.slice(0, 43)
    }

    async uploadImageByUrl(e) {
        if (e.startsWith("data:")) return L.debug("Uploading data URI image via direct upload"), this.uploadDataUri(e);
        const t = await this.getUserConfig();
        if (!(t != null && t.uid)) throw new Error("请先登录微博");
        const r = this.generateReqId();
        try {
            const a = await (await this.runtime.fetch(`https://card.weibo.com/article/v5/aj/editor/plugins/asyncuploadimg?uid=${t.uid}&_rid=${r}`, {
                method: "POST",
                credentials: "include",
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded",
                    accept: "application/json, text/plain, */*",
                    "SN-REQID": r
                },
                body: new URLSearchParams({"urls[0]": e})
            })).json();
            L.debug("Async upload response:", a)
        } catch (i) {
            L.warn("Async upload request failed, will try polling anyway:", i)
        }
        const s = await this.waitForImageDone(e);
        return {url: `https://wx3.sinaimg.cn/large/${s.pid}.jpg`, attrs: {"data-pid": s.pid}}
    }

    async uploadImageBase64(e, t) {
        const r = `data:${t};base64,${e}`;
        return this.uploadDataUri(r)
    }

    async uploadDataUri(e) {
        var p, w, _;
        const t = e.match(/^data:([^;]+);base64,(.+)$/);
        if (!t) throw new Error("Invalid data URI format");
        const r = t[1], s = t[2], n = atob(s), i = new Uint8Array(n.length);
        for (let y = 0; y < n.length; y++) i[y] = n.charCodeAt(y);
        const a = new Blob([i], {type: r});
        L.debug(`Uploading blob: ${r}, size: ${a.size}`);
        const l = `https://picupload.weibo.com/interface/pic_upload.php?app=miniblog&s=json&p=1&data=1&url=&markpos=1&logo=0&nick=&file_source=4&_rid=${this.generateReqId()}`,
            d = await (await this.runtime.fetch(l, {method: "POST", credentials: "include", body: a})).json();
        if (L.debug("Direct upload response:", d), !((_ = (w = (p = d.data) == null ? void 0 : p.pics) == null ? void 0 : w.pic_1) != null && _.pid)) throw new Error("图片上传失败: " + JSON.stringify(d));
        const m = d.data.pics.pic_1.pid;
        return {url: `https://wx3.sinaimg.cn/large/${m}.jpg`, attrs: {"data-pid": m}}
    }

    async processWeiboImages(e, t) {
        var m;
        const r = e, s = /<figure[^>]*>[\s\S]*?<img[^>]+src="([^"]+)"[^>]*>[\s\S]*?<\/figure>/gi,
            n = /<img[^>]+src="([^"]+)"[^>]*>/gi, i = [];
        let a;
        const u = new Set;
        for (; (a = s.exec(r)) !== null;) i.push({full: a[0], src: a[1], hasFigure: !0}), u.add(a[1]);
        for (; (a = n.exec(r)) !== null;) u.has(a[1]) || i.push({full: a[0], src: a[1], hasFigure: !1});
        for (const f of xe(r)) i.push({full: f.full, src: f.src, hasFigure: !1});
        if (i.length === 0) return r;
        L.info(`Found ${i.length} images to process`);
        let l = r;
        const h = new Map;
        let d = 0;
        for (const {full: f, src: p, hasFigure: w} of i) if (p) {
            if (p.includes("sinaimg.cn") || p.includes("weibo.com")) {
                L.debug(`Skipping weibo image: ${p}`);
                continue
            }
            if (!p.startsWith("data:")) {
                d++, t == null || t(d, i.length);
                try {
                    let _ = h.get(p);
                    if (!_) {
                        L.debug(`Uploading image ${d}/${i.length}: ${p}`);
                        const T = await this.uploadImageByUrl(p);
                        _ = {pid: ((m = T.attrs) == null ? void 0 : m["data-pid"]) || "", url: T.url}, h.set(p, _)
                    }
                    let y;
                    w ? y = f.replace(/<img[^>]+src="[^"]+"[^>]*>/i, `<img src="${_.url}" data-pid="${_.pid}" />`) : y = `<figure class="image"><img src="${_.url}" data-pid="${_.pid}" /></figure>`, l = l.replace(f, y), L.debug(`Image uploaded: ${_.url}`)
                } catch (_) {
                    L.error(`Failed to upload image: ${p}`, _)
                }
                await this.delay(300)
            }
        }
        return l
    }

    async waitForImageDone(e) {
        var s;
        const t = await this.getUserConfig(), r = 30;
        for (let n = 0; n < r; n++) {
            const i = this.generateReqId(),
                l = (s = (await (await this.runtime.fetch(`https://card.weibo.com/article/v5/aj/editor/plugins/asyncimginfo?uid=${t.uid}&_rid=${i}`, {
                    method: "POST",
                    credentials: "include",
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                        accept: "application/json, text/plain, */*",
                        "SN-REQID": i
                    },
                    body: new URLSearchParams({"urls[0]": e})
                })).json()).data) == null ? void 0 : s[0], h = l == null ? void 0 : l.task_status_code;
            if (h === 1 && l) return L.debug("Image upload complete:", l), l;
            if (h === 2) throw new Error("图片上传失败");
            await this.delay(1e3)
        }
        throw new Error("图片上传超时")
    }
}

const le = N("Bilibili");

class Xr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "bilibili",
            name: "哔哩哔哩",
            icon: "https://www.bilibili.com/favicon.ico",
            homepage: "https://member.bilibili.com/platform/upload/text",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html", removeLinks: !0});
        g(this, "userInfo", null);
        g(this, "csrf", "");
        g(this, "HEADER_RULES", [{
            urlFilter: "*://api.bilibili.com/*",
            headers: {Origin: "https://member.bilibili.com", Referer: "https://member.bilibili.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e;
        try {
            const t = await this.get("https://api.bilibili.com/x/web-interface/nav?build=0&mobi_app=web");
            return le.debug("checkAuth response:", t), t.code === 0 && ((e = t.data) != null && e.isLogin) ? (this.userInfo = t.data, await this.fetchCsrf(), {
                isAuthenticated: !0,
                userId: String(t.data.mid),
                username: t.data.uname,
                avatar: t.data.face
            }) : {isAuthenticated: !1}
        } catch (t) {
            return le.debug("checkAuth: not logged in -", t), {isAuthenticated: !1, error: t.message}
        }
    }

    async fetchCsrf() {
        try {
            if (this.runtime.getCookie) {
                const e = await this.runtime.getCookie(".bilibili.com", "bili_jct");
                this.csrf = e || ""
            }
            le.debug("CSRF token:", this.csrf ? "obtained" : "not found")
        } catch (e) {
            le.error("Failed to get CSRF:", e)
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var i;
            if (le.info("Starting publish..."), !this.userInfo && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录B站");
            if (!this.csrf) throw new Error("获取 CSRF token 失败，请刷新页面后重试");
            let r = e.html || "";
            r = await this.processImages(r, a => this.uploadImageByUrl(a), {
                skipPatterns: ["hdslb.com", "bilibili.com", "biliimg.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const s = await this.postForm("https://api.bilibili.com/x/article/creative/draft/addupdate", {
                tid: "4",
                title: e.title,
                content: r,
                csrf: this.csrf,
                save: "0",
                pgc_id: "0"
            });
            if (le.debug("Draft response:", s), s.code !== 0 || !((i = s.data) != null && i.aid)) throw new Error(s.message || "保存草稿失败");
            const n = `https://member.bilibili.com/platform/upload/text/edit?aid=${s.data.aid}`;
            return this.createResult(!0, {
                postId: String(s.data.aid),
                postUrl: n,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageByUrl(e) {
        var u;
        if (!this.csrf) throw new Error("CSRF token 未获取");
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData;
        s.append("binary", r, "image.jpg"), s.append("csrf", this.csrf);
        const a = await (await this.runtime.fetch("https://api.bilibili.com/x/article/creative/article/upcover", {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (le.debug("Image upload response:", a), a.code !== 0 || !((u = a.data) != null && u.url)) throw new Error(a.message || "图片上传失败");
        return {url: a.data.url, attrs: {size: String(a.data.size)}}
    }
}

const ye = N("Baijiahao");

class Gr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "baijiahao",
            name: "百家号",
            icon: "https://www.baidu.com/favicon.ico",
            homepage: "https://baijiahao.baidu.com/",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html"});
        g(this, "userInfo", null);
        g(this, "authToken", "");
        g(this, "HEADER_RULES", [{
            urlFilter: "*://baijiahao.baidu.com/*",
            headers: {Origin: "https://baijiahao.baidu.com", Referer: "https://baijiahao.baidu.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e;
        try {
            const t = await this.get(`https://baijiahao.baidu.com/builder/app/appinfo?_=${Date.now()}`);
            return ye.debug("checkAuth response:", t), t.errmsg === "success" && ((e = t.data) != null && e.user) ? (this.userInfo = t.data.user, {
                isAuthenticated: !0,
                userId: t.data.user.userid,
                username: t.data.user.name,
                avatar: t.data.user.avatar
            }) : {isAuthenticated: !1}
        } catch (t) {
            return ye.debug("checkAuth: not logged in -", t), {isAuthenticated: !1, error: t.message}
        }
    }

    async fetchAuthToken() {
        const r = (await (await this.runtime.fetch("https://baijiahao.baidu.com/builder/rc/edit", {credentials: "include"})).text()).match(/window\.__BJH__INIT__AUTH__\s*=\s*['"]([^'"]+)['"]/);
        if (!r) throw new Error("登录失效，请重新登录百家号");
        const s = r[1];
        return ye.debug("Auth token obtained"), s
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var h;
            if (ye.info("Starting publish..."), !this.userInfo && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录百家号");
            this.authToken = await this.fetchAuthToken();
            let r = e.html || "";
            r = await this.processImages(r, d => this.uploadImageByUrl(d), {
                skipPatterns: ["baijiahao.baidu.com", "bdstatic.com", "bcebos.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const i = (await (await this.runtime.fetch("https://baijiahao.baidu.com/pcui/article/save?callback=bjhdraft", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/x-www-form-urlencoded", token: this.authToken},
                body: new URLSearchParams({
                    title: e.title,
                    content: r,
                    feed_cat: "1",
                    len: String(r.length),
                    activity_list: JSON.stringify([{id: 408, is_checked: 0}]),
                    source_reprinted_allow: "0",
                    original_status: "0",
                    original_handler_status: "1",
                    isBeautify: "false",
                    subtitle: "",
                    bjhtopic_id: "",
                    bjhtopic_info: "",
                    type: "news"
                })
            })).text()).replace(/^bjhdraft\(/, "").replace(/\)$/, ""), a = JSON.parse(i);
            if (ye.debug("Save response:", a), a.errmsg !== "success" || !((h = a.ret) != null && h.article_id)) throw new Error(a.errmsg || "保存草稿失败");
            const u = a.ret.article_id, l = `https://baijiahao.baidu.com/builder/rc/edit?type=news&article_id=${u}`;
            return this.createResult(!0, {postId: u, postUrl: l, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageByUrl(e) {
        var u;
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData;
        s.append("media", r, "image.jpg"), s.append("type", "image"), s.append("app_id", "1589639493090963"), s.append("is_waterlog", "1"), s.append("save_material", "1"), s.append("no_compress", "0"), s.append("is_events", ""), s.append("article_type", "news");
        const a = await (await this.runtime.fetch("https://baijiahao.baidu.com/pcui/picture/uploadproxy", {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (ye.debug("Image upload response:", a), a.errmsg !== "success" || !((u = a.ret) != null && u.https_url)) throw new Error(a.errmsg || "图片上传失败");
        return {url: a.ret.https_url}
    }
}

const be = N("Yuque");

class Jr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "yuque",
            name: "语雀",
            icon: "https://gw.alipayobjects.com/zos/rmsportal/UTjFYEzMSYVwzxIGVhMu.png",
            homepage: "https://www.yuque.com/dashboard",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {
            outputFormat: "markdown",
            removeSpecialTags: !0,
            removeSpecialTagsWithParent: !0,
            processCodeBlocks: !0
        });
        g(this, "userInfo", null);
        g(this, "bookId", null);
        g(this, "csrfToken", "");
        g(this, "currentPostId", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://www.yuque.com/api/*",
            headers: {Origin: "https://www.yuque.com", Referer: "https://www.yuque.com/dashboard"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async getCsrfToken() {
        if (this.runtime.getCookie) {
            const e = await this.runtime.getCookie(".yuque.com", "yuque_ctoken");
            if (!e) throw new Error("请先登录语雀");
            return e
        }
        throw new Error("请先登录语雀")
    }

    async checkAuth() {
        var e;
        try {
            this.csrfToken = await this.getCsrfToken();
            const r = await (await this.runtime.fetch("https://www.yuque.com/api/mine/common_used", {
                method: "GET",
                credentials: "include",
                headers: {"x-csrf-token": this.csrfToken}
            })).json();
            if (be.debug("checkAuth response:", r), (e = r.data) != null && e.books && r.data.books.length > 0) {
                const s = r.data.books[0];
                return this.userInfo = s.user, this.bookId = s.target_id, {
                    isAuthenticated: !0,
                    userId: String(s.user.id),
                    username: s.user.name,
                    avatar: s.user.avatar_url
                }
            }
            return {isAuthenticated: !1}
        } catch (t) {
            return be.debug("checkAuth: not logged in -", t.message), {isAuthenticated: !1, error: t.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var f, p;
            if (be.info("Starting publish..."), (!this.userInfo || !this.bookId) && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录语雀");
            const s = await (await this.runtime.fetch("https://www.yuque.com/api/docs", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/json", "x-csrf-token": this.csrfToken},
                body: JSON.stringify({title: e.title, type: "Doc", format: "lake", book_id: this.bookId, status: 0})
            })).json();
            if (be.debug("Create doc response:", s), !((f = s.data) != null && f.id)) throw new Error(s.message || "创建文档失败");
            const n = s.data.id;
            this.currentPostId = n;
            let i = e.markdown || "";
            i = await this.processImages(i, w => this.uploadImageByUrl(w), {
                skipPatterns: ["yuque.com", "cdn.nlark.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const u = await (await this.runtime.fetch("https://www.yuque.com/api/docs/convert", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/json", "x-csrf-token": this.csrfToken},
                body: JSON.stringify({from: "markdown", to: "lake", content: i})
            })).json();
            if (!((p = u.data) != null && p.content)) throw new Error("内容转换失败");
            const l = u.data.content,
                d = await (await this.runtime.fetch(`https://www.yuque.com/api/docs/${n}/content`, {
                    method: "PUT",
                    credentials: "include",
                    headers: {"Content-Type": "application/json", "x-csrf-token": this.csrfToken},
                    body: JSON.stringify({
                        format: "lake",
                        body_asl: l,
                        body: `<div class="lake-content" typography="traditional">${l}</div>`,
                        body_html: `<div class="lake-content" typography="traditional">${l}</div>`,
                        draft_version: 0,
                        sync_dynamic_data: !1,
                        save_type: "auto",
                        edit_type: "Lake"
                    })
                })).json();
            be.debug("Save response:", d);
            const m = `https://www.yuque.com/go/doc/${n}/edit`;
            return this.createResult(!0, {
                postId: String(n),
                postUrl: m,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageByUrl(e) {
        var u;
        if (!this.currentPostId) throw new Error("文档 ID 未设置");
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData;
        s.append("file", r, "image.jpg");
        const n = `https://www.yuque.com/api/upload/attach?attachable_type=Doc&attachable_id=${this.currentPostId}&type=image`,
            a = await (await this.runtime.fetch(n, {
                method: "POST",
                credentials: "include",
                headers: {"x-csrf-token": this.csrfToken},
                body: s
            })).json();
        if (be.debug("Image upload response:", a), !((u = a.data) != null && u.url)) throw new Error("图片上传失败");
        return {url: a.data.url}
    }
}

const de = N("Weixin"), Kr = `
p {
  color: rgb(51, 51, 51);
  font-size: 15px;
  line-height: 1.75em;
  margin: 0 0 1em 0;
}
h1, h2, h3, h4, h5, h6 {
  font-weight: bold;
}
h1 { font-size: 1.25em; line-height: 1.4em; margin: 1em 0 0.5em 0; }
h2 { font-size: 1.125em; margin: 1em 0 0.5em 0; }
h3 { font-size: 1.05em; margin: 0.8em 0 0.4em 0; }
h4, h5, h6 { font-size: 1em; margin: 0.8em 0 0.4em 0; }
li p { margin: 0; }
ul, ol { margin: 1em 0; padding-left: 2em; }
li { margin-bottom: 0.4em; }
pre, tt, code, kbd, samp { font-family: monospace; }
pre { white-space: pre; margin: 1em 0; }
blockquote { border-left: 4px solid #ddd; padding-left: 1em; margin: 1em 0; color: #666; }
hr { border: none; border-top: 1px solid #ddd; margin: 1.5em 0; }
i, cite, em, var, address { font-style: italic; }
b, strong { font-weight: bolder; }
`;

class Yr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "weixin",
            name: "微信公众号",
            icon: "https://mp.weixin.qq.com/favicon.ico",
            homepage: "https://mp.weixin.qq.com",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {
            outputFormat: "html",
            removeLinks: !0,
            keepLinkDomains: ["mp.weixin.qq.com", "weixin.qq.com"],
            compactHtml: !0
        });
        g(this, "weixinMeta", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://mp.weixin.qq.com/cgi-bin/*",
            headers: {Origin: "https://mp.weixin.qq.com", Referer: "https://mp.weixin.qq.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        try {
            const t = await (await this.runtime.fetch("https://mp.weixin.qq.com/", {
                method: "GET",
                credentials: "include"
            })).text(), r = t.match(/data:\s*\{[\s\S]*?t:\s*["']([^"']+)["']/);
            if (!r) return de.debug(" No token found"), {isAuthenticated: !1};
            const s = t.match(/ticket:\s*["']([^"']+)["']/), n = t.match(/user_name:\s*["']([^"']+)["']/),
                i = t.match(/nick_name:\s*["']([^"']+)["']/), a = t.match(/time:\s*["'](\d+)["']/),
                u = t.match(/head_img:\s*['"]([^'"]+)['"]/),
                l = t.match(/class="weui-desktop-account__thumb"[^>]*src="([^"]+)"/);
            let h = l ? l[1] : u ? u[1] : "";
            return h.startsWith("http://") && (h = h.replace("http://", "https://")), this.weixinMeta = {
                token: r[1],
                userName: n ? n[1] : "",
                nickName: i ? i[1] : "",
                ticket: s ? s[1] : "",
                svrTime: a ? Number(a[1]) : Date.now() / 1e3,
                avatar: h
            }, de.debug(" Auth info:", {
                userName: this.weixinMeta.userName,
                nickName: this.weixinMeta.nickName,
                hasToken: !!this.weixinMeta.token
            }), {
                isAuthenticated: !0,
                userId: this.weixinMeta.userName,
                username: this.weixinMeta.nickName,
                avatar: this.weixinMeta.avatar
            }
        } catch (e) {
            return de.debug("checkAuth: not logged in -", e), {isAuthenticated: !1, error: e.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var u, l;
            if (de.info("Starting publish..."), !this.weixinMeta && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录微信公众号");
            let r = ((u = e.source) == null ? void 0 : u.platform) === "weixin" && e.rawHtml ? e.rawHtml : e.html || "";
            ((l = e.source) == null ? void 0 : l.platform) === "weixin" ? de.info("Source is WeChat, using raw HTML, skipping content processing") : (r = this.processLatex(r), r = this.stripExternalLinks(r), r = await this.processImages(r, h => this.uploadImageByUrl(h), {
                skipPatterns: ["mmbiz.qpic.cn", "mmbiz.qlogo.cn"],
                onProgress: t == null ? void 0 : t.onImageProgress
            }), r = this.processContent(r));
            const s = new URLSearchParams({
                    token: this.weixinMeta.token,
                    lang: "zh_CN",
                    f: "json",
                    ajax: "1",
                    random: String(Math.random()),
                    AppMsgId: "",
                    count: "1",
                    data_seq: "0",
                    operate_from: "Chrome",
                    isnew: "0",
                    ad_video_transition0: "",
                    can_reward0: "0",
                    related_video0: "",
                    is_video_recommend0: "-1",
                    title0: e.title,
                    author0: "",
                    writerid0: "0",
                    fileid0: "",
                    digest0: "",
                    auto_gen_digest0: "1",
                    content0: r,
                    sourceurl0: "",
                    need_open_comment0: "1",
                    only_fans_can_comment0: "0",
                    cdn_url0: "",
                    cdn_235_1_url0: "",
                    cdn_1_1_url0: "",
                    cdn_url_back0: "",
                    crop_list0: "",
                    music_id0: "",
                    video_id0: "",
                    voteid0: "",
                    voteismlt0: "",
                    supervoteid0: "",
                    cardid0: "",
                    cardquantity0: "",
                    cardlimit0: "",
                    vid_type0: "",
                    show_cover_pic0: "0",
                    shortvideofileid0: "",
                    copyright_type0: "0",
                    releasefirst0: "",
                    platform0: "",
                    reprint_permit_type0: "",
                    allow_reprint0: "",
                    allow_reprint_modify0: "",
                    original_article_type0: "",
                    ori_white_list0: "",
                    free_content0: "",
                    fee0: "0",
                    ad_id0: "",
                    guide_words0: "",
                    is_share_copyright0: "0",
                    share_copyright_url0: "",
                    source_article_type0: "",
                    reprint_recommend_title0: "",
                    reprint_recommend_content0: "",
                    share_page_type0: "0",
                    share_imageinfo0: '{"list":[]}',
                    share_video_id0: "",
                    dot0: "{}",
                    share_voice_id0: "",
                    insert_ad_mode0: "",
                    categories_list0: "[]"
                }),
                i = await (await this.runtime.fetch(`https://mp.weixin.qq.com/cgi-bin/operate_appmsg?t=ajax-response&sub=create&type=77&token=${this.weixinMeta.token}&lang=zh_CN`, {
                    method: "POST",
                    credentials: "include",
                    headers: {"Content-Type": "application/x-www-form-urlencoded"},
                    body: s
                })).json();
            if (de.debug(" Save response:", i), !i.appMsgId) {
                const h = this.formatError(i);
                throw new Error(h)
            }
            const a = `https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit&action=edit&type=77&appmsgid=${i.appMsgId}&token=${this.weixinMeta.token}&lang=zh_CN`;
            return this.createResult(!0, {
                postId: i.appMsgId,
                postUrl: a,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageByUrl(e) {
        var p;
        if (!this.weixinMeta) throw new Error("未登录");
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData, n = Date.now(), i = `${n}.jpg`;
        s.append("type", r.type || "image/jpeg"), s.append("id", String(n)), s.append("name", i), s.append("lastModifiedDate", new Date().toString()), s.append("size", String(r.size)), s.append("file", r, i);
        const {token: a, userName: u, ticket: l, svrTime: h} = this.weixinMeta, d = Date.now(),
            f = await (await this.runtime.fetch(`https://mp.weixin.qq.com/cgi-bin/filetransfer?action=upload_material&f=json&scene=8&writetype=doublewrite&groupid=1&ticket_id=${u}&ticket=${l}&svr_time=${h}&token=${a}&lang=zh_CN&seq=${d}&t=${Math.random()}`, {
                method: "POST",
                credentials: "include",
                body: s
            })).json();
        if (de.debug(" Image upload response:", f), ((p = f.base_resp) == null ? void 0 : p.err_msg) !== "ok" || !f.cdn_url) throw new Error("图片上传失败: " + e);
        return {url: f.cdn_url}
    }

    isLatexFormula(e) {
        return !!(/[\\^_{}]/.test(e) || /[α-ωΑ-Ω]/.test(e) || /[∑∏∫∂∇∞≠≤≥±×÷√]/.test(e))
    }

    processLatex(e) {
        const t = "https://latex.codecogs.com/png.latex";
        return e = e.replace(/\$\$([^$]+)\$\$/g, (r, s) => {
            if (!this.isLatexFormula(s)) return r;
            const n = encodeURIComponent(s.trim());
            return `<p style="text-align: center;"><img src="${t}?\\dpi{150}${n}" alt="formula" style="vertical-align: middle; max-width: 100%;"></p>`
        }), e = e.replace(/\$([^$]+)\$/g, (r, s) => {
            if (!this.isLatexFormula(s)) return r;
            const n = encodeURIComponent(s.trim());
            return `<img src="${t}?\\dpi{120}${n}" alt="formula" style="vertical-align: middle;">`
        }), e
    }

    processContent(e) {
        const t = `<section style="margin-left: 6px; margin-right: 6px; line-height: 1.75em;">${e}</section>`;
        return rr.inlineContent(t, Kr)
    }

    stripExternalLinks(e) {
        return e.replace(/<a\s+[^>]*href=["']([^"']*)["'][^>]*>([\s\S]*?)<\/a>/gi, (t, r, s) => r && (r.includes("mp.weixin.qq.com") || r.includes("weixin.qq.com") || r.startsWith("#") || r.startsWith("javascript:")) ? t : s)
    }

    formatError(e) {
        var s;
        const t = e.ret ?? ((s = e.base_resp) == null ? void 0 : s.ret);
        return {
            [-6]: "请输入验证码",
            [-8]: "请输入验证码",
            [-1]: "系统错误，请注意备份内容后重试",
            [-2]: "参数错误，请注意备份内容后重试",
            [-5]: "服务错误，请注意备份内容后重试",
            [-99]: "内容超出字数，请调整",
            [-206]: "服务负荷过大，请稍后重试",
            200002: "参数错误，请注意备份内容后重试",
            200003: "登录态超时，请重新登录",
            412: "图文中含非法外链",
            62752: "可能含有具备安全风险的链接，请检查",
            64502: "你输入的微信号不存在",
            64505: "发送预览失败，请稍后再试",
            64506: "保存失败，链接不合法",
            64507: "内容不能包含外部链接",
            64562: "请勿插入非微信域名的链接",
            64509: "正文中不能包含超过3个视频",
            64515: "当前素材非最新内容，请重新打开并编辑",
            64702: "标题超出64字长度限制",
            64703: "摘要超出120字长度限制",
            64705: "内容超出字数，请调整",
            10806: "正文不能有违规内容，请重新编辑",
            10807: "内容不能违反公众平台协议",
            220001: "素材管理中的存储数量已达上限",
            220002: "图片库已达到存储上限"
        }[t] || `同步失败 (错误码: ${t})`
    }
}

class Vr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "51cto",
            name: "51CTO",
            icon: "https://blog.51cto.com/favicon.ico",
            homepage: "https://blog.51cto.com/blogger/publish",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "csrf", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://blog.51cto.com/*",
            headers: {Origin: "https://blog.51cto.com", Referer: "https://blog.51cto.com/blogger/publish"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        try {
            const t = await (await this.runtime.fetch("https://blog.51cto.com/blogger/publish", {credentials: "include"})).text(),
                r = t.match(/<li class="more user">\s*<a[^>]*href="([^"]+)"[^>]*>\s*<img[^>]*src="([^"]+)"/);
            if (!r) return {isAuthenticated: !1, error: "未登录"};
            const s = r[1], n = r[2], i = s.split("/").filter(Boolean).pop() || "",
                a = t.match(/<meta\s+name="csrf-token"\s+content="([^"]+)"/);
            return a && (this.csrf = a[1]), {isAuthenticated: !0, userId: i, username: i, avatar: n}
        } catch (e) {
            return {isAuthenticated: !1, error: e.message}
        }
    }

    async getUploadSign() {
        const t = await (await this.runtime.fetch("https://blog.51cto.com/getUploadSign", {
            method: "POST",
            credentials: "include",
            headers: {
                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                "X-Requested-With": "XMLHttpRequest",
                Referer: "https://blog.51cto.com/blogger/publish",
                Origin: "https://blog.51cto.com"
            },
            body: "upload_type=image"
        })).json();
        if (t.code !== 0) throw new Error(t.msg || "获取上传签名失败");
        return t.data
    }

    async getUploadConfig(e, t, r) {
        const n = await (await this.runtime.fetch("https://blog.51cto.com/getUploadConfig", {
            method: "POST",
            credentials: "include",
            headers: {
                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                "X-Requested-With": "XMLHttpRequest"
            },
            body: new URLSearchParams({upload_type: "image", upload_sign: e, ext: t, name: r}).toString()
        })).json();
        if (n.code !== 0) throw new Error(n.msg || "获取上传配置失败");
        return n.data
    }

    async uploadToCOS(e, t, r) {
        const s = new FormData;
        s.append("key", t.key), s.append("policy", t.policy), s.append("x-amz-algorithm", t["x-amz-algorithm"]), s.append("x-amz-signature", t["x-amz-signature"]), s.append("x-amz-credential", t["x-amz-credential"]), s.append("X-Amz-Date", t["X-Amz-Date"]), s.append("Content-Type", r.type), s.append("file", r);
        const n = await this.runtime.fetch(e, {method: "POST", body: s});
        if (!n.ok) throw new Error(`上传到 COS 失败: ${n.status}`);
        return `https://s2.51cto.com/${t.key}`
    }

    async uploadImageByUrl(e) {
        const r = await (await this.runtime.fetch(e)).blob(), s = r.type || "image/jpeg", n = s.split("/")[1] || "jpeg",
            i = `${Date.now()}.${n}`, a = new File([r], i, {type: s}), u = await this.getUploadSign(),
            l = await this.getUploadConfig(u.sign, s, i);
        return {url: await this.uploadToCOS(l.url, l.fields, a)}
    }

    async publish(e) {
        const t = Date.now();
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            if (!this.csrf && !(await this.checkAuth()).isAuthenticated) throw new Error("未登录");
            const r = !!e.markdown;
            let s = e.markdown || e.html || "";
            s = await this.processImages(s, u => this.uploadImageByUrl(u));
            const n = {
                title: e.title,
                content: s,
                pid: "",
                cate_id: "",
                custom_id: "0",
                tag: "",
                abstract: "",
                banner_type: "0",
                blog_type: "1",
                copy_code: "1",
                is_hide: "0",
                top_time: "0",
                is_comment: "0",
                is_old: r ? "0" : "2",
                blog_id: "",
                did: "",
                work_id: "",
                class_id: "",
                subjectId: "",
                import_type: "-1",
                invite_code: "",
                raffle: "",
                orig: "",
                _csrf: this.csrf || ""
            }, a = await (await this.runtime.fetch("https://blog.51cto.com/blogger/draft", {
                method: "POST",
                credentials: "include",
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                    "X-Requested-With": "XMLHttpRequest",
                    Accept: "application/json, text/javascript, */*; q=0.01"
                },
                body: new URLSearchParams(n).toString()
            })).json();
            if (a.status !== 1 || !a.data) throw new Error(a.msg || "发布失败");
            return {
                platform: this.meta.id,
                success: !0,
                postId: String(a.data.did),
                postUrl: `https://blog.51cto.com/blogger/draft/${a.data.did}`,
                draftOnly: !0,
                timestamp: t
            }
        }).catch(r => ({platform: this.meta.id, success: !1, error: r.message, timestamp: t}))
    }
}

class Qr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "imooc",
            name: "慕课手记",
            icon: "https://www.imooc.com/favicon.ico",
            homepage: "https://www.imooc.com/article",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "HEADER_RULES", [{
            urlFilter: "*://www.imooc.com/article/*",
            headers: {Origin: "https://www.imooc.com", Referer: "https://www.imooc.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            let t = await (await this.runtime.fetch("https://www.imooc.com/u/card", {credentials: "include"})).text();
            t = t.replace("jsonpcallback(", "").replace("})", "}");
            const r = JSON.parse(t);
            return r.result !== 0 ? {isAuthenticated: !1, error: r.msg || "未登录"} : {
                isAuthenticated: !0,
                userId: r.data.uid,
                username: r.data.nickname,
                avatar: r.data.img
            }
        }).catch(e => ({isAuthenticated: !1, error: e.message}))
    }

    async uploadImageByUrl(e) {
        const r = await (await this.runtime.fetch(e)).blob(), s = new FormData, n = `${Date.now()}.jpg`,
            i = new File([r], n, {type: r.type || "image/jpeg"});
        s.append("photo", i, n), s.append("type", i.type), s.append("id", "WU_FILE_0"), s.append("name", n), s.append("lastModifiedDate", new Date().toString()), s.append("size", String(i.size));
        const u = await (await this.runtime.fetch("https://www.imooc.com/article/ajaxuploadimg", {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (u.result !== 0) throw new Error(u.msg || "图片上传失败");
        let l = u.data.imgpath;
        return l.startsWith("//") && (l = "https:" + l), {url: l}
    }

    async publish(e) {
        const t = Date.now();
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            let r = e.markdown || e.html || "";
            r = await this.processImages(r, i => this.uploadImageByUrl(i));
            const n = await (await this.runtime.fetch("https://www.imooc.com/article/savedraft", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/x-www-form-urlencoded"},
                body: new URLSearchParams({editor: "0", draft_id: "0", title: e.title, content: r})
            })).json();
            if (!n.data) throw new Error("发布失败");
            return {
                platform: this.meta.id,
                success: !0,
                postId: n.data,
                postUrl: `https://www.imooc.com/article/draft/id/${n.data}`,
                draftOnly: !0,
                timestamp: t
            }
        }).catch(r => ({platform: this.meta.id, success: !1, error: r.message, timestamp: t}))
    }
}

class Zr extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "oschina",
            name: "开源中国",
            icon: "https://www.oschina.net/favicon.ico",
            homepage: "https://my.oschina.net",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "userId", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://apiv1.oschina.net/oschinapi/*",
            headers: {Origin: "https://my.oschina.net", Referer: "https://my.oschina.net/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e, t, r;
        try {
            const n = await (await this.runtime.fetch("https://apiv1.oschina.net/oschinapi/user/myDetails", {credentials: "include"})).json();
            return !n.success || !((e = n.result) != null && e.userId) ? {
                isAuthenticated: !1,
                error: "未登录"
            } : (this.userId = String(n.result.userId), {
                isAuthenticated: !0,
                userId: this.userId,
                username: ((t = n.result.userVo) == null ? void 0 : t.name) || this.userId,
                avatar: (r = n.result.userVo) == null ? void 0 : r.portraitUrl
            })
        } catch (s) {
            return {isAuthenticated: !1, error: s.message}
        }
    }

    async uploadImageByUrl(e) {
        this.userId || await this.checkAuth();
        const r = await (await this.runtime.fetch(e)).blob(), s = this.getFilenameFromUrl(e) || "image",
            n = new FormData;
        n.append("file", r, s);
        const a = await (await this.runtime.fetch("https://apiv1.oschina.net/oschinapi/ai/creation/project/uploadDetail", {
            method: "POST",
            credentials: "include",
            body: n
        })).json();
        if (!a.success || !a.result) throw new Error(a.message || "图片上传失败");
        return {url: a.result}
    }

    getFilenameFromUrl(e) {
        try {
            const r = new URL(e).pathname.split("/").pop();
            return r && r.trim() ? r : null
        } catch {
            return null
        }
    }

    async publish(e) {
        const t = Date.now();
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var h;
            if (!this.userId && !(await this.checkAuth()).isAuthenticated) throw new Error("未登录");
            const r = e.markdown || "", s = e.html || "", n = r.trim().length > 0;
            let i = n ? r : s;
            i = await this.processImages(i, d => this.uploadImageByUrl(d));
            const u = await (await this.runtime.fetch("https://apiv1.oschina.net/oschinapi/api/draft/save_draft", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/json"},
                body: JSON.stringify({
                    title: e.title,
                    user: Number(this.userId),
                    content: i,
                    contentType: n ? 1 : 2,
                    catalog: 0,
                    originUrl: "",
                    privacy: !0,
                    disableComment: !1
                })
            })).json();
            if (!u.success || !((h = u.result) != null && h.id)) throw new Error(u.message || "发布失败");
            const l = String(u.result.id);
            return {
                platform: this.meta.id,
                success: !0,
                postId: l,
                postUrl: `https://my.oschina.net/u/${this.userId}/blog/write/draft/${l}`,
                draftOnly: !0,
                timestamp: t
            }
        }).catch(r => ({platform: this.meta.id, success: !1, error: r.message, timestamp: t}))
    }
}

class es extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "segmentfault",
            name: "思否",
            icon: "https://imgcache.iyiou.com/Company/2016-05-11/cf-segmentfault.jpg",
            homepage: "https://segmentfault.com/user/draft",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "sessionToken", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://segmentfault.com/gateway/*",
            headers: {Origin: "https://segmentfault.com", Referer: "https://segmentfault.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        try {
            const t = await (await this.runtime.fetch("https://segmentfault.com/user/settings", {credentials: "include"})).text(),
                r = t.match(/href="\/u\/([^"]+)"/);
            if (!r) return {isAuthenticated: !1, error: "未登录"};
            const s = r[1], n = t.match(/src="(https:\/\/avatar-static\.segmentfault\.com\/[^"]+)"/),
                i = n ? n[1] : void 0;
            return {isAuthenticated: !0, userId: s, username: s, avatar: i}
        } catch (e) {
            return {isAuthenticated: !1, error: e.message}
        }
    }

    async getSessionToken() {
        var u, l;
        const t = await (await this.runtime.fetch("https://segmentfault.com/write", {credentials: "include"})).text(),
            r = t.match(/serverData":\s*\{\s*"Token"\s*:\s*"([^"]+)"/);
        if (r) return r[1];
        const s = "window.g_initialProps = ", n = t.indexOf(s);
        if (n === -1) throw new Error("获取 session token 失败");
        const i = t.indexOf(`;
	<\/script>`, n);
        if (i === -1) throw new Error("解析 session token 失败");
        const a = t.substring(n + s.length, i);
        try {
            const h = JSON.parse(a),
                d = (l = (u = h == null ? void 0 : h.global) == null ? void 0 : u.sessionInfo) == null ? void 0 : l.key;
            if (!d) throw new Error("session token 为空");
            return d
        } catch (h) {
            throw new Error("解析 session token 失败: " + h.message)
        }
    }

    async uploadImageByUrl(e) {
        if (!this.sessionToken) throw new Error("未获取 token");
        const r = await (await this.runtime.fetch(e)).blob(), s = new FormData;
        s.append("image", r);
        const i = await (await this.runtime.fetch("https://segmentfault.com/gateway/image", {
            method: "POST",
            credentials: "include",
            headers: {token: this.sessionToken},
            body: s
        })).text();
        if (i === "Unauthorized" || i.includes("禁言") || i.includes("锁定")) throw new Error(i === "Unauthorized" ? "未授权" : i);
        let a;
        try {
            a = JSON.parse(i)
        } catch {
            throw new Error("图片上传失败: " + i)
        }
        const u = a.result || (Array.isArray(a) ? a[0] === 1 ? null : a[1] || `https://image-static.segmentfault.com/${a[2]}` : null);
        if (!u) throw new Error(Array.isArray(a) && a[1] || "图片上传失败");
        return {url: u}
    }

    async publish(e) {
        const t = Date.now();
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            this.sessionToken = await this.getSessionToken();
            let r = e.markdown || e.html || "";
            r = await this.processImages(r, u => this.uploadImageByUrl(u));
            const s = {title: e.title, tags: [], text: r, object_id: "", type: "article"},
                i = await (await this.runtime.fetch("https://segmentfault.com/gateway/draft", {
                    method: "POST",
                    credentials: "include",
                    headers: {"Content-Type": "application/json", token: this.sessionToken, accept: "*/*"},
                    body: JSON.stringify(s)
                })).text();
            if (i === "Unauthorized" || i.includes("禁言") || i.includes("锁定")) throw new Error(i === "Unauthorized" ? "未授权" : i);
            let a;
            try {
                a = JSON.parse(i)
            } catch {
                throw new Error("发布失败: " + i)
            }
            if (Array.isArray(a)) {
                if (a[0] === 1) throw new Error(a[1] || "发布失败");
                const u = a[1];
                if (u != null && u.id) return {
                    platform: this.meta.id,
                    success: !0,
                    postId: u.id,
                    postUrl: `https://segmentfault.com/write?draftId=${u.id}`,
                    draftOnly: !0,
                    timestamp: t
                }
            }
            if (!a.id) {
                const u = a.message || a.msg || a.error || a.errMsg || JSON.stringify(a);
                throw new Error(u)
            }
            return {
                platform: this.meta.id,
                success: !0,
                postId: a.id,
                postUrl: `https://segmentfault.com/write?draftId=${a.id}`,
                draftOnly: !0,
                timestamp: t
            }
        }).catch(r => ({platform: this.meta.id, success: !1, error: r.message, timestamp: t}))
    }
}

const z = N("Cnblogs");

class ts extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "cnblogs",
            name: "博客园",
            icon: "https://www.cnblogs.com/favicon.ico",
            homepage: "https://www.cnblogs.com",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "xsrfToken", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://i.cnblogs.com/*",
            headers: {Origin: "https://i.cnblogs.com", Referer: "https://i.cnblogs.com/"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://upload.cnblogs.com/*",
            headers: {Origin: "https://i.cnblogs.com", Referer: "https://i.cnblogs.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async getXsrfToken() {
        if (this.xsrfToken) return this.xsrfToken;
        try {
            if (await this.runtime.fetch("https://i.cnblogs.com/posts/edit", {
                method: "GET",
                credentials: "include"
            }), this.runtime.getCookie) {
                z.debug("Trying to get XSRF-TOKEN via getCookie API...");
                const e = ["i.cnblogs.com", ".cnblogs.com", "cnblogs.com"];
                for (const t of e) {
                    const r = await this.runtime.getCookie(t, "XSRF-TOKEN");
                    if (z.debug(`getCookie ${t} result:`, r ? `${r.substring(0, 30)}...` : "null"), r) return this.xsrfToken = r, z.debug("Got XSRF-TOKEN from cookies API"), this.xsrfToken
                }
            } else z.warn("getCookie API not available");
            return z.warn("Could not find XSRF-TOKEN"), null
        } catch (e) {
            return z.error("Failed to get XSRF-TOKEN:", e), null
        }
    }

    async checkAuth() {
        try {
            const t = await (await this.runtime.fetch("https://home.cnblogs.com/user/CurrentUserInfo", {
                method: "GET",
                credentials: "include"
            })).text(), r = t.match(/<img[^>]+class="pfs"[^>]+src="([^"]+)"/), s = t.match(/href="\/u\/([^/]+)\/"/);
            if (!s) return {isAuthenticated: !1};
            const n = s[1], i = r ? r[1] : void 0;
            return {isAuthenticated: !0, userId: n, username: n, avatar: i}
        } catch (e) {
            return z.debug("checkAuth: not logged in -", e), {isAuthenticated: !1, error: e.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            z.info("Starting publish to cnblogs...");
            const r = await this.getXsrfToken();
            if (z.info("XSRF-TOKEN:", r ? `${r.substring(0, 20)}...` : "null"), !r) throw new Error("获取 XSRF-TOKEN 失败，请刷新页面后重试");
            this.xsrfToken = r;
            let s = e.markdown || "";
            z.debug("Markdown before processImages:", s.substring(0, 200)), s = await this.processImages(s, d => this.uploadImageByUrl(d), {
                skipPatterns: ["cnblogs.com", "img2024.cnblogs.com", "img2023.cnblogs.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            }), z.debug("Markdown after processImages:", s.substring(0, 200));
            const n = {"Content-Type": "application/json", "x-xsrf-token": r};
            z.debug("Request headers:", JSON.stringify(n)), z.debug("Markdown content length:", s.length);
            const i = await this.runtime.fetch("https://i.cnblogs.com/api/posts", {
                method: "POST",
                credentials: "include",
                headers: n,
                body: JSON.stringify({
                    id: null,
                    postType: 2,
                    accessPermission: 0,
                    title: e.title,
                    url: null,
                    postBody: s,
                    categoryIds: null,
                    categories: null,
                    collectionIds: [],
                    inSiteCandidate: !1,
                    inSiteHome: !1,
                    siteCategoryId: null,
                    blogTeamIds: null,
                    isPublished: !1,
                    displayOnHomePage: !1,
                    isAllowComments: !0,
                    includeInMainSyndication: !1,
                    isPinned: !1,
                    showBodyWhenPinned: !1,
                    isOnlyForRegisterUser: !1,
                    isUpdateDateAdded: !1,
                    entryName: null,
                    description: null,
                    featuredImage: null,
                    tags: null,
                    password: null,
                    publishAt: null,
                    datePublished: new Date().toISOString(),
                    dateUpdated: null,
                    isMarkdown: !0,
                    isDraft: !0,
                    autoDesc: null,
                    changePostType: !1,
                    blogId: 0,
                    author: null,
                    removeScript: !1,
                    clientInfo: null,
                    changeCreatedTime: !1,
                    canChangeCreatedTime: !1,
                    isContributeToImpressiveBugActivity: !1,
                    usingEditorId: 5,
                    sourceUrl: null
                })
            }), a = await i.text();
            if (z.debug("Create post response:", i.status, a.substring(0, 300)), !i.ok) throw i.status === 401 || i.status === 403 ? new Error("未登录或登录已过期，请重新登录博客园") : new Error(`创建草稿失败: ${i.status} - ${a}`);
            let u;
            try {
                u = JSON.parse(a)
            } catch {
                throw new Error(`创建草稿失败: 响应不是有效 JSON - ${a.substring(0, 100)}`)
            }
            if (!u.id) throw new Error(u.error || "创建草稿失败: 无效响应");
            const l = String(u.id), h = `https://i.cnblogs.com/articles/edit;postId=${l}`;
            return z.debug("Draft created:", l), this.createResult(!0, {
                postId: l,
                postUrl: h,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageByUrl(e) {
        if (!this.xsrfToken) throw new Error("XSRF-TOKEN 未获取");
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData;
        s.append("image", r, "image.png"), s.append("app", "blog"), s.append("uploadType", "Select");
        const n = await this.runtime.fetch("https://upload.cnblogs.com/v2/images/cors-upload", {
            method: "POST",
            credentials: "include",
            headers: {"x-xsrf-token": this.xsrfToken},
            body: s
        }), i = await n.text();
        if (z.debug("Image upload raw response:", i), !n.ok) throw new Error(`图片上传失败: ${n.status} - ${i}`);
        let a;
        try {
            a = JSON.parse(i)
        } catch {
            throw new Error(`图片上传失败: 响应不是 JSON - ${i.substring(0, 100)}`)
        }
        z.debug("Image upload parsed response:", JSON.stringify(a));
        const u = a.data || a.url || a.imageUrl || a.src;
        if (!u || typeof u != "string") throw new Error(`图片上传失败: 无法获取图片 URL - ${JSON.stringify(a)}`);
        return z.info("Image uploaded:", u), {url: u}
    }
}

const he = N("ZipDownload");

class rs extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "zip-download",
            name: "Markdown 压缩包",
            icon: "https://cdn-icons-png.flaticon.com/512/337/337946.png",
            homepage: "",
            capabilities: ["article"]
        })
    }

    async checkAuth() {
        return {isAuthenticated: !0, username: "本地下载"}
    }

    async publish(e, t) {
        try {
            const r = new sr, s = r.folder("images");
            let n = e.markdown || ar(e.html || "");
            if (!n.trim()) return this.createResult(!1, {error: "文章内容为空"});
            const i = e.title || "未命名文章";
            n.startsWith("# ") || (n = `# ${i}

${n}`);
            const {
                processedMarkdown: a,
                imageCount: u
            } = await this.processImagesForZip(n, s, t == null ? void 0 : t.onImageProgress);
            r.file("article.md", a);
            const l = await r.generateAsync({type: "blob", compression: "DEFLATE", compressionOptions: {level: 6}}),
                h = this.sanitizeFilename(i) + ".zip";
            if (!this.runtime.downloads) return this.createResult(!1, {error: "当前环境不支持下载功能"});
            const d = await this.runtime.downloads.download(l, h, !0);
            return he.info(`Download started: ${h}, id: ${d}`), this.createResult(!0, {
                postId: String(d),
                postUrl: "",
                message: `已下载 ${h}（${u} 张图片）`
            })
        } catch (r) {
            return he.error("ZIP download failed:", r), this.createResult(!1, {error: r.message})
        }
    }

    async processImagesForZip(e, t, r) {
        const s = xe(e);
        if (s.length === 0) return {processedMarkdown: e, imageCount: 0};
        he.info(`Found ${s.length} images to process`);
        const n = Math.floor(Date.now() / 1e3);
        let i = e, a = 0, u = 0;
        const l = new Map, h = [];
        for (const {src: f} of s) {
            if (f.startsWith("data:")) {
                he.debug("Skipping data URI image");
                continue
            }
            l.has(f) || (l.set(f, ""), h.push(f))
        }
        if (h.length === 0) return {processedMarkdown: e, imageCount: 0};
        const d = async f => {
            try {
                const p = await this.runtime.fetch(f, {credentials: "omit"});
                if (!p.ok) {
                    he.warn(`Failed to download image: ${f}, status: ${p.status}`);
                    return
                }
                const w = await p.blob(), _ = this.getImageExtension(f, w.type);
                a++;
                const y = `image_${n}_${String(a).padStart(3, "0")}.${_}`;
                t.file(y, w), l.set(f, y), he.debug(`Downloaded image: ${y}`)
            } catch (p) {
                he.warn(`Failed to download image: ${f}`, p)
            } finally {
                u++, r == null || r(u, h.length)
            }
        };
        await (async f => {
            let p = 0;
            const w = Array.from({length: Math.min(f, h.length)}, async () => {
                for (; p < h.length;) {
                    const _ = p;
                    p++, await d(h[_])
                }
            });
            await Promise.all(w)
        })(4);
        for (const {full: f, alt: p, src: w} of s) {
            const _ = l.get(w);
            _ && (i = i.replace(f, `![${p}](images/${_})`))
        }
        return {processedMarkdown: i, imageCount: Array.from(l.values()).filter(Boolean).length}
    }

    getImageExtension(e, t) {
        const r = {
            "image/jpeg": "jpg",
            "image/png": "png",
            "image/gif": "gif",
            "image/webp": "webp",
            "image/svg+xml": "svg",
            "image/bmp": "bmp",
            "image/x-icon": "ico"
        };
        if (t && r[t]) return r[t];
        const s = e.match(/\.(png|jpe?g|gif|webp|svg|bmp|ico)(?:\?|$)/i);
        return s ? s[1].toLowerCase().replace("jpeg", "jpg") : "png"
    }

    sanitizeFilename(e) {
        return e.replace(/[<>:"/\\|?*]/g, "_").replace(/[\x00-\x1f]/g, "").replace(/\.+$/, "").trim().slice(0, 200) || "article"
    }
}

const _e = N("Eastmoney");

class ss extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "eastmoney",
            name: "东方财富",
            icon: "https://mp.eastmoney.com/collect/pc_article/favicon.ico",
            homepage: "https://mp.eastmoney.com",
            capabilities: ["article", "draft", "image_upload", "cover"]
        });
        g(this, "preprocessConfig", {
            outputFormat: "html",
            removeComments: !0,
            removeSpecialTags: !0,
            processCodeBlocks: !0,
            convertSectionToDiv: !0,
            removeEmptyLines: !0,
            removeEmptyDivs: !0,
            removeNestedEmptyContainers: !0,
            unwrapSingleChildContainers: !0,
            unwrapNestedFigures: !0,
            removeTrailingBr: !0,
            removeDataAttributes: !0,
            removeSrcset: !0,
            removeSizes: !0,
            compactHtml: !0
        });
        g(this, "ctoken", "");
        g(this, "utoken", "");
        g(this, "deviceId", "");
        g(this, "HEADER_RULES", [{
            urlFilter: "*://mp.eastmoney.com/*",
            headers: {Origin: "https://mp.eastmoney.com", HOST: "emfront.eastmoney.com"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async getDeviceId() {
        if (this.deviceId) return this.deviceId;
        const e = await this.runtime.storage.get("eastmoney_deviceId");
        if (e) return this.deviceId = e, this.deviceId;
        const t = new Uint8Array(16);
        return crypto.getRandomValues(t), this.deviceId = Array.from(t).map(r => r.toString(16).padStart(2, "0").toUpperCase()).join(""), await this.runtime.storage.set("eastmoney_deviceId", this.deviceId), this.deviceId
    }

    async checkAuth() {
        var e;
        try {
            await this.fetchToken();
            const r = await (await this.runtime.fetch(`https://caifuhaoapi.eastmoney.com/api/v2/getauthorinfo?platform=&ctoken=${this.ctoken}&utoken=${this.utoken}`, {
                method: "GET",
                credentials: "include",
                headers: {"x-requested-with": "fetch"}
            })).json();
            return r.Success === 1 && ((e = r.Result) != null && e.accountId) ? {
                isAuthenticated: !0,
                userId: r.Result.accountId,
                username: r.Result.accountName,
                avatar: r.Result.portrait
            } : {isAuthenticated: !1}
        } catch (t) {
            return _e.debug("checkAuth: not logged in -", t), {isAuthenticated: !1, error: t.message}
        }
    }

    async fetchToken() {
        if (!this.runtime.getCookie) throw new Error("Cookie API 不可用，请先登录东方财富");
        const e = await this.runtime.getCookie(".eastmoney.com", "ct"),
            t = await this.runtime.getCookie(".eastmoney.com", "ut");
        if (!e || !t) throw new Error("未检测到登录信息，请先登录东方财富");
        this.ctoken = e, this.utoken = t
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            await this.fetchToken(), _e.info("Starting publish to eastmoney...");
            const r = await this.createDraft(e.title);
            _e.debug("Draft created:", r);
            const s = await this.processImages(e.html || "", i => this.uploadImageByUrl(i), {
                skipPatterns: ["gbres.dfcfw.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            await this.updateDraft(r, e.title, s), _e.debug("Draft updated");
            const n = `https://mp.eastmoney.com/collect/pc_article/index.html#/?id=${r}`;
            return this.createResult(!0, {postId: r, postUrl: n, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async buildParm(e) {
        const t = await this.getDeviceId();
        return [{ip: "$IP$"}, {deviceid: t}, {version: "100"}, {plat: "web"}, {product: "CFH"}, {ctoken: this.ctoken}, {utoken: this.utoken}, {draftid: e.draftid ?? ""}, {drafttype: "0"}, {type: "0"}, {title: encodeURIComponent(e.title)}, {text: encodeURIComponent(e.text)}, {columns: "2"}, {cover: ""}, {issimplevideo: "0"}, {videos: ""}, {vods: ""}, {isoriginal: "0"}, {tgProduct: ""}, {spcolumns: ""}, {textsource: "0"}, {replyauthority: ""}, {modules: encodeURIComponent("[]")}]
    }

    async callDraftApi(e, t) {
        const r = t ? `https://mp.eastmoney.com/collect/pc_article/index.html#/?id=${t}` : "https://mp.eastmoney.com/collect/pc_article/index.html#/",
            s = JSON.stringify({pageUrl: r, path: "draft/api/Article/SaveDraft", parm: JSON.stringify(e)}),
            n = await this.runtime.fetch("https://emfront.eastmoney.com/apifront/Tran/GetData?platform=", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/json"},
                body: s
            }), i = await n.text();
        if (_e.debug("Draft API response:", n.status, i.substring(0, 200)), !n.ok) throw new Error(`草稿 API 请求失败: ${n.status}`);
        let a;
        try {
            a = JSON.parse(i)
        } catch {
            throw new Error("草稿 API 响应不是有效 JSON")
        }
        if (!a.RRquestSuccess || a.RCode !== 200) throw new Error(`草稿 API 错误: ${a.RMsg || "未知错误"}`);
        let u;
        try {
            u = JSON.parse(a.RData)
        } catch {
            throw new Error("无法解析草稿响应数据")
        }
        if (u.error_code !== 0) throw new Error(`草稿业务错误: ${u.me || "未知错误"}`);
        return u
    }

    async createDraft(e) {
        const t = await this.buildParm({title: e, text: '<div class="xeditor_content cfh_web"></div>'}),
            r = await this.callDraftApi(t);
        if (!r.draft_id) throw new Error("创建草稿失败: 响应缺少 draft_id");
        return r.draft_id
    }

    async updateDraft(e, t, r) {
        const s = await this.buildParm({draftid: e, title: t, text: `<div class="xeditor_content cfh_web">${r}</div>`});
        await this.callDraftApi(s, e)
    }

    async uploadImageByUrl(e) {
        var s;
        if (e.startsWith("data:")) {
            _e.debug("Detected data URI, using binary upload");
            const n = await this.dataUriToBlob(e);
            return this.uploadImageBlob(n)
        }
        const r = await (await this.runtime.fetch("https://gbapi.eastmoney.com/iimage/image/byLink?platform=", {
            method: "PUT",
            credentials: "include",
            headers: {"Content-Type": "application/x-www-form-urlencoded"},
            body: new URLSearchParams({noinlist: "1", linkUrl: e, ctoken: this.ctoken, utoken: this.utoken})
        })).json();
        if (r.code === 200 && ((s = r.data) != null && s.url)) return {url: r.data.url};
        throw new Error(`图片上传失败: ${r.message || "未知错误"} (code: ${r.code})`)
    }

    async uploadImageBlob(e) {
        var a;
        const t = e.type.split("/")[1] || "png", r = `${Date.now()}.${t}`, s = new FormData;
        s.append("file", e, r), s.append("noinlist", "1"), s.append("utoken", this.utoken), s.append("ctoken", this.ctoken);
        const i = await (await this.runtime.fetch("https://gbapi.eastmoney.com/iimage/image?platform=", {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (i.code === 200 && ((a = i.data) != null && a.url)) return {url: i.data.url};
        throw new Error(`图片上传失败: ${i.message || "未知错误"} (code: ${i.code})`)
    }
}

const He = N("DaYu");

class as extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "dayu",
            name: "大鱼号",
            icon: "https://image.uc.cn/s/uae/g/1v/images/index/favicon.ico",
            homepage: "https://mp.dayu.com/dashboard/account/profile",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html"});
        g(this, "cacheMeta", null);
        g(this, "uploadedImages", []);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://mp.dayu.com/*",
            headers: {Origin: "https://mp.dayu.com", Referer: "https://mp.dayu.com/"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://ns.dayu.com/*",
            headers: {Origin: "https://mp.dayu.com", Referer: "https://mp.dayu.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e, t;
        try {
            const s = await (await this.runtime.fetch("https://mp.dayu.com/dashboard/index", {
                method: "GET",
                credentials: "include"
            })).text(), n = "var globalConfig = ", i = s.indexOf(n);
            if (i === -1) return {isAuthenticated: !1};
            const a = s.substring(i + n.length, s.indexOf("var G = {", i)), u = this.parseGlobalConfig(a);
            return !u || !u.utoken ? {isAuthenticated: !1} : (this.cacheMeta = {
                utoken: u.utoken,
                uploadSign: u.nsImageUploadSign,
                uid: u.wmid,
                title: u.weMediaName,
                avatar: ((e = u.wmAvator) == null ? void 0 : e.indexOf("http")) > -1 ? u.wmAvator : ((t = u.wmAvator) == null ? void 0 : t.replace("//", "https://")) || ""
            }, {
                isAuthenticated: !0,
                userId: this.cacheMeta.uid,
                username: this.cacheMeta.title,
                avatar: this.cacheMeta.avatar
            })
        } catch (r) {
            return He.debug("checkAuth: not logged in -", r), {isAuthenticated: !1, error: r.message}
        }
    }

    parseGlobalConfig(e) {
        try {
            let t = e.trim();
            t.endsWith(";") && (t = t.slice(0, -1));
            const r = t.replace(/'/g, '"').replace(/(\w+):/g, '"$1":').replace(/,\s*}/g, "}").replace(/,\s*]/g, "]");
            return JSON.parse(r)
        } catch {
            const t = {}, r = {
                utoken: /utoken['":\s]+['"]([^'"]+)['"]/,
                nsImageUploadSign: /nsImageUploadSign['":\s]+['"]([^'"]+)['"]/,
                wmid: /wmid['":\s]+['"]([^'"]+)['"]/,
                weMediaName: /weMediaName['":\s]+['"]([^'"]+)['"]/,
                wmAvator: /wmAvator['":\s]+['"]([^'"]+)['"]/
            };
            for (const [s, n] of Object.entries(r)) {
                const i = e.match(n);
                i && (t[s] = i[1])
            }
            return Object.keys(t).length > 0 ? t : null
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var h;
            if (He.info("Starting publish..."), this.uploadedImages = [], !this.cacheMeta && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录大鱼号");
            let r = e.html || "";
            r = await this.processImages(r, d => this.uploadImageByUrl(d), {
                skipPatterns: ["dayu.com", "uc.cn"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const s = this.uploadedImages.length > 0 ? this.uploadedImages[0].url : "", n = new URLSearchParams;
            n.append("title", e.title), n.append("content", r), n.append("author", this.cacheMeta.title), n.append("coverImg", s), n.append("article_type", "1"), n.append("utoken", this.cacheMeta.utoken), n.append("cover_from", "auto");
            const a = await (await this.runtime.fetch("https://mp.dayu.com/dashboard/save-draft", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/x-www-form-urlencoded", utoken: this.cacheMeta.utoken},
                body: n
            })).json();
            if (He.debug("Save response:", a), a.error) throw new Error(a.error);
            if (!((h = a.data) != null && h._id)) throw new Error("保存草稿失败");
            const u = a.data._id, l = `https://mp.dayu.com/dashboard/article/write?draft_id=${u}`;
            return this.createResult(!0, {postId: u, postUrl: l, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async uploadImageByUrl(e) {
        var h, d;
        if (!this.cacheMeta) throw new Error("未登录");
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(),
            s = `https://ns.dayu.com/article/imageUpload?appid=website&fromMaterial=0&wmid=${this.cacheMeta.uid}&wmname=${encodeURIComponent(this.cacheMeta.title)}&sign=${this.cacheMeta.uploadSign}`,
            n = new FormData, i = `${Date.now()}.jpg`;
        n.append("upfile", r, i), n.append("type", r.type || "image/jpeg"), n.append("id", "WU_FILE_1"), n.append("fileid", `uploadm-${Math.floor(Math.random() * 1e6)}`), n.append("name", i), n.append("lastModifiedDate", new Date().toString()), n.append("size", String(r.size));
        const u = await (await this.runtime.fetch(s, {method: "POST", credentials: "include", body: n})).json();
        if (He.debug("Image upload response:", u), !((d = (h = u.data) == null ? void 0 : h.imgInfo) != null && d.url)) throw new Error("图片上传失败");
        const l = {org_url: u.data.imgInfo.org_url, url: u.data.imgInfo.url};
        return this.uploadedImages.push(l), {url: l.url}
    }
}

const ns = Object.freeze(Object.defineProperty({
    __proto__: null,
    DaYuAdapter: as
}, Symbol.toStringTag, {value: "Module"})), V = N("Douyin"), Tt = "jm8ajry58r", st = "1128";

function os() {
    const c = "abcdefghijklmnopqrstuvwxyz0123456789";
    let o = "";
    for (let e = 0; e < 8; e++) o += c[Math.floor(Math.random() * c.length)];
    return o + Date.now().toString()
}

class is extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "douyin",
            name: "抖音图文",
            icon: "https://lf1-cdn-tos.bytegoofy.com/goofy/ies/douyin_web/public/favicon.ico",
            homepage: "https://creator.douyin.com",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "markdown"});
        g(this, "cachedSTS", null);
        g(this, "stsExpiry", 0);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://imagex.bytedanceapi.com/*",
            headers: {Origin: "https://creator.douyin.com", Referer: "https://creator.douyin.com/"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://tos-hl-x.snssdk.com/*",
            headers: {Origin: "https://creator.douyin.com", Referer: "https://creator.douyin.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        try {
            const t = (await this.runtime.cookies.get(".douyin.com")).find(r => r.name === "passport_assist_user");
            return t != null && t.value ? {isAuthenticated: !0} : {isAuthenticated: !1}
        } catch (e) {
            return V.debug("checkAuth: not logged in -", e), {isAuthenticated: !1, error: e.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            V.info("Starting publish...");
            let r = e.markdown || "";
            const s = [];
            r = await this.processImages(r, async d => {
                const m = await this.uploadImageFull(d);
                return m.imageInfo && s.push(m.imageInfo), {url: m.storeUri}
            }, {
                skipPatterns: ["douyin.com", "snssdk.com", "byteimg.com", "bytedanceapi.com", "jm8ajry58r"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            let n = !1;
            r.length > 8e3 && (r = r.slice(0, 8e3), n = !0, V.warn("Content truncated to 8000 chars for Douyin limit"));
            const i = os(), a = Math.floor(Date.now() / 1e3), u = {
                    item: {
                        common: {
                            draft: {
                                title: e.title,
                                description: "",
                                long_article: r,
                                image_info: s,
                                head_poster: "",
                                text_extra: "[]",
                                visibility_type: 0,
                                timing: 0,
                                creation_id: i,
                                init_timestamp: a,
                                req_type: 0
                            }
                        }, cover: {}
                    }
                },
                l = await this.executeInDouyinTab(`https://creator.douyin.com/web/api/media/aweme/draft?aid=${st}`, "POST", u);
            if (l.status_code !== 0) throw new Error(l.status_msg || "保存草稿失败");
            V.info("Draft saved successfully");
            const h = `https://creator.douyin.com/creator-micro/content/post/article?enter_from=draft&creation_id=${i}&init_timestamp=${a}`;
            return this.createResult(!0, {
                postUrl: h,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0,
                message: n ? "内容已截断至 8000 字（抖音图文字数限制）" : void 0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async ensureDouyinTab() {
        if (!this.runtime.tabs) throw new Error("抖音发布需要浏览器 tabs API 支持");
        const e = await this.runtime.tabs.query("https://creator.douyin.com/*");
        if (e.length > 0 && e[0].id) return e[0].id;
        V.info("No existing tab found, creating new one...");
        const t = await this.runtime.tabs.create("https://creator.douyin.com/creator-micro/content/post/article", !1);
        return await this.runtime.tabs.waitForLoad(t.id, 3e4), V.info("New tab created and loaded:", t.id), t.id
    }

    async executeInDouyinTab(e, t, r) {
        if (!this.runtime.tabs) throw new Error("抖音发布需要浏览器 tabs API 支持");
        const s = await this.ensureDouyinTab();
        V.debug("Using tab:", s, "for", t, e.substring(0, 80));
        const n = await this.runtime.tabs.executeScript(s, async (i, a, u) => {
            try {
                const l = {method: a, credentials: "include"};
                return u && (l.headers = {"Content-Type": "application/json"}, l.body = u), {
                    success: !0,
                    data: await (await fetch(i, l)).json()
                }
            } catch (l) {
                return {success: !1, error: l.message}
            }
        }, [e, t, r ? JSON.stringify(r) : null]);
        if (!n || !n.success) throw new Error((n == null ? void 0 : n.error) || "请求失败");
        return n.data
    }

    async getSTSCredentials() {
        if (this.cachedSTS && Date.now() < this.stsExpiry - 6e4) return this.cachedSTS;
        const e = await this.executeInDouyinTab(`https://creator.douyin.com/web/api/media/upload/auth/v5/?aid=${st}`, "GET");
        if (e.status_code !== 0 || !e.auth) throw new Error("获取上传凭证失败");
        const t = JSON.parse(e.auth);
        if (!t.AccessKeyID || !t.SecretAccessKey) throw new Error("上传凭证无效");
        return this.cachedSTS = t, this.stsExpiry = new Date(t.ExpiredTime).getTime(), V.debug("Got STS credentials, expires:", t.ExpiredTime), this.cachedSTS
    }

    async uploadImageFull(e) {
        var h, d;
        let t;
        if (e.startsWith("data:")) t = await fetch(e).then(m => m.blob()); else {
            const m = await this.runtime.fetch(e, {method: "GET"});
            if (!m.ok) return V.warn("Failed to download image:", m.status), {storeUri: e};
            t = await m.blob()
        }
        const r = await this.getSTSCredentials(), s = await this.applyImageUpload(r),
            n = (h = s.StoreInfos[0]) == null ? void 0 : h.StoreUri;
        if (!n) throw new Error("No store URI in upload address");
        V.debug("Apply upload success, storeUri:", n), await this.uploadToTOS(s, t);
        const a = (d = (await this.commitImageUpload(r, s.SessionKey)).PluginResult) == null ? void 0 : d[0],
            u = await this.getImagePreviewUrl(n), l = {
                key: n,
                value: {
                    url: u,
                    width: (a == null ? void 0 : a.ImageWidth) || 0,
                    height: (a == null ? void 0 : a.ImageHeight) || 0
                }
            };
        return V.debug("Image uploaded:", n, `(${l.value.width}x${l.value.height})`), {storeUri: n, imageInfo: l}
    }

    async uploadImageByUrl(e) {
        try {
            return {url: (await this.uploadImageFull(e)).storeUri}
        } catch (t) {
            return V.warn("Failed to upload image:", e, t), {url: e}
        }
    }

    async applyImageUpload(e) {
        var i;
        const t = `https://imagex.bytedanceapi.com/?Action=ApplyImageUpload&Version=2018-08-01&ServiceId=${Tt}`,
            r = await Ve({
                method: "GET",
                url: t,
                accessKeyId: e.AccessKeyID,
                secretAccessKey: e.SecretAccessKey,
                securityToken: e.SessionToken,
                region: "cn-north-1",
                service: "imagex"
            }), n = await (await this.runtime.fetch(t, {method: "GET", headers: {...r.headers}})).json();
        if (!((i = n.Result) != null && i.UploadAddress)) throw new Error("Failed to apply image upload");
        return n.Result.UploadAddress
    }

    async uploadToTOS(e, t) {
        const r = e.StoreInfos[0], s = e.UploadHosts[0];
        if (!r || !s) throw new Error("Invalid upload address");
        const n = `https://${s}/${r.StoreUri}`, i = await t.arrayBuffer(), a = new Uint8Array(i), u = qt(a);
        V.debug("Uploading to TOS:", n, "size:", t.size, "crc32:", u);
        const l = await this.runtime.fetch(n, {
            method: "PUT",
            headers: {Authorization: r.Auth, "Content-Type": t.type || "application/octet-stream", "Content-CRC32": u},
            body: t
        });
        if (!l.ok) {
            const h = await l.text();
            throw new Error(`TOS upload failed: ${l.status} ${h}`)
        }
        V.debug("TOS upload success")
    }

    async commitImageUpload(e, t) {
        const r = `https://imagex.bytedanceapi.com/?Action=CommitImageUpload&Version=2018-08-01&ServiceId=${Tt}`,
            s = JSON.stringify({SessionKey: t}), n = await Ve({
                method: "POST",
                url: r,
                accessKeyId: e.AccessKeyID,
                secretAccessKey: e.SecretAccessKey,
                securityToken: e.SessionToken,
                region: "cn-north-1",
                service: "imagex",
                body: s
            }), a = await (await this.runtime.fetch(r, {
                method: "POST",
                headers: {...n.headers, "Content-Type": "application/json"},
                body: s
            })).json();
        if (!a.Result) throw new Error("Failed to commit image upload");
        return a.Result
    }

    async getImagePreviewUrl(e) {
        var s, n;
        const r = (n = (s = (await this.executeInDouyinTab(`https://creator.douyin.com/aweme/v1/creator/get/url/?uri=${encodeURIComponent(e)}&aid=${st}`, "GET")).url) == null ? void 0 : s.url_list) == null ? void 0 : n[0];
        if (!r) throw new Error("获取图片预览 URL 失败");
        return r
    }
}

const cs = Object.freeze(Object.defineProperty({
    __proto__: null,
    DouyinAdapter: is
}, Symbol.toStringTag, {value: "Module"})), pe = N("Jianshu");

class us extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "jianshu",
            name: "简书",
            icon: "https://www.jianshu.com/favicon.ico",
            homepage: "https://www.jianshu.com",
            capabilities: ["article", "draft", "image_upload", "categories"]
        });
        g(this, "preprocessConfig", {outputFormat: "html"});
        g(this, "defaultNotebookId", null);
        g(this, "preferredNoteType", "plain");
        g(this, "HEADER_RULES", [{
            urlFilter: "*://www.jianshu.com/*",
            headers: {Origin: "https://www.jianshu.com", Referer: "https://www.jianshu.com/writer"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e;
        try {
            const r = await (await this.runtime.fetch("https://www.jianshu.com/settings/basic.json", {
                method: "GET",
                credentials: "include"
            })).json();
            return (e = r.data) != null && e.nickname ? (this.preferredNoteType = r.data.preferred_note_type === "markdown" ? "markdown" : "plain", pe.debug("preferred_note_type:", this.preferredNoteType), {
                isAuthenticated: !0,
                username: r.data.nickname,
                avatar: r.data.avatar
            }) : {isAuthenticated: !1}
        } catch (t) {
            return pe.debug("checkAuth: not logged in -", t), {isAuthenticated: !1, error: t.message}
        }
    }

    async getNotebooks() {
        return (await this.runtime.fetch("https://www.jianshu.com/author/notebooks", {
            method: "GET",
            credentials: "include",
            headers: {Accept: "application/json"}
        })).json()
    }

    async getDefaultNotebookId() {
        if (this.defaultNotebookId) return this.defaultNotebookId;
        const e = await this.getNotebooks();
        if (e.length === 0) throw new Error("没有可用的文集");
        return this.defaultNotebookId = e[0].id, this.defaultNotebookId
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            pe.info("Starting publish..."), await this.checkAuth();
            const r = await this.getDefaultNotebookId(),
                n = await (await this.runtime.fetch("https://www.jianshu.com/author/notes", {
                    method: "POST",
                    credentials: "include",
                    headers: {"Content-Type": "application/json", Accept: "application/json"},
                    body: JSON.stringify({at_bottom: !1, notebook_id: r, title: e.title})
                })).json();
            if (!n.id) throw new Error("创建草稿失败");
            const i = n.id;
            pe.debug("Draft created:", i);
            let a;
            if (this.preferredNoteType === "markdown" ? a = e.markdown || "" : a = e.html || "", a = await this.processImages(a, d => this.uploadImageByUrl(d), {
                skipPatterns: ["jianshu.com", "jianshuapi.com", "upload-images.jianshu.io"],
                onProgress: t == null ? void 0 : t.onImageProgress
            }), !(await (await this.runtime.fetch(`https://www.jianshu.com/author/notes/${i}`, {
                method: "PUT",
                credentials: "include",
                headers: {"Content-Type": "application/json; charset=UTF-8", Accept: "application/json"},
                body: JSON.stringify({id: String(i), autosave_control: 1, title: e.title, content: a})
            })).json()).id) throw new Error("更新草稿失败");
            pe.debug("Draft updated");
            const h = `https://www.jianshu.com/writer#/notebooks/${r}/notes/${i}`;
            return this.createResult(!0, {
                postId: String(i),
                postUrl: h,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async getUploadToken(e) {
        return (await this.runtime.fetch(`https://www.jianshu.com/upload_images/token.json?filename=${encodeURIComponent(e)}`, {
            method: "GET",
            credentials: "include",
            headers: {Accept: "application/json"}
        })).json()
    }

    async uploadImageByUrl(e) {
        var t;
        try {
            const r = await fetch(e);
            if (!r.ok) throw new Error("图片下载失败");
            const s = await r.blob(),
                n = ((t = s.type.split("/")[1]) == null ? void 0 : t.replace("jpeg", "jpg")) || "jpg";
            let i = `image_${Date.now()}.${n}`;
            try {
                if (!e.startsWith("data:")) {
                    const f = new URL(e).pathname.split("/").pop() || "";
                    /\.(jpe?g|png|gif|webp|bmp|svg)$/i.test(f) && (i = f)
                }
            } catch {
            }
            const {token: a, key: u} = await this.getUploadToken(i), l = new FormData;
            l.append("token", a), l.append("key", u), l.append("file", s, i), l.append("x:protocol", "https");
            const d = await (await fetch("https://upload.qiniup.com/", {method: "POST", body: l})).json();
            if (pe.debug("Image upload response:", d), d.url) return {url: d.url};
            throw new Error("图片上传失败")
        } catch (r) {
            return pe.warn("Failed to upload image:", e, r), {url: e}
        }
    }
}

const ls = Object.freeze(Object.defineProperty({
    __proto__: null,
    JianshuAdapter: us
}, Symbol.toStringTag, {value: "Module"})), ee = N("Netease");

class ds extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "netease",
            name: "网易号",
            icon: "https://static.ws.126.net/163/f2e/news/yxybd_pc/resource/static/share-icon.png",
            homepage: "https://mp.163.com/#/article-publish",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html", convertTablesToText: !0});
        g(this, "accountInfo", null);
        g(this, "HEADER_RULES", [{
            urlFilter: "*://mp.163.com/*",
            headers: {Origin: "https://mp.163.com", Referer: "https://mp.163.com/subscribe_v4/index.html"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e;
        try {
            const t = await this.get(`https://mp.163.com/wemedia/navinfo.do?_=${Date.now()}`);
            return ee.debug("checkAuth response:", t), t.code !== 1 || !((e = t.data) != null && e.tid) ? {isAuthenticated: !1} : (this.accountInfo = t.data, {
                isAuthenticated: !0,
                userId: t.data.tid,
                username: t.data.tname,
                avatar: t.data.icon
            })
        } catch (t) {
            return ee.debug("checkAuth: not logged in -", t), {isAuthenticated: !1, error: t.message}
        }
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            if (ee.info("Starting publish..."), !this.accountInfo && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录网易号");
            const r = await this.fetchUrsToken();
            let s = e.html || "";
            s = await this.processImages(s, p => this.uploadImageByUrl(p), {
                skipPatterns: ["126.net", "163.com", "netease.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            });
            const n = this.accountInfo.tid, i = this.accountInfo.realUserId || "", a = Date.now(),
                u = new URLSearchParams;
            u.append("wemediaId", n), u.append("articleId", "-1"), u.append("title", e.title), u.append("content", s), u.append("cover", "threeImg"), u.append("operation", "saveDraft"), u.append("scheduled", "0"), u.append("ursToken", r), u.append("onlineState", "1"), u.append("picUrl", ""), u.append("original", "0"), u.append("subjectId", "");
            const l = `https://mp.163.com/wemedia/article/status/api/publishV2.do?_=${a}&wemediaId=${n}&realUserId=${encodeURIComponent(i)}`,
                d = await (await this.runtime.fetch(l, {
                    method: "POST",
                    credentials: "include",
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                        "X-Requested-With": "XMLHttpRequest"
                    },
                    body: u.toString()
                })).json();
            if (ee.debug("Publish response:", d), d.code !== 1) throw new Error(d.msg || "保存草稿失败");
            let m = "";
            d.data && (m = new URLSearchParams(d.data).get("docId") || d.data);
            const f = `https://mp.163.com/subscribe_v4/index.html#/article-publish/${m}?option=editDraft`;
            return this.createResult(!0, {postId: m, postUrl: f, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async ensureNeteaseTab() {
        if (!this.runtime.tabs) throw new Error("网易号发布需要浏览器 tabs API 支持");
        const e = await this.runtime.tabs.query("https://mp.163.com/*");
        if (e.length > 0 && e[0].id) return e[0].id;
        ee.info("No existing tab found, creating new one...");
        const t = await this.runtime.tabs.create("https://mp.163.com/subscribe_v4/index.html#/article-publish", !1);
        return await this.runtime.tabs.waitForLoad(t.id, 3e4), ee.info("New tab created and loaded:", t.id), t.id
    }

    async fetchUrsToken() {
        if (!this.runtime.tabs) return ee.warn("No tabs API, cannot get ursToken"), "";
        const e = await this.ensureNeteaseTab();
        ee.debug("Using tab:", e, "to get ursToken");
        const t = await this.runtime.tabs.executeScript(e, async () => {
            try {
                const r = window.neg;
                if (!(r != null && r.getToken)) return {success: !1, error: "neg.getToken not available"};
                const s = await r.getToken();
                return s.code === 200 && s.token ? {success: !0, token: s.token} : {
                    success: !1,
                    error: `getToken returned code ${s.code}`
                }
            } catch (r) {
                return {success: !1, error: r.message}
            }
        }, []);
        return t != null && t.success && t.token ? (ee.debug("Got ursToken via neg.getToken()"), t.token) : (ee.warn("Failed to get ursToken:", t == null ? void 0 : t.error), "")
    }

    async uploadImageByUrl(e) {
        if (!this.accountInfo) throw new Error("未登录");
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = new FormData;
        s.append("file", r, "image.jpg");
        const i = await (await this.runtime.fetch(`https://mp.163.com/wemedia/article/api/uploadCoverImage.do?wemediaId=${this.accountInfo.tid}`, {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (ee.debug("Image upload response:", i), i.code !== 1 || !i.data) throw new Error("图片上传失败: " + (i.msg || "未知错误"));
        const a = i.data.url || i.data.picUrl;
        if (!a) throw new Error("图片上传返回数据不完整");
        return {url: a}
    }
}

const hs = Object.freeze(Object.defineProperty({
    __proto__: null,
    NeteaseAdapter: ds
}, Symbol.toStringTag, {value: "Module"})), qe = N("Smzdm");

function ps(c) {
    return c.includes("probe.js") || c.includes("var buid")
}

function xt(c) {
    const o = Math.floor(Math.random() * 500);
    return new Promise(e => setTimeout(e, c + o))
}

const ms = {
    Accept: "application/json, text/plain, */*",
    "sec-ch-ua": '"Not:A-Brand";v="99", "Google Chrome";v="145", "Chromium";v="145"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"macOS"',
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin"
};

class gs extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "smzdm",
            name: "什么值得买",
            icon: "https://www.smzdm.com/favicon.ico",
            homepage: "https://post.smzdm.com/tougao/",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html", removeLinks: !0});
        g(this, "HEADER_RULES", [{
            urlFilter: "*://post.smzdm.com/*",
            headers: {Origin: "https://post.smzdm.com", Referer: "https://post.smzdm.com/"},
            resourceTypes: ["xmlhttprequest"]
        }]);
        g(this, "_currentArticleId", null)
    }

    async fetchWithRetry(e, t, r = 5) {
        const s = {...ms, ...t.headers || {}}, n = {...t, headers: s};
        for (let i = 1; i <= r; i++) {
            const a = await this.runtime.fetch(e, n), l = await a.clone().text();
            if (!ps(l)) return new Response(l, {status: a.status, statusText: a.statusText, headers: a.headers});
            qe.warn(`WAF challenge on attempt ${i}/${r}: ${e}`), i < r && await xt(1500 * i)
        }
        throw new Error("请求被 WAF 拦截，请稍后重试")
    }

    async checkAuth() {
        try {
            const t = await (await this.fetchWithRetry("https://post.smzdm.com/tougao/", {credentials: "include"})).text();
            if (!t.includes("release-new")) return {isAuthenticated: !1, error: "未登录"};
            const s = t.match(/class="user-name[^"]*"[^>]*>([^<]+)</) || t.match(/nickname['"]\s*:\s*['"]([^'"]+)/),
                n = s ? s[1].trim() : void 0,
                i = t.match(/class="user-avatar[^"]*"[^>]*src="([^"]+)"/) || t.match(/avatar['"]\s*:\s*['"]([^'"]+)/),
                a = i ? i[1] : void 0;
            return {isAuthenticated: !0, username: n, avatar: a}
        } catch (e) {
            return {isAuthenticated: !1, error: e.message}
        }
    }

    async createNewArticle() {
        const t = await (await this.fetchWithRetry("https://post.smzdm.com/tougao/", {credentials: "include"})).text(),
            r = t.match(/href="\/edit\/([^"]+)"\s+class="release-new"/) || t.match(/class="release-new"[^>]*href="\/edit\/([^"]+)"/);
        if (!r) throw new Error("无法创建新文章，请确认已登录什么值得买");
        const s = r[1];
        return qe.debug("Created new article:", s), s
    }

    async uploadImageByUrl(e) {
        var a;
        const r = await (await this.runtime.fetch(e)).blob();
        if (!this._currentArticleId) throw new Error("上传图片需要先创建文章");
        const s = new FormData;
        s.append("imgFile", r, "WU_FILE_0"), s.append("type", r.type || "image/png"), s.append("article_id", this._currentArticleId), s.append("insert", "1"), s.append("storage", "1"), s.append("size", String(r.size));
        const i = await (await this.fetchWithRetry("https://post.smzdm.com/api/images/upload/local", {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (i.error_code !== 0 || !((a = i.data) != null && a.url)) throw new Error(`图片上传失败: ${i.error_msg || JSON.stringify(i)}`);
        return qe.debug(`Image uploaded: ${i.data.url}`), {url: i.data.url}
    }

    async publish(e) {
        const t = Date.now();
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            try {
                const r = await this.createNewArticle();
                this._currentArticleId = r, await xt(800);
                let s = e.html || "";
                s = await this.processImages(s, u => this.uploadImageByUrl(u), {skipPatterns: ["zdmimg.com", "smzdm.com"]});
                const n = new URLSearchParams;
                n.append("article_id", r), n.append("submit_type", "auto_save"), n.append("title", e.title), n.append("editorValue", s), n.append("series_title", ""), n.append("focus_image", ""), n.append("series_order_id", "0"), n.append("series_id", "0"), n.append("anonymous", "0"), n.append("first_publish", "0"), n.append("remark", ""), n.append("create_state_type", "3"), n.append("ai_state_type", "3"), n.append("square_pic_url", ""), n.append("cover_image_rectangle", ""), n.append("custom_topics", ""), n.append("group_id", "");
                const a = await (await this.fetchWithRetry("https://post.smzdm.com/api/editor/article/submit", {
                    method: "POST",
                    credentials: "include",
                    headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"},
                    body: n.toString()
                })).json();
                if (a.error_code !== 0) throw new Error(`保存草稿失败: ${a.error_msg || JSON.stringify(a)}`);
                return qe.debug("Draft saved:", a.data), {
                    platform: this.meta.id,
                    success: !0,
                    postId: r,
                    postUrl: `https://post.smzdm.com/edit/${r}`,
                    draftOnly: !0,
                    timestamp: t
                }
            } catch (r) {
                return {platform: this.meta.id, success: !1, error: r.message, timestamp: t}
            } finally {
                this._currentArticleId = null
            }
        })
    }
}

const fs = Object.freeze(Object.defineProperty({
    __proto__: null,
    SmzdmAdapter: gs
}, Symbol.toStringTag, {value: "Module"}));

class ws extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "sohufocus",
            name: "搜狐焦点",
            icon: "https://mp.focus.cn/favicon.ico",
            homepage: "https://mp.focus.cn/fe/index.html#/info/draft",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html"})
    }

    async checkAuth() {
        var e;
        try {
            const r = await (await this.runtime.fetch("https://mp-fe-pc.focus.cn/user/status", {credentials: "include"})).json();
            return (e = r.data) != null && e.uid ? {
                isAuthenticated: !0,
                userId: r.data.uid,
                username: r.data.accountName
            } : {isAuthenticated: !1, error: "未登录"}
        } catch (t) {
            return {isAuthenticated: !1, error: t.message}
        }
    }

    async uploadImageByUrl(e) {
        const r = await (await this.runtime.fetch(e)).blob(), s = new FormData;
        s.append("image", r, `${Date.now()}.jpg`);
        const i = await (await this.runtime.fetch("https://mp-fe-pc.focus.cn/common/image/upload?type=2", {
            method: "POST",
            credentials: "include",
            body: s
        })).json();
        if (i.code !== 200) throw new Error("图片上传失败");
        return {url: `https://t-img.51f.com/sh740wsh${i.data}`}
    }

    async publish(e) {
        var r;
        const t = Date.now();
        try {
            let s = e.html || e.markdown || "";
            s = await this.processImages(s, a => this.uploadImageByUrl(a)), s = s.replace(/>\s+</g, "><");
            const i = await (await this.runtime.fetch("https://mp-fe-pc.focus.cn/news/info/publishNewsInfo", {
                method: "POST",
                credentials: "include",
                headers: {"Content-Type": "application/json"},
                body: JSON.stringify({
                    projectIds: [],
                    newsBasic: {
                        id: "",
                        cityId: 0,
                        title: e.title,
                        category: 1,
                        headImg: "",
                        newsAbstract: "",
                        isGuide: 0,
                        status: 4
                    },
                    newsContent: {content: s},
                    videoIds: []
                })
            })).json();
            if (!((r = i.data) != null && r.id)) throw new Error("发布失败");
            return {
                platform: this.meta.id,
                success: !0,
                postId: i.data.id,
                postUrl: `https://mp.focus.cn/fe/index.html#/info/subinfo/${i.data.id}`,
                draftOnly: !0,
                timestamp: t
            }
        } catch (s) {
            return {platform: this.meta.id, success: !1, error: s.message, timestamp: t}
        }
    }
}

const ys = Object.freeze(Object.defineProperty({
    __proto__: null,
    SohuFocusAdapter: ws
}, Symbol.toStringTag, {value: "Module"})), oe = N("Toutiao");

class bs extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "toutiao",
            name: "头条",
            icon: "https://sf1-ttcdn-tos.pstatp.com/obj/ttfe/pgcfe/sz/mp_logo.png",
            homepage: "https://mp.toutiao.com/profile_v4/graphic/publish",
            capabilities: ["article", "draft", "image_upload", "cover"]
        });
        g(this, "preprocessConfig", {
            outputFormat: "html",
            removeLinks: !0,
            removeEmptyImages: !0,
            removeDataAttributes: !0,
            flattenNestedBold: !0,
            unwrapSingleChildSpans: !0
        });
        g(this, "HEADER_RULES", [{
            urlFilter: "*://mp.toutiao.com/*",
            headers: {Origin: "https://mp.toutiao.com", Referer: "https://mp.toutiao.com/profile_v4/graphic/publish"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e, t;
        try {
            const r = await this.get("https://mp.toutiao.com/mp/agw/media/get_media_info");
            return oe.debug("checkAuth response:", r), (t = (e = r.data) == null ? void 0 : e.user) != null && t.id ? {
                isAuthenticated: !0,
                userId: String(r.data.user.id),
                username: r.data.user.screen_name,
                avatar: r.data.user.https_avatar_url
            } : {isAuthenticated: !1}
        } catch (r) {
            return oe.debug("checkAuth: not logged in -", r), {isAuthenticated: !1, error: r.message}
        }
    }

    async getCsrfToken() {
        return (await this.runtime.fetch("https://mp.toutiao.com/ttwid/check/", {
            method: "HEAD",
            credentials: "include",
            headers: {"x-secsdk-csrf-request": "1", "x-secsdk-csrf-version": "1.2.22"}
        })).headers.get("x-ware-csrf-token") || ""
    }

    async publish(e, t) {
        return this.withHeaderRules(this.HEADER_RULES, async () => {
            var d;
            oe.info("Starting publish...");
            let r = e.html || "";
            r = r.replace(/<figure[^>]*>\s*<\/figure>/gi, ""), r = r.replace(/\n{3,}/g, `

`), r = await this.processImages(r, m => this.uploadImageByUrl(m), {
                skipPatterns: ["pstatp.com", "toutiao.com", "byteimg.com"],
                onProgress: t == null ? void 0 : t.onImageProgress
            }), r = r.replace(/<img\s+([^>]+)>/gi, '<div class="pgc-img"><img $1><p class="pgc-img-caption"></p></div>');
            const s = "[]", n = JSON.stringify({
                content_source: 100000000402,
                content_word_cnt: r.length,
                is_multi_title: 0,
                sub_titles: [],
                gd_ext: {
                    entrance: "",
                    from_page: "publisher_mp",
                    enter_from: "PC",
                    device_platform: "mp",
                    is_message: 0
                }
            }), i = `${Date.now()}_${Math.random().toString().slice(2, 18)}`, a = new URLSearchParams;
            a.append("pgc_id", "0"), a.append("source", "29"), a.append("extra", n), a.append("content", r), a.append("title", e.title), a.append("search_creation_info", JSON.stringify({
                searchTopOne: 0,
                abstract: "",
                clue_id: ""
            })), a.append("title_id", i), a.append("mp_editor_stat", "{}"), a.append("is_refute_rumor", "0"), a.append("save", "0"), a.append("timer_status", "0"), a.append("timer_time", ""), a.append("educluecard", ""), a.append("draft_form_data", JSON.stringify({coverType: 3})), a.append("pgc_feed_covers", s), a.append("article_ad_type", "3"), a.append("is_fans_article", "0"), a.append("govern_forward", "0"), a.append("praise", "0"), a.append("disable_praise", "0"), a.append("tree_plan_article", "0"), a.append("activity_tag", "0"), a.append("trends_writing_tag", "0"), a.append("claim_exclusive", "0");
            const u = await this.publishViaContentScript("https://mp.toutiao.com/mp/agw/article/publish?source=mp&type=article&aid=1231", a.toString());
            if (oe.debug("publish response:", u), u.err_no !== 0 || !((d = u.data) != null && d.pgc_id)) throw new Error(u.message || "发布失败");
            const l = u.data.pgc_id, h = `https://mp.toutiao.com/profile_v4/graphic/publish?pgc_id=${l}`;
            return this.createResult(!0, {postId: l, postUrl: h, draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0})
        }).catch(r => this.createResult(!1, {error: r.message}))
    }

    async ensureToutiaoTab() {
        if (!this.runtime.tabs) throw new Error("头条发布需要浏览器 tabs API 支持");
        const e = await this.runtime.tabs.query("https://mp.toutiao.com/*");
        if (e.length > 0 && e[0].id) return e[0].id;
        oe.info("No existing tab found, creating new one...");
        const t = await this.runtime.tabs.create("https://mp.toutiao.com/profile_v4/graphic/publish", !1);
        return await this.runtime.tabs.waitForLoad(t.id, 3e4), oe.info("New tab created and loaded:", t.id), t.id
    }

    async publishViaContentScript(e, t) {
        if (!this.runtime.tabs) throw new Error("头条发布需要浏览器 tabs API 支持");
        const r = await this.ensureToutiaoTab();
        oe.debug("Using tab:", r, "to execute fetch in MAIN world");
        const s = await this.runtime.tabs.executeScript(r, async (n, i) => {
            try {
                return {
                    success: !0,
                    data: await (await fetch(n, {
                        method: "POST",
                        headers: {"Content-Type": "application/x-www-form-urlencoded"},
                        body: i,
                        credentials: "include"
                    })).json()
                }
            } catch (a) {
                return {success: !1, error: a.message}
            }
        }, [e, t]);
        if (!s || !s.success) throw new Error((s == null ? void 0 : s.error) || "发布请求失败");
        return s.data
    }

    async uploadImageByUrl(e) {
        const t = await fetch(e);
        if (!t.ok) throw new Error("图片下载失败: " + e);
        const r = await t.blob(), s = await this.getCsrfToken(), n = new FormData;
        n.append("image", r, "image.jpg");
        const u = await (await this.runtime.fetch("https://mp.toutiao.com/spice/image?upload_source=20020002&aid=1231&device_platform=web", {
            method: "POST",
            credentials: "include",
            headers: {"x-secsdk-csrf-token": s},
            body: n
        })).text();
        let l;
        try {
            l = JSON.parse(u)
        } catch {
            throw new Error("图片上传响应解析失败")
        }
        if (oe.debug("Image upload response:", l), l.code !== 0 || !l.data) throw new Error(l.message || "图片上传失败");
        if (!l.data.image_url || !l.data.image_uri) throw oe.error("Upload response missing URL:", l), new Error("图片上传返回数据不完整");
        return {
            url: l.data.image_url,
            attrs: {
                class: "",
                "ic-uri": "",
                image_type: "image/png",
                mime_type: "",
                web_uri: l.data.image_uri,
                img_width: String(l.data.image_width || 0),
                img_height: String(l.data.image_height || 0)
            }
        }
    }
}

const _s = Object.freeze(Object.defineProperty({
        __proto__: null,
        ToutiaoAdapter: bs
    }, Symbol.toStringTag, {value: "Module"})), R = N("X"), Be = {
        createDraft: "ArticleEntityDraftCreate",
        updateTitle: "ArticleEntityUpdateTitle",
        updateContent: "ArticleEntityUpdateContent"
    }, Rt = {
        createDraft: "t5-e2kJcCqqJ_MsZ0c07Rg",
        updateTitle: "5wp_YbfxSfYJTiLWb4tYnA",
        updateContent: "IzVdegTuct9uoXRK5L93Qg"
    }, Is = ["https://x.com/?lang=en", "https://x.com/explore", "https://x.com/compose/articles"],
    Ss = /https:\/\/abs\.twimg\.com\/responsive-web\/client-web(?:-legacy)?\/[A-Za-z0-9.-]+\.js/g, Ts = [{
        regex: /e\.exports=\{queryId\s*:\s*["']([^"']+)["']\s*,\s*operationName\s*:\s*["']([^"']+)["']/g,
        queryIdGroup: 1,
        operationGroup: 2
    }, {
        regex: /e\.exports=\{operationName\s*:\s*["']([^"']+)["']\s*,\s*queryId\s*:\s*["']([^"']+)["']/g,
        operationGroup: 1,
        queryIdGroup: 2
    }, {
        regex: /operationName\s*[:=]\s*["']([^"']+)["'][\s\S]{0,500}?queryId\s*[:=]\s*["']([^"']+)["']/g,
        operationGroup: 1,
        queryIdGroup: 2
    }, {
        regex: /queryId\s*[:=]\s*["']([^"']+)["'][\s\S]{0,500}?operationName\s*[:=]\s*["']([^"']+)["']/g,
        queryIdGroup: 1,
        operationGroup: 2
    }], xs = 24 * 60 * 60 * 1e3, kt = "x_query_id_cache", Rs = {
        profile_label_improvements_pcf_label_in_post_enabled: !0,
        responsive_web_profile_redirect_enabled: !1,
        rweb_tipjar_consumption_enabled: !0,
        verified_phone_label_enabled: !1,
        responsive_web_graphql_skip_user_profile_image_extensions_enabled: !1,
        responsive_web_graphql_timeline_navigation_enabled: !0
    }, ks = "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs=1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA";

class As extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "x",
            name: "X (Twitter)",
            icon: "https://abs.twimg.com/favicons/twitter.3.ico",
            homepage: "https://x.com/compose/articles",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "userInfo", null);
        g(this, "csrfToken", null);
        g(this, "xpForwardedFor", null);
        g(this, "queryIdRefreshInProgress", null)
    }

    async getQueryIdCache() {
        try {
            return await this.runtime.storage.get(kt)
        } catch (e) {
            return R.debug("Failed to get query ID cache from storage:", e), null
        }
    }

    async setQueryIdCache(e) {
        try {
            await this.runtime.storage.set(kt, e)
        } catch (t) {
            R.debug("Failed to save query ID cache to storage:", t)
        }
    }

    async getQueryId(e) {
        const t = await this.getQueryIdCache();
        if (t && Date.now() - t.fetchedAt < t.ttlMs) {
            const s = Be[e], n = t.ids[s];
            if (n) return R.debug(`Using cached query ID for ${e}: ${n}`), n
        }
        try {
            await this.refreshQueryIds();
            const r = await this.getQueryIdCache(), s = Be[e], n = r == null ? void 0 : r.ids[s];
            if (n) return R.debug(`Using refreshed query ID for ${e}: ${n}`), n
        } catch (r) {
            R.warn("Failed to refresh query IDs:", r)
        }
        return R.debug(`Using fallback query ID for ${e}: ${Rt[e]}`), Rt[e]
    }

    async refreshQueryIds(e = !1) {
        if (this.queryIdRefreshInProgress) return this.queryIdRefreshInProgress;
        if (!e) {
            const t = await this.getQueryIdCache();
            if (t && Date.now() - t.fetchedAt < t.ttlMs) {
                R.debug("Query ID cache still fresh, skipping refresh");
                return
            }
        }
        this.queryIdRefreshInProgress = this.doRefreshQueryIds();
        try {
            await this.queryIdRefreshInProgress
        } finally {
            this.queryIdRefreshInProgress = null
        }
    }

    async doRefreshQueryIds() {
        R.info("Refreshing X Query IDs from JS bundles...");
        try {
            const e = await this.discoverBundles();
            if (R.debug(`Discovered ${e.length} bundles`), e.length === 0) throw new Error("No JS bundles found");
            const t = new Set(Object.values(Be)), r = await this.extractQueryIdsFromBundles(e, t);
            if (R.debug("Discovered query IDs:", Object.fromEntries(r)), r.size === 0) throw new Error("No query IDs extracted from bundles");
            const s = {ids: Object.fromEntries(r), fetchedAt: Date.now(), ttlMs: xs};
            await this.setQueryIdCache(s), R.info(`Refreshed ${r.size} query IDs`)
        } catch (e) {
            throw R.error("Failed to refresh query IDs:", e), e
        }
    }

    async discoverBundles() {
        const e = new Set;
        for (const t of Is) try {
            R.debug(`Fetching discovery page: ${t}`);
            const n = (await (await this.runtime.fetch(t, {credentials: "include"})).text()).matchAll(Ss);
            for (const i of n) e.add(i[0])
        } catch (r) {
            R.debug(`Failed to fetch ${t}:`, r)
        }
        return Array.from(e)
    }

    async extractQueryIdsFromBundles(e, t) {
        const r = new Map, s = 4;
        for (let n = 0; n < e.length && !(r.size >= t.size); n += s) {
            const i = e.slice(n, n + s);
            await Promise.all(i.map(async a => {
                if (!(r.size >= t.size)) try {
                    const l = await (await this.runtime.fetch(a)).text();
                    this.extractOperationsFromJs(l, t, r)
                } catch (u) {
                    R.debug(`Failed to fetch bundle ${a}:`, u)
                }
            }))
        }
        return r
    }

    extractOperationsFromJs(e, t, r) {
        for (const s of Ts) {
            s.regex.lastIndex = 0;
            let n;
            for (; (n = s.regex.exec(e)) !== null;) {
                const i = n[s.operationGroup], a = n[s.queryIdGroup];
                if (!(!i || !a) && t.has(i) && !r.has(i) && /^[a-zA-Z0-9_-]+$/.test(a) && (r.set(i, a), R.debug(`Found ${i}: ${a}`), r.size >= t.size)) return
            }
        }
    }

    async graphqlRequest(e, t, r) {
        const s = async () => {
            const i = await this.getQueryId(e), a = Be[e], u = await this.getCommonHeaders(),
                l = await this.runtime.fetch(`https://x.com/i/api/graphql/${i}/${a}`, {
                    method: "POST",
                    credentials: "include",
                    headers: {...u, "content-type": "application/json"},
                    body: JSON.stringify({variables: t, features: Rs, queryId: i})
                });
            return {data: await l.json(), status: l.status}
        }, n = await s();
        return n.status === 404 && (r == null ? void 0 : r.retry404) !== !1 ? (R.warn(`Got 404 for ${e}, refreshing query IDs and retrying...`), await this.refreshQueryIds(!0), (await s()).data) : n.data
    }

    async getCsrfToken() {
        var e, t;
        if (this.csrfToken) return this.csrfToken;
        try {
            const r = await ((t = (e = this.runtime).getCookie) == null ? void 0 : t.call(e, "https://x.com", "ct0"));
            if (r) return this.csrfToken = r, R.debug("Got CSRF token from cookie API"), this.csrfToken
        } catch (r) {
            R.debug("Cookie API failed:", r)
        }
        if (this.runtime.tabs) try {
            const r = await this.ensureXTab(), s = await this.runtime.tabs.executeScript(r, async () => {
                try {
                    const n = document.cookie.split(";");
                    for (const i of n) {
                        const [a, u] = i.trim().split("=");
                        if (a === "ct0" && u) return {success: !0, token: u}
                    }
                    return {success: !1, error: "ct0 cookie not found"}
                } catch (n) {
                    return {success: !1, error: n.message}
                }
            }, []);
            if (s != null && s.success && s.token) return this.csrfToken = s.token, R.debug("Got CSRF token from executeScript"), this.csrfToken;
            R.debug("executeScript failed to get ct0:", s == null ? void 0 : s.error)
        } catch (r) {
            R.debug("executeScript error:", r)
        }
        throw new Error("请先登录 X (Twitter)")
    }

    async ensureXTab() {
        if (!this.runtime.tabs) throw new Error("X 发布需要浏览器 tabs API 支持");
        const e = await this.runtime.tabs.query("https://x.com/*");
        if (e.length > 0 && e[0].id) return e[0].id;
        R.info("No existing X tab found, creating new one...");
        const t = await this.runtime.tabs.create("https://x.com/compose/articles", !1);
        return await this.runtime.tabs.waitForLoad(t.id, 3e4), R.info("New X tab created and loaded:", t.id), t.id
    }

    async getXPForwardedFor() {
        if (this.xpForwardedFor && Date.now() < this.xpForwardedFor.expiryTimeMillis) return R.debug("Using cached XP forwarded-for"), this.xpForwardedFor.str;
        if (!this.runtime.tabs) return R.warn("tabs API not available, skipping XP forwarded-for"), "";
        try {
            const e = await this.ensureXTab();
            R.debug("Getting XP forwarded-for from tab:", e);
            const t = await this.runtime.tabs.executeScript(e, async () => {
                try {
                    const r = window.XPForwardedForSDK;
                    return !r || typeof r.getForwardedForStr != "function" ? {
                        success: !1,
                        error: "XPForwardedForSDK not found"
                    } : {success: !0, data: await r.getForwardedForStr()}
                } catch (r) {
                    return {success: !1, error: r.message}
                }
            }, []);
            return !t || !t.success || !t.data ? (R.warn("Failed to get XP forwarded-for:", t == null ? void 0 : t.error), "") : (this.xpForwardedFor = {
                str: t.data.str,
                expiryTimeMillis: parseInt(t.data.expiryTimeMillis, 10)
            }, R.debug("Got XP forwarded-for, expires at:", new Date(this.xpForwardedFor.expiryTimeMillis)), this.xpForwardedFor.str)
        } catch (e) {
            return R.warn("Error getting XP forwarded-for:", e), ""
        }
    }

    generateTransactionId() {
        const e = Date.now().toString(36), t = Math.random().toString(36).substring(2, 15);
        return `${e}${t}`
    }

    async getCommonHeaders() {
        const [e, t] = await Promise.all([this.getCsrfToken(), this.getXPForwardedFor()]), s = {
            authorization: `Bearer ${ks.replace(/=/g, "%3D")}`,
            "x-csrf-token": e,
            "x-twitter-active-user": "yes",
            "x-twitter-auth-type": "OAuth2Session",
            "x-twitter-client-language": "en",
            "x-client-transaction-id": this.generateTransactionId(),
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": '"macOS"'
        };
        return t && (s["x-xp-forwarded-for"] = t), s
    }

    async setupHeaderRules() {
        this.headerRuleIds.length > 0 || await this.addHeaderRules([{
            urlFilter: "*://x.com/i/api/*",
            headers: {Origin: "https://x.com", Referer: "https://x.com/compose/articles"},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://upload.x.com/*",
            headers: {Origin: "https://x.com", Referer: "https://x.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async checkAuth() {
        var e, t;
        try {
            await this.setupHeaderRules();
            const s = await (await this.runtime.fetch("https://x.com/home", {credentials: "include"})).text();
            R.debug("Fetched x.com/home, length:", s.length);
            const n = s.indexOf("window.__INITIAL_STATE__=");
            if (n === -1) return R.debug("Failed to find __INITIAL_STATE__"), await this.clearHeaderRules(), {isAuthenticated: !1};
            const i = s.indexOf("{", n);
            if (i === -1) return R.debug("Failed to find JSON start"), await this.clearHeaderRules(), {isAuthenticated: !1};
            let a = 0, u = i;
            for (let w = i; w < s.length; w++) if (s[w] === "{" ? a++ : s[w] === "}" && a--, a === 0) {
                u = w + 1;
                break
            }
            const l = s.slice(i, u);
            R.debug("Extracted JSON length:", l.length);
            let h;
            try {
                h = JSON.parse(l)
            } catch (w) {
                return R.debug("Failed to parse __INITIAL_STATE__:", w), await this.clearHeaderRules(), {isAuthenticated: !1}
            }
            const d = (t = (e = h.entities) == null ? void 0 : e.users) == null ? void 0 : t.entities;
            if (!d) return R.debug("No user entities found in state"), await this.clearHeaderRules(), {isAuthenticated: !1};
            const m = Object.keys(d);
            if (m.length === 0) return R.debug("No user IDs found"), await this.clearHeaderRules(), {isAuthenticated: !1};
            const f = m[0], p = d[f];
            return p ? (this.userInfo = {
                userId: p.id_str,
                username: p.screen_name,
                name: p.name,
                avatar: p.profile_image_url_https
            }, R.info("X auth success:", this.userInfo.username), await this.clearHeaderRules(), {
                isAuthenticated: !0,
                userId: this.userInfo.userId,
                username: this.userInfo.username,
                avatar: this.userInfo.avatar
            }) : (await this.clearHeaderRules(), {isAuthenticated: !1})
        } catch (r) {
            return await this.clearHeaderRules(), R.error("checkAuth error:", r), {
                isAuthenticated: !1,
                error: r.message
            }
        }
    }

    async publish(e, t) {
        await this.setupHeaderRules();
        try {
            R.info("Starting publish to X...");
            const r = await this.createDraft();
            R.debug("Created draft:", r), await this.updateTitle(r, e.title), R.debug("Updated title");
            const s = await this.markdownToDraftContent(e.markdown, t == null ? void 0 : t.onImageProgress);
            R.debug("Converted content to Draft.js format"), await this.updateContent(r, s), R.debug("Updated content");
            const n = `https://x.com/compose/articles/edit/${r}`;
            return await this.clearHeaderRules(), this.createResult(!0, {
                postId: r,
                postUrl: n,
                draftOnly: (t == null ? void 0 : t.draftOnly) ?? !0
            })
        } catch (r) {
            return await this.clearHeaderRules(), R.error("Publish failed:", r), this.createResult(!1, {error: r.message})
        }
    }

    async createDraft() {
        var r, s, n, i, a;
        const e = await this.graphqlRequest("createDraft", {content_state: {blocks: [], entity_map: []}, title: ""});
        if ((r = e.errors) != null && r.length) throw new Error(e.errors[0].message);
        const t = (a = (i = (n = (s = e.data) == null ? void 0 : s.articleentity_create_draft) == null ? void 0 : n.article_entity_results) == null ? void 0 : i.result) == null ? void 0 : a.rest_id;
        if (!t) throw new Error("创建草稿失败");
        return t
    }

    async updateTitle(e, t) {
        var s;
        const r = await this.graphqlRequest("updateTitle", {articleEntityId: e, title: t});
        if ((s = r.errors) != null && s.length) throw new Error(r.errors[0].message)
    }

    async updateContent(e, t) {
        var s;
        const r = await this.graphqlRequest("updateContent", {content_state: t, article_entity: e});
        if ((s = r.errors) != null && s.length) throw new Error(r.errors[0].message)
    }

    async uploadImageByUrl(e) {
        let t, r;
        if (e.startsWith("data:")) {
            const p = e.match(/^data:([^;]+);base64,(.+)$/);
            if (!p) throw new Error("Invalid data URI");
            r = p[1];
            const w = atob(p[2]), _ = new Uint8Array(w.length);
            for (let y = 0; y < w.length; y++) _[y] = w.charCodeAt(y);
            t = new Blob([_], {type: r})
        } else t = await (await fetch(e)).blob(), r = t.type || "image/jpeg";
        const s = await this.getCommonHeaders(),
            n = `https://upload.x.com/i/media/upload.json?command=INIT&total_bytes=${t.size}&media_type=${encodeURIComponent(r)}&media_category=tweet_image`,
            a = await (await this.runtime.fetch(n, {
                method: "POST",
                credentials: "include",
                headers: {...s, "content-length": "0"}
            })).json();
        if (!a.media_id_string) throw new Error(a.error || "图片上传初始化失败");
        const u = a.media_id_string;
        R.debug("Media INIT complete, mediaId:", u);
        const l = new FormData;
        l.append("media", t, "image.jpg");
        const h = `https://upload.x.com/i/media/upload.json?command=APPEND&media_id=${u}&segment_index=0`;
        await this.runtime.fetch(h, {
            method: "POST",
            credentials: "include",
            headers: s,
            body: l
        }), R.debug("Media APPEND complete");
        const d = `https://upload.x.com/i/media/upload.json?command=FINALIZE&media_id=${u}`,
            f = await (await this.runtime.fetch(d, {
                method: "POST",
                credentials: "include",
                headers: {...s, "content-length": "0"}
            })).json();
        if (!f.media_id_string) throw new Error(f.error || "图片上传完成失败");
        return R.debug("Media FINALIZE complete"), {url: u, attrs: {"media-id": u}}
    }

    generateBlockKey() {
        const e = "abcdefghijklmnopqrstuvwxyz0123456789";
        let t = "";
        for (let r = 0; r < 5; r++) t += e.charAt(Math.floor(Math.random() * e.length));
        return t
    }

    generateUUID() {
        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, e => {
            const t = Math.random() * 16 | 0;
            return (e === "x" ? t : t & 3 | 8).toString(16)
        })
    }

    convertInlineStyle(e) {
        return {
            BOLD: "Bold",
            bold: "Bold",
            ITALIC: "Italic",
            italic: "Italic",
            STRIKETHROUGH: "Strikethrough",
            strikethrough: "Strikethrough"
        }[e] || null
    }

    async markdownToDraftContent(e, t) {
        var p, w, _;
        const r = [];
        let s = 0, n = e;
        for (const y of xe(e)) {
            const T = `

[XIMG_PLACEHOLDER_${s}]

`;
            r.push({
                placeholder: `[XIMG_PLACEHOLDER_${s}]`,
                src: y.src,
                alt: y.alt || ""
            }), n = n.replace(y.full, T), s++
        }
        const i = new Map;
        let a = 0;
        for (const {src: y} of r) if (!i.has(y)) {
            a++, t == null || t(a, r.length);
            try {
                R.debug(`Uploading image ${a}/${r.length}: ${y.substring(0, 50)}...`);
                const T = await this.uploadImageByUrl(y);
                i.set(y, T.url), R.debug(`Uploaded image ${a}, mediaId: ${T.url}`), await this.delay(500)
            } catch (T) {
                R.error("Failed to upload image:", T)
            }
        }
        const u = Lt(n), l = [], h = [];
        let d = 1;
        const m = new Map;
        let f = 0;
        for (const [y, T] of Object.entries(u.entityMap)) {
            const O = parseInt(y, 10), A = T.type.toUpperCase();
            if (A === "IMAGE") {
                const S = ((p = T.data) == null ? void 0 : p.src) || "", v = i.get(S);
                if (v) {
                    const C = f++;
                    m.set(O, C), h.push({
                        key: String(C),
                        value: {
                            type: "MEDIA",
                            mutability: "Immutable",
                            data: {
                                entity_key: this.generateUUID(),
                                media_items: [{local_media_id: d++, media_category: "DraftTweetImage", media_id: v}]
                            }
                        }
                    })
                }
            } else if (A === "LINK") {
                const S = f++;
                m.set(O, S), h.push({
                    key: String(S),
                    value: {
                        type: "LINK",
                        mutability: "Mutable",
                        data: {url: ((w = T.data) == null ? void 0 : w.url) || ((_ = T.data) == null ? void 0 : _.href) || ""}
                    }
                })
            }
        }
        for (const y of u.blocks) {
            const T = y.key || this.generateBlockKey(), O = y.text.match(/^\[XIMG_PLACEHOLDER_(\d+)\]$/);
            if (O) {
                const k = parseInt(O[1], 10), P = r[k];
                if (P) {
                    const b = i.get(P.src);
                    if (b) {
                        const I = f++;
                        h.push({
                            key: String(I),
                            value: {
                                type: "MEDIA",
                                mutability: "Immutable",
                                data: {
                                    entity_key: this.generateUUID(),
                                    media_items: [{local_media_id: d++, media_category: "DraftTweetImage", media_id: b}]
                                }
                            }
                        }), l.push({
                            key: T,
                            type: "atomic",
                            text: " ",
                            data: {},
                            entity_ranges: [{key: I, offset: 0, length: 1}],
                            inline_style_ranges: []
                        });
                        continue
                    }
                }
                continue
            }
            let A = "unstyled";
            const S = y.type;
            if (S === "header-one" || S === "header-two") A = S; else if (S === "header-three" || S === "header-four" || S === "header-five" || S === "header-six") A = "header-two"; else if (S === "blockquote") A = "blockquote"; else if (S === "unordered-list-item") A = "unordered-list-item"; else if (S === "ordered-list-item") A = "ordered-list-item"; else if (S === "code-block") {
                const k = f++;
                h.push({
                    key: String(k),
                    value: {type: "MARKDOWN", mutability: "Mutable", data: {markdown: "```\n" + y.text + "\n```"}}
                }), l.push({
                    key: T,
                    type: "atomic",
                    text: " ",
                    data: {},
                    entity_ranges: [{key: k, offset: 0, length: 1}],
                    inline_style_ranges: []
                });
                continue
            } else if (S === "hr" || S === "horizontal-rule" || S === "unstyled" && /^(-{3,}|\*{3,}|_{3,})$/.test(y.text.trim())) {
                const k = f++;
                h.push({key: String(k), value: {type: "DIVIDER", mutability: "Immutable", data: {}}}), l.push({
                    key: T,
                    type: "atomic",
                    text: " ",
                    data: {},
                    entity_ranges: [{key: k, offset: 0, length: 1}],
                    inline_style_ranges: []
                });
                continue
            } else if (S === "unstyled" && /^\$\$[\s\S]+\$\$$/.test(y.text.trim())) {
                const k = y.text.trim().slice(2, -2).trim(), P = f++;
                h.push({key: String(P), value: {type: "LATEX", mutability: "Immutable", data: {}}}), l.push({
                    key: T,
                    type: "atomic",
                    text: k,
                    data: {},
                    entity_ranges: [{key: P, offset: 0, length: k.length}],
                    inline_style_ranges: []
                });
                continue
            } else S === "atomic" ? A = "atomic" : A = "unstyled";
            const v = [];
            if (y.entityRanges) for (const k of y.entityRanges) {
                const P = m.get(k.key);
                P !== void 0 && v.push({key: P, offset: k.offset, length: k.length})
            }
            const C = [];
            if (y.inlineStyleRanges) for (const k of y.inlineStyleRanges) {
                const P = this.convertInlineStyle(k.style);
                P && C.push({style: P, offset: k.offset, length: k.length})
            }
            l.push({key: T, type: A, text: y.text || "", data: y.data || {}, entity_ranges: v, inline_style_ranges: C})
        }
        return l.length === 0 && l.push({
            key: this.generateBlockKey(),
            type: "unstyled",
            text: "",
            data: {},
            entity_ranges: [],
            inline_style_ranges: []
        }), {blocks: l, entity_map: h}
    }
}

const Es = Object.freeze(Object.defineProperty({__proto__: null, XAdapter: As}, Symbol.toStringTag, {value: "Module"})),
    vs = {
        id: "xiaohongshu",
        outputFormat: "prosemirror",
        maxHeadingLevel: 3,
        supportNestedList: !1,
        supportTable: !1,
        supportCodeBlock: !1,
        supportInlineCode: !1,
        supportLink: !1,
        supportImage: !0,
        supportBlockquote: !0,
        supportHorizontalRule: !1,
        supportBold: !1,
        supportItalic: !1,
        supportStrikethrough: !1,
        supportHighlight: !0,
        supportLatex: !1
    }, Cs = {
        id: "juejin",
        outputFormat: "markdown",
        maxHeadingLevel: 6,
        supportNestedList: !0,
        supportTable: !0,
        supportCodeBlock: !0,
        supportInlineCode: !0,
        supportLink: !0,
        supportImage: !0,
        supportBlockquote: !0,
        supportHorizontalRule: !0,
        supportBold: !0,
        supportItalic: !0,
        supportStrikethrough: !0,
        supportHighlight: !1,
        supportLatex: !0
    }, Us = {
        id: "zhihu",
        outputFormat: "html",
        maxHeadingLevel: 4,
        supportNestedList: !1,
        supportTable: !0,
        supportCodeBlock: !0,
        supportInlineCode: !0,
        supportLink: !1,
        supportImage: !0,
        supportBlockquote: !0,
        supportHorizontalRule: !0,
        supportBold: !0,
        supportItalic: !0,
        supportStrikethrough: !0,
        supportHighlight: !1,
        supportLatex: !0
    }, $s = {xiaohongshu: vs, juejin: Cs, zhihu: Us};

function Ps(c) {
    return $s[c]
}

const Os = {
    id: "default",
    outputFormat: "markdown",
    maxHeadingLevel: 6,
    supportNestedList: !0,
    supportTable: !0,
    supportCodeBlock: !0,
    supportInlineCode: !0,
    supportLink: !0,
    supportImage: !0,
    supportBlockquote: !0,
    supportHorizontalRule: !0,
    supportBold: !0,
    supportItalic: !0,
    supportStrikethrough: !0,
    supportHighlight: !0,
    supportLatex: !0
};

function Bt(c) {
    const o = c.split(`
`), e = [];
    let t = 0;
    for (; t < o.length;) {
        const r = o[t];
        if (r.trim() === "") {
            t++;
            continue
        }
        if (r.startsWith("```")) {
            const i = r.slice(3).trim(), a = [];
            for (t++; t < o.length && !o[t].startsWith("```");) a.push(o[t]), t++;
            t++, e.push({
                type: "code", lang: i || void 0, value: a.join(`
`)
            });
            continue
        }
        const s = r.match(/^(#{1,6})\s+(.+)$/);
        if (s) {
            e.push({type: "heading", depth: s[1].length, children: Ce(s[2])}), t++;
            continue
        }
        if (/^[-*_]{3,}\s*$/.test(r)) {
            e.push({type: "thematicBreak"}), t++;
            continue
        }
        if (r.startsWith(">")) {
            const i = [];
            for (; t < o.length && (o[t].startsWith(">") || o[t].trim() !== "" && i.length > 0 && !o[t].match(/^[#\-*\d]/));) i.push(o[t].replace(/^>\s?/, "")), t++;
            e.push({
                type: "blockquote", children: Bt(i.join(`
`)).children
            });
            continue
        }
        if (/^[\-*+]\s+/.test(r)) {
            const i = [];
            for (; t < o.length && /^[\-*+]\s+/.test(o[t]);) {
                const a = o[t].replace(/^[\-*+]\s+/, "");
                i.push({type: "listItem", children: [{type: "paragraph", children: Ce(a)}]}), t++
            }
            e.push({type: "list", ordered: !1, children: i});
            continue
        }
        if (/^\d+\.\s+/.test(r)) {
            const i = [], a = r.match(/^(\d+)\.\s+/), u = a ? parseInt(a[1], 10) : 1;
            for (; t < o.length && /^\d+\.\s+/.test(o[t]);) {
                const l = o[t].replace(/^\d+\.\s+/, "");
                i.push({type: "listItem", children: [{type: "paragraph", children: Ce(l)}]}), t++
            }
            e.push({type: "list", ordered: !0, start: u, children: i});
            continue
        }
        if (r.includes("|") && r.trim().startsWith("|")) {
            const i = [];
            for (; t < o.length && o[t].includes("|");) {
                const a = o[t].trim();
                if (/^\|[\s\-:|]+\|$/.test(a)) {
                    t++;
                    continue
                }
                const u = a.split("|").slice(1, -1).map(l => l.trim());
                i.push({type: "tableRow", children: u.map(l => ({type: "tableCell", children: Ce(l)}))}), t++
            }
            i.length > 0 && e.push({type: "table", children: i});
            continue
        }
        const n = [];
        for (; t < o.length && o[t].trim() !== "" && !o[t].startsWith("#") && !o[t].startsWith(">") && !o[t].startsWith("```") && !/^[-*+]\s+/.test(o[t]) && !/^\d+\.\s+/.test(o[t]) && !/^[-*_]{3,}\s*$/.test(o[t]) && !(o[t].includes("|") && o[t].trim().startsWith("|"));) n.push(o[t]), t++;
        n.length > 0 && e.push({
            type: "paragraph", children: Ce(n.join(`
`))
        })
    }
    return {type: "root", children: e}
}

function Ce(c) {
    const o = [];
    let e = c;
    for (; e.length > 0;) {
        const t = e.match(/^!\[([^\]]*)\]\(([^)]+)\)/);
        if (t) {
            o.push({type: "image", alt: t[1], url: t[2]}), e = e.slice(t[0].length);
            continue
        }
        const r = e.match(/^\[([^\]]+)\]\(([^)]+)\)/);
        if (r) {
            o.push({type: "link", url: r[2], children: [{type: "text", value: r[1]}]}), e = e.slice(r[0].length);
            continue
        }
        const s = e.match(/^(\*\*|__)([^*_]+)\1/);
        if (s) {
            o.push({type: "strong", children: [{type: "text", value: s[2]}]}), e = e.slice(s[0].length);
            continue
        }
        const n = e.match(/^(\*|_)([^*_]+)\1/);
        if (n) {
            o.push({type: "emphasis", children: [{type: "text", value: n[2]}]}), e = e.slice(n[0].length);
            continue
        }
        const i = e.match(/^~~([^~]+)~~/);
        if (i) {
            o.push({type: "delete", children: [{type: "text", value: i[1]}]}), e = e.slice(i[0].length);
            continue
        }
        const a = e.match(/^`([^`]+)`/);
        if (a) {
            o.push({type: "inlineCode", value: a[1]}), e = e.slice(a[0].length);
            continue
        }
        if (e.startsWith(`  
`) || e.startsWith(`
`)) {
            o.push({type: "break"}), e = e.replace(/^(\s*\n|\n)/, "");
            continue
        }
        const u = e.search(/[!\[*_~`\n]/);
        if (u === -1) {
            o.push({type: "text", value: e});
            break
        } else u === 0 ? (o.push({type: "text", value: e[0]}), e = e.slice(1)) : (o.push({
            type: "text",
            value: e.slice(0, u)
        }), e = e.slice(u))
    }
    return o
}

async function Ds(c, o, e) {
    var s;
    const t = {
        capabilities: o,
        uploadImage: e == null ? void 0 : e.uploadImage,
        uploadedImages: new Map,
        imageQueue: [],
        onImageProgress: e == null ? void 0 : e.onImageProgress
    };
    if (Wt(c, t), t.uploadImage && t.imageQueue.length > 0) {
        let n = 0;
        for (const i of t.imageQueue) if (!t.uploadedImages.has(i.src)) try {
            n++, (s = t.onImageProgress) == null || s.call(t, n, t.imageQueue.length);
            const a = await t.uploadImage(i.src);
            t.uploadedImages.set(i.src, {
                url: a.url,
                width: a.width || 800,
                height: a.height || 600,
                fileId: a.fileId
            }), await zs(300)
        } catch (a) {
            console.error("Failed to upload image:", i.src, a)
        }
    }
    let r = lt(c.children, t);
    for (; r.length > 0 && Ms(r[0]);) r.shift();
    return r.length === 0 && r.push({type: "paragraph", content: []}), r = r.map(zt), {type: "doc", content: r}
}

function Ms(c) {
    return c.type === "paragraph" && (!c.content || c.content.length === 0)
}

function zt(c) {
    const o = {type: c.type};
    if (c.attrs !== void 0 && (o.attrs = c.attrs), c.marks !== void 0 && (o.marks = c.marks.map(e => {
        const t = {type: e.type};
        return e.attrs !== void 0 && (t.attrs = e.attrs), t
    })), c.content !== void 0) {
        const e = c.content.filter(t => !(t.type === "text" && (!t.text || t.text === ""))).map(zt);
        e.length > 0 && (o.content = e)
    }
    return c.text !== void 0 && (o.text = c.text), o
}

function Wt(c, o) {
    if ("type" in c && c.type === "image") {
        const e = c;
        o.imageQueue.push({src: e.url, alt: e.alt || ""})
    }
    if ("children" in c && Array.isArray(c.children)) for (const e of c.children) Wt(e, o)
}

function lt(c, o) {
    const e = [];
    for (const t of c) {
        const r = js(t, o);
        e.push(...r)
    }
    return e
}

function js(c, o) {
    const {capabilities: e} = o;
    switch (c.type) {
        case"heading":
            return Ns(c, o);
        case"paragraph":
            return Fs(c, o);
        case"blockquote":
            return e.supportBlockquote ? Ls(c, o) : Hs(c, o);
        case"list":
            return Xt(c, o);
        case"listItem":
            return qs(c, o);
        case"table":
            return e.supportTable ? [] : Bs(c);
        case"thematicBreak":
            return e.supportHorizontalRule ? [{type: "horizontalRule"}] : [];
        case"code":
            return e.supportCodeBlock ? [{
                type: "codeBlock",
                attrs: {language: c.lang || ""},
                content: [{type: "text", text: c.value}]
            }] : [{type: "paragraph", content: [{type: "text", text: c.value}]}];
        case"image":
            return e.supportImage ? Gt(c, o) : [{
                type: "paragraph",
                content: [{type: "text", text: `[图片: ${c.alt || c.url}]`}]
            }];
        default:
            return []
    }
}

function Ns(c, o) {
    const {capabilities: e} = o;
    return [{type: "heading", attrs: {level: Math.min(c.depth, e.maxHeadingLevel)}, content: X(c.children, o)}]
}

function Fs(c, o) {
    const e = [];
    if (c.children.some(s => s.type === "image") && o.capabilities.supportImage) {
        let s = [];
        for (const n of c.children) if (n.type === "image") {
            if (s.length > 0) {
                const a = X(s, o);
                a.length > 0 && e.push({type: "paragraph", content: a}), s = []
            }
            const i = Gt(n, o);
            e.push(...i)
        } else s.push(n);
        if (s.length > 0) {
            const n = X(s, o);
            n.length > 0 && e.push({type: "paragraph", content: n})
        }
        return e.length > 0 ? e : [{type: "paragraph"}]
    }
    const r = X(c.children, o);
    return r.length === 0 ? [{type: "paragraph"}] : [{type: "paragraph", content: r}]
}

function Ls(c, o) {
    return [{type: "blockquote", content: lt(c.children, o)}]
}

function Hs(c, o) {
    const e = [];
    for (const t of c.children) if (t.type === "paragraph") {
        const r = X(t.children, o);
        r.unshift({type: "text", text: "> "}), e.push({type: "paragraph", content: r})
    }
    return e
}

function Xt(c, o) {
    const e = lt(c.children, o);
    return c.ordered ? [{
        type: "orderedList",
        attrs: {start: c.start || 1, type: null},
        content: e
    }] : [{type: "bulletList", content: e}]
}

function qs(c, o) {
    const {capabilities: e} = o, t = [];
    for (const r of c.children) if (r.type === "paragraph") t.push({
        type: "paragraph",
        content: X(r.children, o)
    }); else if (r.type === "list") {
        if (e.supportNestedList) t.push(...Xt(r, o)); else for (const s of r.children) if (s.type === "listItem") for (const n of s.children) n.type === "paragraph" && t.push({
            type: "paragraph",
            content: [{type: "text", text: "  • "}, ...X(n.children, o)]
        })
    }
    return [{type: "listItem", content: t.length > 0 ? t : [{type: "paragraph"}]}]
}

function Bs(c, o) {
    const e = [];
    for (const t of c.children) {
        if (t.type !== "tableRow") continue;
        const s = t.children.filter(n => n.type === "tableCell").map(n => n.children.map(i => i.type === "text" ? i.value : "children" in i ? i.children.map(a => a.value || "").join("") : "").join("")).join(" | ");
        s.trim() && e.push({type: "paragraph", content: [{type: "text", text: s}]})
    }
    return e
}

function Gt(c, o) {
    const e = o.uploadedImages.get(c.url), t = 410;
    if (e) {
        const r = t, s = e.width > 0 ? Math.round(t * e.height / e.width) : 0;
        return [{type: "image", attrs: {imgs: [{src: e.url, desc: "", percent: 30, width: r, height: s}]}}]
    }
    return [{type: "image", attrs: {imgs: [{src: c.url, desc: "", percent: 30, width: t, height: 0}]}}]
}

function X(c, o) {
    const e = [];
    for (const t of c) switch (t.type) {
        case"text":
            t.value && e.push({type: "text", text: t.value});
            break;
        case"strong":
            if (o.capabilities.supportBold) {
                const r = X(t.children, o);
                for (const s of r) s.type === "text" && (s.marks = [...s.marks || [], {type: "bold"}]);
                e.push(...r)
            } else if (o.capabilities.supportHighlight) {
                const r = X(t.children, o);
                for (const s of r) s.type === "text" && (s.marks = [...s.marks || [], {type: "highlight"}]);
                e.push(...r)
            } else e.push(...X(t.children, o));
            break;
        case"emphasis":
            if (o.capabilities.supportItalic) {
                const r = X(t.children, o);
                for (const s of r) s.type === "text" && (s.marks = [...s.marks || [], {type: "italic"}]);
                e.push(...r)
            } else e.push(...X(t.children, o));
            break;
        case"delete":
            if (o.capabilities.supportStrikethrough) {
                const r = X(t.children, o);
                for (const s of r) s.type === "text" && (s.marks = [...s.marks || [], {type: "strike"}]);
                e.push(...r)
            } else e.push(...X(t.children, o));
            break;
        case"inlineCode":
            o.capabilities.supportInlineCode ? e.push({
                type: "text",
                text: t.value,
                marks: [{type: "code"}]
            }) : e.push({type: "text", text: t.value});
            break;
        case"link":
            if (o.capabilities.supportLink) {
                const r = X(t.children, o);
                for (const s of r) s.type === "text" && (s.marks = [...s.marks || [], {
                    type: "link",
                    attrs: {href: t.url}
                }]);
                e.push(...r)
            } else e.push(...X(t.children, o));
            break;
        case"image":
            break;
        case"break":
            break;
        default:
            "children" in t && Array.isArray(t.children) && e.push(...X(t.children, o))
    }
    return e
}

function zs(c) {
    return new Promise(o => setTimeout(o, c))
}

async function Ws(c, o) {
    const e = Ps(o.platform) || Os, t = Bt(c);
    if (e.outputFormat === "prosemirror") return {
        prosemirror: await Ds(t, e, {
            uploadImage: o.uploadImage,
            onImageProgress: o.onImageProgress
        })
    };
    throw new Error(`Output format "${e.outputFormat}" not implemented yet`)
}

async function Xs(c, o, e) {
    return (await Ws(c, {platform: "xiaohongshu", uploadImage: o, onImageProgress: e})).prosemirror
}

const te = N("Xiaohongshu"), ze = "https://creator.xiaohongshu.com/publish/publish?from=menu&target=article",
    Gs = "https://creator.xiaohongshu.com", At = 1e4;

class Js extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "xiaohongshu",
            name: "小红书",
            icon: "https://www.xiaohongshu.com/favicon.ico",
            homepage: ze,
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "userId", null)
    }

    async setupHeaderRules() {
        await this.addHeaderRules([{
            urlFilter: "*://creator.xiaohongshu.com/*",
            headers: {Origin: "https://creator.xiaohongshu.com", Referer: ze},
            resourceTypes: ["xmlhttprequest"]
        }, {
            urlFilter: "*://ros-upload.xiaohongshu.com/*",
            headers: {Origin: "https://creator.xiaohongshu.com", Referer: "https://creator.xiaohongshu.com/"},
            resourceTypes: ["xmlhttprequest"]
        }])
    }

    async ensureXHSTab() {
        if (!this.runtime.tabs) throw new Error("小红书发布需要浏览器 tabs API 支持");
        const e = await this.runtime.tabs.query("https://creator.xiaohongshu.com/*");
        if (e.length > 0 && e[0].id) return e[0].id;
        te.info("No existing XHS creator tab found, creating new one...");
        const t = await this.runtime.tabs.create(ze, !1);
        return await this.runtime.tabs.waitForLoad(t.id, 3e4), te.info("New XHS creator tab created and loaded:", t.id), t.id
    }

    async checkAuth() {
        try {
            await this.setupHeaderRules();
            const t = await (await this.runtime.fetch(`${Gs}/api/galaxy/user/info`, {
                credentials: "include",
                headers: {Accept: "application/json, text/plain, */*"}
            })).json();
            return await this.clearHeaderRules(), t.success && t.data ? (this.userId = t.data.userId, te.info("XHS auth success:", t.data.userName), {
                isAuthenticated: !0,
                userId: this.userId,
                username: t.data.userName,
                avatar: t.data.userAvatar
            }) : {isAuthenticated: !1, error: "未登录小红书创作者平台"}
        } catch (e) {
            return await this.clearHeaderRules(), te.error("checkAuth error:", e), {
                isAuthenticated: !1,
                error: e.message
            }
        }
    }

    async publish(e, t) {
        await this.setupHeaderRules();
        try {
            te.info("Starting publish to Xiaohongshu...");
            const r = e.markdown || "", s = this.getPlainTextLength(r);
            if (s > At) throw new Error(`文章字数超出小红书限制：当前 ${s} 字，最多 ${At} 字`);
            if (!this.runtime.tabs) throw new Error("小红书发布需要浏览器 tabs API 支持");
            const n = await this.ensureXHSTab(), i = await Xs(r, async l => {
                var d, m, f;
                const h = await this.uploadImageByUrl(l);
                return {
                    url: h.url,
                    width: (d = h.attrs) == null ? void 0 : d.width,
                    height: (m = h.attrs) == null ? void 0 : m.height,
                    fileId: (f = h.attrs) == null ? void 0 : f.fileId
                }
            }, t == null ? void 0 : t.onImageProgress), a = this.generateUUID();
            if (!this.userId && !(await this.checkAuth()).isAuthenticated) throw new Error("请先登录小红书创作者平台");
            te.info("userId before save:", this.userId);
            const u = await this.runtime.tabs.executeScript(n, async (l, h, d, m) => {
                const f = new Promise(w => {
                    setTimeout(() => w({success: !1, error: "IndexedDB timeout (10s)"}), 1e4)
                }), p = new Promise(w => {
                    try {
                        const _ = indexedDB.open("draft-database-v1");
                        _.onerror = y => {
                            var T;
                            w({
                                success: !1,
                                error: "IndexedDB open error: " + ((T = y.target.error) == null ? void 0 : T.message)
                            })
                        }, _.onsuccess = () => {
                            try {
                                const y = _.result, T = window.location.href, O = Array.from(y.objectStoreNames);
                                if (!y.objectStoreNames.contains("article-draft")) {
                                    y.close(), w({
                                        success: !1,
                                        error: `article-draft store not found. URL: ${T}, stores: ${O.join(", ")}`
                                    });
                                    return
                                }
                                const A = y.transaction(["article-draft"], "readwrite"),
                                    S = A.objectStore("article-draft"), v = {
                                        content: {
                                            contextStore: {
                                                liveContext: {time: 0, title: ""},
                                                previewAuditContext: {
                                                    status: 0,
                                                    detail: {
                                                        hasLimit: !0,
                                                        remainingCalls: 0,
                                                        taskId: "",
                                                        taskType: "1",
                                                        status: 0,
                                                        taskResultInfo: {detectionStatus: 1, optimizationPoints: []}
                                                    },
                                                    isChange: !1
                                                },
                                                coverContext: {
                                                    coverUrl: "",
                                                    cover: {
                                                        width: 0,
                                                        height: 0,
                                                        fileid: "",
                                                        frame: {ts: 0, isUserSelect: !1, isUpload: !1},
                                                        stickers: {version: 2, neptune: []},
                                                        fonts: [],
                                                        coverTemplateId: "",
                                                        extra_info_json: ""
                                                    },
                                                    templateBlob: null,
                                                    rate: 0,
                                                    recommendCoverIdx: -1
                                                },
                                                goodsContext: {goodsInfo: {}, goodsPreviewDetail: []},
                                                bizRelationContext: {bizRelation: []},
                                                recommendCovers: []
                                            },
                                            draftStore: {
                                                descInnerHTML: "",
                                                descLength: 0,
                                                video: {
                                                    width: 0,
                                                    height: 0,
                                                    fileid: "",
                                                    fsize: 0,
                                                    duration: 0,
                                                    videoId: "",
                                                    videoMarks: [],
                                                    timelines: [],
                                                    frame: {ts: 0, userSelect: !1},
                                                    transcodeVideoFileId: "",
                                                    coverInfo: {}
                                                },
                                                videoInfo: null,
                                                audioInfo: null,
                                                videoMeta: "",
                                                audioMeta: "",
                                                cover: {
                                                    width: 0,
                                                    height: 0,
                                                    fileid: "",
                                                    frame: {ts: 0, isUserSelect: !1, isUpload: !1},
                                                    stickers: {neptune: [], version: 2},
                                                    fonts: []
                                                },
                                                chapters: [],
                                                markers: [],
                                                needTranscode: !1,
                                                imgList: [],
                                                colorGroup: null,
                                                title: h,
                                                desc: "",
                                                ats: [],
                                                hashTag: []
                                            },
                                            settingStore: {
                                                privacyInfo: {opType: 1, type: 0, userIds: []},
                                                collectionId: "",
                                                orderId: "",
                                                brandAccountId: "",
                                                noteSketch: {id: "", name: ""},
                                                original: !1,
                                                originalDateStamp: "",
                                                coProduceBind: {enable: !0},
                                                noteCopyBind: {copyable: !0},
                                                coOrderId: "",
                                                interactionPermissionBind: {commentPermission: 0},
                                                fileRelate: {
                                                    fileId: "",
                                                    docId: "",
                                                    docName: "",
                                                    docShowName: "",
                                                    docType: "",
                                                    docSize: 0
                                                }
                                            },
                                            articleStore: {
                                                articleContent: "",
                                                summeryContent: "",
                                                orderPattern: "",
                                                richJson: d,
                                                articleTitle: h,
                                                articleEditorMode: 0,
                                                authorAndSummaryTemp: {author: "", summary: "", readingStats: ""},
                                                selectedThemeId: 6,
                                                selectedColorIndexMap: {},
                                                blob2Map: {},
                                                coverSetting: {
                                                    styleType: 0,
                                                    showAuthor: !0,
                                                    showReadingStats: !0,
                                                    showSummery: !0
                                                },
                                                editPageSource: "import",
                                                schemaCopy: {},
                                                url2FileIdMap: {}
                                            },
                                            shortDraftStore: {
                                                isShort: !0,
                                                editStatus: 0,
                                                textCardList: [{
                                                    createTime: Date.now(),
                                                    text: "",
                                                    originText: "",
                                                    length: 0,
                                                    image: "",
                                                    imageFileId: "",
                                                    isManualInsert: !1
                                                }],
                                                coverList: [],
                                                currentCoverIdx: 0,
                                                cacheData: {}
                                            },
                                            publishStore: {
                                                publishType: 1,
                                                imageNoteOrigin: 0,
                                                systemId: "web",
                                                step: 0,
                                                uploadState: 2,
                                                status: 0,
                                                codec: "unknown"
                                            }
                                        }, draftId: l, uid: m, timeStamp: Date.now()
                                    }, C = S.put(v);
                                C.onsuccess = () => {
                                    y.close(), w({success: !0, error: `saved with uid: ${m}`})
                                }, C.onerror = () => {
                                    var k;
                                    y.close(), w({
                                        success: !1,
                                        error: "put error: " + ((k = C.error) == null ? void 0 : k.message)
                                    })
                                }, A.onerror = () => {
                                    var k;
                                    y.close(), w({
                                        success: !1,
                                        error: "transaction error: " + ((k = A.error) == null ? void 0 : k.message)
                                    })
                                }
                            } catch (y) {
                                w({success: !1, error: "db error: " + y.message})
                            }
                        }
                    } catch (_) {
                        w({success: !1, error: "open error: " + _.message})
                    }
                });
                return Promise.race([p, f])
            }, [a, e.title, i, this.userId]);
            if (!(u != null && u.success)) throw new Error((u == null ? void 0 : u.error) || "保存草稿失败");
            return te.info("Draft saved to IndexedDB:", a, "debug:", u == null ? void 0 : u.error), await this.clearHeaderRules(), this.createResult(!0, {
                postId: a,
                postUrl: ze,
                draftOnly: !0,
                message: "请到「草稿箱 → 长文笔记」查看"
            })
        } catch (r) {
            return await this.clearHeaderRules(), te.error("Publish failed:", r), this.createResult(!1, {error: r.message})
        }
    }

    async uploadImageByUrl(e) {
        if (!this.runtime.tabs) throw new Error("小红书图片上传需要浏览器 tabs API 支持");
        const t = await this.ensureXHSTab();
        let r, s, n = 0, i = 0;
        if (e.startsWith("data:")) {
            const l = e.match(/^data:([^;]+);base64,(.+)$/);
            if (!l) throw new Error("Invalid data URI");
            s = l[1], r = l[2];
            try {
                const h = atob(r), d = new Uint8Array(h.length);
                for (let p = 0; p < h.length; p++) d[p] = h.charCodeAt(p);
                const m = new Blob([d], {type: s}), f = await createImageBitmap(m);
                n = f.width, i = f.height, f.close()
            } catch (h) {
                te.warn("Failed to get image dimensions from data URI:", h)
            }
        } else {
            const h = await (await fetch(e)).blob();
            s = h.type || "image/jpeg";
            try {
                const p = await createImageBitmap(h);
                n = p.width, i = p.height, p.close()
            } catch (p) {
                te.warn("Failed to get image dimensions:", p)
            }
            const d = await h.arrayBuffer(), m = new Uint8Array(d);
            let f = "";
            for (let p = 0; p < m.length; p++) f += String.fromCharCode(m[p]);
            r = btoa(f)
        }
        const a = await this.runtime.tabs.executeScript(t, async (l, h) => {
            var d, m, f;
            try {
                const p = "/api/media/v1/upload/creator/permit?biz_name=spectrum&scene=image&file_count=1&version=1&source=web",
                    w = window;
                let _ = {Accept: "application/json, text/plain, */*"};
                if (typeof w._webmsxyw == "function") {
                    const I = w._webmsxyw(p);
                    I && (_["X-s"] = I["X-s"], _["X-t"] = I["X-t"], _["X-s-common"] = I["X-s-common"])
                }
                const T = await (await fetch("https://creator.xiaohongshu.com" + p, {
                    method: "GET",
                    credentials: "include",
                    headers: _
                })).json();
                if (!T.success || !((m = (d = T.data) == null ? void 0 : d.uploadTempPermits) != null && m[0])) return {
                    success: !1,
                    error: "获取上传凭证失败: " + JSON.stringify(T)
                };
                const O = T.data.uploadTempPermits.find(I => I.uploadAddr === "ros-upload.xiaohongshu.com") || T.data.uploadTempPermits[0],
                    A = (f = O.fileIds) == null ? void 0 : f[0];
                if (!A) return {success: !1, error: "获取 fileId 失败"};
                const S = atob(l), v = new Uint8Array(S.length);
                for (let I = 0; I < S.length; I++) v[I] = S.charCodeAt(I);
                const C = new Blob([v], {type: h}), k = `https://${O.uploadAddr}/${A}`, P = await fetch(k, {
                    method: "PUT",
                    headers: {Authorization: O.token, "Content-Type": h, "x-cos-security-token": O.token},
                    body: C
                });
                if (!P.ok) return {success: !1, error: `上传失败: ${P.status} ${P.statusText}`};
                const b = P.headers.get("x-ros-preview-url");
                return {success: !0, fileId: A, previewUrl: b}
            } catch (p) {
                return {success: !1, error: p.message}
            }
        }, [r, s]);
        if (!(a != null && a.success) || !a.fileId) throw new Error((a == null ? void 0 : a.error) || "图片上传失败");
        return te.debug("Image uploaded:", a.fileId), {
            url: a.previewUrl || `https://ros-preview.xhscdn.com/${a.fileId}`,
            attrs: {fileId: a.fileId, width: n, height: i}
        }
    }

    generateUUID() {
        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, e => {
            const t = Math.random() * 16 | 0;
            return (e === "x" ? t : t & 3 | 8).toString(16)
        })
    }

    getPlainTextLength(e) {
        let t = e;
        return /<[^>]+>/.test(e) ? t = e.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<style[\s\S]*?<\/style>/gi, "").replace(/<[^>]+>/g, "").replace(/&nbsp;/g, " ").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&#(\d+);/g, (r, s) => String.fromCharCode(parseInt(s, 10))) : t = e.replace(/!\[[^\]]*\]\([^)]+\)/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/`[^`]+`/g, "").replace(/^#{1,6}\s+/gm, "").replace(/(\*\*|__)(.*?)\1/g, "$2").replace(/(\*|_)(.*?)\1/g, "$2").replace(/~~(.*?)~~/g, "$1").replace(/^[\-*+]\s+/gm, "").replace(/^\d+\.\s+/gm, "").replace(/^>\s*/gm, "").replace(/^[-*_]{3,}\s*$/gm, ""), t.replace(/\s+/g, " ").trim().length
    }
}

const Ks = Object.freeze(Object.defineProperty({
    __proto__: null,
    XiaohongshuAdapter: Js
}, Symbol.toStringTag, {value: "Module"})), Ue = N("Yidian");

class Ys extends D {
    constructor() {
        super(...arguments);
        g(this, "meta", {
            id: "yidian",
            name: "一点号",
            icon: "https://www.yidianzixun.com/favicon.ico",
            homepage: "https://mp.yidianzixun.com",
            capabilities: ["article", "draft", "image_upload"]
        });
        g(this, "preprocessConfig", {outputFormat: "html", removeLinks: !0});
        g(this, "mpCode", null)
    }

    async checkAuth() {
        try {
            const r = (await (await this.runtime.fetch("https://mp.yidianzixun.com", {credentials: "include"})).text()).match(/<script id="__val_"[^>]*>([\s\S]*?)<\/script>/);
            if (!r) return {isAuthenticated: !1, error: "未找到用户数据"};
            const s = r[1], n = s.match(/window\.mpcode\s*=\s*['"]([a-f0-9]+)['"]/);
            n && (this.mpCode = n[1], Ue.debug("mpCode extracted:", this.mpCode));
            const i = s.match(/window\.mpuser\s*=\s*(\{[\s\S]*?\});/);
            if (!i) return {isAuthenticated: !1, error: "未登录"};
            try {
                const a = JSON.parse(i[1]);
                return a.id ? {
                    isAuthenticated: !0,
                    userId: a.id,
                    username: a.media_name,
                    avatar: a.media_pic
                } : {isAuthenticated: !1, error: "未登录"}
            } catch {
                return {isAuthenticated: !1, error: "解析用户数据失败"}
            }
        } catch (e) {
            return {isAuthenticated: !1, error: e.message}
        }
    }

    getHeaders(e) {
        const t = {Accept: "application/json, text/plain, */*"};
        return e && (t["Content-Type"] = e), this.mpCode && (t["x-mp-code"] = this.mpCode), t
    }

    async ensureMpCode() {
        this.mpCode || (await this.checkAuth(), this.mpCode || Ue.warn("mpCode not found, requests may fail"))
    }

    async uploadImageByUrl(e) {
        var h;
        await this.ensureMpCode();
        try {
            const d = this.getHeaders(),
                m = `https://mp.yidianzixun.com/api/getImageFromUrl?src=${encodeURIComponent(e)}`,
                p = await (await this.runtime.fetch(m, {credentials: "include", headers: d})).json();
            if (p.status === "success" && p.inner_addr) return Ue.debug(`Image uploaded via URL: ${p.inner_addr}`), {url: p.inner_addr}
        } catch (d) {
            Ue.debug("URL upload failed, trying multipart upload:", d)
        }
        const r = await (await this.runtime.fetch(e)).blob(),
            s = ((h = e.match(/\.(png|jpg|jpeg|gif|webp)/i)) == null ? void 0 : h[1]) || "png",
            n = `image_${Date.now()}.${s}`, i = new FormData;
        i.append("upfile", r, n);
        const a = this.getHeaders(),
            l = await (await this.runtime.fetch("https://mp.yidianzixun.com/upload?action=uploadimage&picType=wemedia_cnt", {
                method: "POST",
                credentials: "include",
                headers: a,
                body: i
            })).json();
        if (l.status !== "success" || !l.url) throw new Error(`图片上传失败: ${JSON.stringify(l)}`);
        return Ue.debug(`Image uploaded via multipart: ${l.url}`), {url: l.url}
    }

    async publish(e) {
        const t = Date.now();
        try {
            await this.ensureMpCode();
            let r = e.html || "";
            r = await this.processImages(r, a => this.uploadImageByUrl(a));
            const s = {
                title: e.title,
                cate: "",
                cateB: "",
                coverType: "default",
                covers: [],
                content: r,
                hasSubTitle: 0,
                subTitle: "",
                original: 0,
                reward: 0,
                videos: [],
                audios: [],
                votes: {vote_id: "", vote_options: [], vote_end_time: "", vote_title: "", vote_type: 1, isAdded: !1},
                images: [],
                goods: [],
                is_mobile: 0,
                status: 0,
                import_url: "",
                import_hash: "",
                image_urls: {},
                minTimingHour: 3,
                maxTimingDay: 7,
                tags: [],
                isPubed: !1,
                lastSaveTime: "",
                dirty: !1,
                editorType: "articleEditor",
                activity_id: 0,
                join_activity: 0,
                wm_globallink: "",
                wm_globaltime: "",
                outsideImages: [],
                wm_content_source: {type: 1},
                notSaveToStore: !0
            }, i = await (await this.runtime.fetch("https://mp.yidianzixun.com/model/Article", {
                method: "POST",
                credentials: "include",
                headers: this.getHeaders("application/json;charset=UTF-8"),
                body: JSON.stringify(s)
            })).json();
            if (!i.id) throw new Error("同步错误: " + JSON.stringify(i));
            return {
                platform: this.meta.id,
                success: !0,
                postId: i.id,
                postUrl: `https://mp.yidianzixun.com/#/Writing/${i.id}`,
                draftOnly: !0,
                timestamp: t
            }
        } catch (r) {
            return {platform: this.meta.id, success: !1, error: r.message, timestamp: t}
        }
    }
}

const Vs = Object.freeze(Object.defineProperty({
    __proto__: null,
    YidianAdapter: Ys
}, Symbol.toStringTag, {value: "Module"})), Qs = 30 * 1e3;

class Zs {
    constructor(o) {
        g(this, "config");
        g(this, "type", "extension");
        g(this, "ruleIdBase", Date.now() % 1e5);
        g(this, "ruleIdCounter", 0);
        g(this, "cookies", {
            async get(o) {
                return (await chrome.cookies.getAll({domain: o})).map(t => ({
                    name: t.name,
                    value: t.value,
                    domain: t.domain,
                    path: t.path,
                    secure: t.secure,
                    httpOnly: t.httpOnly,
                    expirationDate: t.expirationDate
                }))
            }, async set(o) {
                await chrome.cookies.set({
                    url: `https://${o.domain}${o.path || "/"}`,
                    name: o.name,
                    value: o.value,
                    domain: o.domain,
                    path: o.path,
                    secure: o.secure,
                    httpOnly: o.httpOnly,
                    expirationDate: o.expirationDate
                })
            }, async remove(o, e) {
                await chrome.cookies.remove({url: `https://${e}`, name: o})
            }
        });
        g(this, "storage", {
            async get(o) {
                return (await chrome.storage.local.get(o))[o] ?? null
            }, async set(o, e) {
                await chrome.storage.local.set({[o]: e})
            }, async remove(o) {
                await chrome.storage.local.remove(o)
            }
        });
        g(this, "session", {
            async get(o) {
                return (await chrome.storage.session.get(o))[o] ?? null
            }, async set(o, e) {
                await chrome.storage.session.set({[o]: e})
            }
        });
        g(this, "headerRules", {
            add: async o => {
                const e = this.ruleIdBase + this.ruleIdCounter++, t = `rule_${e}`;
                return await chrome.declarativeNetRequest.updateDynamicRules({
                    addRules: [{
                        id: e,
                        priority: 1,
                        action: {
                            type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS,
                            requestHeaders: Object.entries(o.headers).map(([r, s]) => ({
                                header: r,
                                operation: chrome.declarativeNetRequest.HeaderOperation.SET,
                                value: s
                            }))
                        },
                        condition: {
                            urlFilter: o.urlFilter,
                            initiatorDomains: [chrome.runtime.id],
                            resourceTypes: o.resourceTypes || ["xmlhttprequest"]
                        }
                    }]
                }), t
            }, remove: async o => {
                const e = parseInt(o.replace("rule_", ""), 10);
                await chrome.declarativeNetRequest.updateDynamicRules({removeRuleIds: [e]})
            }, clear: async () => {
                const o = await chrome.declarativeNetRequest.getDynamicRules();
                await chrome.declarativeNetRequest.updateDynamicRules({removeRuleIds: o.map(e => e.id)})
            }
        });
        g(this, "downloads", {
            async download(o, e, t = !0) {
                const r = await o.arrayBuffer(),
                    s = btoa(new Uint8Array(r).reduce((u, l) => u + String.fromCharCode(l), "")),
                    i = `data:${o.type || "application/octet-stream"};base64,${s}`;
                return await chrome.downloads.download({url: i, filename: e, saveAs: t})
            }
        });
        g(this, "tabs", {
            async query(o) {
                return (await chrome.tabs.query({url: o})).filter(t => t.id !== void 0).map(t => ({
                    id: t.id,
                    url: t.url
                }))
            }, async create(o, e = !1) {
                return {id: (await chrome.tabs.create({url: o, active: e})).id}
            }, async waitForLoad(o, e = 3e4) {
                return new Promise((t, r) => {
                    const s = setTimeout(() => {
                        chrome.tabs.onUpdated.removeListener(n), r(new Error("Tab load timeout"))
                    }, e), n = (i, a) => {
                        i === o && a.status === "complete" && (clearTimeout(s), chrome.tabs.onUpdated.removeListener(n), setTimeout(t, 1e3))
                    };
                    chrome.tabs.onUpdated.addListener(n)
                })
            }, async executeScript(o, e, t) {
                var n;
                return (n = (await chrome.scripting.executeScript({
                    target: {tabId: o},
                    world: "MAIN",
                    func: e,
                    args: t
                }))[0]) == null ? void 0 : n.result
            }
        });
        g(this, "dom", {
            parseHTML: async o => new DOMParser().parseFromString(o, "text/html"),
            querySelector: (o, e) => o.querySelector(e),
            querySelectorAll: (o, e) => Array.from(o.querySelectorAll(e)),
            getTextContent: o => o.textContent || "",
            getInnerHTML: o => o.innerHTML
        });
        this.config = o
    }

    async fetch(o, e) {
        var n;
        const t = ((n = this.config) == null ? void 0 : n.timeout) ?? Qs, r = new AbortController,
            s = setTimeout(() => r.abort(), t);
        try {
            return await fetch(o, {...e, credentials: "include", signal: r.signal})
        } catch (i) {
            throw i.name === "AbortError" ? new Error(`请求超时（${t / 1e3}秒）: ${o}`) : i
        } finally {
            clearTimeout(s)
        }
    }

    async getCookie(o, e) {
        const t = await chrome.cookies.getAll({domain: o, name: e});
        return t.length > 0 ? t[0].value : null
    }
}

function ea(c) {
    return new Zs(c)
}

const ta = Object.assign({
    "../core/src/adapters/platforms/private/dayu.ts": ns,
    "../core/src/adapters/platforms/private/douyin.ts": cs,
    "../core/src/adapters/platforms/private/jianshu.ts": ls,
    "../core/src/adapters/platforms/private/netease.ts": hs,
    "../core/src/adapters/platforms/private/smzdm.ts": fs,
    "../core/src/adapters/platforms/private/sohufocus.ts": ys,
    "../core/src/adapters/platforms/private/toutiao.ts": _s,
    "../core/src/adapters/platforms/private/x.ts": Es,
    "../core/src/adapters/platforms/private/xiaohongshu.ts": Ks,
    "../core/src/adapters/platforms/private/yidian.ts": Vs
});

function ra() {
    const c = [];
    for (const o of Object.values(ta)) for (const [e, t] of Object.entries(o)) if (typeof t == "function" && e.endsWith("Adapter")) try {
        const r = new t;
        r && r.meta && c.push(t)
    } catch {
    }
    return c
}

const sa = [Hr, Br, Wr, Xr, Gr, zr, Jr, Mr, Nr, jr, Yr, Fr, Vr, Qr, Zr, es, ts, rs, ss, ...ra()], aa = sa.map(c => {
    const o = new c;
    return {meta: o.meta, factory: () => new c, preprocessConfig: o.preprocessConfig}
}), ge = Te("WechatSync"), na = ea();
let Et = !1;

async function Me() {
    if (!Et) {
        fe.setRuntime(na);
        for (const c of aa) try {
            fe.register(c)
        } catch (o) {
            ge.error("Failed to register adapter:", o)
        }
        Et = !0
    }
}

async function je(c) {
    return await Me(), fe.get(c)
}

function Oe() {
    return fe.getAllMeta()
}

function at(c) {
    return fe.getPreprocessConfigs(c)
}

const nt = "authCache", oa = 5 * 60 * 1e3, ia = 30 * 1e3, vt = 5, Qe = 10 * 1e3, Ct = 10 * 60 * 1e3;

function dt(c, o, e) {
    return new Promise((t, r) => {
        const s = setTimeout(() => {
            r(new Error(e))
        }, o);
        c.then(n => {
            clearTimeout(s), t(n)
        }).catch(n => {
            clearTimeout(s), r(n)
        })
    })
}

async function Jt(c) {
    const o = await je(c);
    if (!o) return {isAuthenticated: !1, error: "Platform not found"};
    try {
        return await dt(o.checkAuth(), Qe, `认证检查超时2（${Qe / 1e3}秒）${c}`)
    } catch (e) {
        return {isAuthenticated: !1, error: e.message}
    }
}

async function ca() {
    try {
        return (await chrome.storage.local.get(nt))[nt] || {}
    } catch {
        return {}
    }
}

async function ua(c) {
    await chrome.storage.local.set({[nt]: c})
}

async function Ne(c = !1) {
    await Me();
    const o = fe.getAllMeta(), e = await ca(), t = Date.now(), r = [], s = [];
    ge.debug(" Checking auth for platforms:", o.map(i => i.id), c ? "(force refresh)" : "");
    for (const i of o) {
        const a = e[i.id], u = a != null && a.isAuthenticated ? oa : ia;
        a && t - a.timestamp < u && !c ? (ge.debug(` Using cached auth for ${i.id} (TTL: ${u / 1e3}s)`), r.push({
            ...i,
            isAuthenticated: a.isAuthenticated,
            username: a.username,
            error: a.error
        })) : s.push(i)
    }
    if (s.length > 0) {
        ge.debug(` Need to check ${s.length} platforms in parallel`);
        for (let i = 0; i < s.length; i += vt) {
            const a = s.slice(i, i + vt), u = await Promise.all(a.map(async l => {
                try {
                    const h = await fe.get(l.id);
                    if (h) {
                        ge.debug(` Checking auth for ${l.id}...`);
                        const d = await dt(h.checkAuth(), Qe, `认证检查超时2（${Qe / 1e3}秒）${l.id}`);
                        return ge.debug(` ${l.id} auth result:`, d), or(l.id, d.isAuthenticated).catch(() => {
                        }), e[l.id] = {
                            isAuthenticated: d.isAuthenticated,
                            username: d.username,
                            error: d.error,
                            timestamp: t
                        }, {...l, isAuthenticated: d.isAuthenticated, username: d.username, error: d.error}
                    }
                    return {...l, isAuthenticated: !1, error: "Adapter not found"}
                } catch (h) {
                    return ge.error(`${l.id} auth error:`, h), e[l.id] = {
                        isAuthenticated: !1,
                        error: h.message,
                        timestamp: t
                    }, {...l, isAuthenticated: !1, error: h.message}
                }
            }));
            r.push(...u)
        }
    }
    return await ua(e), r.some(i => i.isAuthenticated) && De("first_platform_login").catch(() => {
    }), r
}

async function la(c, o, e, t) {
    const r = await je(c);
    if (!r) return {platform: c, success: !1, error: "Platform not found", timestamp: Date.now()};
    try {
        let s = o;
        const n = o.platformContents;
        if (n != null && n[c]) {
            const i = n[c];
            s = {...o, html: i.html, markdown: i.markdown}
        }
        return await dt(r.publish(s, {
            draftOnly: (e == null ? void 0 : e.draftOnly) ?? !0,
            onImageProgress: t ? (i, a) => t(c, i, a) : void 0
        }), Ct, `发布超时（${Ct / 6e4}分钟）`)
    } catch (s) {
        return {platform: c, success: !1, error: s.message, timestamp: Date.now()}
    }
}

const Ut = 3;
let Se = null;

function da() {
    return Se ? (Se.abort(), Se = null, !0) : !1
}

async function ot(c, o, e, t = "popup") {
    var h;
    Se = new AbortController;
    const r = Se.signal, s = [], n = Date.now();
    ir(t, c).catch(() => {
    }), cr().catch(() => {
    }), ur(c).catch(() => {
    }), De("first_sync_attempt").catch(() => {
    });
    const i = d => {
        const m = Oe().find(f => f.id === d);
        return (m == null ? void 0 : m.name) || d
    }, a = async d => {
        var y, T, O, A;
        const m = i(d);
        if (r.aborted) {
            const S = {platform: d, success: !1, error: "已取消", timestamp: Date.now()};
            return (y = e == null ? void 0 : e.onDetailProgress) == null || y.call(e, {
                platform: d,
                platformName: m,
                stage: "failed",
                result: S,
                error: "已取消"
            }), S
        }
        (T = e == null ? void 0 : e.onDetailProgress) == null || T.call(e, {
            platform: d,
            platformName: m,
            stage: "starting"
        });
        const f = Date.now(), p = e != null && e.onImageProgress || e != null && e.onDetailProgress ? (S, v, C) => {
            var k, P, b;
            (k = e == null ? void 0 : e.onImageProgress) == null || k.call(e, S, v, C), (P = e == null ? void 0 : e.onDetailProgress) == null || P.call(e, {
                platform: d,
                platformName: m,
                stage: "uploading_images",
                imageProgress: {current: v, total: C}
            }), v === C && C > 0 && ((b = e == null ? void 0 : e.onDetailProgress) == null || b.call(e, {
                platform: d,
                platformName: m,
                stage: "saving"
            }))
        } : void 0, w = await la(d, o, void 0, p);
        (O = e == null ? void 0 : e.onDetailProgress) == null || O.call(e, {
            platform: d,
            platformName: m,
            stage: w.success ? "completed" : "failed",
            result: w,
            error: w.error
        }), (A = e == null ? void 0 : e.onResult) == null || A.call(e, w);
        const _ = Date.now() - f;
        return hr(t, d, w.success, {
            draftOnly: w.draftOnly,
            errorType: w.error ? jt(w.error) : void 0,
            duration: _
        }).catch(() => {
        }), w
    };
    for (let d = 0; d < c.length; d += Ut) {
        if (r.aborted) {
            const p = c.slice(d);
            for (const w of p) {
                const _ = {platform: w, success: !1, error: "已取消", timestamp: Date.now()};
                s.push(_), (h = e == null ? void 0 : e.onResult) == null || h.call(e, _)
            }
            break
        }
        const m = c.slice(d, d + Ut), f = await Promise.all(m.map(a));
        s.push(...f)
    }
    Se = null;
    const u = s.filter(d => d.success).length, l = s.filter(d => d.error === "已取消").length;
    return lr({
        source: t,
        total: s.length,
        success: u,
        failed: s.length - u - l,
        platforms: c,
        duration: Date.now() - n
    }).catch(() => {
    }), u > 0 && De("first_sync_success").catch(() => {
    }), dr(c).catch(() => {
    }), s
}

const Y = Te("WordPress");

function ht(c, o) {
    const e = o.map(t => typeof t == "string" ? `<param><value><string>${it(t)}</string></value></param>` : typeof t == "number" ? `<param><value><int>${t}</int></value></param>` : typeof t == "object" && t !== null ? `<param><value><struct>${ha(t)}</struct></value></param>` : `<param><value><string>${String(t)}</string></value></param>`).join("");
    return `<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
  <methodName>${c}</methodName>
  <params>${e}</params>
</methodCall>`
}

function ha(c) {
    return Object.entries(c).map(([o, e]) => {
        let t;
        return typeof e == "string" ? t = `<string>${it(e)}</string>` : typeof e == "number" ? t = `<int>${e}</int>` : typeof e == "boolean" ? t = `<boolean>${e ? 1 : 0}</boolean>` : e instanceof Uint8Array ? t = `<base64>${pa(e)}</base64>` : t = `<string>${it(String(e))}</string>`, `<member><name>${o}</name><value>${t}</value></member>`
    }).join("")
}

function pa(c) {
    let o = "";
    const e = c.byteLength;
    for (let t = 0; t < e; t++) o += String.fromCharCode(c[t]);
    return btoa(o)
}

function it(c) {
    return c.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;")
}

function Kt(c) {
    if (c.includes("<fault>")) {
        const e = c.match(/<string>([^<]+)<\/string>/);
        return {success: !1, error: (e == null ? void 0 : e[1]) || "XML-RPC 错误"}
    }
    const o = c.match(/<value>[\s\S]*?<(string|int|boolean)>([^<]*)<\/\1>/);
    return o ? {success: !0, value: o[2]} : c.includes("<struct>") ? {success: !0, value: {}} : {success: !0}
}

async function ma(c) {
    const o = c.url.replace(/\/$/, "") + "/xmlrpc.php";
    try {
        const e = ht("wp.getUsersBlogs", [c.username, c.password]),
            t = await fetch(o, {method: "POST", headers: {"Content-Type": "text/xml"}, body: e});
        if (!t.ok) return {success: !1, error: `HTTP ${t.status}`};
        const r = await t.text(), s = Kt(r);
        return s.success ? {success: !0} : {success: !1, error: s.error}
    } catch (e) {
        return {success: !1, error: e.message}
    }
}

async function ga(c, o, e, t) {
    const r = c.url.replace(/\/$/, "") + "/xmlrpc.php";
    try {
        const s = {name: e, type: t, bits: o, overwrite: !0}, n = ht("wp.uploadFile", [0, c.username, c.password, s]),
            i = await fetch(r, {method: "POST", headers: {"Content-Type": "text/xml"}, body: n});
        if (!i.ok) return {success: !1, error: `HTTP ${i.status}`};
        const a = await i.text(),
            u = a.match(/<name>url<\/name>\s*<value>(?:<string>)?([^<]+)(?:<\/string>)?<\/value>/);
        if (u) return {success: !0, url: u[1]};
        if (a.includes("<fault>")) {
            const l = a.match(/<string>([^<]+)<\/string>/);
            return {success: !1, error: (l == null ? void 0 : l[1]) || "Upload failed"}
        }
        return {success: !1, error: "无法解析上传结果"}
    } catch (s) {
        return {success: !1, error: s.message}
    }
}

const fa = {
    "image/jpeg": "jpg",
    "image/jpg": "jpg",
    "image/png": "png",
    "image/gif": "gif",
    "image/webp": "webp",
    "image/bmp": "bmp",
    "image/svg+xml": "svg"
};

function wa(c) {
    const o = fa[c] || "png";
    return `image_${Date.now()}.${o}`
}

const $e = 10, ya = 1e3;

function ba(c) {
    return new Promise(o => setTimeout(o, c))
}

async function _a(c, o, e) {
    let t = null;
    for (let r = 1; r <= $e; r++) {
        if (e != null && e.aborted) return Y.debug(` Upload aborted for: ${o}`), null;
        try {
            const s = await Ia(c, o, e);
            if (s) return r > 1 && Y.debug(` Upload succeeded on attempt ${r}: ${o}`), s;
            Y.warn(` Upload attempt ${r}/${$e} failed for: ${o}`)
        } catch (s) {
            t = s, Y.warn(` Upload attempt ${r}/${$e} error:`, s)
        }
        if (r < $e) {
            const s = ya * r;
            Y.debug(` Retrying in ${s}ms...`), await ba(s)
        }
    }
    return Y.error(` All ${$e} upload attempts failed for: ${o}`, t), null
}

async function Ia(c, o, e) {
    const t = new AbortController, r = setTimeout(() => t.abort(), 3e4);
    e && e.addEventListener("abort", () => t.abort());
    try {
        const s = await fetch(o, {signal: t.signal});
        if (clearTimeout(r), !s.ok) return Y.error(` Failed to download image (HTTP ${s.status}): ${o}`), null;
        const n = await s.blob(), i = await n.arrayBuffer(), a = new Uint8Array(i), u = n.type || "image/jpeg",
            l = wa(u);
        Y.debug(` Uploading image: ${l}, type: ${u}`);
        const h = await ga(c, a, l, u);
        return h.success && h.url ? {url: h.url} : (Y.error(` Failed to upload image: ${h.error}`), null)
    } catch (s) {
        throw clearTimeout(r), s
    }
}

async function Sa(c, o, e, t) {
    const r = /<img[^>]+src="([^"]+)"[^>]*>/gi, s = [];
    let n;
    for (; (n = r.exec(o)) !== null;) s.push({full: n[0], src: n[1]});
    for (const h of xe(o)) s.push({full: h.full, src: h.src});
    if (s.length === 0) return {content: o, failedImages: 0};
    Y.debug(` Found ${s.length} images to process`);
    let i = o;
    const a = new Map;
    let u = 0, l = 0;
    for (const {full: h, src: d} of s) {
        if (t != null && t.aborted) throw new Error("操作已取消");
        if (!d || d.startsWith("data:")) continue;
        const m = new URL(c.url).hostname;
        try {
            if (new URL(d).hostname === m) {
                Y.debug(` Skipping same-domain image: ${d}`);
                continue
            }
        } catch {
        }
        u++, e == null || e(u, s.length);
        let f = a.get(d);
        if (!f) {
            Y.debug(` Uploading image ${u}/${s.length}: ${d}`);
            const p = await _a(c, d, t);
            if (p != null && p.url) f = p.url, a.set(d, f); else {
                l++, Y.warn(`图片上传失败，跳过: ${d.substring(0, 100)}...`);
                continue
            }
        }
        if (f) {
            const p = h.replace(d, f);
            i = i.replace(h, p), Y.debug(` Image uploaded: ${f}`)
        }
        await new Promise(p => setTimeout(p, 300))
    }
    return {content: i, failedImages: l}
}

async function Ge(c, o, e) {
    var r, s;
    const t = c.url.replace(/\/$/, "") + "/xmlrpc.php";
    try {
        if ((r = e == null ? void 0 : e.signal) != null && r.aborted) return {success: !1, error: "操作已取消"};
        let n = o.content, i = 0;
        if ((e == null ? void 0 : e.processImages) !== !1) {
            Y.debug(" Processing images before publish...");
            const w = await Sa(c, n, e == null ? void 0 : e.onImageProgress, e == null ? void 0 : e.signal);
            n = w.content, i = w.failedImages
        }
        if ((s = e == null ? void 0 : e.signal) != null && s.aborted) return {success: !1, error: "操作已取消"};
        const a = {
                post_title: o.title,
                post_content: n,
                post_status: e != null && e.draftOnly ? "draft" : "publish",
                post_type: "post"
            }, u = ht("wp.newPost", [0, c.username, c.password, a]),
            l = await fetch(t, {method: "POST", headers: {"Content-Type": "text/xml"}, body: u});
        if (!l.ok) return {success: !1, error: `HTTP ${l.status}`};
        const h = await l.text(), d = Kt(h);
        if (!d.success) return {success: !1, error: d.error};
        const m = String(d.value),
            f = e != null && e.draftOnly ? `${c.url.replace(/\/$/, "")}/wp-admin/post.php?post=${m}&action=edit` : `${c.url.replace(/\/$/, "")}/?p=${m}`,
            p = i > 0 ? `${i} 张图片上传失败` : void 0;
        return {success: !0, postId: m, postUrl: f, message: p}
    } catch (n) {
        return {success: !1, error: n.message}
    }
}

const W = Te("MetaWeblog");

function Re(c, o) {
    const e = o.map(t => typeof t == "string" ? `<param><value><string>${ct(t)}</string></value></param>` : typeof t == "number" ? `<param><value><i4>${t}</i4></value></param>` : typeof t == "boolean" ? `<param><value><boolean>${t ? 1 : 0}</boolean></value></param>` : typeof t == "object" && t !== null ? `<param><value><struct>${Ta(t)}</struct></value></param>` : `<param><value><string>${String(t)}</string></value></param>`).join("");
    return `<?xml version="1.0"?><methodCall><methodName>${c}</methodName><params>${e}</params></methodCall>`
}

function Ta(c) {
    return Object.entries(c).map(([o, e]) => {
        let t;
        return typeof e == "string" ? t = `<string>${ct(e)}</string>` : typeof e == "number" ? t = `<i4>${e}</i4>` : typeof e == "boolean" ? t = `<boolean>${e ? 1 : 0}</boolean>` : e instanceof Uint8Array ? t = `<base64>${xa(e)}</base64>` : t = `<string>${ct(String(e))}</string>`, `<member><name>${o}</name><value>${t}</value></member>`
    }).join("")
}

function xa(c) {
    let o = "";
    const e = c.byteLength;
    for (let t = 0; t < e; t++) o += String.fromCharCode(c[t]);
    return btoa(o)
}

function ct(c) {
    return c.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;")
}

function Ze(c) {
    if (c.includes("<fault>")) {
        const r = c.match(/<string>([^<]+)<\/string>/);
        return {success: !1, error: (r == null ? void 0 : r[1]) || "XML-RPC 错误"}
    }
    const o = c.match(/<string>([^<]*)<\/string>/);
    if (o) return {success: !0, value: o[1]};
    const e = c.match(/<int>([^<]*)<\/int>/);
    if (e) return {success: !0, value: e[1]};
    const t = c.match(/<i4>([^<]*)<\/i4>/);
    return t ? {success: !0, value: t[1]} : c.includes("<array>") || c.includes("<struct>") ? {
        success: !0,
        value: {}
    } : {success: !0}
}

function Ra(c) {
    const o = c.match(/<name>postid<\/name>\s*<value>(?:<string>)?([^<]+)(?:<\/string>)?<\/value>/);
    return o ? o[1] : null
}

async function ka(c, o) {
    try {
        const e = Re("metaWeblog.getRecentPosts", [0, c.username, c.password, 1]),
            t = await fetch(o, {method: "POST", headers: {"Content-Type": "text/xml"}, body: e});
        if (!t.ok) return null;
        const r = await t.text();
        return Ra(r)
    } catch {
        return null
    }
}

function pt(c) {
    return c.endpoint ? c.endpoint : c.url.replace(/\/$/, "") + "/xmlrpc.php"
}

async function Aa(c) {
    const o = pt(c);
    try {
        const e = Re("blogger.getUsersBlogs", ["", c.username, c.password]),
            t = await fetch(o, {method: "POST", headers: {"Content-Type": "text/xml"}, body: e});
        if (!t.ok) return {success: !1, error: `HTTP ${t.status}`};
        const r = await t.text(), s = Ze(r);
        return s.success ? {success: !0} : {success: !1, error: s.error}
    } catch (e) {
        return {success: !1, error: e.message}
    }
}

async function Ea(c, o, e, t) {
    const r = pt(c);
    try {
        const s = {name: e, type: t, bits: o, bytes: o},
            i = Re("metaWeblog.newMediaObject", [0, c.username, c.password, s]),
            a = await fetch(r, {method: "POST", headers: {"Content-Type": "text/xml"}, body: i});
        if (!a.ok) return {success: !1, error: `HTTP ${a.status}`};
        const u = await a.text(),
            l = u.match(/<name>url<\/name>\s*<value>(?:<string>)?([^<]+)(?:<\/string>)?<\/value>/);
        if (l) return {success: !0, url: l[1]};
        if (u.includes("<fault>")) {
            const h = u.match(/<string>([^<]+)<\/string>/);
            return {success: !1, error: (h == null ? void 0 : h[1]) || "Upload failed"}
        }
        return {success: !1, error: "无法解析上传结果"}
    } catch (s) {
        return {success: !1, error: s.message}
    }
}

const va = {
    "image/jpeg": "jpg",
    "image/jpg": "jpg",
    "image/png": "png",
    "image/gif": "gif",
    "image/webp": "webp",
    "image/bmp": "bmp",
    "image/svg+xml": "svg"
};

function Ca(c) {
    const o = va[c] || "png";
    return `image_${Date.now()}.${o}`
}

const Pe = 10, Ua = 1e3;

function $a(c) {
    return new Promise(o => setTimeout(o, c))
}

async function Pa(c, o, e) {
    let t = null;
    for (let r = 1; r <= Pe; r++) {
        if (e != null && e.aborted) return W.debug(` Upload aborted for: ${o}`), null;
        try {
            const s = await Oa(c, o, e);
            if (s) return r > 1 && W.debug(` Upload succeeded on attempt ${r}: ${o}`), s;
            W.warn(` Upload attempt ${r}/${Pe} failed for: ${o}`)
        } catch (s) {
            t = s, W.warn(` Upload attempt ${r}/${Pe} error:`, s)
        }
        if (r < Pe) {
            const s = Ua * r;
            W.debug(` Retrying in ${s}ms...`), await $a(s)
        }
    }
    return W.error(` All ${Pe} upload attempts failed for: ${o}`, t), null
}

async function Oa(c, o, e) {
    const t = new AbortController, r = setTimeout(() => t.abort(), 3e4);
    e && e.addEventListener("abort", () => t.abort());
    try {
        const s = await fetch(o, {signal: t.signal});
        if (clearTimeout(r), !s.ok) return W.error(` Failed to download image (HTTP ${s.status}): ${o}`), null;
        const n = await s.blob(), i = await n.arrayBuffer(), a = new Uint8Array(i), u = n.type || "image/jpeg",
            l = Ca(u);
        W.debug(` Uploading image: ${l}, type: ${u}`);
        const h = await Ea(c, a, l, u);
        return h.success && h.url ? {url: h.url} : (W.error(` Failed to upload image: ${h.error}`), null)
    } catch (s) {
        throw clearTimeout(r), s
    }
}

async function Yt(c, o, e, t) {
    const r = /<img[^>]+src="([^"]+)"[^>]*>/gi, s = [];
    let n;
    for (; (n = r.exec(o)) !== null;) s.push({full: n[0], src: n[1]});
    for (const h of xe(o)) s.push({full: h.full, src: h.src});
    if (s.length === 0) return {content: o, failedImages: 0};
    W.debug(` Found ${s.length} images to process`);
    let i = o;
    const a = new Map;
    let u = 0, l = 0;
    for (const {full: h, src: d} of s) {
        if (t != null && t.aborted) throw new Error("操作已取消");
        if (!d || d.startsWith("data:")) continue;
        const m = new URL(c.url).hostname;
        try {
            if (new URL(d).hostname === m) {
                W.debug(` Skipping same-domain image: ${d}`);
                continue
            }
        } catch {
        }
        u++, e == null || e(u, s.length);
        let f = a.get(d);
        if (!f) {
            W.debug(` Uploading image ${u}/${s.length}: ${d}`);
            const p = await Pa(c, d, t);
            if (p != null && p.url) f = p.url, a.set(d, f); else {
                l++, W.warn(`图片上传失败，跳过: ${d.substring(0, 100)}...`);
                continue
            }
        }
        if (f) {
            const p = h.replace(d, f);
            i = i.replace(h, p), W.debug(` Image uploaded: ${f}`)
        }
        await new Promise(p => setTimeout(p, 300))
    }
    return {content: i, failedImages: l}
}

async function Je(c, o, e) {
    const t = pt(c);
    try {
        let r = o.content, s = 0;
        if ((e == null ? void 0 : e.processImages) !== !1) {
            W.debug(" Processing images before publish...");
            const p = await Yt(c, r, e == null ? void 0 : e.onImageProgress);
            r = p.content, s = p.failedImages
        }
        const n = {title: o.title, description: r, categories: []},
            i = Re("metaWeblog.newPost", ["0", c.username, c.password, n, !(e != null && e.draftOnly)]),
            a = await fetch(t, {method: "POST", headers: {"Content-Type": "text/xml"}, body: i});
        if (!a.ok) return {success: !1, error: `HTTP ${a.status}`};
        const u = await a.text(), l = Ze(u);
        if (!l.success) return {success: !1, error: l.error};
        const h = String(l.value), d = c.url.replace(/\/$/, ""),
            m = e != null && e.draftOnly ? `${d}/admin/manage-posts.php?cid=${h}` : `${d}/archives/${h}/`,
            f = s > 0 ? `${s} 张图片上传失败` : void 0;
        return {success: !0, postId: h, postUrl: m, message: f}
    } catch (r) {
        return {success: !1, error: r.message}
    }
}

async function Da(c) {
    const o = c.url.replace(/\/$/, "") + "/action/xmlrpc";
    try {
        const e = Re("metaWeblog.getUsersBlogs", ["", c.username, c.password]),
            t = await fetch(o, {method: "POST", headers: {"Content-Type": "text/xml"}, body: e});
        if (!t.ok) return {success: !1, error: `HTTP ${t.status}`};
        const r = await t.text(), s = Ze(r);
        return s.success ? {success: !0} : {success: !1, error: s.error}
    } catch (e) {
        return {success: !1, error: e.message}
    }
}

async function Ke(c, o, e) {
    const t = c.url.replace(/\/$/, "") + "/action/xmlrpc", r = {...c, endpoint: t};
    try {
        let s = o.content, n = 0;
        if ((e == null ? void 0 : e.processImages) !== !1) {
            W.debug(" Processing images before publish...");
            const w = await Yt(r, s, e == null ? void 0 : e.onImageProgress, e == null ? void 0 : e.signal);
            s = w.content, n = w.failedImages
        }
        const i = {title: o.title, description: s.trim()},
            a = Re("metaWeblog.newPost", [0, c.username, c.password, i, !1]),
            u = await fetch(t, {method: "POST", headers: {"Content-Type": "text/xml"}, body: a});
        if (!u.ok) return {success: !1, error: `HTTP ${u.status}`};
        const l = await u.text(), h = Ze(l);
        if (!h.success) return {success: !1, error: h.error};
        let d = String(h.value);
        const m = c.url.replace(/\/$/, "");
        if (!d || d === "0") {
            W.debug("Typecho returned postId=0, fetching latest post...");
            const w = await ka(c, t);
            w && (d = w, W.debug(`Got latest postId: ${d}`))
        }
        let f;
        d && d !== "0" ? f = `${m}/admin/write-post.php?cid=${d}` : f = `${m}/admin/manage-posts.php`;
        const p = n > 0 ? `${n} 张图片上传失败` : void 0;
        return {success: !0, postId: d, postUrl: f, message: p}
    } catch (s) {
        return {success: !1, error: s.message}
    }
}

const ie = Te("SyncService"), Ie = "activeSyncState", Ma = 25,
    We = {success: "#22C55E", error: "#EF4444", partial: "#F59E0B"};

function ja() {
    return `sync_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
}

async function Na(c) {
    if (!c) {
        await chrome.action.setBadgeText({text: ""});
        return
    }
    if (c.status === "syncing") await chrome.action.setBadgeText({text: ""}); else if (c.status === "completed") {
        const o = c.results.filter(r => r.success).length;
        c.selectedPlatforms.length - o === 0 ? (await chrome.action.setBadgeText({text: "✓"}), await chrome.action.setBadgeBackgroundColor({color: We.success})) : o === 0 ? (await chrome.action.setBadgeText({text: "!"}), await chrome.action.setBadgeBackgroundColor({color: We.error})) : (await chrome.action.setBadgeText({text: `${o}`}), await chrome.action.setBadgeBackgroundColor({color: We.partial})), setTimeout(async () => {
            var s;
            ((s = (await chrome.storage.local.get(Ie))[Ie]) == null ? void 0 : s.status) === "completed" && await chrome.action.setBadgeText({text: ""})
        }, 5e3)
    } else (c.status === "failed" || c.status === "cancelled") && (await chrome.action.setBadgeText({text: "!"}), await chrome.action.setBadgeBackgroundColor({color: We.error}), setTimeout(async () => {
        var e, t;
        const o = await chrome.storage.local.get(Ie);
        (((e = o[Ie]) == null ? void 0 : e.status) === "failed" || ((t = o[Ie]) == null ? void 0 : t.status) === "cancelled") && await chrome.action.setBadgeText({text: ""})
    }, 5e3))
}

async function me(c) {
    await chrome.storage.local.set({[Ie]: c}), await Na(c)
}

async function Fa(c, o, e) {
    try {
        const r = (await chrome.storage.local.get("syncHistory")).syncHistory || [], s = {
            id: c,
            status: "syncing",
            title: o.title || "未知文章",
            cover: o.cover,
            platforms: e,
            results: [],
            startTime: Date.now()
        }, n = [s, ...r].slice(0, Ma);
        await chrome.storage.local.set({syncHistory: n}), ie.info("History created:", c, s.title)
    } catch (t) {
        ie.error("Failed to create history:", t)
    }
}

async function La(c, o, e, t) {
    try {
        const s = (await chrome.storage.local.get("syncHistory")).syncHistory || [], n = e.map(a => {
            var u;
            return {
                ...a,
                platformName: a.platformName || ((u = t.find(l => l.id === a.platform)) == null ? void 0 : u.name) || a.platform
            }
        }), i = s.map(a => a.id === c ? {...a, status: o, results: n, endTime: Date.now()} : a);
        await chrome.storage.local.set({syncHistory: i}), ie.info("History updated:", c, o)
    } catch (r) {
        ie.error("Failed to update history:", r)
    }
}

async function Ha(c, o, e = {}, t = {}) {
    var P;
    const {skipHistory: r = !1, source: s = "mcp"} = e, {onResult: n, onImageProgress: i, onDetailProgress: a} = t,
        u = Oe(), l = new Map(u.map(b => [b.id, b.name])), h = ja(), d = {
            title: c.title,
            content: c.content || c.html || "",
            html: c.html || c.content || "",
            markdown: c.markdown || "",
            cover: c.cover
        }, f = (await chrome.storage.local.get("cmsAccounts")).cmsAccounts || [], p = new Set(f.map(b => b.id)),
        w = o.filter(b => !p.has(b)), _ = o.filter(b => p.has(b)), y = {
            syncId: h,
            status: "syncing",
            article: {title: d.title, cover: d.cover, content: d.content, html: d.html, markdown: d.markdown},
            selectedPlatforms: o,
            results: [],
            startTime: Date.now()
        };
    await me(y), r || await Fa(h, d, o);
    const T = (P = c.source) == null ? void 0 : P.platform, O = w.filter(b => b !== T);
    let A = d;
    if (O.length > 0) {
        const b = at(O), I = d.html || d.content || "";
        if (I) {
            const U = await qa(I, O, b);
            U ? (A = {
                ...d,
                platformContents: U
            }, ie.debug("Preprocessed for platforms:", Object.keys(U))) : ie.warn("DOM preprocessing unavailable — please ensure at least one web page is open in Chrome")
        }
    }
    const S = [];
    w.length > 0 && await ot(w, A, {
        onResult: b => {
            const I = {...b, platformName: l.get(b.platform) || b.platform};
            y.results.push(I), S.push(I), me(y).catch(() => {
            }), n == null || n(I)
        }, onImageProgress: (b, I, U) => {
            i == null || i(b, I, U)
        }, onDetailProgress: b => {
            a == null || a(b)
        }
    }, s);
    for (const b of _) {
        const I = f.find(U => U.id === b);
        if (!I) {
            const U = {platform: b, platformName: l.get(b) || b, success: !1, error: "CMS 账户不存在"};
            S.push(U), y.results.push(U), me(y).catch(() => {
            }), n == null || n(U), a == null || a({
                platform: b,
                platformName: U.platformName || b,
                stage: "failed",
                error: U.error
            });
            continue
        }
        a == null || a({platform: b, platformName: I.name, stage: "starting"});
        try {
            const F = (await chrome.storage.local.get(`cms_pwd_${b}`))[`cms_pwd_${b}`];
            if (!F) {
                const E = {platform: b, platformName: I.name, success: !1, error: "密码未找到"};
                S.push(E), y.results.push(E), me(y).catch(() => {
                }), n == null || n(E), a == null || a({
                    platform: b,
                    platformName: I.name,
                    stage: "failed",
                    error: "密码未找到"
                });
                continue
            }
            a == null || a({platform: b, platformName: I.name, stage: "saving"});
            const J = {url: I.url, username: I.username, password: F};
            let $;
            switch (I.type) {
                case"wordpress":
                    $ = await Ge(J, d, {draftOnly: !0});
                    break;
                case"typecho":
                    $ = await Ke(J, d, {draftOnly: !0});
                    break;
                case"metaweblog":
                    $ = await Je(J, d, {draftOnly: !0});
                    break;
                default:
                    $ = {success: !1, error: "不支持的 CMS 类型"}
            }
            const x = {
                platform: b,
                platformName: I.name,
                success: $.success,
                postUrl: $.postUrl,
                draftOnly: !0,
                message: $.message,
                error: $.error
            };
            S.push(x), y.results.push(x), me(y).catch(() => {
            }), n == null || n(x), a == null || a({
                platform: b,
                platformName: I.name,
                stage: $.success ? "completed" : "failed",
                error: $.error
            })
        } catch (U) {
            const F = {platform: b, platformName: I.name, success: !1, error: U.message};
            S.push(F), y.results.push(F), me(y).catch(() => {
            }), n == null || n(F), a == null || a({
                platform: b,
                platformName: I.name,
                stage: "failed",
                error: U.message
            })
        }
    }
    const v = S.filter(b => b.success).length, C = S.length - v,
        k = S.length === 0 && o.length > 0 || C === S.length && S.length > 0 ? "failed" : "completed";
    return y.status = k, await me(y), r || await La(h, k, S, u), {results: S, syncId: h}
}

async function qa(c, o, e) {
    var r;
    const t = {type: "PREPROCESS_FOR_PLATFORMS", payload: {rawHtml: c, platforms: o, configs: e}};
    try {
        const s = [], [n] = await chrome.tabs.query({active: !0, currentWindow: !0});
        n != null && n.id && ((r = n.url) != null && r.match(/^https?:\/\//)) && s.push(n.id);
        const i = await chrome.tabs.query({url: ["http://*/*", "https://*/*"]});
        for (const a of i) a.id && !s.includes(a.id) && s.push(a.id);
        for (const a of s) try {
            const u = await chrome.tabs.sendMessage(a, t);
            if (u != null && u.platformContents) return u.platformContents
        } catch {
            continue
        }
    } catch (s) {
        ie.debug("Tab preprocess failed:", s)
    }
    return await za(t)
}

const Ba = chrome.runtime.getURL("src/preprocessor/index.html");

async function za(c) {
    var t, r;
    let o, e;
    try {
        const s = await chrome.windows.create({
            url: Ba,
            type: "popup",
            width: 1,
            height: 1,
            left: 0,
            top: 0,
            focused: !1
        });
        if (o = s.id, e = (r = (t = s.tabs) == null ? void 0 : t[0]) == null ? void 0 : r.id, !e) return null;
        await new Promise((i, a) => {
            const u = setTimeout(() => {
                chrome.tabs.onUpdated.removeListener(l), a(new Error("Tab load timeout"))
            }, 5e3), l = (h, d) => {
                h === e && d.status === "complete" && (chrome.tabs.onUpdated.removeListener(l), clearTimeout(u), i())
            };
            chrome.tabs.onUpdated.addListener(l)
        });
        const n = await chrome.tabs.sendMessage(e, c);
        return n != null && n.platformContents ? (ie.debug("Preprocessed via temporary window"), n.platformContents) : null
    } catch (s) {
        return ie.debug("Temporary window preprocess failed:", s), null
    } finally {
        o && chrome.windows.remove(o).catch(() => {
        })
    }
}

const H = Te("MCPClient"), $t = "ws://localhost:9527";

class Wa {
    constructor() {
        g(this, "ws", null);
        g(this, "reconnectTimer", null);
        g(this, "serverUrl", $t);
        g(this, "token", null);
        g(this, "reconnectAttempts", 0);
        g(this, "lastConnectedAt", 0);
        g(this, "activelyWatched", !1);
        g(this, "WARM_WINDOW", 5 * 60 * 1e3);
        g(this, "warmMinInterval", 500);
        g(this, "warmMaxInterval", 5e3);
        g(this, "coldMinInterval", 1e4);
        g(this, "coldMaxInterval", 6e4);
        g(this, "maxReconnectAttempts", 1 / 0);
        g(this, "pendingUploads", new Map);
        g(this, "UPLOAD_TIMEOUT", 6e4);
        g(this, "MAX_CONCURRENT_UPLOADS", 5)
    }

    setToken(o) {
        this.token = o, H.debug("Token set")
    }

    clearToken() {
        this.token = null
    }

    setServerUrl(o) {
        this.serverUrl = o || $t, H.debug(`Server URL set to ${this.serverUrl}`)
    }

    getServerUrl() {
        return this.serverUrl
    }

    connect() {
        if (this.ws) {
            if (this.ws.readyState === WebSocket.OPEN) {
                H.debug("Already connected");
                return
            }
            this.ws.onclose = null, this.ws.onerror = null, this.ws.onmessage = null, this.ws.onopen = null, this.ws.readyState === WebSocket.CONNECTING && this.ws.close(), this.ws = null
        }
        H.debug(`Connecting to ${this.serverUrl} (attempt ${this.reconnectAttempts + 1})`);
        try {
            this.ws = new WebSocket(this.serverUrl), this.ws.onopen = () => {
                H.debug("Connected to MCP Server"), this.reconnectAttempts = 0, this.lastConnectedAt = Date.now(), this.reconnectTimer && (clearTimeout(this.reconnectTimer), this.reconnectTimer = null)
            }, this.ws.onmessage = o => {
                this.handleMessage(o.data)
            }, this.ws.onclose = o => {
                H.debug(`Disconnected (code: ${o.code}), scheduling reconnect...`), this.ws = null, this.scheduleReconnect()
            }, this.ws.onerror = () => {
                H.debug("Connection error")
            }
        } catch (o) {
            H.error("Connection failed:", o), this.ws = null, this.scheduleReconnect()
        }
    }

    disconnect() {
        this.reconnectAttempts = this.maxReconnectAttempts, this.reconnectTimer && (clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.ws && (this.ws.onclose = null, this.ws.close(), this.ws = null)
    }

    isConnected() {
        var o;
        return ((o = this.ws) == null ? void 0 : o.readyState) === WebSocket.OPEN
    }

    scheduleReconnect() {
        if (!this.reconnectTimer) {
            if (this.reconnectAttempts >= this.maxReconnectAttempts) {
                H.debug("Max reconnect attempts reached, stopping");
                return
            }
            chrome.storage.local.get("mcpEnabled").then(o => {
                if (!o.mcpEnabled) {
                    H.debug("MCP disabled, skip reconnect");
                    return
                }
                this._doScheduleReconnect()
            }).catch(() => this._doScheduleReconnect())
        }
    }

    _doScheduleReconnect() {
        const o = Date.now() - this.lastConnectedAt,
            e = this.activelyWatched || this.lastConnectedAt > 0 && o < this.WARM_WINDOW;
        let t;
        e ? t = Math.min(this.warmMinInterval * Math.pow(2, this.reconnectAttempts), this.warmMaxInterval) : t = Math.min(this.coldMinInterval * Math.pow(2, this.reconnectAttempts), this.coldMaxInterval), H.debug(`Reconnecting in ${t / 1e3}s (${e ? "warm" : "cold"})...`), this.reconnectAttempts++, this.reconnectTimer = setTimeout(() => {
            this.reconnectTimer = null, this.connect()
        }, t)
    }

    setActivelyWatched(o) {
        this.activelyWatched = o, o && !this.isConnected() && (this.reconnectAttempts = 0, this.reconnectTimer && (clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.connect())
    }

    resetReconnect() {
        this.reconnectAttempts = 0, this.isConnected() || this.connect()
    }

    async handleMessage(o) {
        var e;
        try {
            const t = JSON.parse(o);
            H.debug("Received:", t.method);
            let r, s;
            if (!this.token) s = {
                code: 401,
                message: "MCP token not configured"
            }; else if (t.token !== this.token) H.warn("Invalid token received"), s = {
                code: 403,
                message: "Invalid or missing token"
            }; else try {
                r = await this.handleMethod(t.method, t.params)
            } catch (i) {
                s = {code: -1, message: i.message}
            }
            const n = {id: t.id, result: r, error: s};
            (e = this.ws) == null || e.send(JSON.stringify(n))
        } catch (t) {
            H.error("Failed to handle message:", t)
        }
    }

    async handleMethod(o, e) {
        var t, r;
        switch (o) {
            case"listPlatforms": {
                const s = (e == null ? void 0 : e.forceRefresh) ?? !1;
                return await Ne(s)
            }
            case"checkAuth": {
                const s = e == null ? void 0 : e.platform;
                if (!s) throw new Error("Missing platform parameter");
                return await Jt(s)
            }
            case"syncArticle": {
                const s = e == null ? void 0 : e.platforms, n = e == null ? void 0 : e.article;
                if (!(s != null && s.length)) throw new Error("Missing platforms parameter");
                if (!(n != null && n.title)) throw new Error("Missing article title");
                if (!(n != null && n.markdown) && !(n != null && n.content)) throw new Error("Missing article content (markdown or content required)");
                let i = n.content || "";
                const a = n.markdown || "";
                if (a) try {
                    i = nr(a)
                } catch (d) {
                    H.error("Markdown conversion failed:", d), i = a.replace(/\n/g, "<br>")
                }
                const u = {title: n.title, content: i, html: i, markdown: a, cover: n.cover}, {
                    results: l,
                    syncId: h
                } = await Ha(u, s, {source: "mcp"});
                return {results: l, syncId: h}
            }
            case"extractArticle": {
                const s = await chrome.tabs.query({active: !0, currentWindow: !0});
                if (!((t = s[0]) != null && t.id)) throw new Error("No active tab found");
                return ((r = (await chrome.scripting.executeScript({
                    target: {tabId: s[0].id}, func: () => {
                        const i = window.extractArticle;
                        return typeof i == "function" ? i() : null
                    }
                }))[0]) == null ? void 0 : r.result) || null
            }
            case"uploadImage": {
                const s = e == null ? void 0 : e.imageData, n = e == null ? void 0 : e.mimeType,
                    i = (e == null ? void 0 : e.platform) || "weibo";
                if (!s) throw new Error("Missing imageData parameter");
                if (!n) throw new Error("Missing mimeType parameter");
                return await this.performImageUpload(s, n, i)
            }
            case"uploadImage:start": {
                const s = e == null ? void 0 : e.uploadId, n = e == null ? void 0 : e.totalChunks,
                    i = e == null ? void 0 : e.mimeType, a = (e == null ? void 0 : e.platform) || "weibo";
                if (!s) throw new Error("Missing uploadId");
                if (!n) throw new Error("Missing totalChunks");
                if (!i) throw new Error("Missing mimeType");
                if (this.pendingUploads.size >= this.MAX_CONCURRENT_UPLOADS) throw new Error(`Too many concurrent uploads (max: ${this.MAX_CONCURRENT_UPLOADS})`);
                const u = setTimeout(() => {
                    this.cleanupUpload(s, "timeout")
                }, this.UPLOAD_TIMEOUT);
                return this.pendingUploads.set(s, {
                    chunks: new Map,
                    totalChunks: n,
                    mimeType: i,
                    platform: a,
                    createdAt: Date.now(),
                    timeoutId: u
                }), H.debug(`Chunked upload started: ${s}, ${n} chunks`), {success: !0}
            }
            case"uploadImage:chunk": {
                const s = e == null ? void 0 : e.uploadId, n = e == null ? void 0 : e.chunkIndex,
                    i = e == null ? void 0 : e.data;
                if (!s) throw new Error("Missing uploadId");
                if (n === void 0) throw new Error("Missing chunkIndex");
                if (!i) throw new Error("Missing chunk data");
                const a = this.pendingUploads.get(s);
                if (!a) throw new Error(`Upload session not found: ${s}`);
                return a.chunks.set(n, i), H.debug(`Chunk received: ${s} [${n + 1}/${a.totalChunks}]`), {
                    success: !0,
                    received: a.chunks.size,
                    total: a.totalChunks
                }
            }
            case"uploadImage:complete": {
                const s = e == null ? void 0 : e.uploadId;
                if (!s) throw new Error("Missing uploadId");
                const n = this.pendingUploads.get(s);
                if (!n) throw new Error(`Upload session not found: ${s}`);
                if (n.chunks.size !== n.totalChunks) throw new Error(`Incomplete upload: received ${n.chunks.size}/${n.totalChunks} chunks`);
                const i = [];
                for (let u = 0; u < n.totalChunks; u++) {
                    const l = n.chunks.get(u);
                    if (!l) throw new Error(`Missing chunk ${u}`);
                    i.push(l)
                }
                const a = i.join("");
                return H.debug(`Chunks merged: ${s}, total size: ${a.length}`), this.cleanupUpload(s, "completed"), await this.performImageUpload(a, n.mimeType, n.platform)
            }
            default:
                throw new Error(`Unknown method: ${o}`)
        }
    }

    async performImageUpload(o, e, t) {
        const r = await je(t);
        if (!r) throw new Error(`Platform not found: ${t}`);
        if (typeof r.uploadImage != "function") throw new Error(`Platform ${t} does not support image upload`);
        const s = atob(o), n = new Uint8Array(s.length);
        for (let u = 0; u < s.length; u++) n[u] = s.charCodeAt(u);
        const i = new Blob([n], {type: e});
        return {url: await r.uploadImage(i), platform: t}
    }

    cleanupUpload(o, e) {
        const t = this.pendingUploads.get(o);
        t && (clearTimeout(t.timeoutId), t.chunks.clear(), this.pendingUploads.delete(o), H.debug(`Upload cleanup: ${o} (${e})`))
    }
}

const G = new Wa;

function Vt() {
    G.resetReconnect()
}

function Xa() {
    G.disconnect()
}

function Ga() {
    return {connected: G.isConnected(), serverUrl: G.getServerUrl()}
}

const j = Te("Background");

function Pt() {
    return `sync_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
}

const Z = "activeSyncState", Ye = {success: "#22C55E", error: "#EF4444", partial: "#F59E0B", update: "#8B5CF6"};

async function Ja(c) {
    if (!c) {
        await chrome.action.setBadgeText({text: ""});
        return
    }
    if (c.status === "syncing") await chrome.action.setBadgeText({text: ""}); else if (c.status === "completed") {
        const o = c.results.filter(r => r.success).length;
        c.selectedPlatforms.length - o === 0 ? (await chrome.action.setBadgeText({text: "✓"}), await chrome.action.setBadgeBackgroundColor({color: Ye.success})) : o === 0 ? (await chrome.action.setBadgeText({text: "!"}), await chrome.action.setBadgeBackgroundColor({color: Ye.error})) : (await chrome.action.setBadgeText({text: `${o}`}), await chrome.action.setBadgeBackgroundColor({color: Ye.partial})), setTimeout(async () => {
            var s;
            ((s = (await chrome.storage.local.get(Z))[Z]) == null ? void 0 : s.status) === "completed" && await chrome.action.setBadgeText({text: ""})
        }, 5e3)
    }
}

async function K(c) {
    await chrome.storage.local.set({[Z]: c}), await Ja(c)
}

async function Ka() {
    await chrome.storage.local.remove(Z), await chrome.action.setBadgeText({text: ""})
}

chrome.runtime.onMessage.addListener((c, o, e) => (Ya(c, o).then(e).catch(t => e({error: t.message})), !0));

async function Ya(c, o) {
    var e, t, r, s, n, i;
    switch (c.type) {
        case"GET_PLATFORMS":
            return await Me(), {platforms: Oe()};
        case"CHECK_ALL_AUTH": {
            const a = ((e = c.payload) == null ? void 0 : e.forceRefresh) ?? !1,
                l = (await Ne(a)).map(p => ({...p, sourceType: "dsl"})),
                m = ((await chrome.storage.local.get("cmsAccounts")).cmsAccounts || []).filter(p => p.isConnected).map(p => ({
                    id: p.id,
                    name: p.name,
                    icon: ut(p.type),
                    homepage: p.url,
                    isAuthenticated: !0,
                    username: p.username,
                    sourceType: "cms",
                    cmsType: p.type
                })), f = [...l, ...m];
            return chrome.storage.local.set({platformListCache: f}).catch(() => {
            }), {platforms: f}
        }
        case"CHECK_AUTH": {
            const {platformId: a} = c.payload;
            return {auth: await Jt(a)}
        }
        case"SYNC_ARTICLE": {
            const {
                    article: a,
                    platforms: u,
                    allSelectedPlatforms: l,
                    skipHistory: h,
                    source: d = "popup",
                    syncId: m
                } = c.payload, f = Oe(), p = m || Pt(), w = (t = o == null ? void 0 : o.tab) == null ? void 0 : t.id,
                _ = x => {
                    const E = {...x, syncId: p};
                    chrome.runtime.sendMessage(E).catch(() => {
                    }), w && chrome.tabs.sendMessage(w, E).catch(() => {
                    })
                }, y = await mt(u), O = (await chrome.storage.local.get("cmsAccounts")).cmsAccounts || [],
                A = new Set(O.map(x => x.id)), S = u.filter(x => !A.has(x)), v = u.filter(x => A.has(x)),
                C = (r = a.source) == null ? void 0 : r.platform, k = S.filter(x => x !== C);
            let P = a;
            if (!a.platformContents && k.length > 0) try {
                const x = at(k), E = a.html || a.content || "";
                if (E) {
                    let q = w;
                    if (!q) {
                        const [M] = await chrome.tabs.query({active: !0, currentWindow: !0});
                        q = M == null ? void 0 : M.id
                    }
                    if (q) {
                        const M = await chrome.tabs.sendMessage(q, {
                            type: "PREPROCESS_FOR_PLATFORMS",
                            payload: {rawHtml: E, platforms: k, configs: x}
                        });
                        M != null && M.platformContents && (P = {
                            ...a,
                            platformContents: M.platformContents
                        }, j.debug("Preprocessed for platforms:", Object.keys(M.platformContents)))
                    }
                }
            } catch (x) {
                j.debug("Preprocess failed, using original content:", x)
            }
            const b = {
                syncId: p,
                status: "syncing",
                article: {title: a.title, cover: a.cover, content: a.content, html: a.html, markdown: a.markdown},
                selectedPlatforms: l || u,
                results: [],
                startTime: Date.now()
            };
            await K(b), h || await Ot(p, a, u);
            const I = [];
            S.length > 0 && await ot(S, P, {
                onResult: x => {
                    var q;
                    const E = {
                        ...x,
                        platformName: ((q = f.find(M => M.id === x.platform)) == null ? void 0 : q.name) || x.platform
                    };
                    b.results.push(E), I.push(E), K(b).catch(() => {
                    }), _({type: "SYNC_PROGRESS", payload: {result: E}})
                }, onImageProgress: (x, E, q) => {
                    _({type: "IMAGE_PROGRESS", payload: {platform: x, current: E, total: q}})
                }, onDetailProgress: x => {
                    _({type: "SYNC_DETAIL_PROGRESS", payload: x})
                }
            }, d);
            for (const x of v) {
                const E = O.find(q => q.id === x);
                if (E) {
                    _({type: "SYNC_DETAIL_PROGRESS", payload: {platform: x, platformName: E.name, stage: "starting"}});
                    try {
                        const M = (await chrome.storage.local.get(`cms_pwd_${x}`))[`cms_pwd_${x}`];
                        if (!M) {
                            const Le = {platform: x, platformName: E.name, success: !1, error: "密码未找到"};
                            I.push(Le), b.results.push(Le), K(b).catch(() => {
                            }), _({type: "SYNC_PROGRESS", payload: {result: Le}}), _({
                                type: "SYNC_DETAIL_PROGRESS",
                                payload: {
                                    platform: x,
                                    platformName: E.name,
                                    stage: "failed",
                                    result: Le,
                                    error: "密码未找到"
                                }
                            });
                            continue
                        }
                        _({
                            type: "SYNC_DETAIL_PROGRESS",
                            payload: {platform: x, platformName: E.name, stage: "saving"}
                        });
                        const re = {url: E.url, username: E.username, password: M};
                        let se;
                        switch (E.type) {
                            case"wordpress":
                                se = await Ge(re, a, {draftOnly: !0});
                                break;
                            case"typecho":
                                se = await Ke(re, a, {draftOnly: !0});
                                break;
                            case"metaweblog":
                                se = await Je(re, a, {draftOnly: !0});
                                break;
                            default:
                                se = {success: !1, error: "不支持的 CMS 类型"}
                        }
                        const Fe = {
                            platform: x,
                            platformName: E.name,
                            success: se.success,
                            postUrl: se.postUrl,
                            draftOnly: !0,
                            error: se.error
                        };
                        I.push(Fe), b.results.push(Fe), K(b).catch(() => {
                        }), _({type: "SYNC_PROGRESS", payload: {result: Fe}}), _({
                            type: "SYNC_DETAIL_PROGRESS",
                            payload: {
                                platform: x,
                                platformName: E.name,
                                stage: se.success ? "completed" : "failed",
                                result: Fe,
                                error: se.error
                            }
                        })
                    } catch (q) {
                        const M = {platform: x, platformName: E.name, success: !1, error: q.message};
                        I.push(M), b.results.push(M), K(b).catch(() => {
                        }), _({type: "SYNC_PROGRESS", payload: {result: M}}), _({
                            type: "SYNC_DETAIL_PROGRESS",
                            payload: {platform: x, platformName: E.name, stage: "failed", result: M, error: q.message}
                        })
                    }
                }
            }
            const U = I.filter(x => x.success).length, J = I.length - U === I.length ? "failed" : "completed";
            b.status = J, await K(b), h || await Dt(p, J, I, f);
            const $ = I.filter(x => x.success).map(x => x.platform);
            return $.length > 0 && et($).catch(() => {
            }), {results: I, rateLimitWarning: y, syncId: p}
        }
        case"OPEN_SYNC_PAGE": {
            const a = c.path || "", u = chrome.runtime.getURL("src/popup/index.html") + (a ? `#${a}` : ""), l = 396,
                h = 560, d = await chrome.windows.getCurrent(),
                m = d.left !== void 0 && d.width !== void 0 ? Math.round(d.left + (d.width - l) / 2) : void 0,
                f = d.top !== void 0 && d.height !== void 0 ? Math.round(d.top + (d.height - h) / 2) : void 0;
            return await chrome.windows.create({
                url: u,
                type: "popup",
                width: l,
                height: h,
                left: m,
                top: f,
                focused: !0
            }), {success: !0}
        }
        case"TEST_CMS_CONNECTION": {
            const {type: a, url: u, username: l, password: h} = c.payload, d = {url: u, username: l, password: h};
            try {
                let m;
                switch (a) {
                    case"wordpress":
                        m = await ma(d);
                        break;
                    case"typecho":
                        m = await Da(d);
                        break;
                    case"metaweblog":
                        m = await Aa(d);
                        break;
                    default:
                        return {success: !1, error: "不支持的 CMS 类型"}
                }
                return ft("test", a, m.success).catch(() => {
                }), m
            } catch (m) {
                return ft().catch(() => {
                }), {success: !1, error: m.message}
            }
        }
        case"SYNC_TO_CMS": {
            const {accountId: a, article: u} = c.payload;
            try {
                const l = await chrome.storage.local.get(["cmsAccounts", `cms_pwd_${a}`]),
                    d = (l.cmsAccounts || []).find(y => y.id === a);
                if (!d) return {success: !1, error: "账户不存在"};
                const m = l[`cms_pwd_${a}`];
                if (!m) return {success: !1, error: "密码未找到，请重新添加账户"};
                const f = {url: d.url, username: d.username, password: m};
                let p;
                switch (d.type) {
                    case"wordpress":
                        p = await Ge(f, u, {draftOnly: !0});
                        break;
                    case"typecho":
                        p = await Ke(f, u, {draftOnly: !0});
                        break;
                    case"metaweblog":
                        p = await Je(f, u, {draftOnly: !0});
                        break;
                    default:
                        return {success: !1, error: "不支持的 CMS 类型"}
                }
                mr("popup", d.type, p.success).catch(() => {
                }), p.success ? De("cms_user").catch(() => {
                }) : p.error && gr("cms_sync_error", {cms_type: d.type, error_type: jt(p.error)}).catch(() => {
                });
                const _ = (await chrome.storage.local.get(Z))[Z];
                if (_) {
                    const y = {
                        platform: a,
                        platformName: d.name,
                        success: p.success,
                        postUrl: p.postUrl,
                        draftOnly: !0,
                        error: p.error
                    };
                    _.results.push(y), await K(_)
                }
                return p.success && et([a]).catch(() => {
                }), {
                    platform: d.name,
                    success: p.success,
                    postUrl: p.postUrl,
                    postId: p.postId,
                    error: p.error,
                    draftOnly: !0,
                    timestamp: Date.now()
                }
            } catch (l) {
                const d = (await chrome.storage.local.get(Z))[Z];
                if (d) {
                    const m = {platform: a, platformName: a, success: !1, error: l.message};
                    d.results.push(m), await K(d)
                }
                return {success: !1, error: l.message}
            }
        }
        case"MCP_ENABLE": {
            const a = await chrome.storage.local.get(["mcpToken", "mcpServerUrl"]),
                u = a.mcpToken || crypto.randomUUID();
            return await chrome.storage.local.set({
                mcpEnabled: !0,
                mcpToken: u
            }), G.setToken(u), a.mcpServerUrl && G.setServerUrl(a.mcpServerUrl), Vt(), j.info(" MCP enabled"), gt().catch(() => {
            }), De("mcp_user").catch(() => {
            }), {success: !0, token: u}
        }
        case"MCP_DISABLE":
            return await chrome.storage.local.set({mcpEnabled: !1}), G.clearToken(), Xa(), j.info(" MCP disabled"), gt().catch(() => {
            }), {success: !0};
        case"MCP_SET_SERVER_URL": {
            const a = c.payload.url;
            return await chrome.storage.local.set({mcpServerUrl: a || ""}), G.setServerUrl(a), G.isConnected() && G.disconnect(), G.resetReconnect(), {success: !0}
        }
        case"MCP_WATCH_START":
            return G.setActivelyWatched(!0), {success: !0};
        case"MCP_WATCH_STOP":
            return G.setActivelyWatched(!1), {success: !0};
        case"MCP_STATUS": {
            const a = await chrome.storage.local.get(["mcpEnabled", "mcpToken", "mcpServerUrl"]), u = Ga();
            return {
                enabled: a.mcpEnabled ?? !1,
                connected: u.connected,
                token: a.mcpToken,
                serverUrl: a.mcpServerUrl || ""
            }
        }
        case"TRACK_ARTICLE_EXTRACT": {
            const {source: a, success: u, hasTitle: l, hasContent: h, hasCover: d, contentLength: m} = c.payload;
            return pr().catch(() => {
            }), {success: !0}
        }
        case"GET_SYNC_STATE":
            return {syncState: (await chrome.storage.local.get(Z))[Z] || null};
        case"CLEAR_SYNC_STATE":
            return await Ka(), {success: !0};
        case"UPDATE_SYNC_STATUS": {
            const {status: a} = c.payload, l = (await chrome.storage.local.get(Z))[Z];
            return l && (l.status = a, await K(l)), {success: !0}
        }
        case"CANCEL_SYNC": {
            const a = da();
            return j.info("Sync cancelled:", a), {success: a}
        }
        case"START_SYNC_FROM_EDITOR": {
            const {article: a, platforms: u, syncId: l} = c,
                h = (s = o == null ? void 0 : o.tab) == null ? void 0 : s.id, d = Oe();
            if (!h) return {error: "No tab ID found"};
            const m = l || Pt(), f = b => {
                    chrome.tabs.sendMessage(h, {...b, syncId: m}).catch(() => {
                    })
                }, p = await mt(u), _ = (await chrome.storage.local.get("cmsAccounts")).cmsAccounts || [],
                y = new Set(_.map(b => b.id)), T = u.filter(b => !y.has(b)), O = u.filter(b => y.has(b)), A = {
                    syncId: m,
                    status: "syncing",
                    article: {title: a.title, cover: a.cover, content: a.content, html: a.html},
                    selectedPlatforms: u,
                    results: [],
                    startTime: Date.now()
                };
            await K(A), await Ot(m, a, u);
            const S = [];
            T.length > 0 && await ot(T, a, {
                onResult: b => {
                    var U;
                    const I = {
                        ...b,
                        platformName: ((U = d.find(F => F.id === b.platform)) == null ? void 0 : U.name) || b.platform
                    };
                    A.results.push(I), S.push(I), K(A).catch(() => {
                    }), f({type: "SYNC_PROGRESS", result: I})
                }, onImageProgress: (b, I, U) => {
                    f({type: "IMAGE_PROGRESS", platform: b, current: I, total: U})
                }, onDetailProgress: b => {
                    f({type: "SYNC_DETAIL_PROGRESS", ...b})
                }
            }, "editor");
            for (const b of O) {
                const I = _.find(U => U.id === b);
                if (I) {
                    f({type: "SYNC_DETAIL_PROGRESS", platform: b, platformName: I.name, stage: "starting"});
                    try {
                        const F = (await chrome.storage.local.get(`cms_pwd_${b}`))[`cms_pwd_${b}`];
                        if (!F) {
                            const E = {platform: b, platformName: I.name, success: !1, error: "密码未找到"};
                            S.push(E), A.results.push(E), K(A).catch(() => {
                            }), f({type: "SYNC_PROGRESS", result: E}), f({
                                type: "SYNC_DETAIL_PROGRESS",
                                platform: b,
                                platformName: I.name,
                                stage: "failed",
                                result: E,
                                error: "密码未找到"
                            });
                            continue
                        }
                        f({type: "SYNC_DETAIL_PROGRESS", platform: b, platformName: I.name, stage: "saving"});
                        const J = {url: I.url, username: I.username, password: F};
                        let $;
                        switch (I.type) {
                            case"wordpress":
                                $ = await Ge(J, a, {draftOnly: !0});
                                break;
                            case"typecho":
                                $ = await Ke(J, a, {draftOnly: !0});
                                break;
                            case"metaweblog":
                                $ = await Je(J, a, {draftOnly: !0});
                                break;
                            default:
                                $ = {success: !1, error: "不支持的 CMS 类型"}
                        }
                        const x = {
                            platform: b,
                            platformName: I.name,
                            success: $.success,
                            postUrl: $.postUrl,
                            draftOnly: !0,
                            error: $.error
                        };
                        S.push(x), A.results.push(x), K(A).catch(() => {
                        }), f({type: "SYNC_PROGRESS", result: x}), f({
                            type: "SYNC_DETAIL_PROGRESS",
                            platform: b,
                            platformName: I.name,
                            stage: $.success ? "completed" : "failed",
                            result: x,
                            error: $.error
                        })
                    } catch (U) {
                        const F = {platform: b, platformName: I.name, success: !1, error: U.message};
                        S.push(F), A.results.push(F), K(A).catch(() => {
                        }), f({type: "SYNC_PROGRESS", result: F}), f({
                            type: "SYNC_DETAIL_PROGRESS",
                            platform: b,
                            platformName: I.name,
                            stage: "failed",
                            result: F,
                            error: U.message
                        })
                    }
                }
            }
            const v = S.filter(b => b.success).length, k = S.length - v === S.length ? "failed" : "completed";
            A.status = k, await K(A), f({type: "SYNC_COMPLETE", rateLimitWarning: p}), await Dt(m, k, S, d);
            const P = S.filter(b => b.success).map(b => b.platform);
            return P.length > 0 && et(P).catch(() => {
            }), {results: S, rateLimitWarning: p, syncId: m}
        }
        case"UPLOAD_IMAGE": {
            const {src: a, platform: u = "weibo"} = c.payload;
            try {
                const l = await je(u);
                if (!l) return {error: `Platform not found: ${u}`};
                if (typeof l.uploadImage != "function") return {error: `Platform ${u} does not support image upload`};
                let h;
                if (a.startsWith("data:")) {
                    const m = a.match(/^data:([^;]+);base64,(.+)$/);
                    if (!m) return {error: "Invalid data URI format"};
                    const f = m[1], p = m[2], w = atob(p), _ = new Uint8Array(w.length);
                    for (let y = 0; y < w.length; y++) _[y] = w.charCodeAt(y);
                    h = new Blob([_], {type: f})
                } else h = await (await fetch(a)).blob();
                return {result: {url: await l.uploadImage(h), platform: u}}
            } catch (l) {
                return j.error("Upload image failed:", l), {error: l.message}
            }
        }
        case"MAGIC_CALL": {
            const {methodName: a, data: u} = c.payload;
            try {
                const l = ((n = u.account) == null ? void 0 : n.type) || u.platform || "weibo", h = await je(l);
                return h ? typeof h[a] != "function" ? {error: `Method ${a} not found on platform ${l}`} : {result: await h[a](u)} : {error: `Platform not found: ${l}`}
            } catch (l) {
                return j.error(`Magic call ${a} failed:`, l), {error: l.message}
            }
        }
        case"CLEAR_UPDATE_BADGE":
            return await chrome.action.setBadgeText({text: ""}), j.info("Update badge cleared"), {success: !0};
        case"GET_PREPROCESS_CONFIGS":
            return await Me(), {configs: at(c.platforms)};
        case"TRIGGER_OPEN_EDITOR": {
            const a = (i = o == null ? void 0 : o.tab) == null ? void 0 : i.id;
            if (!a) return {success: !1};
            const l = (await Ne(!1)).map(f => ({...f, sourceType: "dsl"})),
                m = ((await chrome.storage.local.get("cmsAccounts")).cmsAccounts || []).filter(f => f.isConnected).map(f => ({
                    id: f.id,
                    name: f.name,
                    icon: ut(f.type),
                    homepage: f.url,
                    isAuthenticated: !0,
                    username: f.username,
                    sourceType: "cms",
                    cmsType: f.type
                }));
            return chrome.tabs.sendMessage(a, {
                type: "OPEN_EDITOR",
                platforms: [...l, ...m],
                selectedPlatforms: []
            }), {success: !0}
        }
        default:
            return {error: "Unknown message type"}
    }
}

function Va() {
    chrome.contextMenus.create({
        id: "wechatsync-open-editor",
        title: "同步助手 - 提取并编辑文章",
        contexts: ["page", "selection"]
    })
}

function ut(c) {
    switch (c) {
        case"wordpress":
            return "https://s.w.org/style/images/about/WordPress-logotype-simplified.png";
        case"typecho":
            return chrome.runtime.getURL("assets/typecho.ico");
        case"metaweblog":
            return "https://www.cnblogs.com/favicon.ico";
        default:
            return chrome.runtime.getURL("assets/icon.png")
    }
}

chrome.contextMenus.onClicked.addListener(async (c, o) => {
    if (c.menuItemId === "wechatsync-open-editor" && (o != null && o.id)) try {
        const t = (await Ne(!1)).map(a => ({...a, sourceType: "dsl"})),
            n = ((await chrome.storage.local.get("cmsAccounts")).cmsAccounts || []).filter(a => a.isConnected).map(a => ({
                id: a.id,
                name: a.name,
                icon: ut(a.type),
                homepage: a.url,
                isAuthenticated: !0,
                username: a.username,
                sourceType: "cms",
                cmsType: a.type
            })), i = [...t, ...n];
        chrome.tabs.sendMessage(o.id, {type: "OPEN_EDITOR", platforms: i, selectedPlatforms: []})
    } catch (e) {
        j.error(" Failed to open editor from context menu:", e)
    }
});
chrome.runtime.onInstalled.addListener(async c => {
    if (j.info(" Installed:", c.reason, c.previousVersion), Va(), await Me(), fr(c.reason, c.previousVersion).catch(() => {
    }), Ft().catch(() => {
    }), c.reason === "install" && wr().catch(() => {
    }), c.reason === "update") {
        const o = c.previousVersion || "0.0.0", e = chrome.runtime.getManifest().version;

    }
});

async function Qa() {
    const c = await chrome.storage.local.get(["mcpEnabled", "mcpToken", "mcpServerUrl"]);
    if (c.mcpEnabled) {
        if (c.mcpToken) G.setToken(c.mcpToken), j.info(" Starting MCP client with existing token..."); else {
            const o = crypto.randomUUID();
            await chrome.storage.local.set({mcpToken: o}), G.setToken(o), j.info(" Starting MCP client with new token...")
        }
        c.mcpServerUrl && G.setServerUrl(c.mcpServerUrl), Vt()
    }
}

Qa();

async function Qt() {
    j.info(" Pre-checking platform auth...");
    try {
        await Ne(!1), j.info(" Pre-check completed")
    } catch (c) {
        j.error(" Pre-check failed:", c)
    }
}

chrome.runtime.onStartup.addListener(() => {
    j.info(" Browser started, pre-checking auth..."), Qt()
});
Qt();
chrome.alarms.create("daily_growth_metrics", {periodInMinutes: 24 * 60});
chrome.alarms.create("remote_config_fetch", {periodInMinutes: 6 * 60});
chrome.alarms.onAlarm.addListener(c => {
    c.name === "daily_growth_metrics" && Nt().catch(() => {
    }), c.name === "remote_config_fetch" && Ft().catch(() => {
    })
});
Nt().catch(() => {
});
_r().catch(() => {
});
yr().then(async c => {
    c.hasUpdate && c.info && (await br(c.info.version) || (await chrome.action.setBadgeText({text: "NEW"}), await chrome.action.setBadgeBackgroundColor({color: Ye.update}), j.info("Update badge shown for version:", c.info.version)))
}).catch(() => {
});

async function Za() {
    try {
        const c = await chrome.declarativeNetRequest.getDynamicRules();
        c.length > 0 && (j.info(`Clearing ${c.length} orphaned dynamic rules...`), await chrome.declarativeNetRequest.updateDynamicRules({removeRuleIds: c.map(o => o.id)}), j.info("Orphaned rules cleared"))
    } catch (c) {
        j.error("Failed to clear orphaned rules:", c)
    }
}

Za();
j.info("Service Worker started");
const en = 25;

async function Ot(c, o, e) {
    try {
        const r = (await chrome.storage.local.get("syncHistory")).syncHistory || [], s = {
            id: c,
            status: "syncing",
            title: o.title || "未知文章",
            cover: o.cover,
            platforms: e,
            results: [],
            startTime: Date.now()
        }, n = [s, ...r].slice(0, en);
        await chrome.storage.local.set({syncHistory: n}), j.info("History created:", c, s.title)
    } catch (t) {
        j.error("Failed to create history:", t)
    }
}

async function Dt(c, o, e, t) {
    try {
        const s = (await chrome.storage.local.get("syncHistory")).syncHistory || [], n = e.map(a => {
            var u;
            return {
                ...a,
                platformName: a.platformName || ((u = t.find(l => l.id === a.platform)) == null ? void 0 : u.name) || a.platform
            }
        }), i = s.map(a => a.id === c ? {...a, status: o, results: n, endTime: Date.now()} : a);
        await chrome.storage.local.set({syncHistory: i}), j.info("History updated:", c, o)
    } catch (r) {
        j.error("Failed to update history:", r)
    }
}
