! function(e, t) { "object" == typeof exports && "undefined" != typeof module ? t(exports) : "function" == typeof define && define .amd ? define(["exports"], t) : t((e = "undefined" != typeof globalThis ? globalThis : e || self).Artalk = {}) }(this, (function(e) { "use strict"; var t, n, i, s, r = Object.defineProperty, o = Object.defineProperties, a = Object.getOwnPropertyDescriptors, l = Object.getOwnPropertySymbols, c = Object.prototype.hasOwnProperty, d = Object.prototype.propertyIsEnumerable, h = (e, t, n) => t in e ? r(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n, u = (e, t) => { for (var n in t || (t = {})) c.call(t, n) && h(e, n, t[n]); if (l) for (var n of l(t)) d.call(t, n) && h(e, n, t[n]); return e }, p = (e, t) => o(e, a(t)), g = (e, t, n) => (h(e, "symbol" != typeof t ? t + "" : t, n), n), m = (e, t, n) => { if (t.has(e)) throw TypeError("Cannot add the same private member more than once"); t instanceof WeakSet ? t.add(e) : t.set(e, n) }, f = (e, t, n) => (((e, t, n) => { if (!t.has(e)) throw TypeError("Cannot " + n) })(e, t, "access private method"), n), k = (e, t, n) => new Promise(((i, s) => { var r = e => { try { a(n.next(e)) } catch (t) { s(t) } }, o = e => { try { a(n.throw(e)) } catch (t) { s(t) } }, a = e => e.done ? i(e.value) : Promise.resolve(e.value).then(r, o); a((n = n.apply(e, t)).next()) })); function y(e = "") { const t = document.createElement("div"); return t.innerHTML = e.trim(), t.firstElementChild || t } function v(e) { return parseFloat(getComputedStyle(e, null).height.replace("px", "")) } function $(e) { const t = document.createElement("div"); t.innerText = e; return t.innerHTML } function b(e) { const t = RegExp(`[?&]${e}=([^&]*)`).exec(window.location.search); return t && decodeURIComponent(t[1].replace(/\+/g, " ")) } function w(e, t) { const n = e => { const t = e.getBoundingClientRect(), n = window.pageXOffset || document.documentElement.scrollLeft, i = window.pageYOffset || document.documentElement.scrollTop; return { top: t.top + i, left: t.left + n } }, i = n(e); if (!t) return i; const s = n(t); return { top: i.top - s.top, left: i.left - s.left } } function x(e, t) { let n = e.toString(); for (; n.length < t;) n = `0${n}`; return n } function C(e, t = (e => e)) { try { const n = e.getTime(), i = (new Date).getTime() - n, s = Math.floor(i / 864e5); if (0 === s) { const e = i % 864e5, n = Math.floor(e / 36e5); if (0 === n) { const n = e % 36e5, i = Math.floor(n / 6e4); if (0 === i) { const e = n % 6e4, i = Math.round(e / 1e3); return i < 10 ? t("now") : `${i} ${t("seconds")}` } return `${i} ${t("minutes")}` } return `${n} ${t("hours")}` } return s < 0 ? t("now") : s < 8 ? `${s} ${t("days")}` : function(e) { const t = x(e.getDate(), 2), n = x(e.getMonth() + 1, 2); return `${x(e.getFullYear(),2)}-${n}-${t}` }(e) } catch (n) { return console.error(n), " - " } } function S() { return k(this, null, (function*() { const e = navigator.userAgent; if (!navigator.userAgentData || !navigator.userAgentData.getHighEntropyValues) return e; const t = navigator.userAgentData; let n = null; try { n = yield t.getHighEntropyValues(["platformVersion"]) } catch (s) { return console.error(s), e } const i = Number(n.platformVersion.split(".")[0]); return "Windows" === t.platform && i >= 13 ? e.replace(/Windows NT 10.0/, "Windows NT 11.0") : "macOS" === t.platform && i >= 11 ? e.replace( /(Mac OS X \d+_\d+_\d+|Mac OS X)/, `Mac OS X ${n.platformVersion.replace(/\./g,"_")}`) : e })) } function E(e) { let t; try { t = new URL(e) } catch (n) { return !1 } return "http:" === t.protocol || "https:" === t.protocol } function T(e) { return t = e.base, n = e.path, `${t.replace(/\/$/,"")}/${n.replace(/^\//,"")}`; var t, n } var _ = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {}; function L(e) { return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e }! function() { function e(e, t) { if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") } function t(e, t) { for (var n = 0; n < t.length; n++) { var i = t[n]; i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i) } } function n(e, n, i) { return n && t(e.prototype, n), i && t(e, i), Object.defineProperty(e, "prototype", { writable: !1 }), e } function i(e, t) { if ("function" != typeof t && null !== t) throw new TypeError( "Super expression must either be null or a function"); e.prototype = Object.create(t && t.prototype, { constructor: { value: e, writable: !0, configurable: !0 } }), Object.defineProperty(e, "prototype", { writable: !1 }), t && r(e, t) } function s(e) { return (s = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(e) { return e.__proto__ || Object.getPrototypeOf(e) })(e) } function r(e, t) { return (r = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(e, t) { return e.__proto__ = t, e })(e, t) } function o() { if ("undefined" == typeof Reflect || !Reflect.construct) return !1; if (Reflect.construct.sham) return !1; if ("function" == typeof Proxy) return !0; try { return Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], (function() {}))), !0 } catch (e) { return !1 } } function a(e) { if (void 0 === e) throw new ReferenceError( "this hasn't been initialised - super() hasn't been called"); return e } function l(e, t) { if (t && ("object" == typeof t || "function" == typeof t)) return t; if (void 0 !== t) throw new TypeError("Derived constructors may only return object or undefined"); return a(e) } function c(e) { var t = o(); return function() { var n, i = s(e); if (t) { var r = s(this).constructor; n = Reflect.construct(i, arguments, r) } else n = i.apply(this, arguments); return l(this, n) } } function d(e, t) { for (; !Object.prototype.hasOwnProperty.call(e, t) && null !== (e = s(e));); return e } function h() { return h = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function(e, t, n) { var i = d(e, t); if (i) { var s = Object.getOwnPropertyDescriptor(i, t); return s.get ? s.get.call(arguments.length < 3 ? e : n) : s.value } }, h.apply(this, arguments) } var u = function() { function t() { e(this, t), Object.defineProperty(this, "listeners", { value: {}, writable: !0, configurable: !0 }) } return n(t, [{ key: "addEventListener", value: function(e, t, n) { e in this.listeners || (this.listeners[e] = []), this.listeners[e] .push({ callback: t, options: n }) } }, { key: "removeEventListener", value: function(e, t) { if (e in this.listeners) for (var n = this.listeners[e], i = 0, s = n.length; i < s; i++) if (n[i].callback === t) return void n.splice(i, 1) } }, { key: "dispatchEvent", value: function(e) { if (e.type in this.listeners) { for (var t = this.listeners[e.type].slice(), n = 0, i = t .length; n < i; n++) { var s = t[n]; try { s.callback.call(this, e) } catch (r) { Promise.resolve().then((function() { throw r })) } s.options && s.options.once && this.removeEventListener(e.type, s.callback) } return !e.defaultPrevented } } }]), t }(), p = function(t) { i(o, t); var r = c(o); function o() { var t; return e(this, o), (t = r.call(this)).listeners || u.call(a(t)), Object.defineProperty(a(t), "aborted", { value: !1, writable: !0, configurable: !0 }), Object.defineProperty(a(t), "onabort", { value: null, writable: !0, configurable: !0 }), Object.defineProperty(a(t), "reason", { value: void 0, writable: !0, configurable: !0 }), t } return n(o, [{ key: "toString", value: function() { return "[object AbortSignal]" } }, { key: "dispatchEvent", value: function(e) { "abort" === e.type && (this.aborted = !0, "function" == typeof this .onabort && this.onabort.call(this, e)), h(s(o.prototype), "dispatchEvent", this).call(this, e) } }]), o }(u), g = function() { function t() { e(this, t), Object.defineProperty(this, "signal", { value: new p, writable: !0, configurable: !0 }) } return n(t, [{ key: "abort", value: function(e) { var t; try { t = new Event("abort") } catch (i) { "undefined" != typeof document ? document.createEvent ? (t = document.createEvent("Event")).initEvent("abort", !1, !1) : (t = document.createEventObject()).type = "abort" : t = { type: "abort", bubbles: !1, cancelable: !1 } } var n = e; if (void 0 === n) if ("undefined" == typeof document)(n = new Error( "This operation was aborted")).name = "AbortError"; else try { n = new DOMException("signal is aborted without reason") } catch (s) { (n = new Error("This operation was aborted")).name = "AbortError" } this.signal.reason = n, this.signal.dispatchEvent(t) } }, { key: "toString", value: function() { return "[object AbortController]" } }]), t }(); function m(e) { return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL ? (console.log( "__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"), ! 0) : "function" == typeof e.Request && !e.Request.prototype.hasOwnProperty("signal") || !e .AbortController } function f(e) { "function" == typeof e && (e = { fetch: e }); var t = e, n = t.fetch, i = t.Request, s = void 0 === i ? n.Request : i, r = t.AbortController, o = t.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL, a = void 0 !== o && o; if (!m({ fetch: n, Request: s, AbortController: r, __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: a })) return { fetch: n, Request: l }; var l = s; (l && !l.prototype.hasOwnProperty("signal") || a) && ((l = function(e, t) { var n; t && t.signal && (n = t.signal, delete t.signal); var i = new s(e, t); return n && Object.defineProperty(i, "signal", { writable: !1, enumerable: !1, configurable: !0, value: n }), i }).prototype = s.prototype); var c = n; return { fetch: function(e, t) { var n = l && l.prototype.isPrototypeOf(e) ? e.signal : t ? t.signal : void 0; if (n) { var i; try { i = new DOMException("Aborted", "AbortError") } catch (r) { (i = new Error("Aborted")).name = "AbortError" } if (n.aborted) return Promise.reject(i); var s = new Promise((function(e, t) { n.addEventListener("abort", (function() { return t(i) }), { once: !0 }) })); return t && t.signal && delete t.signal, Promise.race([s, c(e, t)]) } return c(e, t) }, Request: l } } "undefined" != typeof Symbol && Symbol.toStringTag && (g.prototype[Symbol.toStringTag] = "AbortController", p.prototype[Symbol.toStringTag] = "AbortSignal"), function(e) { if (m(e)) if (e.fetch) { var t = f(e), n = t.fetch, i = t.Request; e.fetch = n, e.Request = i, Object.defineProperty(e, "AbortController", { writable: !0, enumerable: !1, configurable: !0, value: g }), Object.defineProperty(e, "AbortSignal", { writable: !0, enumerable: !1, configurable: !0, value: p }) } else console.warn("fetch() is not available, cannot install abortcontroller-polyfill") }("undefined" != typeof self ? self : _) }(); const A = { placeholder: "Leave a comment", noComment: "No Comment", send: "Send", save: "Save", nick: "Nickname", email: "Email", link: "Website", emoticon: "Emoji", preview: "Preview", image: "Image", uploadFail: "Upload Failed", commentFail: "Failed to comment", restoredMsg: "Content has been restored", onlyAdminCanReply: "Only admin can reply", uploadLoginMsg: "Please fill in your name and email to upload", counter: "{count} Comments", sortLatest: "Latest", sortOldest: "Oldest", sortBest: "Best", sortAuthor: "Author", openComment: "Open Comment", closeComment: "Close Comment", listLoadFailMsg: "Failed to load comments", listRetry: "Click to retry", loadMore: "Load More", admin: "Admin", reply: "Reply", voteUp: "Up", voteDown: "Down", voteFail: "Vote Failed", readMore: "Read More", actionConfirm: "Confirm", collapse: "Collapse", collapsed: "Collapsed", collapsedMsg: "This comment has been collapsed", expand: "Expand", approved: "Approved", pending: "Pending", pendingMsg: "Pending, visible only to commenter.", edit: "Edit", editCancel: "Cancel Edit", delete: "Delete", deleteConfirm: "Confirm", pin: "Pin", unpin: "Unpin", seconds: "seconds ago", minutes: "minutes ago", hours: "hours ago", days: "days ago", now: "just now", adminCheck: "Enter admin password:", captchaCheck: "Enter the CAPTCHA to continue:", confirm: "Confirm", cancel: "Cancel", msgCenter: "Messages", ctrlCenter: "Admin", frontend: "Frontend", backend: "Backend", loading: "Loading", loadFail: "Load Failed", editing: "Editing", editFail: "Edit Failed", deleting: "Deleting", deleteFail: "Delete Failed", reqGot: "Request got", reqAborted: "Request timed out or terminated unexpectedly", updateMsg: "Please update Artalk {name} to get the full experience", currentVersion: "Current Version", ignore: "Ignore", open: "Open" }, O = "ArtalkI18n", P = { en: A, "en-US": A, "zh-CN": { placeholder: "键入内容...", noComment: "「此时无声胜有声」", send: "发送评论", save: "保存评论", nick: "昵称", email: "邮箱", link: "网址", emoticon: "表情", preview: "预览", image: "图片", uploadFail: "上传失败", commentFail: "评论失败", restoredMsg: "内容已自动恢复", onlyAdminCanReply: "仅管理员可评论", uploadLoginMsg: "填入你的名字邮箱才能上传哦", counter: "{count} 条评论", sortLatest: "最新", sortOldest: "最早", sortBest: "最热", sortAuthor: "作者", openComment: "打开评论", closeComment: "关闭评论", listLoadFailMsg: "无法获取评论列表数据", listRetry: "点击重新获取", loadMore: "加载更多", admin: "管理员", reply: "回复", voteUp: "赞同", voteDown: "反对", voteFail: "投票失败", readMore: "阅读更多", actionConfirm: "确认操作", collapse: "折叠", collapsed: "已折叠", collapsedMsg: "该评论已被系统或管理员折叠", expand: "展开", approved: "已审", pending: "待审", pendingMsg: "审核中,仅本人可见。", edit: "编辑", editCancel: "取消编辑", delete: "删除", deleteConfirm: "确认删除", pin: "置顶", unpin: "取消置顶", seconds: "秒前", minutes: "分钟前", hours: "小时前", days: "天前", now: "刚刚", adminCheck: "键入密码来验证管理员身份:", captchaCheck: "键入验证码继续:", confirm: "确认", cancel: "取消", msgCenter: "通知中心", ctrlCenter: "控制中心", frontend: "前端", backend: "后端", loading: "加载中", loadFail: "加载失败", editing: "修改中", editFail: "修改失败", deleting: "删除中", deleteFail: "删除失败", reqGot: "请求响应", reqAborted: "请求超时或意外终止", updateMsg: "请更新 Artalk {name} 以获得完整体验", currentVersion: "当前版本", ignore: "忽略", open: "打开" } }; function R(e) { return e = e.replace(/^([a-zA-Z]+)(-[a-zA-Z]+)?$/, ((e, t, n) => t.toLowerCase() + (n || "") .toUpperCase())), P[e] ? P[e] : window[O] && window[O][e] ? window[O][e] : P.en } let M = "en", I = R(M); function U(e) { e !== M && (M = e, I = "string" == typeof e ? R(e) : e) } function D(e, t = {}) { let n = (null == I ? void 0 : I[e]) || e; return n = n.replace(/\{\s*(\w+?)\s*\}/g, ((e, n) => t[n] || "")), n } function B(e, t, n, i) { return k(this, null, (function*() { var s, r; if (e.apiToken) { const t = new Headers(n.headers); t.set("Authorization", `Bearer ${e.apiToken}`), n.headers = t } const o = yield function(e, t, n) { var i; const s = new AbortController; null == (i = n.signal) || i.addEventListener("abort", (() => s.abort())); let r = fetch(e, p(u({}, n), { signal: s.signal })); if (t > 0) { const e = setTimeout((() => s.abort()), t); r.finally((() => { clearTimeout(e) })) } return r = r.catch((e => { throw "AbortError" === (e || {}).name ? new Error(D( "reqAborted")) : e })), r }(t, i || e.timeout || 15e3, n), a = o.status, l = [401, 400].includes(a); if (!o.ok && !l) throw new Error(`${D("reqGot")} ${a}`); let c = yield o.json(); const d = (i, s) => { B(e, t, n).then((e => { i(e) })).catch((e => { s(e) })) }; if ((null == (s = c.data) ? void 0 : s.need_captcha) ? c = yield new Promise(((t, n) => { e.onNeedCheckCaptcha && e.onNeedCheckCaptcha({ data: { imgData: c.data.img_data, iframe: c.data.iframe }, recall: () => { d(t, n) }, reject: () => { n(c) } }) })): ((null == (r = c.data) ? void 0 : r.need_login) || l) && (c = yield new Promise(((t, n) => { e.onNeedCheckAdmin && e.onNeedCheckAdmin({ recall: () => { d(t, n) }, reject: () => { n(c) } }) }))), !c.success) throw c; return c })) } function q(e) { const t = new FormData; return Object.keys(e).forEach((n => t.append(n, String(e[n])))), t } class F { constructor(e) { this.options = e } POST(e, t) { return k(this, null, (function*() { return function(e, t, n) { return k(this, null, (function*() { const i = { method: "POST" }; return n = u({ site_name: e.siteName || "" }, n || {}), i.body = q(n), (yield B(e, t, i)) .data || {} })) }(this.options, this.options.baseURL + e, t) })) } Fetch(e, t, n) { return k(this, null, (function*() { return B(this.options, this.options.baseURL + e, t, n) })) } withUserInfo(e) { const t = this.options.userInfo; return (null == t ? void 0 : t.name) && (e.name = t.name), (null == t ? void 0 : t.email) && (e .email = t.email), e } } const z = { comment: class extends F { get(e, t, n, i) { const s = { page_key: this.options.pageKey, site_name: this.options.siteName, limit: t, offset: e }; return n && (s.flat_mode = n), this.withUserInfo(s), i && i(s), this.POST("/get", s) } add(e) { return k(this, null, (function*() { const t = { name: e.nick, email: e.email, link: e.link, content: e.content, rid: e.rid, page_key: e.page_key, ua: yield S() }; e.page_title && (t.page_title = e.page_title), e.site_name && (t .site_name = e.site_name); return (yield this.POST("/add", t)).comment })) } commentEdit(e) { return k(this, null, (function*() { const t = u({}, e); return (yield this.POST("/admin/comment-edit", t)).comment })) } commentDel(e, t) { const n = { id: String(e), site_name: t || "" }; return this.POST("/admin/comment-del", n) } vote(e, t) { return k(this, null, (function*() { const n = { target_id: e, type: t }; this.withUserInfo(n); return yield this.POST("/vote", n) })) } }, page: class extends F { pageGet(e, t, n) { return k(this, null, (function*() { const i = { site_name: e || "", offset: t || 0, limit: n || 15 }; return yield this.POST("/admin/page-get", i) })) } pageEdit(e) { return k(this, null, (function*() { const t = { id: e.id, key: e.key, title: e.title, admin_only: e.admin_only, site_name: e.site_name || this.options.siteName }; return (yield this.POST("/admin/page-edit", t)).page })) } pageDel(e, t) { const n = { key: String(e), site_name: t || "" }; return this.POST("/admin/page-del", n) } pageFetch(e, t, n) { return k(this, null, (function*() { const i = {}; e && (i.id = e), t && (i.site_name = t), n && (i.get_status = n); return yield this.POST("/admin/page-fetch", i) })) } pv() { return k(this, null, (function*() { const e = { page_key: this.options.pageKey || "", page_title: this.options.pageTitle || "" }; return (yield this.POST("/pv", e)).pv })) } stat(e, t, n) { return k(this, null, (function*() { const i = { type: e }; t && (i.page_keys = Array.isArray(t) ? t.join(",") : t), n && (i .limit = n); return yield this.POST("/stat", i) })) } }, site: class extends F { siteGet() { return k(this, null, (function*() { return (yield this.POST("/admin/site-get", {})).sites })) } siteAdd(e, t) { return k(this, null, (function*() { const n = { name: e, urls: t, site_name: "" }; return (yield this.POST("/admin/site-add", n)).site })) } siteEdit(e) { return k(this, null, (function*() { const t = { id: e.id, name: e.name || "", urls: e.urls || "" }; return (yield this.POST("/admin/site-edit", t)).site })) } siteDel(e, t = !1) { const n = { id: e, del_content: t }; return this.POST("/admin/site-del", n) } export () { return k(this, null, (function*() { var e; return (null == (e = (yield this.Fetch("/admin/export", { method: "POST" }, 0)).data) ? void 0 : e.data) || "" })) } }, user: class extends F { login(e, t, n) { return k(this, null, (function*() { const i = { name: e, email: t, password: n }; return yield this.POST("/login", i) })) } userGet(e, t) { const n = new AbortController, i = { name: e, email: t }; return { req: this.Fetch("/user-get", { method: "POST", body: q(i), signal: n.signal }).then((e => ({ user: e.data.user, is_login: e.data.is_login, unread: e.data.unread || [], unread_count: e.data.unread_count || 0 }))), abort: () => { n.abort() } } } loginStatus() { return k(this, null, (function*() { return (yield this.POST("/login-status", this.withUserInfo({}))) || { is_login: !1, is_admin: !1 } })) } logout() { return k(this, null, (function*() { return this.POST("/logout") })) } markRead(e, t, n = !1) { const i = { comment_id: e, notify_key: t }; return n && (delete i.comment_id, delete i.notify_key, i.read_all = !0, this .withUserInfo(i)), this.POST("/mark-read", i) } userList(e, t, n) { return k(this, null, (function*() { const i = { offset: e || 0, limit: t || 15 }; n && (i.type = n); return yield this.POST("/admin/user-get", i) })) } userAdd(e, t) { return k(this, null, (function*() { const n = { name: e.name || "", email: e.email || "", password: t || "", link: e.link || "", is_admin: e.is_admin || !1, site_names: e.site_names_raw || "", receive_email: e.receive_email || !0, badge_name: e.badge_name || "", badge_color: e.badge_color || "" }; return (yield this.POST("/admin/user-add", n)).user })) } userEdit(e, t) { return k(this, null, (function*() { const n = { id: e.id, name: e.name || "", email: e.email || "", password: t || "", link: e.link || "", is_admin: e.is_admin || !1, site_names: e.site_names_raw || "", receive_email: e.receive_email || !0, badge_name: e.badge_name || "", badge_color: e.badge_color || "" }; return (yield this.POST("/admin/user-edit", n)).user })) } userDel(e) { return this.POST("/admin/user-del", { id: String(e) }) } }, system: class extends F { conf() { return k(this, null, (function*() { const e = yield this.POST("/conf"); return { frontend_conf: e.frontend_conf, version: e.version } })) } getSettings() { return k(this, null, (function*() { return yield this.POST("/admin/setting-get") })) } saveSettings(e) { return k(this, null, (function*() { return yield this.POST("/admin/setting-save", { data: e }) })) } version() { return k(this, null, (function*() { const e = yield fetch(`${this.options.baseURL}/version`, { method: "POST" }); return yield e.json() })) } }, captcha: class extends F { captchaGet() { return k(this, null, (function*() { return (yield this.POST("/captcha/refresh")).img_data || "" })) } captchaCheck(e) { return k(this, null, (function*() { return (yield this.POST("/captcha/check", { value: e })).img_data || "" })) } captchaStatus() { return k(this, null, (function*() { return (yield this.POST("/captcha/status")) || { is_pass: !1 } })) } }, admin: class extends F { cacheFlushAll() { return this.POST("/admin/cache-flush", { flush_all: !0 }) } cacheWarmUp() { return this.POST("/admin/cache-warm", {}) } }, upload: class extends F { imgUpload(e) { return k(this, null, (function*() { const t = { page_key: this.options.pageKey }; this.withUserInfo(t); const n = q(t); n.set("file", e); const i = { method: "POST", body: n }; return (yield this.Fetch("/img-upload", i)).data || {} })) } } }; class W { constructor(e) { Object.entries(z).forEach((([t, n]) => { this[t] = new n(e) })) } } function j() { return { async: !1, baseUrl: null, breaks: !1, extensions: null, gfm: !0, headerIds: !1, headerPrefix: "", highlight: null, hooks: null, langPrefix: "language-", mangle: !1, pedantic: !1, renderer: null, sanitize: !1, sanitizer: null, silent: !1, smartypants: !1, tokenizer: null, walkTokens: null, xhtml: !1 } } let N = { async: !1, baseUrl: null, breaks: !1, extensions: null, gfm: !0, headerIds: !1, headerPrefix: "", highlight: null, hooks: null, langPrefix: "language-", mangle: !1, pedantic: !1, renderer: null, sanitize: !1, sanitizer: null, silent: !1, smartypants: !1, tokenizer: null, walkTokens: null, xhtml: !1 }; function H(e) { N = e } const Q = /[&<>"']/, V = new RegExp(Q.source, "g"), G = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, K = new RegExp(G.source, "g"), Z = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }, Y = e => Z[e]; function X(e, t) { if (t) { if (Q.test(e)) return e.replace(V, Y) } else if (G.test(e)) return e.replace(K, Y); return e } const J = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi; function ee(e) { return e.replace(J, ((e, t) => "colon" === (t = t.toLowerCase()) ? ":" : "#" === t.charAt(0) ? "x" === t .charAt(1) ? String.fromCharCode(parseInt(t.substring(2), 16)) : String.fromCharCode(+t .substring(1)) : "")) } const te = /(^|[^\[])\^/g; function ne(e, t) { e = "string" == typeof e ? e : e.source, t = t || ""; const n = { replace: (t, i) => (i = (i = "object" == typeof i && "source" in i ? i.source : i).replace(te, "$1"), e = e.replace(t, i), n), getRegex: () => new RegExp(e, t) }; return n } const ie = /[^\w:]/g, se = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; function re(e, t, n) { if (e) { let e; try { e = decodeURIComponent(ee(n)).replace(ie, "").toLowerCase() } catch (i) { return null } if (0 === e.indexOf("javascript:") || 0 === e.indexOf("vbscript:") || 0 === e.indexOf("data:")) return null } t && !se.test(n) && (n = function(e, t) { oe[" " + e] || (ae.test(e) ? oe[" " + e] = e + "/" : oe[" " + e] = ue(e, "/", !0)); e = oe[" " + e]; const n = -1 === e.indexOf(":"); return "//" === t.substring(0, 2) ? n ? t : e.replace(le, "$1") + t : "/" === t.charAt(0) ? n ? t : e.replace(ce, "$1") + t : e + t }(t, n)); try { n = encodeURI(n).replace(/%25/g, "%") } catch (i) { return null } return n } const oe = {}, ae = /^[^:]+:\/*[^/]*$/, le = /^([^:]+:)[\s\S]*$/, ce = /^([^:]+:\/*[^/]*)[\s\S]*$/; const de = { exec: () => null }; function he(e, t) { const n = e.replace(/\|/g, ((e, t, n) => { let i = !1, s = t; for (; --s >= 0 && "\\" === n[s];) i = !i; return i ? "|" : " |" })).split(/ \|/); let i = 0; if (n[0].trim() || n.shift(), n.length > 0 && !n[n.length - 1].trim() && n.pop(), t) if (n.length > t) n.splice(t); else for (; n.length < t;) n.push(""); for (; i < n.length; i++) n[i] = n[i].trim().replace(/\\\|/g, "|"); return n } function ue(e, t, n) { const i = e.length; if (0 === i) return ""; let s = 0; for (; s < i;) { const r = e.charAt(i - s - 1); if (r !== t || n) { if (r === t || !n) break; s++ } else s++ } return e.slice(0, i - s) } function pe(e, t, n, i) { const s = t.href, r = t.title ? X(t.title) : null, o = e[1].replace(/\\([\[\]])/g, "$1"); if ("!" !== e[0].charAt(0)) { i.state.inLink = !0; const e = { type: "link", raw: n, href: s, title: r, text: o, tokens: i.inlineTokens(o) }; return i.state.inLink = !1, e } return { type: "image", raw: n, href: s, title: r, text: X(o) } } class ge { constructor(e) { g(this, "options"), g(this, "rules"), g(this, "lexer"), this.options = e || N } space(e) { const t = this.rules.block.newline.exec(e); if (t && t[0].length > 0) return { type: "space", raw: t[0] } } code(e) { const t = this.rules.block.code.exec(e); if (t) { const e = t[0].replace(/^ {1,4}/gm, ""); return { type: "code", raw: t[0], codeBlockStyle: "indented", text: this.options.pedantic ? e : ue(e, "\n") } } } fences(e) { const t = this.rules.block.fences.exec(e); if (t) { const e = t[0], n = function(e, t) { const n = e.match(/^(\s+)(?:```)/); if (null === n) return t; const i = n[1]; return t.split("\n").map((e => { const t = e.match(/^\s+/); if (null === t) return e; const [n] = t; return n.length >= i.length ? e.slice(i.length) : e })).join("\n") }(e, t[3] || ""); return { type: "code", raw: e, lang: t[2] ? t[2].trim().replace(this.rules.inline._escapes, "$1") : t[2], text: n } } } heading(e) { const t = this.rules.block.heading.exec(e); if (t) { let e = t[2].trim(); if (/#$/.test(e)) { const t = ue(e, "#"); this.options.pedantic ? e = t.trim() : t && !/ $/.test(t) || (e = t.trim()) } return { type: "heading", raw: t[0], depth: t[1].length, text: e, tokens: this.lexer.inline(e) } } } hr(e) { const t = this.rules.block.hr.exec(e); if (t) return { type: "hr", raw: t[0] } } blockquote(e) { const t = this.rules.block.blockquote.exec(e); if (t) { const e = t[0].replace(/^ *>[ \t]?/gm, ""), n = this.lexer.state.top; this.lexer.state.top = !0; const i = this.lexer.blockTokens(e); return this.lexer.state.top = n, { type: "blockquote", raw: t[0], tokens: i, text: e } } } list(e) { let t = this.rules.block.list.exec(e); if (t) { let n = t[1].trim(); const i = n.length > 1, s = { type: "list", raw: "", ordered: i, start: i ? +n.slice(0, -1) : "", loose: !1, items: [] }; n = i ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = i ? n : "[*+-]"); const r = new RegExp(`^( {0,3}${n})((?:[\t ][^\\n]*)?(?:\\n|$))`); let o = "", a = "", l = !1; for (; e;) { let n = !1; if (!(t = r.exec(e))) break; if (this.rules.block.hr.test(e)) break; o = t[0], e = e.substring(o.length); let i = t[2].split("\n", 1)[0].replace(/^\t+/, (e => " ".repeat(3 * e.length))), c = e.split("\n", 1)[0], d = 0; this.options.pedantic ? (d = 2, a = i.trimLeft()) : (d = t[2].search(/[^ ]/), d = d > 4 ? 1 : d, a = i.slice(d), d += t[1].length); let h = !1; if (!i && /^ *$/.test(c) && (o += c + "\n", e = e.substring(c.length + 1), n = !0), ! n) { const t = new RegExp( `^ {0,${Math.min(3,d-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))` ), n = new RegExp( `^ {0,${Math.min(3,d-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)` ), s = new RegExp(`^ {0,${Math.min(3,d-1)}}(?:\`\`\`|~~~)`), r = new RegExp(`^ {0,${Math.min(3,d-1)}}#`); for (; e;) { const l = e.split("\n", 1)[0]; if (c = l, this.options.pedantic && (c = c.replace(/^ {1,4}(?=( {4})*[^ ])/g, " ")), s.test(c)) break; if (r.test(c)) break; if (t.test(c)) break; if (n.test(e)) break; if (c.search(/[^ ]/) >= d || !c.trim()) a += "\n" + c.slice(d); else { if (h) break; if (i.search(/[^ ]/) >= 4) break; if (s.test(i)) break; if (r.test(i)) break; if (n.test(i)) break; a += "\n" + c } h || c.trim() || (h = !0), o += l + "\n", e = e.substring(l.length + 1), i = c .slice(d) } } s.loose || (l ? s.loose = !0 : /\n *\n *$/.test(o) && (l = !0)); let u, p = null; this.options.gfm && (p = /^\[[ xX]\] /.exec(a), p && (u = "[ ] " !== p[0], a = a .replace(/^\[[ xX]\] +/, ""))), s.items.push({ type: "list_item", raw: o, task: !!p, checked: u, loose: !1, text: a, tokens: [] }), s.raw += o } s.items[s.items.length - 1].raw = o.trimRight(), s.items[s.items.length - 1].text = a .trimRight(), s.raw = s.raw.trimRight(); for (let e = 0; e < s.items.length; e++) if (this.lexer.state.top = !1, s.items[e].tokens = this.lexer.blockTokens(s.items[e] .text, []), !s.loose) { const t = s.items[e].tokens.filter((e => "space" === e.type)), n = t.length > 0 && t.some((e => /\n.*\n/.test(e.raw))); s.loose = n } if (s.loose) for (let e = 0; e < s.items.length; e++) s.items[e].loose = !0; return s } } html(e) { const t = this.rules.block.html.exec(e); if (t) { const e = { type: "html", block: !0, raw: t[0], pre: !this.options.sanitizer && ("pre" === t[1] || "script" === t[1] || "style" === t[1]), text: t[0] }; if (this.options.sanitize) { const n = this.options.sanitizer ? this.options.sanitizer(t[0]) : X(t[0]), i = e; i.type = "paragraph", i.text = n, i.tokens = this.lexer.inline(n) } return e } } def(e) { const t = this.rules.block.def.exec(e); if (t) { const e = t[1].toLowerCase().replace(/\s+/g, " "), n = t[2] ? t[2].replace(/^<(.*)>$/, "$1").replace(this.rules.inline._escapes, "$1") : "", i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline._escapes, "$1") : t[3]; return { type: "def", tag: e, raw: t[0], href: n, title: i } } } table(e) { const t = this.rules.block.table.exec(e); if (t) { const e = { type: "table", raw: t[0], header: he(t[1]).map((e => ({ text: e, tokens: [] }))), align: t[2].replace(/^ *|\| *$/g, "").split(/ *\| */), rows: t[3] && t[3].trim() ? t[3].replace(/\n[ \t]*$/, "").split("\n") : [] }; if (e.header.length === e.align.length) { let t, n, i, s, r = e.align.length; for (t = 0; t < r; t++) { const n = e.align[t]; n && (/^ *-+: *$/.test(n) ? e.align[t] = "right" : /^ *:-+: *$/.test(n) ? e.align[ t] = "center" : /^ *:-+ *$/.test(n) ? e.align[t] = "left" : e.align[t] = null) } for (r = e.rows.length, t = 0; t < r; t++) e.rows[t] = he(e.rows[t], e.header.length) .map((e => ({ text: e, tokens: [] }))); for (r = e.header.length, n = 0; n < r; n++) e.header[n].tokens = this.lexer.inline(e .header[n].text); for (r = e.rows.length, n = 0; n < r; n++) for (s = e.rows[n], i = 0; i < s.length; i++) s[i].tokens = this.lexer.inline(s[i] .text); return e } } } lheading(e) { const t = this.rules.block.lheading.exec(e); if (t) return { type: "heading", raw: t[0], depth: "=" === t[2].charAt(0) ? 1 : 2, text: t[1], tokens: this.lexer.inline(t[1]) } } paragraph(e) { const t = this.rules.block.paragraph.exec(e); if (t) { const e = "\n" === t[1].charAt(t[1].length - 1) ? t[1].slice(0, -1) : t[1]; return { type: "paragraph", raw: t[0], text: e, tokens: this.lexer.inline(e) } } } text(e) { const t = this.rules.block.text.exec(e); if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) } } escape(e) { const t = this.rules.inline.escape.exec(e); if (t) return { type: "escape", raw: t[0], text: X(t[1]) } } tag(e) { const t = this.rules.inline.tag.exec(e); if (t) return !this.lexer.state.inLink && /^/i.test(t[0]) && (this.lexer.state.inLink = !1), !this .lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(t[0]) ? this.lexer .state.inRawBlock = !0 : this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0]) && (this.lexer.state.inRawBlock = !1), { type: this.options.sanitize ? "text" : "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: !1, text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(t[ 0]) : X(t[0]) : t[0] } } link(e) { const t = this.rules.inline.link.exec(e); if (t) { const e = t[2].trim(); if (!this.options.pedantic && /^$/.test(e)) return; const t = ue(e.slice(0, -1), "\\"); if ((e.length - t.length) % 2 == 0) return } else { const e = function(e, t) { if (-1 === e.indexOf(t[1])) return -1; let n = 0; for (let i = 0; i < e.length; i++) if ("\\" === e[i]) i++; else if (e[i] === t[0]) n++; else if (e[i] === t[1] && (n--, n < 0)) return i; return -1 }(t[2], "()"); if (e > -1) { const n = (0 === t[0].indexOf("!") ? 5 : 4) + t[1].length + e; t[2] = t[2].substring(0, e), t[0] = t[0].substring(0, n).trim(), t[3] = "" } } let n = t[2], i = ""; if (this.options.pedantic) { const e = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(n); e && (n = e[1], i = e[3]) } else i = t[3] ? t[3].slice(1, -1) : ""; return n = n.trim(), /^$/.test(e) ? n.slice( 1) : n.slice(1, -1)), pe(t, { href: n ? n.replace(this.rules.inline._escapes, "$1") : n, title: i ? i.replace(this.rules.inline._escapes, "$1") : i }, t[0], this.lexer) } } reflink(e, t) { let n; if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) { let e = (n[2] || n[1]).replace(/\s+/g, " "); if (e = t[e.toLowerCase()], !e) { const e = n[0].charAt(0); return { type: "text", raw: e, text: e } } return pe(n, e, n[0], this.lexer) } } emStrong(e, t, n = "") { let i = this.rules.inline.emStrong.lDelim.exec(e); if (!i) return; if (i[3] && n.match(/[\p{L}\p{N}]/u)) return; if (!(i[1] || i[2] || "") || !n || this.rules.inline.punctuation.exec(n)) { const n = [...i[0]].length - 1; let s, r, o = n, a = 0; const l = "*" === i[0][0] ? this.rules.inline.emStrong.rDelimAst : this.rules.inline .emStrong.rDelimUnd; for (l.lastIndex = 0, t = t.slice(-1 * e.length + n); null != (i = l.exec(t));) { if (s = i[1] || i[2] || i[3] || i[4] || i[5] || i[6], !s) continue; if (r = [...s].length, i[3] || i[4]) { o += r; continue } if ((i[5] || i[6]) && n % 3 && !((n + r) % 3)) { a += r; continue } if (o -= r, o > 0) continue; r = Math.min(r, r + o + a); const t = [...e].slice(0, n + i.index + r + 1).join(""); if (Math.min(n, r) % 2) { const e = t.slice(1, -1); return { type: "em", raw: t, text: e, tokens: this.lexer.inlineTokens(e) } } const l = t.slice(2, -2); return { type: "strong", raw: t, text: l, tokens: this.lexer.inlineTokens(l) } } } } codespan(e) { const t = this.rules.inline.code.exec(e); if (t) { let e = t[2].replace(/\n/g, " "); const n = /[^ ]/.test(e), i = /^ /.test(e) && / $/.test(e); return n && i && (e = e.substring(1, e.length - 1)), e = X(e, !0), { type: "codespan", raw: t[0], text: e } } } br(e) { const t = this.rules.inline.br.exec(e); if (t) return { type: "br", raw: t[0] } } del(e) { const t = this.rules.inline.del.exec(e); if (t) return { type: "del", raw: t[0], text: t[2], tokens: this.lexer.inlineTokens(t[2]) } } autolink(e, t) { const n = this.rules.inline.autolink.exec(e); if (n) { let e, i; return "@" === n[2] ? (e = X(this.options.mangle ? t(n[1]) : n[1]), i = "mailto:" + e) : ( e = X(n[1]), i = e), { type: "link", raw: n[0], text: e, href: i, tokens: [{ type: "text", raw: e, text: e }] } } } url(e, t) { let n; if (n = this.rules.inline.url.exec(e)) { let e, i; if ("@" === n[2]) e = X(this.options.mangle ? t(n[0]) : n[0]), i = "mailto:" + e; else { let t; do { t = n[0], n[0] = this.rules.inline._backpedal.exec(n[0])[0] } while (t !== n[0]); e = X(n[0]), i = "www." === n[1] ? "http://" + n[0] : n[0] } return { type: "link", raw: n[0], text: e, href: i, tokens: [{ type: "text", raw: e, text: e }] } } } inlineText(e, t) { const n = this.rules.inline.text.exec(e); if (n) { let e; return e = this.lexer.state.inRawBlock ? this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(n[0]) : X(n[0]) : n[0] : X(this.options.smartypants ? t(n[0]) : n[0]), { type: "text", raw: n[0], text: e } } } } const me = { newline: /^(?: *(?:\n|$))+/, code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))", def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, table: de, lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/, _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, text: /^[^\n]+/, _label: /(?!\s*\])(?:\\.|[^\[\]\\])+/, _title: /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/ }; me.def = ne(me.def).replace("label", me._label).replace("title", me._title).getRegex(), me.bullet = /(?:[*+-]|\d{1,9}[.)])/, me.listItemStart = ne(/^( *)(bull) */).replace("bull", me.bullet).getRegex(), me.list = ne(me.list).replace(/bull/g, me.bullet).replace("hr", "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def", "\\n+(?=" + me.def .source + ")").getRegex(), me._tag = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul", me._comment = /|$)/, me.html = ne(me.html, "i").replace("comment", me._comment) .replace("tag", me._tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(), me .lheading = ne(me.lheading).replace(/bull/g, me.bullet).getRegex(), me.paragraph = ne(me._paragraph) .replace("hr", me.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("|table", "") .replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n") .replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", me._tag).getRegex(), me.blockquote = ne(me.blockquote).replace("paragraph", me.paragraph).getRegex(), me.normal = u({}, me), me.gfm = p(u({}, me.normal), { table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)" }), me.gfm.table = ne(me.gfm.table).replace("hr", me.hr).replace("heading", " {0,3}#{1,6} ").replace( "blockquote", " {0,3}>").replace("code", " {4}[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace( "html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", me._tag) .getRegex(), me.gfm.paragraph = ne(me._paragraph).replace("hr", me.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("table", me.gfm.table).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", me._tag).getRegex(), me.pedantic = p(u({}, me.normal), { html: ne( "^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))" ).replace("comment", me._comment).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b" ).getRegex(), def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: de, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: ne(me.normal._paragraph).replace("hr", me.hr).replace("heading", " *#{1,6} *[^\n]") .replace("lheading", me.lheading).replace("blockquote", " {0,3}>").replace("|fences", "") .replace("|list", "").replace("|html", "").getRegex() }); const fe = { escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, url: de, tag: "^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^", link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, reflink: /^!?\[(label)\]\[(ref)\]/, nolink: /^!?\[(ref)\](?:\[\])?/, reflinkSearch: "reflink|nolink(?!\\()", emStrong: { lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/, rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ }, code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, br: /^( {2,}|\\)\n(?!\s*$)/, del: de, text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\ .5 ? "x" + e.charCodeAt(n).toString(16) : e.charCodeAt(n).toString()) + ";" } return t } fe._punctuation = "\\p{P}$+<=>`^|~", fe.punctuation = ne(fe.punctuation, "u").replace(/punctuation/g, fe ._punctuation).getRegex(), fe.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g, fe .anyPunctuation = /\\[punct]/g, fe._escapes = /\\([punct])/g, fe._comment = ne(me._comment).replace( "(?:--\x3e|$)", "--\x3e").getRegex(), fe.emStrong.lDelim = ne(fe.emStrong.lDelim, "u").replace( /punct/g, fe._punctuation).getRegex(), fe.emStrong.rDelimAst = ne(fe.emStrong.rDelimAst, "gu") .replace(/punct/g, fe._punctuation).getRegex(), fe.emStrong.rDelimUnd = ne(fe.emStrong.rDelimUnd, "gu") .replace(/punct/g, fe._punctuation).getRegex(), fe.anyPunctuation = ne(fe.anyPunctuation, "gu").replace( /punct/g, fe._punctuation).getRegex(), fe._escapes = ne(fe._escapes, "gu").replace(/punct/g, fe ._punctuation).getRegex(), fe._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/, fe._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/, fe.autolink = ne(fe.autolink).replace("scheme", fe._scheme).replace("email", fe._email).getRegex(), fe ._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/, fe.tag = ne(fe.tag).replace("comment", fe._comment).replace("attribute", fe._attribute).getRegex(), fe._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/, fe._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/, fe._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/, fe.link = ne(fe.link).replace("label", fe ._label).replace("href", fe._href).replace("title", fe._title).getRegex(), fe.reflink = ne(fe .reflink).replace("label", fe._label).replace("ref", me._label).getRegex(), fe.nolink = ne(fe .nolink).replace("ref", me._label).getRegex(), fe.reflinkSearch = ne(fe.reflinkSearch, "g").replace( "reflink", fe.reflink).replace("nolink", fe.nolink).getRegex(), fe.normal = u({}, fe), fe.pedantic = p(u({}, fe.normal), { strong: { start: /^__|\*\*/, middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, endAst: /\*\*(?!\*)/g, endUnd: /__(?!_)/g }, em: { start: /^_|\*/, middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, endAst: /\*(?!\*)/g, endUnd: /_(?!_)/g }, link: ne(/^!?\[(label)\]\((.*?)\)/).replace("label", fe._label).getRegex(), reflink: ne(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", fe._label).getRegex() }), fe.gfm = p(u({}, fe.normal), { escape: ne(fe.escape).replace("])", "~|])").getRegex(), _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ t + " ".repeat(n.length))); e;) if (!(this.options.extensions && this.options.extensions.block && this.options.extensions .block.some((i => !!(n = i.call({ lexer: this }, e, t)) && (e = e.substring(n.raw.length), t.push(n), !0))))) if (n = this.tokenizer.space(e)) e = e.substring(n.raw.length), 1 === n.raw.length && t .length > 0 ? t[t.length - 1].raw += "\n" : t.push(n); else if (n = this.tokenizer.code(e)) e = e.substring(n.raw.length), i = t[t.length - 1], !i || "paragraph" !== i.type && "text" !== i.type ? t.push(n) : (i.raw += "\n" + n.raw, i .text += "\n" + n.text, this.inlineQueue[this.inlineQueue.length - 1].src = i.text); else if (n = this.tokenizer.fences(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.heading(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.hr(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.blockquote(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.list(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.html(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.def(e)) e = e.substring(n.raw.length), i = t[t.length - 1], !i || "paragraph" !== i.type && "text" !== i.type ? this.tokens.links[n.tag] || (this.tokens .links[n.tag] = { href: n.href, title: n.title }) : (i.raw += "\n" + n.raw, i.text += "\n" + n.raw, this.inlineQueue[this.inlineQueue .length - 1].src = i.text); else if (n = this.tokenizer.table(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.lheading(e)) e = e.substring(n.raw.length), t.push(n); else { if (s = e, this.options.extensions && this.options.extensions.startBlock) { let t = 1 / 0; const n = e.slice(1); let i; this.options.extensions.startBlock.forEach((e => { i = e.call({ lexer: this }, n), "number" == typeof i && i >= 0 && (t = Math.min(t, i)) })), t < 1 / 0 && t >= 0 && (s = e.substring(0, t + 1)) } if (this.state.top && (n = this.tokenizer.paragraph(s))) i = t[t.length - 1], r && "paragraph" === i.type ? (i.raw += "\n" + n.raw, i.text += "\n" + n.text, this .inlineQueue.pop(), this.inlineQueue[this.inlineQueue.length - 1].src = i.text) : t .push(n), r = s.length !== e.length, e = e.substring(n.raw.length); else if (n = this.tokenizer.text(e)) e = e.substring(n.raw.length), i = t[t.length - 1], i && "text" === i.type ? (i.raw += "\n" + n.raw, i.text += "\n" + n.text, this .inlineQueue.pop(), this.inlineQueue[this.inlineQueue.length - 1].src = i.text) : t .push(n); else if (e) { const t = "Infinite loop on byte: " + e.charCodeAt(0); if (this.options.silent) { console.error(t); break } throw new Error(t) } } return this.state.top = !0, t } inline(e, t = []) { return this.inlineQueue.push({ src: e, tokens: t }), t } inlineTokens(e, t = []) { let n, i, s, r, o, a, l = e; if (this.tokens.links) { const e = Object.keys(this.tokens.links); if (e.length > 0) for (; null != (r = this.tokenizer.rules.inline.reflinkSearch.exec(l));) e.includes(r[0] .slice(r[0].lastIndexOf("[") + 1, -1)) && (l = l.slice(0, r.index) + "[" + "a" .repeat(r[0].length - 2) + "]" + l.slice(this.tokenizer.rules.inline .reflinkSearch.lastIndex)) } for (; null != (r = this.tokenizer.rules.inline.blockSkip.exec(l));) l = l.slice(0, r.index) + "[" + "a".repeat(r[0].length - 2) + "]" + l.slice(this.tokenizer.rules.inline.blockSkip .lastIndex); for (; null != (r = this.tokenizer.rules.inline.anyPunctuation.exec(l));) l = l.slice(0, r .index) + "++" + l.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex); for (; e;) if (o || (a = ""), o = !1, !(this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some((i => !!(n = i.call({ lexer: this }, e, t)) && (e = e.substring(n.raw.length), t.push(n), !0))))) if (n = this.tokenizer.escape(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.tag(e)) e = e.substring(n.raw.length), i = t[t.length - 1], i && "text" === n.type && "text" === i.type ? (i.raw += n.raw, i.text += n.text) : t.push( n); else if (n = this.tokenizer.link(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.reflink(e, this.tokens.links)) e = e.substring(n.raw.length), i = t[ t.length - 1], i && "text" === n.type && "text" === i.type ? (i.raw += n.raw, i.text += n.text) : t.push(n); else if (n = this.tokenizer.emStrong(e, l, a)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.codespan(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.br(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.del(e)) e = e.substring(n.raw.length), t.push(n); else if (n = this.tokenizer.autolink(e, ye)) e = e.substring(n.raw.length), t.push(n); else if (this.state.inLink || !(n = this.tokenizer.url(e, ye))) { if (s = e, this.options.extensions && this.options.extensions.startInline) { let t = 1 / 0; const n = e.slice(1); let i; this.options.extensions.startInline.forEach((e => { i = e.call({ lexer: this }, n), "number" == typeof i && i >= 0 && (t = Math.min(t, i)) })), t < 1 / 0 && t >= 0 && (s = e.substring(0, t + 1)) } if (n = this.tokenizer.inlineText(s, ke)) e = e.substring(n.raw.length), "_" !== n.raw .slice(-1) && (a = n.raw.slice(-1)), o = !0, i = t[t.length - 1], i && "text" === i .type ? (i.raw += n.raw, i.text += n.text) : t.push(n); else if (e) { const t = "Infinite loop on byte: " + e.charCodeAt(0); if (this.options.silent) { console.error(t); break } throw new Error(t) } } else e = e.substring(n.raw.length), t.push(n); return t } } class $e { constructor(e) { g(this, "options"), this.options = e || N } code(e, t, n) { var i; const s = null == (i = (t || "").match(/^\S*/)) ? void 0 : i[0]; if (this.options.highlight) { const t = this.options.highlight(e, s); null != t && t !== e && (n = !0, e = t) } return e = e.replace(/\n$/, "") + "\n", s ? '
' + (n ? e : X(e, !0)) + "
\n" : "
" + (n ? e : X(e, !
				0)) + "
\n" } blockquote(e) { return `
\n${e}
\n` } html(e, t) { return e } heading(e, t, n, i) { if (this.options.headerIds) { return `${e}\n` } return `${e}\n` } hr() { return this.options.xhtml ? "
\n" : "
\n" } list(e, t, n) { const i = t ? "ol" : "ul"; return "<" + i + (t && 1 !== n ? ' start="' + n + '"' : "") + ">\n" + e + "\n" } listitem(e, t, n) { return `
  • ${e}
  • \n` } checkbox(e) { return " " } paragraph(e) { return `

    ${e}

    \n` } table(e, t) { return t && (t = `${t}`), "\n\n" + e + "\n" + t + "
    \n" } tablerow(e) { return `\n${e}\n` } tablecell(e, t) { const n = t.header ? "th" : "td"; return (t.align ? `<${n} align="${t.align}">` : `<${n}>`) + e + `\n` } strong(e) { return `${e}` } em(e) { return `${e}` } codespan(e) { return `${e}` } br() { return this.options.xhtml ? "
    " : "
    " } del(e) { return `${e}` } link(e, t, n) { const i = re(this.options.sanitize, this.options.baseUrl, e); if (null === i) return n; let s = '
    ", s } image(e, t, n) { const i = re(this.options.sanitize, this.options.baseUrl, e); if (null === i) return n; let s = `${n}" : ">", s } text(e) { return e } } class be { strong(e) { return e } em(e) { return e } codespan(e) { return e } del(e) { return e } html(e) { return e } text(e) { return e } link(e, t, n) { return "" + n } image(e, t, n) { return "" + n } br() { return "" } } class we { constructor() { g(this, "seen"), this.seen = {} } serialize(e) { return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi, "").replace( /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-") } getNextSafeSlug(e, t) { let n = e, i = 0; if (this.seen.hasOwnProperty(n)) { i = this.seen[e]; do { i++, n = e + "-" + i } while (this.seen.hasOwnProperty(n)) } return t || (this.seen[e] = i, this.seen[n] = 0), n } slug(e, t = {}) { const n = this.serialize(e); return this.getNextSafeSlug(n, t.dryrun) } } class xe { constructor(e) { g(this, "options"), g(this, "renderer"), g(this, "textRenderer"), g(this, "slugger"), this .options = e || N, this.options.renderer = this.options.renderer || new $e, this.renderer = this.options.renderer, this.renderer.options = this.options, this.textRenderer = new be, this.slugger = new we } static parse(e, t) { return new xe(t).parse(e) } static parseInline(e, t) { return new xe(t).parseInline(e) } parse(e, t = !0) { let n = ""; for (let i = 0; i < e.length; i++) { const s = e[i]; if (this.options.extensions && this.options.extensions.renderers && this.options.extensions .renderers[s.type]) { const e = s, t = this.options.extensions.renderers[e.type].call({ parser: this }, e); if (!1 !== t || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text" ].includes(e.type)) { n += t || ""; continue } } switch (s.type) { case "space": continue; case "hr": n += this.renderer.hr(); continue; case "heading": { const e = s; n += this.renderer.heading(this.parseInline(e.tokens), e.depth, ee(this.parseInline( e.tokens, this.textRenderer)), this.slugger); continue } case "code": { const e = s; n += this.renderer.code(e.text, e.lang, !!e.escaped); continue } case "table": { const e = s; let t = "", i = ""; for (let n = 0; n < e.header.length; n++) i += this.renderer.tablecell(this .parseInline(e.header[n].tokens), { header: !0, align: e.align[n] }); t += this.renderer.tablerow(i); let r = ""; for (let n = 0; n < e.rows.length; n++) { const t = e.rows[n]; i = ""; for (let n = 0; n < t.length; n++) i += this.renderer.tablecell(this .parseInline(t[n].tokens), { header: !1, align: e.align[n] }); r += this.renderer.tablerow(i) } n += this.renderer.table(t, r); continue } case "blockquote": { const e = s, t = this.parse(e.tokens); n += this.renderer.blockquote(t); continue } case "list": { const e = s, t = e.ordered, i = e.start, r = e.loose; let o = ""; for (let n = 0; n < e.items.length; n++) { const t = e.items[n], i = t.checked, s = t.task; let a = ""; if (t.task) { const e = this.renderer.checkbox(!!i); r ? t.tokens.length > 0 && "paragraph" === t.tokens[0].type ? (t.tokens[0] .text = e + " " + t.tokens[0].text, t.tokens[0].tokens && t.tokens[ 0].tokens.length > 0 && "text" === t.tokens[0].tokens[0].type && (t.tokens[0].tokens[0].text = e + " " + t.tokens[0].tokens[0].text) ) : t.tokens.unshift({ type: "text", text: e }) : a += e } a += this.parse(t.tokens, r), o += this.renderer.listitem(a, s, !!i) } n += this.renderer.list(o, t, i); continue } case "html": { const e = s; n += this.renderer.html(e.text, e.block); continue } case "paragraph": { const e = s; n += this.renderer.paragraph(this.parseInline(e.tokens)); continue } case "text": { let r = s, o = r.tokens ? this.parseInline(r.tokens) : r.text; for (; i + 1 < e.length && "text" === e[i + 1].type;) r = e[++i], o += "\n" + (r .tokens ? this.parseInline(r.tokens) : r.text); n += t ? this.renderer.paragraph(o) : o; continue } default: { const e = 'Token with "' + s.type + '" type was not found.'; if (this.options.silent) return console.error(e), ""; throw new Error(e) } } } return n } parseInline(e, t) { t = t || this.renderer; let n = ""; for (let i = 0; i < e.length; i++) { const s = e[i]; if (this.options.extensions && this.options.extensions.renderers && this.options.extensions .renderers[s.type]) { const e = this.options.extensions.renderers[s.type].call({ parser: this }, s); if (!1 !== e || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text" ].includes(s.type)) { n += e || ""; continue } } switch (s.type) { case "escape": { const e = s; n += t.text(e.text); break } case "html": { const e = s; n += t.html(e.text); break } case "link": { const e = s; n += t.link(e.href, e.title, this.parseInline(e.tokens, t)); break } case "image": { const e = s; n += t.image(e.href, e.title, e.text); break } case "strong": { const e = s; n += t.strong(this.parseInline(e.tokens, t)); break } case "em": { const e = s; n += t.em(this.parseInline(e.tokens, t)); break } case "codespan": { const e = s; n += t.codespan(e.text); break } case "br": n += t.br(); break; case "del": { const e = s; n += t.del(this.parseInline(e.tokens, t)); break } case "text": { const e = s; n += t.text(e.text); break } default: { const e = 'Token with "' + s.type + '" type was not found.'; if (this.options.silent) return console.error(e), ""; throw new Error(e) } } } return n } } class Ce { constructor(e) { g(this, "options"), this.options = e || N } preprocess(e) { return e } postprocess(e) { return e } } g(Ce, "passThroughHooks", new Set(["preprocess", "postprocess"])); t = new WeakSet, n = function(e, t) { return (n, r, o) => { "function" == typeof r && (o = r, r = null); const a = u({}, r), l = u(u({}, this.defaults), a); !0 === this.defaults.async && !1 === a.async && (l.silent || console.warn( "marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored." ), l.async = !0); const c = f(this, i, s).call(this, !!l.silent, !!l.async, o); if (null == n) return c(new Error("marked(): input parameter is undefined or null")); if ("string" != typeof n) return c(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected")); if (function(e, t) { e && !e.silent && (t && console.warn( "marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async" ), (e.sanitize || e.sanitizer) && console.warn( "marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options" ), (e.highlight || "language-" !== e.langPrefix) && console.warn( "marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight." ), e.mangle && console.warn( "marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`." ), e.baseUrl && console.warn( "marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url." ), e.smartypants && console.warn( "marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants." ), e.xhtml && console.warn( "marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml." ), (e.headerIds || e.headerPrefix) && console.warn( "marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`." )) }(l, o), l.hooks && (l.hooks.options = l), o) { const i = o, s = l.highlight; let r; try { l.hooks && (n = l.hooks.preprocess(n)), r = e(n, l) } catch (d) { return c(d) } const a = e => { let n; if (!e) try { l.walkTokens && this.walkTokens(r, l.walkTokens), n = t(r, l), l .hooks && (n = l.hooks.postprocess(n)) } catch (d) { e = d } return l.highlight = s, e ? c(e) : i(null, n) }; if (!s || s.length < 3) return a(); if (delete l.highlight, !r.length) return a(); let h = 0; return this.walkTokens(r, (e => { "code" === e.type && (h++, setTimeout((() => { s(e.text, e.lang, ((t, n) => { if (t) return a(t); null != n && n !== e.text && (e .text = n, e.escaped = !0), h--, 0 === h && a() })) }), 0)) })), void(0 === h && a()) } if (l.async) return Promise.resolve(l.hooks ? l.hooks.preprocess(n) : n).then((t => e(t, l))).then((e => l.walkTokens ? Promise.all(this.walkTokens(e, l.walkTokens)) .then((() => e)) : e)).then((e => t(e, l))).then((e => l.hooks ? l.hooks .postprocess(e) : e)).catch(c); try { l.hooks && (n = l.hooks.preprocess(n)); const i = e(n, l); l.walkTokens && this.walkTokens(i, l.walkTokens); let s = t(i, l); return l.hooks && (s = l.hooks.postprocess(s)), s } catch (d) { return c(d) } } }, i = new WeakSet, s = function(e, t, n) { return i => { if (i.message += "\nPlease report this to https://github.com/markedjs/marked.", e) { const e = "

    An error occurred:

    " + X(i.message + "", !0) + "
    "; return t ? Promise.resolve(e) : n ? void n(null, e) : e } if (t) return Promise.reject(i); if (!n) throw i; n(i) } }; const Se = new class { constructor(...e) { m(this, t), m(this, i), g(this, "defaults", { async: !1, baseUrl: null, breaks: !1, extensions: null, gfm: !0, headerIds: !1, headerPrefix: "", highlight: null, hooks: null, langPrefix: "language-", mangle: !1, pedantic: !1, renderer: null, sanitize: !1, sanitizer: null, silent: !1, smartypants: !1, tokenizer: null, walkTokens: null, xhtml: !1 }), g(this, "options", this.setOptions), g(this, "parse", f(this, t, n).call(this, ve .lex, xe.parse)), g(this, "parseInline", f(this, t, n).call(this, ve.lexInline, xe .parseInline)), g(this, "Parser", xe), g(this, "parser", xe.parse), g(this, "Renderer", $e), g(this, "TextRenderer", be), g(this, "Lexer", ve), g(this, "lexer", ve.lex), g(this, "Tokenizer", ge), g(this, "Slugger", we), g(this, "Hooks", Ce), this.use(...e) } walkTokens(e, t) { var n, i; let s = []; for (const r of e) switch (s = s.concat(t.call(this, r)), r.type) { case "table": { const e = r; for (const n of e.header) s = s.concat(this.walkTokens(n.tokens, t)); for (const n of e.rows) for (const e of n) s = s.concat(this.walkTokens(e.tokens, t)); break } case "list": { const e = r; s = s.concat(this.walkTokens(e.items, t)); break } default: { const e = r; (null == (i = null == (n = this.defaults.extensions) ? void 0 : n.childTokens) ? void 0 : i[e.type]) ? this.defaults.extensions.childTokens[e.type].forEach(( n => { s = s.concat(this.walkTokens(e[n], t)) })): e.tokens && (s = s.concat(this.walkTokens(e.tokens, t))) } } return s } use(...e) { const t = this.defaults.extensions || { renderers: {}, childTokens: {} }; return e.forEach((e => { const n = u({}, e); if (n.async = this.defaults.async || n.async || !1, e.extensions && (e .extensions.forEach((e => { if (!e.name) throw new Error("extension name required"); if ("renderer" in e) { const n = t.renderers[e.name]; t.renderers[e.name] = n ? function(...t) { let i = e.renderer.apply(this, t); return !1 === i && (i = n.apply(this, t)), i } : e.renderer } if ("tokenizer" in e) { if (!e.level || "block" !== e.level && "inline" !== e.level) throw new Error( "extension level must be 'block' or 'inline'" ); const n = t[e.level]; n ? n.unshift(e.tokenizer) : t[e.level] = [e .tokenizer ], e.start && ("block" === e.level ? t .startBlock ? t.startBlock.push(e.start) : t .startBlock = [e.start] : "inline" === e .level && (t.startInline ? t.startInline .push(e.start) : t.startInline = [e .start ])) } "childTokens" in e && e.childTokens && (t.childTokens[e .name] = e.childTokens) })), n.extensions = t), e.renderer) { const t = this.defaults.renderer || new $e(this.defaults); for (const n in e.renderer) { const i = e.renderer[n], s = n, r = t[s]; t[s] = (...e) => { let n = i.apply(t, e); return !1 === n && (n = r.apply(t, e)), n || "" } } n.renderer = t } if (e.tokenizer) { const t = this.defaults.tokenizer || new ge(this.defaults); for (const n in e.tokenizer) { const i = e.tokenizer[n], s = n, r = t[s]; t[s] = (...e) => { let n = i.apply(t, e); return !1 === n && (n = r.apply(t, e)), n } } n.tokenizer = t } if (e.hooks) { const t = this.defaults.hooks || new Ce; for (const n in e.hooks) { const i = e.hooks[n], s = n, r = t[s]; Ce.passThroughHooks.has(n) ? t[s] = e => { if (this.defaults.async) return Promise.resolve(i.call(t, e)).then((e => r.call(t, e))); const n = i.call(t, e); return r.call(t, n) } : t[s] = (...e) => { let n = i.apply(t, e); return !1 === n && (n = r.apply(t, e)), n } } n.hooks = t } if (e.walkTokens) { const t = this.defaults.walkTokens, i = e.walkTokens; n.walkTokens = function(e) { let n = []; return n.push(i.call(this, e)), t && (n = n.concat(t.call(this, e))), n } } this.defaults = u(u({}, this.defaults), n) })), this } setOptions(e) { return this.defaults = u(u({}, this.defaults), e), this } }; function Ee(e, t, n) { return Se.parse(e, t, n) } Ee.options = Ee.setOptions = function(e) { return Se.setOptions(e), Ee.defaults = Se.defaults, H(Ee.defaults), Ee }, Ee.getDefaults = j, Ee.defaults = N, Ee.use = function(...e) { return Se.use(...e), Ee.defaults = Se.defaults, H(Ee.defaults), Ee }, Ee.walkTokens = function(e, t) { return Se.walkTokens(e, t) }, Ee.parseInline = Se.parseInline, Ee.Parser = xe, Ee.parser = xe.parse, Ee.Renderer = $e, Ee .TextRenderer = be, Ee.Lexer = ve, Ee.lexer = ve.lex, Ee.Tokenizer = ge, Ee.Slugger = we, Ee.Hooks = Ce, Ee.parse = Ee, Ee.options, Ee.setOptions, Ee.use, Ee.walkTokens, Ee.parseInline; var Te = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }, _e = { "&": "&", "<": "<", ">": ">", """: '"', "'": "'" }, Le = /(&|<|>|"|')/g, Ae = /[&<>"']/g; function Oe(e) { return Te[e] } function Pe(e) { return _e[e] } function Re(e) { return null == e ? "" : String(e).replace(Ae, Oe) } function Me(e) { return null == e ? "" : String(e).replace(Le, Pe) } Re.options = Me.options = {}; var Ie = { encode: Re, escape: Re, decode: Me, unescape: Me, version: "1.0.0-browser" }; var Ue = function e(t) { for (var n, i, s = Array.prototype.slice.call(arguments, 1); s.length;) for (i in n = s.shift()) n.hasOwnProperty(i) && ("[object Object]" === Object.prototype.toString .call(t[i]) ? t[i] = e(t[i], n[i]) : t[i] = n[i]); return t }, De = function(e) { return "string" == typeof e ? e.toLowerCase() : e }; function Be(e, t) { return e[t] = !0, e } var qe = function(e) { return e.reduce(Be, {}) }, Fe = { uris: qe(["background", "base", "cite", "href", "longdesc", "src", "usemap"]) }, ze = { voids: qe(["area", "br", "col", "hr", "img", "wbr", "input", "base", "basefont", "link", "meta"]) }, We = Ie, je = De, Ne = ze, He = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, Qe = /^<\s*\/\s*([\w:-]+)[^>]*>/, Ve = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, Ge = /^= 0 && (t.comment && t .comment(e.substring(4, i)), e = e.substring(i + 3), n = !1) : Ke.test(e) ? o( Qe, l) : Ge.test(e) && o(He, a); var i; ! function() { if (!n) return; var i, s = e.indexOf("<"); s >= 0 ? (i = e.substring(0, s), e = e.substring(s)) : (i = e, e = ""); t.chars && t.chars(i) }() }(); var i = e === s; s = e, i && (e = "") } function o(t, i) { var s = e.match(t); s && (e = e.substring(s[0].length), s[0].replace(t, i), n = !1) } function a(e, n, s, r) { var o = {}, a = je(n), l = Ne.voids[a] || !!r; s.replace(Ve, (function(e, t, n, i, s) { o[t] = void 0 === n && void 0 === i && void 0 === s ? void 0 : We.decode(n || i || s || "") })), l || i.push(a), t.start && t.start(a, o, l) } function l(e, n) { var s, r = 0, o = je(n); if (o) for (r = i.length - 1; r >= 0 && i[r] !== o; r--); if (r >= 0) { for (s = i.length - 1; s >= r; s--) t.end && t.end(i[s]); i.length = r } } l() }, nt = function(e, t) { var n, i = t || {}; return a(), { start: function(e, t, o) { var a = Ye(e); if (n.ignoring) return void r(a); if (-1 === (i.allowedTags || []).indexOf(a)) return void r(a); if (i.filter && !i.filter({ tag: a, attrs: t })) return void r(a); s("<"), s(a), Object.keys(t).forEach((function(e) { var n = t[e], r = (i.allowedClasses || {})[a] || [], o = (i.allowedAttributes || {})[a] || [], l = Ye(e); ("class" === l && -1 === o.indexOf(l) ? (n = n.split(" ").filter(( function(e) { return r && -1 !== r.indexOf(e) })).join(" ").trim()).length : -1 !== o.indexOf(l) && (! 0 !== Xe.uris[l] || function(e) { var t = e[0]; if ("#" === t || "/" === t) return !0; var n = e.indexOf(":"); if (-1 === n) return !0; var s = e.indexOf("?"); if (-1 !== s && n > s) return !0; var r = e.indexOf("#"); return -1 !== r && n > r || i.allowedSchemes.some(o); function o(t) { return 0 === e.indexOf(t + ":") } }(n))) && (s(" "), s(e), "string" == typeof n && (s('="'), s(Ze .encode(n)), s('"'))) })), s(o ? "/>" : ">") }, end: function(e) { var t = Ye(e); - 1 !== (i.allowedTags || []).indexOf(t) && !1 === n.ignoring ? (s( "")) : o(t) }, chars: function(e) { !1 === n.ignoring && s(i.transformText ? i.transformText(e) : e) } }; function s(t) { e.push(t) } function r(e) { Je.voids[e] || (!1 === n.ignoring ? n = { ignoring: e, depth: 1 } : n.ignoring === e && n.depth++) } function o(e) { n.ignoring === e && --n.depth <= 0 && a() } function a() { n = { ignoring: !1, depth: 0 } } }, it = { allowedAttributes: { a: ["href", "name", "target", "title", "aria-label"], iframe: ["allowfullscreen", "frameborder", "src"], img: ["src", "alt", "title", "aria-label"] }, allowedClasses: {}, allowedSchemes: ["http", "https", "mailto"], allowedTags: ["a", "abbr", "article", "b", "blockquote", "br", "caption", "code", "del", "details", "div", "em", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "ins", "kbd", "li", "main", "mark", "ol", "p", "pre", "section", "span", "strike", "strong", "sub", "summary", "sup", "table", "tbody", "td", "th", "thead", "tr", "u", "ul" ], filter: null }; function st(e, t, n) { var i = [], s = !0 === n ? t : et({}, it, t), r = nt(i, s); return tt(e, r), i.join("") } st.defaults = it; const rt = L(st), ot = { allowedClasses: {}, allowedSchemes: ["http", "https", "mailto", "data"], allowedTags: ["a", "abbr", "article", "b", "blockquote", "br", "caption", "code", "del", "details", "div", "em", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "ins", "kbd", "li", "main", "mark", "ol", "p", "pre", "section", "span", "strike", "strong", "sub", "summary", "sup", "table", "tbody", "td", "th", "thead", "tr", "u", "ul" ], allowedAttributes: { "*": ["title", "accesskey"], a: ["href", "name", "target", "aria-label", "rel"], img: ["src", "alt", "title", "atk-emoticon", "aria-label"], code: ["class"], span: ["class", "style"] }, filter: e => ([ ["code", /^hljs\W+language-(.*)$/], ["span", /^(hljs-.*)$/] ].forEach((([t, n]) => { e.tag === t && e.attrs.class && !n.test(e.attrs.class) && delete e.attrs.class })), "span" === e.tag && e.attrs.style && !/^color:(\W+)?#[0-9a-f]{3,6};?$/i.test(e.attrs .style) && delete e.attrs.style, !0) }; function at(e) { return rt(e, ot) } var lt = { exports: {} }; lt.exports = function() { function e(e, t) { return e(t = { exports: {} }, t.exports), t.exports } var t = e((function(e) { var t = e.exports = function() { return new RegExp("(?:" + t.line().source + ")|(?:" + t.block().source + ")", "gm") }; t.line = function() { return /(?:^|\s)\/\/(.+?)$/gm }, t.block = function() { return /\/\*([\S\s]*?)\*\//gm } })), n = ["23AC69", "91C132", "F19726", "E8552D", "1AAB8E", "E1147F", "2980C1", "1BA1E6", "9FA0A0", "F19726", "E30B20", "E30B20", "A3338B" ]; function i(e) { return '' + e + "" } return function(e, s) { void 0 === s && (s = {}); var r = s.colors; void 0 === r && (r = n); var o = 0, a = {}, l = new RegExp("(" + /[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|\w+/ .source + "|" + /' + t + ""; return o = ++o % r.length, l })) } }(); const ct = L(lt.exports); function dt(e) { return ct(e) } function ht() { const e = new Ee.Renderer; return e.link = ut(e, e.link), e.code = pt(), e } const ut = (e, t) => (n, i, s) => { const r = null == n ? void 0 : n.startsWith( `${window.location.protocol}//${window.location.hostname}`); return t.call(e, n, i, s).replace(/^
    (e, t) => { const n = t || "plaintext"; let i = e; return window.hljs ? n && window.hljs.getLanguage(n) && (i = window.hljs.highlight(n, e).value) : i = dt(e), `
    \n${i.replace(/&/g,"&")}\n
    ` }; let gt, mt = []; const ft = { pedantic: !1, gfm: !0, breaks: !0, smartLists: !0, smartypants: !0, xhtml: !1, sanitize: !1, silent: !0 }; function kt() { return gt } function yt(e) { var t; let n = null == (t = kt()) ? void 0 : t.parse(e); n || (n = function(e) { return e.replace(/```\s*([^]+?.*?[^]+?[^]+?)```/g, ((e, t) => `
    ${dt(t)}
    `)).replace(/!\[(.*?)\]\((.*?)\)/g, ((e, t, n) => `${t}`)).replace(/\[(.*?)\]\((.*?)\)/g, ((e, t, n) => `
    ${t}`)).replace(/\n/g, "
    ") }(e)); let i = at(n); return mt.forEach((e => { "function" == typeof e && (i = e(i)) })), i } function vt(...e) { const t = e => e && "object" == typeof e && e.constructor === Object; return e.reduce(((e, n) => (Object.keys(null != n ? n : {}).forEach((i => { if ("__proto__" === i || "constructor" === i || "prototype" === i) return; const s = e[i], r = n[i]; Array.isArray(s) && Array.isArray(r) ? e[i] = s.concat(...r) : t(s) && t( r) ? e[i] = vt(s, r) : e[i] = r })), e)), {}) } class $t { constructor(e) { g(this, "loading", !1), g(this, "listLastFetch"), g(this, "comments", []), g(this, "unreads", []), g(this, "page"), this.events = e } getLoading() { return this.loading } setLoading(e) { this.loading = e } getListLastFetch() { return this.listLastFetch } setListLastFetch(e) { this.listLastFetch = e } getComments() { return this.comments } fetchComments(e) { this.events.trigger("list-fetch", e) } findComment(e) { return this.comments.find((t => t.id === e)) } clearComments() { this.comments = [], this.events.trigger("list-loaded", this.comments) } loadComments(e) { this.events.trigger("list-load", e), this.comments.push(...e), this.events.trigger( "list-loaded", this.comments) } insertComment(e) { this.comments.push(e), this.events.trigger("comment-inserted", e), this.events.trigger( "list-loaded", this.comments) } updateComment(e) { this.comments = this.comments.map((t => t.id === e.id ? e : t)), this.events.trigger( "comment-updated", e), this.events.trigger("list-loaded", this.comments) } deleteComment(e) { const t = this.comments.find((t => t.id === e)); if (!t) throw new Error(`Comment ${e} not found`); this.comments = this.comments.filter((t => t.id !== e)), this.events.trigger("comment-deleted", t), this.events.trigger("list-loaded", this.comments) } getUnreads() { return this.unreads } updateUnreads(e) { this.unreads = e, this.events.trigger("unreads-updated", this.unreads) } getPage() { return this.page } updatePage(e) { this.page = e, this.events.trigger("page-loaded", e) } } class bt { constructor() { g(this, "events", []) } on(e, t, n = {}) { this.events.push(u({ name: e, handler: t }, n)) } off(e, t) { t && (this.events = this.events.filter((n => !(n.name === e && n.handler === t)))) } trigger(e, t) { this.events.slice(0).filter((t => t.name === e && "function" == typeof t.handler)).forEach(( n => { n.once && this.off(e, n.handler), n.handler(t) })) } } const wt = { el: "", pageKey: "", pageTitle: "", server: "", site: "", placeholder: "", noComment: "", sendBtn: "", darkMode: !1, editorTravel: !0, flatMode: "auto", nestMax: 2, nestSort: "DATE_ASC", emoticons: "https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json", vote: !0, voteDown: !1, uaBadge: !0, listSort: !0, preview: !0, countEl: "#ArtalkCount", pvEl: "#ArtalkPV", gravatar: { mirror: "https://cravatar.cn/avatar/", params: "d=mp&s=240" }, pagination: { pageSize: 20, readMore: !0, autoLoad: !0 }, heightLimit: { content: 300, children: 400, scrollable: !1 }, imgUpload: !0, reqTimeout: 15e3, versionCheck: !0, useBackendConf: !0, locale: "zh-CN" }; function xt(e, t = !1) { const n = t ? vt(wt, e) : e; if (n.el && "string" == typeof n.el) try { const e = document.querySelector(n.el); if (!e) throw Error(`Target element "${n.el}" was not found.`); n.el = e } catch (i) { throw console.error(i), new Error("Please check your Artalk `el` config.") } return "" === n.pageKey && (n.pageKey = `${window.location.pathname}`), "" === n.pageTitle && (n .pageTitle = `${document.title}`), n.server && (n.server = n.server.replace(/\/$/, "").replace( /\/api\/?$/, "")), "auto" === n.locale && (n.locale = navigator.language), "auto" === n .flatMode && (n.flatMode = window.matchMedia("(max-width: 768px)").matches), "number" == typeof n .nestMax && Number(n.nestMax) <= 1 && (n.flatMode = !0), n } function Ct(e, t) { return { baseURL: `${e.server}/api`, siteName: e.site || "", pageKey: e.pageKey || "", pageTitle: e.pageTitle || "", timeout: e.reqTimeout, apiToken: null == t ? void 0 : t.get("user").getData().token, userInfo: (null == t ? void 0 : t.get("user").checkHasBasicUserInfo()) ? { name: null == t ? void 0 : t.get("user").getData().nick, email: null == t ? void 0 : t.get("user").getData().email } : void 0, onNeedCheckAdmin(e) { null == t || t.checkAdmin({ onSuccess: () => { e.recall() }, onCancel: () => { e.reject() } }) }, onNeedCheckCaptcha(e) { null == t || t.checkCaptcha({ imgData: e.data.imgData, iframe: e.data.iframe, onSuccess: () => { e.recall() }, onCancel: () => { e.reject() } }) } } } class St { constructor(e) { g(this, "conf"), g(this, "data"), g(this, "$root"), g(this, "events", new bt), this.conf = e, this.$root = e.el, this.$root.classList.add("artalk"), this.$root.innerHTML = "", this .data = new $t(this.events) } inject(e, t) { this[e] = t } get(e) { return this[e] } getApi() { return new W(Ct(this.conf, this)) } getData() { return this.data } replyComment(e, t) { this.editor.setReply(e, t) } editComment(e, t) { this.editor.setEditComment(e, t) } fetch(e) { this.data.fetchComments(e) } reload() { this.data.fetchComments({ offset: 0 }) } listGotoFirst() { this.events.trigger("list-goto-first") } editorShowLoading() { this.editor.showLoading() } editorHideLoading() { this.editor.hideLoading() } editorShowNotify(e, t) { this.editor.showNotify(e, t) } editorResetState() { this.editor.resetState() } showSidebar(e) { this.sidebarLayer.show(e) } hideSidebar() { this.sidebarLayer.hide() } checkAdmin(e) { this.checkerLauncher.checkAdmin(e) } checkCaptcha(e) { this.checkerLauncher.checkCaptcha(e) } on(e, t) { this.events.on(e, t) } off(e, t) { this.events.off(e, t) } trigger(e, t) { this.events.trigger(e, t) } $t(e, t = {}) { return D(e, t) } setDarkMode(e) { this.conf.darkMode = e, this.events.trigger("dark-mode-changed", e) } updateConf(e) { this.conf = vt(this.conf, xt(e, !1)), this.events.trigger("conf-loaded", this.conf) } getConf() { return this.conf } getEl() { return this.$root } getMarked() { return kt() } } class Et { constructor(e) { g(this, "$el"), g(this, "$content"), g(this, "$actions"), this.$el = y( '
    \n
    \n
    \n
    \n
    \n
    ' ), this.$actions = this.$el.querySelector(".atk-layer-dialog-actions"), this.$content = this.$el.querySelector(".atk-layer-dialog-content"), this.$content.appendChild(e) } setYes(e) { const t = y(``); return t.onclick = this.onBtnClick(e), this.$actions.appendChild(t), this } setNo(e) { const t = y(``); return t.onclick = this.onBtnClick(e), this.$actions.appendChild(t), this } onBtnClick(e) { return t => { const n = e(t.currentTarget, this); void 0 !== n && !0 !== n || this.$el.remove() } } } function Tt(e, t) { let n = e.querySelector(":scope > .atk-loading"); n || (n = y( ''), (null == t ? void 0 : t.transparentBg) && (n.style.background = "transparent"), e.appendChild(n) ), n.style.display = ""; const i = n.querySelector(".atk-loading-spinner"); i && (i.style.display = "none", window.setTimeout((() => { i.style.display = "" }), 500)) } function _t(e) { const t = e.querySelector(":scope > .atk-loading"); t && (t.style.display = "none") } function Lt(e, t) { e ? Tt(t) : _t(t) } function At(e, t = !0, n) { let i; if (n) { const t = n.getBoundingClientRect(); i = e.getBoundingClientRect().top - t.top + n.scrollTop, i += v(n) / 2 - v(e) / 2 } else { const t = e.getBoundingClientRect(); i = t.top + window.scrollY - (window.innerHeight / 2 - t.height / 2) } const s = { top: i, left: 0, behavior: "instant" }; n ? n.scroll(s) : window.scroll(s) } function Ot(e, t) { ! function(e, t, n = "in") { e.classList.add(`atk-fade-${n}`); const i = () => { e.classList.remove(`atk-fade-${n}`), e.removeEventListener("animationend", i), t && t() }; e.addEventListener("animationend", i) }(e, t, "in") } function Pt(e, t, n = 'Artalk Error') { let i = e.querySelector(".atk-error-layer"); if (null === t) return void(null !== i && i.remove()); i || (i = y(`
    ${n}
    `), e .appendChild(i)); const s = i.querySelector(".atk-error-text"); s.innerHTML = "", null !== t && (t instanceof HTMLElement ? s.appendChild(t) : s.innerText = t) } function Rt(e) { const t = y('
    '), n = y(''); n.style.display = "none", Tt(t, { transparentBg: !0 }), n.src = `${e.getOpts().getIframeURLBase()||""}/api/captcha/get?t=${+new Date}`, n.onload = () => { n.style.display = "", _t(t) }, t.append(n); const i = y('
    '); t.append(i), e.hideInteractInput(); let s = !1; return function t() { return k(this, null, (function*() { var n; if (yield(n = 1e3, new Promise((e => { window.setTimeout((() => { e(null) }), n) }))), s) return; let i = !1; try { i = (yield e.getApi().captcha.captchaStatus()).is_pass } catch (r) { i = !1 } i ? e.triggerSuccess() : t() })) }(), i.onclick = () => { s = !0, e.cancel() }, t } const Mt = { request: (e, t) => e.getApi().captcha.captchaCheck(t), body: e => e.get("iframe") ? Rt(e) : function(e) { const t = y( `${D("captchaCheck")}` ); return t.querySelector(".atk-captcha-img").onclick = () => { const n = t.querySelector(".atk-captcha-img"); e.getApi().captcha.captchaGet().then((e => { n.setAttribute("src", e) })).catch((e => { console.error("Failed to get captcha image ", e) })) }, t }(e), onSuccess(e, t, n, i) { e.set("val", n) }, onError(e, t, n, i) { i.querySelector(".atk-captcha-img").click(), i.querySelector('input[type="text"]').value = "" } }, It = { inputType: "password", request(e, t) { const n = { name: e.getUser().getData().nick, email: e.getUser().getData().email, password: t }; return (() => k(this, null, (function*() { return (yield e.getApi().user.login(n.name, n.email, n.password)).token })))() }, body: e => y(`${D("adminCheck")}`), onSuccess(e, t, n, i) { e.getUser().update({ isAdmin: !0, token: t }), e.getOpts().onReload() }, onError(e, t, n, i) {} }; class Ut { constructor(e) { this.opts = e } checkCaptcha(e) { this.fire(Mt, e, (t => { t.set("img_data", e.imgData), t.set("iframe", e.iframe) })) } checkAdmin(e) { this.fire(It, e) } fire(e, t, n) { const i = this.opts.getCtx().get("layerManager").create(`checker-${(new Date).getTime()}`); i.show(); const s = {}; let r = !1; const o = { set: (e, t) => { s[e] = t }, get: e => s[e], getOpts: () => this.opts, getUser: () => this.opts.getCtx().get("user"), getApi: () => this.opts.getApi(), hideInteractInput: () => { r = !0 }, triggerSuccess: () => { this.close(e, i), e.onSuccess && e.onSuccess(o, "", "", a), t.onSuccess && t .onSuccess("", d.$el) }, cancel: () => { this.close(e, i), t.onCancel && t.onCancel() } }; n && n(o); const a = y(); a.appendChild(e.body(o)); const l = y( `` ); let c; a.appendChild(l), setTimeout((() => l.focus()), 80), l.onkeyup = e => { "Enter" !== e.key && 13 !== e.keyCode || (e.preventDefault(), i.getEl().querySelector( 'button[data-action="confirm"]').click()) }; const d = new Et(a); d.setYes((n => { const s = l.value.trim(); c || (c = n.innerText); const r = () => { n.innerText = c || "", n.classList.remove("error") }; return n.innerText = `${D("loading")}...`, e.request(o, s).then((n => { this.close(e, i), e.onSuccess && e.onSuccess(o, n, s, a), t .onSuccess && t.onSuccess(s, d.$el) })).catch((t => { var i; i = String(t.msg || String(t)), n.innerText = i, n.classList .add("error"), e.onError && e.onError(o, t, s, a); const c = setTimeout((() => r()), 3e3); l.onfocus = () => { r(), clearTimeout(c) } })), !1 })), d.setNo((() => (this.close(e, i), t.onCancel && t.onCancel(), !1))), r && (l.style .display = "none", d.$el.querySelector(".atk-layer-dialog-actions").style.display = "none"), i.getEl().append(d.$el), t.onMount && t.onMount(d.$el) } close(e, t) { t.destroy() } } class Dt { constructor(e) { g(this, "$el"), g(this, "conf"), this.ctx = e, this.conf = e.conf } } const Bt = { $header: ".atk-header", $nick: '.atk-header [name="nick"]', $email: '.atk-header [name="email"]', $link: '.atk-header [name="link"]', $textareaWrap: ".atk-textarea-wrap", $textarea: ".atk-textarea", $bottom: ".atk-bottom", $submitBtn: ".atk-send-btn", $notifyWrap: ".atk-notify-wrap", $plugBtnWrap: ".atk-plug-btn-wrap", $plugPanelWrap: ".atk-plug-panel-wrap" }; class qt { constructor(e) { this.kit = e } useBtn(e = "
    ") { return this.$btn = y(`${e}`), this.$btn } usePanel(e = "
    ") { return this.$panel = y(e), this.$panel } useContentTransformer(e) { this.contentTransformer = e } usePanelShow(e) { this.kit.useEvents().on("panel-show", (t => { t === this && e() })) } usePanelHide(e) { this.kit.useEvents().on("panel-hide", (t => { t === this && e() })) } useEditorStateEffect(e, t) { this.editorStateEffectWhen = e, this.editorStateEffect = t } } class Ft extends qt { constructor() { super(...arguments), g(this, "isMoved", !1) } move(e) { if (this.isMoved) return; this.isMoved = !0; const t = this.kit.useUI().$el; t.after(y('
    ')); const n = y("
    "); e.after(n), n.replaceWith(t), t.classList.add("atk-fade-in"), t.classList.add( "editor-traveling") } back() { var e; this.isMoved && (this.isMoved = !1, null == (e = this.kit.useGlobalCtx().$root.querySelector( ".atk-editor-travel-placeholder")) || e.replaceWith(this.kit.useUI().$el), this.kit .useUI().$el.classList.remove("editor-traveling")) } } class zt { constructor(e) { g(this, "stateCurt", "normal"), g(this, "stateUnmountFn", null), this.editor = e } get() { return this.stateCurt } switch (e, t) { var n, i, s, r, o; if (this.stateUnmountFn && (this.stateUnmountFn(), this.stateUnmountFn = null, null == (i = null == (n = this.editor.getPlugs()) ? void 0 : n.get(Ft)) || i.back()), "normal" !== e && t) { let n = t.$comment; this.editor.conf.flatMode || (n = n.querySelector(".atk-footer")), null == (r = null == (s = this.editor.getPlugs()) ? void 0 : s.get(Ft)) || r.move(n); const i = this.editor.ctx.conf.scrollRelativeTo && this.editor.ctx.conf.scrollRelativeTo(); At(this.editor.getUI().$el, !0, i); const a = null == (o = this.editor.getPlugs()) ? void 0 : o.getPlugs().find((t => t .editorStateEffectWhen === e)); a && a.editorStateEffect && (this.stateUnmountFn = a.editorStateEffect(t.comment)) } this.stateCurt = e } } class Wt extends Dt { constructor(e) { super(e), g(this, "ui"), g(this, "state"), this.ui = function() { const e = y( '
    \n
    \n \n \n \n
    \n
    \n \n
    \n \n
    \n
    \n
    \n \n
    \n
    \n
    \n
    \n' ), t = { $el: e }; return Object.entries(Bt).forEach((([n, i]) => { t[n] = e.querySelector(i) })), t }(), this.$el = this.ui.$el, this.state = new zt(this) } getUI() { return this.ui } getPlugs() { return this.ctx.get("editorPlugs") } getState() { return this.state.get() } getHeaderInputEls() { return { nick: this.ui.$nick, email: this.ui.$email, link: this.ui.$link } } getContentFinal() { let e = this.getContentRaw(); const t = this.getPlugs(); return t && (e = t.getTransformedContent(e)), e } getContentRaw() { return this.ui.$textarea.value || "" } getContentMarked() { return yt(this.getContentFinal()) } setContent(e) { var t; this.ui.$textarea.value = e, null == (t = this.getPlugs()) || t.getEvents().trigger( "content-updated", e) } insertContent(e) { if (document.selection) this.ui.$textarea.focus(), document.selection.createRange().text = e, this.ui.$textarea.focus(); else if (this.ui.$textarea.selectionStart || 0 === this.ui.$textarea.selectionStart) { const t = this.ui.$textarea.selectionStart, n = this.ui.$textarea.selectionEnd, i = this.ui.$textarea.scrollTop; this.setContent(this.ui.$textarea.value.substring(0, t) + e + this.ui.$textarea.value .substring(n, this.ui.$textarea.value.length)), this.ui.$textarea.focus(), this.ui .$textarea.selectionStart = t + e.length, this.ui.$textarea.selectionEnd = t + e.length, this.ui.$textarea.scrollTop = i } else this.ui.$textarea.focus(), this.ui.$textarea.value += e } focus() { this.ui.$textarea.focus() } reset() { this.setContent(""), this.resetState() } resetState() { this.state.switch("normal") } setReply(e, t) { this.state.switch("reply", { comment: e, $comment: t }) } setEditComment(e, t) { this.state.switch("edit", { comment: e, $comment: t }) } showNotify(e, t) { ! function(e, t, n) { const i = y( `
    ` ); i.querySelector(".atk-notify-content").innerHTML = $(t).replace("\n", "
    "), e .appendChild(i); const s = () => { i.classList.add("atk-fade-out"), setTimeout((() => { i.remove() }), 200) }; let r; r = window.setTimeout((() => { s() }), 3e3), i.addEventListener("click", (() => { s(), window.clearTimeout(r) })) }(this.ui.$notifyWrap, e, t) } showLoading() { Tt(this.ui.$el) } hideLoading() { _t(this.ui.$el) } submit() { this.ctx.trigger("editor-submit") } } class jt extends Dt { constructor(e) { super(e), g(this, "layer"), g(this, "$header"), g(this, "$closeBtn"), g(this, "$iframeWrap"), g( this, "$iframe"), g(this, "firstShow", !0), this.$el = y( '
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n' ), this.$header = this.$el.querySelector(".atk-sidebar-header"), this.$closeBtn = this .$header.querySelector(".atk-sidebar-close"), this.$iframeWrap = this.$el.querySelector( ".atk-sidebar-iframe-wrap"), this.$closeBtn.onclick = () => { this.hide() }, this.ctx.on("user-changed", (() => { this.firstShow = !0 })) } show() { return k(this, arguments, (function*(e = {}) { if (this.$el.style.transform = "", this.initLayer(), this.layer.show(), this .authCheck({ onSuccess: () => this.show(e) }), this.firstShow) this.$iframeWrap.innerHTML = "", this.$iframe = this .createIframe(e.view), this.$iframeWrap.append(this.$iframe), this .firstShow = !1; else { const e = this.$iframe, t = e.src.includes("darkMode=1"); this.conf.darkMode && !t && this.iframeLoad(e, `${this.$iframe.src}&darkMode=1`), !this.conf.darkMode && t && this .iframeLoad(e, this.$iframe.src.replace("&darkMode=1", "")) } setTimeout((() => { this.$el.style.transform = "translate(0, 0)" }), 100), setTimeout((() => { this.ctx.getData().updateUnreads([]) }), 0), this.ctx.trigger("sidebar-show") })) } hide() { var e; this.$el.style.transform = "", null == (e = this.layer) || e.hide(), this.ctx.trigger( "sidebar-hide") } authCheck(e) { return k(this, null, (function*() { const t = yield this.ctx.getApi().user.loginStatus(); t.is_admin && !t.is_login && (this.firstShow = !0, this.ctx.checkAdmin({ onSuccess: () => { setTimeout((() => { e.onSuccess() }), 500) }, onCancel: () => { this.hide() } })) })) } initLayer() { this.layer || (this.layer = this.ctx.get("layerManager").create("sidebar", this.$el), this.layer .setOnAfterHide((() => { this.ctx.editorResetState() }))) } createIframe(e) { const t = y(''), n = T({ base: this.ctx.conf.server, path: "/sidebar/" }), i = { pageKey: this.conf.pageKey, site: this.conf.site || "", user: JSON.stringify(this.ctx.get("user").getData()), time: +new Date }; e && (i.view = e), this.conf.darkMode && (i.darkMode = "1"), "string" == typeof this.conf .locale && (i.locale = this.conf.locale); const s = new URLSearchParams(i); return this.iframeLoad(t, `${n}?${s.toString()}`), t } iframeLoad(e, t) { e.src = t, Tt(this.$iframeWrap), e.onload = () => { _t(this.$iframeWrap) } } } class Nt { constructor(e) { this.options = e } import(e) { this.options.flatMode ? e.forEach((t => { this.putCommentFlatMode(t, e, "append") })) : this.importCommentsNestMode(e) } insert(e) { this.options.flatMode ? this.insertCommentFlatMode(e) : this.insertCommentNest(e) } importCommentsNestMode(e) { const t = function(e, t = "DATE_DESC", n = 2) { const i = []; e.filter((e => 0 === e.rid)).forEach((t => { const s = { id: t.id, comment: t, children: [], level: 1 }; s.parent = s, i.push(s), function t(i) { const s = e.filter((e => e.rid === i.id)); 0 !== s.length && (i.level >= n && (i = i.parent), s.forEach(( e => { const n = { id: e.id, comment: e, children: [], parent: i, level: i.level + 1 }; i.children.push(n), t(n) }))) }(s) })); const s = (n, i) => { let s = n.id - i.id; return "DATE_ASC" === t ? s = +new Date(n.comment.date) - +new Date(i.comment .date) : "DATE_DESC" === t ? s = +new Date(i.comment.date) - +new Date(n .comment.date) : "SRC_INDEX" === t ? s = e.indexOf(n.comment) - e .indexOf(i.comment) : "VOTE_UP_DESC" === t && (s = i.comment.vote_up - n .comment.vote_up), s }; return function e(t) { t.forEach((t => { t.children = t.children.sort(s), e(t.children) })) }(i), i }(e, this.options.nestSortBy, this.options.nestMax); t.forEach((t => { var n; const i = this.options.createCommentNode(t.comment, e); null == (n = this.options.$commentsWrap) || n.appendChild(i.getEl()), i .getRender().playFadeAnim(); const s = (t, n) => { n.children.forEach((n => { const i = n.comment, r = this.options.createCommentNode(i, e); t.putChild(r), s(r, n) })) }; s(i, t), i.getRender().checkHeightLimit() })) } putCommentFlatMode(e, t, n) { var i, s; e.is_collapsed && (e.is_allow_reply = !1); const r = this.options.createCommentNode(e, t); return e.visible && ("append" === n && (null == (i = this.options.$commentsWrap) || i.append(r .getEl())), "prepend" === n && (null == (s = this.options.$commentsWrap) || s .prepend(r.getEl())), r.getRender().playFadeAnim()), r.getRender().checkHeightLimit(), r } insertCommentNest(e) { var t; const n = this.options.createCommentNode(e, this.options.getCommentDataList()); if (0 === e.rid) null == (t = this.options.$commentsWrap) || t.prepend(n.getEl()); else { const t = this.options.findCommentNode(e.rid); t && (t.putChild(n, "DATE_ASC" === this.options.nestSortBy ? "append" : "prepend"), n .getParents().forEach((e => { e.getRender().heightLimitRemoveForChildren() }))) } n.getRender().checkHeightLimit(), At(n.getEl()), n.getRender().playFadeAnim() } insertCommentFlatMode(e) { At(this.putCommentFlatMode(e, this.options.getCommentDataList(), "prepend").getEl()) } } function Ht(e, t) { t.forEach((({ el: t, max: n, imgContains: i }) => { const s = () => { t && (e.scrollable ? function(e) { if (!e.el) return; if (e.el.classList.contains(Gt)) return; e.el.classList.add(Gt), e.el.style.height = `${e.maxHeight}px` }({ el: t, maxHeight: n }) : function(e) { if (!e.el) return; if (!e.maxHeight) return; if (e.el.classList.contains(Qt)) return; e.el.classList.add(Qt), e.el.style.height = `${e.maxHeight}px`, e.el .style.overflow = "hidden"; const t = y( `
    ${D("readMore")}`); t.onclick = t => { t.stopPropagation(), Vt(e.el), e.postBtnClick && e .postBtnClick(t) }, e.el.append(t) }({ el: t, maxHeight: n, postBtnClick: e.postExpandBtnClick })) }, r = () => { t && v(t) > n && s() }; r(), i && t && function(e, t) { if (!e) return; const n = e.getElementsByTagName("img"); if (!n.length) return; let i = n.length; for (let s = 0; s < n.length; s++) n[s].complete ? i-- : n[s].addEventListener( "load", (() => { i--, 0 === i && t() })), 0 === i && t() }(t, (() => r())) })) } const Qt = "atk-height-limit"; function Vt(e) { e && e.classList.contains(Qt) && (e.classList.remove(Qt), Array.from(e.children).forEach((e => { e.classList.contains("atk-height-limit-btn") && e.remove() })), e.style.height = "", e.style.overflow = "") } const Gt = "atk-height-limit-scroll"; function Kt(e) { if (e.$headerNick = e.$el.querySelector(".atk-nick"), e.data.link) { const t = y(''); t.innerText = e.data.nick, t.href = E(e.data.link) ? e.data.link : `https://${e.data.link}`, e .$headerNick.append(t) } else e.$headerNick.innerText = e.data.nick } function Zt(e) { e.$headerBadgeWrap = e.$el.querySelector(".atk-badge-wrap"), e.$headerBadgeWrap.innerHTML = ""; const t = e.data.badge_name, n = e.data.badge_color; if (t) { const i = y(''); i.innerText = t.replace("管理员", e.ctx.$t("admin")), i.style.backgroundColor = n || "", e .$headerBadgeWrap.append(i) } if (e.data.is_pinned) { const t = y(`${e.ctx.$t("pin")}`); e.$headerBadgeWrap.append(t) } } function Yt(e) { const t = e.$el.querySelector(".atk-date"); t.innerText = e.comment.getDateFormatted(), t.setAttribute("data-atk-comment-date", String(+new Date(e .data.date))) } function Xt(e) { if (!e.ctx.conf.uaBadge && !e.data.ip_region) return; let t = e.$header.querySelector("atk-ua-wrap"); if (t || (t = y(''), e.$header.append(t)), t.innerHTML = "", e.data .ip_region) { const n = y(''); n.innerText = e.data.ip_region, t.append(n) } if (e.ctx.conf.uaBadge) { const { browser: n, os: i } = e.comment.getUserUA(); if (String(n).trim()) { const e = y(''); e.innerText = n, t.append(e) } if (String(i).trim()) { const e = y(''); e.innerText = i, t.append(e) } } } class Jt { constructor(e) { g(this, "opts"), g(this, "$el"), g(this, "isLoading", !1), g(this, "msgRecTimer"), g(this, "msgRecTimerFunc"), g(this, "isConfirming", !1), g(this, "confirmRecTimer"), this.$el = y(''), this.opts = "object" != typeof e ? { text: e } : e, this.$el.innerText = this.getText(), this.opts.adminOnly && this.$el.setAttribute( "atk-only-admin-show", "") } get isMessaging() { return !!this.msgRecTimer } appendTo(e) { return e.append(this.$el), this } getText() { return "string" == typeof this.opts.text ? this.opts.text : this.opts.text() } setClick(e) { this.$el.onclick = t => { if (t.stopPropagation(), !this.isLoading) { if (this.opts.confirm && !this.isMessaging) { const e = () => { this.isConfirming = !1, this.$el.classList.remove("atk-btn-confirm"), this.$el.innerText = this.getText() }; if (!this.isConfirming) return this.isConfirming = !0, this.$el.classList.add( "atk-btn-confirm"), this.$el.innerText = this.opts.confirmText || D( "actionConfirm"), void(this.confirmRecTimer = window.setTimeout(( () => e()), 5e3)); this.confirmRecTimer && window.clearTimeout(this.confirmRecTimer), e() } if (this.msgRecTimer) return this.fireMsgRecTimer(), void this.clearMsgRecTimer(); e() } } } updateText(e) { e && (this.opts.text = e), this.setLoading(!1), this.$el.innerText = this.getText() } setLoading(e, t) { this.isLoading !== e && (this.isLoading = e, e ? (this.$el.classList.add("atk-btn-loading"), this.$el.innerText = t || `${D("loading")}...`) : (this.$el.classList.remove( "atk-btn-loading"), this.$el.innerText = this.getText())) } setError(e) { this.setMsg(e, "atk-btn-error") } setWarn(e) { this.setMsg(e, "atk-btn-warn") } setSuccess(e) { this.setMsg(e, "atk-btn-success") } setMsg(e, t, n, i) { this.setLoading(!1), t && this.$el.classList.add(t), this.$el.innerText = e, this .setMsgRecTimer((() => { this.$el.innerText = this.getText(), t && this.$el.classList.remove(t), i && i() }), n || 2500) } setMsgRecTimer(e, t) { this.fireMsgRecTimer(), this.clearMsgRecTimer(), this.msgRecTimerFunc = e, this.msgRecTimer = window.setTimeout((() => { e(), this.clearMsgRecTimer() }), t) } fireMsgRecTimer() { this.msgRecTimerFunc && this.msgRecTimerFunc() } clearMsgRecTimer() { this.msgRecTimer && window.clearTimeout(this.msgRecTimer), this.msgRecTimer = void 0, this .msgRecTimerFunc = void 0 } } function en(e) { e.ctx.conf.vote && (e.voteBtnUp = new Jt((() => `${e.ctx.$t("voteUp")} (${e.data.vote_up||0})`)) .appendTo(e.$actions), e.voteBtnUp.setClick((() => { e.comment.getActions().vote("up") })), e.ctx.conf.voteDown && (e.voteBtnDown = new Jt((() => `${e.ctx.$t("voteDown")} (${e.data.vote_down||0})`)).appendTo(e.$actions), e.voteBtnDown .setClick((() => { e.comment.getActions().vote("down") })))) } function tn(e) { if (!e.data.is_allow_reply) return; const t = y(`${e.ctx.$t("reply")}`); e.$actions.append(t), t.addEventListener("click", (t => { t.stopPropagation(), e.cConf.onReplyBtnClick ? e.cConf.onReplyBtnClick() : e.ctx .replyComment(e.data, e.$el) })) } function nn(e) { const t = new Jt({ text: () => e.data.is_collapsed ? e.ctx.$t("expand") : e.ctx.$t("collapse"), adminOnly: !0 }); t.appendTo(e.$actions), t.setClick((() => { e.comment.getActions().adminEdit("collapsed", t) })) } function sn(e) { const t = new Jt({ text: () => e.data.is_pending ? e.ctx.$t("pending") : e.ctx.$t("approved"), adminOnly: !0 }); t.appendTo(e.$actions), t.setClick((() => { e.comment.getActions().adminEdit("pending", t) })) } function rn(e) { const t = new Jt({ text: () => e.data.is_pinned ? e.ctx.$t("unpin") : e.ctx.$t("pin"), adminOnly: !0 }); t.appendTo(e.$actions), t.setClick((() => { e.comment.getActions().adminEdit("pinned", t) })) } function on(e) { const t = new Jt({ text: e.ctx.$t("edit"), adminOnly: !0 }); t.appendTo(e.$actions), t.setClick((() => { e.ctx.editComment(e.data, e.$el) })) } function an(e) { const t = new Jt({ text: e.ctx.$t("delete"), confirm: !0, confirmText: e.ctx.$t("deleteConfirm"), adminOnly: !0 }); t.appendTo(e.$actions), t.setClick((() => { e.comment.getActions().adminDelete(t) })) } const ln = { Avatar: function(e) { const t = e.$el.querySelector(".atk-avatar"), n = y(""), i = e.conf.avatarURLBuilder; if (n.src = i ? i(e.data) : e.comment.getGravatarURL(), e.data.link) { const i = y(''); i.href = E(e.data.link) ? e.data.link : `https://${e.data.link}`, i.append(n), t.append( i) } else t.append(n) }, Header: function(e) { Object.entries({ renderNick: Kt, renderVerifyBadge: Zt, renderDate: Yt, renderUABadge: Xt }).forEach((([t, n]) => { n(e) })) }, Content: function(e) { if (!e.data.is_collapsed) return e.$content.innerHTML = e.comment.getContentMarked(), void e .$content.classList.remove("atk-hide", "atk-collapsed"); e.$content.classList.add("atk-hide", "atk-type-collapsed"); const t = y( `\n
    \n ${e.ctx.$t("collapsedMsg")}\n ${e.ctx.$t("expand")}\n
    ` ); e.$body.insertAdjacentElement("beforeend", t); const n = t.querySelector(".atk-show-btn"); n.addEventListener("click", (t => { t.stopPropagation(), e.$content.classList.contains("atk-hide") ? (e.$content .innerHTML = e.comment.getContentMarked(), e.$content.classList .remove("atk-hide"), Ot(e.$content), n.innerText = e.ctx.$t( "collapse")) : (e.$content.innerHTML = "", e.$content.classList .add("atk-hide"), n.innerText = e.ctx.$t("expand")) })) }, ReplyAt: function(e) { e.cConf.isFlatMode || 0 === e.data.rid || e.cConf.replyTo && (e.$replyAt = y( '' ), e.$replyAt.querySelector(".atk-nick").innerText = `${e.cConf.replyTo.nick}`, e.$replyAt.onclick = () => { e.comment.getActions().goToReplyComment() }, e.$headerBadgeWrap.insertAdjacentElement("afterend", e.$replyAt)) }, ReplyTo: function(e) { if (!e.cConf.isFlatMode) return; if (!e.cConf.replyTo) return; e.$replyTo = y( `\n
    \n
    ${e.ctx.$t("reply")} :
    \n
    \n
    ` ); const t = e.$replyTo.querySelector(".atk-nick"); t.innerText = `@${e.cConf.replyTo.nick}`, t.onclick = () => { e.comment.getActions().goToReplyComment() }; let n = yt(e.cConf.replyTo.content); e.cConf.replyTo.is_collapsed && (n = `[${$(e.ctx.$t("collapsed"))}]`), e.$replyTo .querySelector(".atk-content").innerHTML = n, e.$body.prepend(e.$replyTo) }, Pending: function(e) { if (!e.data.is_pending) return; const t = y(`
    ${e.ctx.$t("pendingMsg")}
    `); e.$body.prepend(t) }, Actions: function(e) { Object.entries({ renderVote: en, renderReply: tn, renderCollapse: nn, renderModerator: sn, renderPin: rn, renderEdit: on, renderDel: an }).forEach((([t, n]) => { n(e) })) } }; class cn { constructor(e) { g(this, "comment"), g(this, "$el"), g(this, "$main"), g(this, "$header"), g(this, "$headerNick"), g(this, "$headerBadgeWrap"), g(this, "$body"), g(this, "$content"), g(this, "$childrenWrap"), g(this, "$actions"), g(this, "voteBtnUp"), g(this, "voteBtnDown"), g( this, "$replyTo"), g(this, "$replyAt"), this.comment = e } get ctx() { return this.comment.ctx } get data() { return this.comment.getData() } get conf() { return this.comment.conf } get cConf() { return this.comment.getConf() } render() { var e; return this.$el = y( '
    \n
    \n
    \n
    \n
    \n \n \n \n
    \n
    \n
    \n
    \n \n
    \n
    \n
    \n' ), this.$main = this.$el.querySelector(".atk-main"), this.$header = this.$el .querySelector(".atk-header"), this.$body = this.$el.querySelector(".atk-body"), this .$content = this.$body.querySelector(".atk-content"), this.$actions = this.$el .querySelector(".atk-actions"), this.$el.setAttribute("id", `atk-comment-${this.data.id}`), e = this, Object.entries(ln).forEach((([t, n]) => { n(e) })), this.recoveryChildrenWrap(), this.$el } checkHeightLimit() { const e = this.ctx.conf.heightLimit; if (!e || !e.content || !e.children) return; const t = e.content, n = e.children; Ht({ postExpandBtnClick: () => { const e = this.comment.getChildren(); 1 === e.length && Vt(e[0].getRender().$content) }, scrollable: e.scrollable }, [{ el: this.$content, max: t, imgContains: !0 }, { el: this.$replyTo, max: t, imgContains: !0 }, { el: this.$childrenWrap, max: n, imgContains: !1 }]) } heightLimitRemoveForChildren() { this.$childrenWrap && Vt(this.$childrenWrap) } playFadeAnim() { Ot(this.comment.getRender().$el) } playFadeAnimForBody() { Ot(this.comment.getRender().$body) } getChildrenWrap() { return this.$childrenWrap } renderChildrenWrap() { return this.$childrenWrap || (this.$childrenWrap = y( '
    '), this.$main.append(this.$childrenWrap)), this.$childrenWrap } recoveryChildrenWrap() { this.$childrenWrap && this.$main.append(this.$childrenWrap) } setUnread(e) { e ? this.$el.classList.add("atk-unread") : this.$el.classList.remove("atk-unread") } setOpenable(e) { e ? this.$el.classList.add("atk-openable") : this.$el.classList.remove("atk-openable") } setOpenURL(e) { this.setOpenable(!0), this.$el.onclick = t => { t.preventDefault(), window.open(e), this.cConf.openEvt && this.cConf.openEvt() } } setOpenAction(e) { this.setOpenable(!0), this.$el.onclick = t => { t.preventDefault(), e() } } } class dn { constructor(e) { g(this, "comment"), this.comment = e } get ctx() { return this.comment.ctx } get data() { return this.comment.getData() } get cConf() { return this.comment.getConf() } vote(e) { const t = "up" === e ? this.comment.getRender().voteBtnUp : this.comment.getRender() .voteBtnDown; this.ctx.getApi().comment.vote(this.data.id, `comment_${e}`).then((e => { var t, n; this.data.vote_up = e.up, this.data.vote_down = e.down, null == (t = this .comment.getRender().voteBtnUp) || t.updateText(), null == (n = this .comment.getRender().voteBtnDown) || n.updateText() })).catch((e => { null == t || t.setError(this.ctx.$t("voteFail")), console.log(e) })) } adminEdit(e, t) { if (t.isLoading) return; t.setLoading(!0, `${this.ctx.$t("editing")}...`); const n = u({}, this.data); "collapsed" === e ? n.is_collapsed = !n.is_collapsed : "pending" === e ? n.is_pending = !n .is_pending : "pinned" === e && (n.is_pinned = !n.is_pinned), this.ctx.getApi().comment .commentEdit(n).then((e => { t.setLoading(!1), this.comment.setData(e) })).catch((e => { console.error(e), t.setError(this.ctx.$t("editFail")) })) } adminDelete(e) { e.isLoading || (e.setLoading(!0, `${this.ctx.$t("deleting")}...`), this.ctx.getApi().comment .commentDel(this.data.id, this.data.site_name).then((() => { e.setLoading(!1), this.cConf.onDelete && this.cConf.onDelete(this.comment) })).catch((t => { console.error(t), e.setError(this.ctx.$t("deleteFail")) }))) } goToReplyComment() { const e = window.location.hash, t = `#atk-comment-${this.data.rid}`; window.location.hash = t, t === e && window.dispatchEvent(new Event("hashchange")) } } class hn extends Dt { constructor(e, t, n) { super(e), g(this, "renderInstance"), g(this, "actionInstance"), g(this, "data"), g(this, "cConf"), g(this, "parent"), g(this, "children", []), g(this, "nestCurt"), g(this, "nestMax"), this.nestMax = e.conf.nestMax || 3, this.cConf = n, this.data = u({}, t), this.data.date = this.data.date.replace(/-/g, "/"), this.parent = null, this.nestCurt = 1, this.actionInstance = new dn(this), this.renderInstance = new cn(this) } render() { const e = this.renderInstance.render(); this.$el && this.$el.replaceWith(e), this.$el = e, this.cConf.afterRender && this.cConf .afterRender() } getActions() { return this.actionInstance } getRender() { return this.renderInstance } getData() { return this.data } setData(e) { this.data = e, this.render(), this.getRender().playFadeAnimForBody() } getParent() { return this.parent } getChildren() { return this.children } getNestCurt() { return this.nestCurt } getIsRoot() { return 0 === this.data.rid } getID() { return this.data.id } putChild(e, t = "append") { e.parent = this, e.nestCurt = this.nestCurt + 1, this.children.push(e); const n = this.getChildrenEl(); "append" === t ? n.append(e.getEl()) : "prepend" === t && n.prepend(e.getEl()), e.getRender() .playFadeAnim(), e.getRender().checkHeightLimit() } getChildrenEl() { let e = this.getRender().getChildrenWrap(); return e || (e = this.nestCurt < this.nestMax ? this.getRender().renderChildrenWrap() : this .parent.getChildrenEl()), e } getParents() { const e = [], t = n => { n.parent && (e.push(n.parent), t(n.parent)) }; return t(this), e } getEl() { return this.$el } getGravatarURL() { return `${(e={mirror:this.ctx.conf.gravatar.mirror,params:this.ctx.conf.gravatar.params,emailMD5:this.data.email_encrypted}).mirror.replace(/\/$/,"")}/${e.emailMD5}?${e.params.replace(/^\?/,"")}`; var e } getContentMarked() { return yt(this.data.content) } getDateFormatted() { return C(new Date(this.data.date), this.ctx.$t) } getUserUA() { const e = function(e) { const t = window || {}, n = navigator || {}, i = String(e || n.userAgent), s = { os: "", osVersion: "", engine: "", browser: "", device: "", language: "", version: "" }, r = { Trident: i.includes("Trident") || i.includes("NET CLR"), Presto: i.includes("Presto"), WebKit: i.includes("AppleWebKit"), Gecko: i.includes("Gecko/") }, o = { Safari: i.includes("Safari"), Chrome: i.includes("Chrome") || i.includes("CriOS"), IE: i.includes("MSIE") || i.includes("Trident"), Edge: i.includes("Edge") || i.includes("Edg"), Firefox: i.includes("Firefox") || i.includes("FxiOS"), "Firefox Focus": i.includes("Focus"), Chromium: i.includes("Chromium"), Opera: i.includes("Opera") || i.includes("OPR"), Vivaldi: i.includes("Vivaldi"), Yandex: i.includes("YaBrowser"), Kindle: i.includes("Kindle") || i.includes("Silk/"), 360: i.includes("360EE") || i.includes("360SE"), UC: i.includes("UC") || i.includes(" UBrowser"), QQBrowser: i.includes("QQBrowser"), QQ: i.includes("QQ/"), Baidu: i.includes("Baidu") || i.includes("BIDUBrowser"), Maxthon: i.includes("Maxthon"), Sogou: i.includes("MetaSr") || i.includes("Sogou"), LBBROWSER: i.includes("LBBROWSER"), "2345Explorer": i.includes("2345Explorer"), TheWorld: i.includes("TheWorld"), MIUI: i.includes("MiuiBrowser"), Quark: i.includes("Quark"), Qiyu: i.includes("Qiyu"), Wechat: i.includes("MicroMessenger"), Taobao: i.includes("AliApp(TB"), Alipay: i.includes("AliApp(AP"), Weibo: i.includes("Weibo"), Douban: i.includes("com.douban.frodo"), Suning: i.includes("SNEBUY-APP"), iQiYi: i.includes("IqiyiApp") }, a = { Windows: i.includes("Windows"), Linux: i.includes("Linux") || i.includes("X11"), macOS: i.includes("Macintosh"), Android: i.includes("Android") || i.includes("Adr"), Ubuntu: i.includes("Ubuntu"), FreeBSD: i.includes("FreeBSD"), Debian: i.includes("Debian"), "Windows Phone": i.includes("IEMobile") || i.includes("Windows Phone"), BlackBerry: i.includes("BlackBerry") || i.includes("RIM"), MeeGo: i.includes("MeeGo"), Symbian: i.includes("Symbian"), iOS: i.includes("like Mac OS X"), "Chrome OS": i.includes("CrOS"), WebOS: i.includes("hpwOS") }, l = { Mobile: i.includes("Mobi") || i.includes("iPh") || i.includes("480"), Tablet: i.includes("Tablet") || i.includes("Pad") || i.includes("Nexus 7") }; l.Mobile ? l.Mobile = !i.includes("iPad") : o.Chrome && i.includes("Edg") ? (o .Chrome = !1, o.Edge = !0) : t.showModalDialog && t.chrome && (o.Chrome = !1, o[ 360] = !0), s.device = "PC", s.language = (() => { const e = (n.browserLanguage || n.language).split("-"); return e[1] && (e[1] = e[1].toUpperCase()), e.join("_") })(); const c = { engine: r, browser: o, os: a, device: l }; Object.entries(c).forEach((([e, t]) => { Object.entries(t).forEach((([t, n]) => { !0 === n && (s[e] = t) })) })); const d = { Windows: () => { const e = i.replace(/^.*Windows NT ([\d.]+);.*$/, "$1"); return { 6.4: "10", 6.3: "8.1", 6.2: "8", 6.1: "7", "6.0": "Vista", 5.2: "XP", 5.1: "XP", "5.0": "2000", "10.0": "10", "11.0": "11" } [e] || e }, Android: () => i.replace(/^.*Android ([\d.]+);.*$/, "$1"), iOS: () => i.replace(/^.*OS ([\d_]+) like.*$/, "$1").replace(/_/g, "."), Debian: () => i.replace(/^.*Debian\/([\d.]+).*$/, "$1"), "Windows Phone": () => i.replace(/^.*Windows Phone( OS)? ([\d.]+);.*$/, "$2"), macOS: () => i.replace(/^.*Mac OS X ([\d_]+).*$/, "$1").replace(/_/g, "."), WebOS: () => i.replace(/^.*hpwOS\/([\d.]+);.*$/, "$1") }; s.osVersion = "", d[s.os] && (s.osVersion = d[s.os](), s.osVersion === i && (s .osVersion = "")); const h = { Safari: () => i.replace(/^.*Version\/([\d.]+).*$/, "$1"), Chrome: () => i.replace(/^.*Chrome\/([\d.]+).*$/, "$1").replace( /^.*CriOS\/([\d.]+).*$/, "$1"), IE: () => i.replace(/^.*MSIE ([\d.]+).*$/, "$1").replace(/^.*rv:([\d.]+).*$/, "$1"), Edge: () => i.replace(/^.*(Edge|Edg|Edg[A-Z]{1})\/([\d.]+).*$/, "$2"), Firefox: () => i.replace(/^.*Firefox\/([\d.]+).*$/, "$1").replace( /^.*FxiOS\/([\d.]+).*$/, "$1"), "Firefox Focus": () => i.replace(/^.*Focus\/([\d.]+).*$/, "$1"), Chromium: () => i.replace(/^.*Chromium\/([\d.]+).*$/, "$1"), Opera: () => i.replace(/^.*Opera\/([\d.]+).*$/, "$1").replace( /^.*OPR\/([\d.]+).*$/, "$1"), Vivaldi: () => i.replace(/^.*Vivaldi\/([\d.]+).*$/, "$1"), Yandex: () => i.replace(/^.*YaBrowser\/([\d.]+).*$/, "$1"), Kindle: () => i.replace(/^.*Version\/([\d.]+).*$/, "$1"), Maxthon: () => i.replace(/^.*Maxthon\/([\d.]+).*$/, "$1"), QQBrowser: () => i.replace(/^.*QQBrowser\/([\d.]+).*$/, "$1"), QQ: () => i.replace(/^.*QQ\/([\d.]+).*$/, "$1"), Baidu: () => i.replace(/^.*BIDUBrowser[\s/]([\d.]+).*$/, "$1"), UC: () => i.replace(/^.*UC?Browser\/([\d.]+).*$/, "$1"), Sogou: () => i.replace(/^.*SE ([\d.X]+).*$/, "$1").replace( /^.*SogouMobileBrowser\/([\d.]+).*$/, "$1"), "2345Explorer": () => i.replace(/^.*2345Explorer\/([\d.]+).*$/, "$1"), TheWorld: () => i.replace(/^.*TheWorld ([\d.]+).*$/, "$1"), MIUI: () => i.replace(/^.*MiuiBrowser\/([\d.]+).*$/, "$1"), Quark: () => i.replace(/^.*Quark\/([\d.]+).*$/, "$1"), Qiyu: () => i.replace(/^.*Qiyu\/([\d.]+).*$/, "$1"), Wechat: () => i.replace(/^.*MicroMessenger\/([\d.]+).*$/, "$1"), Taobao: () => i.replace(/^.*AliApp\(TB\/([\d.]+).*$/, "$1"), Alipay: () => i.replace(/^.*AliApp\(AP\/([\d.]+).*$/, "$1"), Weibo: () => i.replace(/^.*weibo__([\d.]+).*$/, "$1"), Douban: () => i.replace(/^.*com.douban.frodo\/([\d.]+).*$/, "$1"), Suning: () => i.replace(/^.*SNEBUY-APP([\d.]+).*$/, "$1"), iQiYi: () => i.replace(/^.*IqiyiVersion\/([\d.]+).*$/, "$1") }; return s.version = "", h[s.browser] && (s.version = h[s.browser](), s.version === i && ( s.version = "")), s.version.indexOf(".") && (s.version = s.version.substring(0, s.version.indexOf("."))), "iOS" === s.os && i.includes("iPad") ? s.os = "iPadOS" : "Edge" !== s.browser || i.includes("Edg") ? "MIUI" === s.browser ? s.os = "Android" : "Chrome" === s.browser && Number(s.version) > 27 || "Opera" === s .browser && Number(s.version) > 12 || "Yandex" === s.browser ? s.engine = "Blink" : void 0 === s.browser && (s.browser = "Unknow App") : s.engine = "EdgeHTML", s }(this.data.ua); return { browser: `${e.browser} ${e.version}`, os: `${e.os} ${e.osVersion}` } } getConf() { return this.cConf } } class un { constructor(e) { g(this, "opts"), g(this, "$el"), g(this, "$loading"), g(this, "$text"), g(this, "offset", 0), g( this, "total", 0), g(this, "origText", "Load More"), this.opts = e, this.origText = this .opts.text || this.origText, this.$el = y( `` ), this.$loading = this.$el.querySelector(".atk-loading-icon"), this.$text = this.$el .querySelector(".atk-text"), this.$el.onclick = () => { this.click() } } get hasMore() { return this.total > this.offset + this.opts.pageSize } click() { this.hasMore && this.opts.onClick(this.offset + this.opts.pageSize), this.checkDisabled() } show() { this.$el.style.display = "" } hide() { this.$el.style.display = "none" } setLoading(e) { this.$loading.style.display = e ? "" : "none", this.$text.style.display = e ? "none" : "" } showErr(e) { this.setLoading(!1), this.$text.innerText = e, this.$el.classList.add("atk-err"), window .setTimeout((() => { this.$text.innerText = this.origText, this.$el.classList.remove("atk-err") }), 2e3) } update(e, t) { this.offset = e, this.total = t, this.checkDisabled() } checkDisabled() { this.hasMore ? this.show() : this.hide() } } class pn { constructor() { g(this, "instance"), g(this, "onReachedBottom", null), g(this, "opt") } create(e) { return this.opt = e, this.instance = new un({ pageSize: e.pageSize, onClick: t => k(this, null, (function*() { e.ctx.fetch({ offset: t }) })), text: D("loadMore") }), e.readMoreAutoLoad && (this.onReachedBottom = () => { this.instance.hasMore && !this.opt.ctx.getData().getLoading() && this.instance .click() }, this.opt.ctx.on("list-reach-bottom", this.onReachedBottom)), this.instance.$el } setLoading(e) { this.instance.setLoading(e) } update(e, t) { this.instance.update(e, t) } showErr(e) { this.instance.showErr(e) } next() { this.instance.click() } getHasMore() { return this.instance.hasMore } getIsClearComments(e) { return 0 === e.offset } dispose() { this.onReachedBottom && this.opt.ctx.off("list-reach-bottom", this.onReachedBottom), this .instance.$el.remove() } } class gn { constructor(e, t) { g(this, "opts"), g(this, "total"), g(this, "$el"), g(this, "$input"), g(this, "inputTimer"), g( this, "$prevBtn"), g(this, "$nextBtn"), g(this, "page", 1), this.total = e, this.opts = t, this.$el = y( '
    \n
    \n
    Prev
    \n \n
    Next
    \n
    \n
    ' ), this.$input = this.$el.querySelector(".atk-input"), this.$input.value = `${this.page}`, this.$input.oninput = () => this.input(), this.$input.onkeydown = e => this .keydown(e), this.$prevBtn = this.$el.querySelector(".atk-btn-prev"), this.$nextBtn = this .$el.querySelector(".atk-btn-next"), this.$prevBtn.onclick = () => this.prev(), this .$nextBtn.onclick = () => this.next(), this.checkDisabled() } get pageSize() { return this.opts.pageSize } get offset() { return this.pageSize * (this.page - 1) } get maxPage() { return Math.ceil(this.total / this.pageSize) } update(e, t) { this.page = Math.ceil(e / this.pageSize) + 1, this.total = t, this.setInput(this.page), this .checkDisabled() } setInput(e) { this.$input.value = `${e}` } input(e = !1) { window.clearTimeout(this.inputTimer); const t = this.$input.value.trim(), n = () => { if ("" === t) return void this.setInput(this.page); let e = Number(t); Number.isNaN(e) || e < 1 ? this.setInput(this.page) : (e > this.maxPage && (this .setInput(this.maxPage), e = this.maxPage), this.change(e)) }; e ? n() : this.inputTimer = window.setTimeout((() => n()), 800) } prev() { const e = this.page - 1; e < 1 || this.change(e) } next() { const e = this.page + 1; e > this.maxPage || this.change(e) } getHasMore() { return this.page + 1 <= this.maxPage } change(e) { this.page = e, this.opts.onChange(this.offset), this.setInput(e), this.checkDisabled() } checkDisabled() { this.page + 1 > this.maxPage ? this.$nextBtn.classList.add("atk-disabled") : this.$nextBtn .classList.remove("atk-disabled"), this.page - 1 < 1 ? this.$prevBtn.classList.add( "atk-disabled") : this.$prevBtn.classList.remove("atk-disabled") } keydown(e) { const t = e.keyCode || e.which; if (38 === t) { const e = Number(this.$input.value) + 1; if (e > this.maxPage) return; this.setInput(e), this.input() } else if (40 === t) { const e = Number(this.$input.value) - 1; if (e < 1) return; this.setInput(e), this.input() } else 13 === t && this.input(!0) } setLoading(e) { e ? Tt(this.$el) : _t(this.$el) } } class mn { constructor() { g(this, "instance") } create(e) { return this.instance = new gn(e.total, { pageSize: e.pageSize, onChange: t => k(this, null, (function*() { e.ctx.editorResetState(), e.ctx.fetch({ offset: t, onSuccess: () => { e.ctx.listGotoFirst() } }) })) }), this.instance.$el } setLoading(e) { this.instance.setLoading(e) } update(e, t) { this.instance.update(e, t) } next() { this.instance.next() } getHasMore() { return this.instance.getHasMore() } getIsClearComments() { return !0 } dispose() { this.instance.$el.remove() } } function fn(e) { const t = e.getData().getListLastFetch(), n = { offset: 0, total: 0 }; return t ? (n.offset = t.params.offset, t.data && (n.total = t.params.flatMode ? t.data.total : t.data .total_roots), n) : n } const kn = e => { let t = null; e.on("conf-loaded", (n => { const i = e.get("list"); t && t.dispose(), t = function(e) { return e.pagination.readMore ? new pn : new mn }(n); const { offset: s, total: r } = fn(e), o = t.create({ ctx: e, pageSize: n.pagination.pageSize, total: r, readMoreAutoLoad: n.pagination.autoLoad }); i.$commentsWrap.after(o), null == t || t.update(s, r) })), e.on("list-loaded", (n => { const { offset: i, total: s } = fn(e); null == t || t.update(i, s) })), e.on("list-fetch", (n => { e.getData().getComments().length > 0 && (null == t ? void 0 : t.getIsClearComments( n)) && e.getData().clearComments() })), e.on("list-error", (() => { var e; null == (e = null == t ? void 0 : t.showErr) || e.call(t, D("loadFail")) })), e.on("list-fetch", (e => { null == t || t.setLoading(!0) })), e.on("list-fetched", (({ params: e }) => { null == t || t.setLoading(!1) })) }; class yn extends Dt { constructor(e) { super(e), g(this, "$commentsWrap"), g(this, "commentNodes", []), this.$el = y( '
    \n
    \n
    \n
    \n
    \n
    \n \n \n \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n \n
    \n' ), this.$commentsWrap = this.$el.querySelector(".atk-list-comments-wrap"), kn(e), this .initCrudEvents() } getCommentsWrapEl() { return this.$commentsWrap } getCommentNodes() { return this.commentNodes } getListLayout() { return new Nt({ $commentsWrap: this.$commentsWrap, nestSortBy: this.ctx.conf.nestSort, nestMax: this.ctx.conf.nestMax, flatMode: this.ctx.conf.flatMode, createCommentNode: (e, t) => { const n = function(e, t, n) { var i; const s = new hn(e, t, { isFlatMode: null == (i = e.getData() .getListLastFetch()) ? void 0 : i.params.flatMode, afterRender: () => { e.trigger("comment-rendered", s) }, onDelete: t => { e.getData().deleteComment(t.getID()) }, replyTo: t.rid ? n.find((e => e.id === t.rid)) : void 0 }); return s.render(), s }(this.ctx, e, t); return this.commentNodes.push(n), n }, findCommentNode: e => this.commentNodes.find((t => t.getID() === e)), getCommentDataList: () => this.ctx.getData().getComments() }) } initCrudEvents() { this.ctx.on("list-load", (e => { this.getListLayout().import(e) })), this.ctx.on("list-loaded", (e => { 0 === e.length && (this.$commentsWrap.innerHTML = "") })), this.ctx.on("comment-inserted", (e => { this.getListLayout().insert(e) })), this.ctx.on("comment-deleted", (e => { const t = this.commentNodes.find((t => t.getID() === e.id)); t ? (t.getEl().remove(), this.commentNodes = this.commentNodes.filter((t => t .getID() !== e.id))) : console.error( `comment node id=${e.id} not found`) })), this.ctx.on("comment-updated", (e => { const t = this.commentNodes.find((t => t.getID() === e.id)); t && t.setData(e) })) } } let vn, $n; function bn() { return { init() { vn = document.body.style.overflow, $n = document.body.style.paddingRight }, unlock() { document.body.style.overflow = vn, document.body.style.paddingRight = $n }, lock() { document.body.style.overflow = "hidden"; const e = parseInt(window.getComputedStyle(document.body, null).getPropertyValue( "padding-right"), 10); document.body.style.paddingRight = `${function(){const e=document.createElement("p");e.style.width="100%",e.style.height="200px";const t=document.createElement("div");t.style.position="absolute",t.style.top="0px",t.style.left="0px",t.style.visibility="hidden",t.style.width="200px",t.style.height="150px",t.style.overflow="hidden",t.appendChild(e),document.body.appendChild(t);const n=e.offsetWidth;t.style.overflow="scroll";let i=e.offsetWidth;return n===i&&(i=t.clientWidth),document.body.removeChild(t),n-i}()+e||0}px` } } } class wn { constructor() { g(this, "$wrap"), g(this, "$mask"), g(this, "allowMaskClose", !0), g(this, "items", []), this .$wrap = y( '' ), this.$mask = this.$wrap.querySelector(".atk-layer-mask") } createItem(e, t) { return t || ((t = document.createElement("div")).classList.add("atk-layer-item"), t .setAttribute("data-layer-name", e), t.style.display = "none"), this.$wrap.appendChild( t), this.items.push(t), t } getWrap() { return this.$wrap } getMask() { return this.$mask } setMaskClose(e) { this.allowMaskClose = e } show() { this.$wrap.style.display = "block", this.$mask.style.display = "block", this.$mask.classList .add("atk-fade-in"), this.$mask.onclick = () => { this.allowMaskClose && this.hide() }, bn().lock() } hide(e) { if (this.items.filter((e => e.isConnected && "none" !== e.style.display)).length > 1) return void(e && e()); const t = () => { this.$wrap.style.display = "none", this.$wrap.classList.remove("atk-fade-out"), e && e(), bn().unlock(), this.$wrap.onanimationend = null }; this.$wrap.classList.add("atk-fade-out"), "none" !== window.getComputedStyle(this.$wrap)[ "animation-name"] ? this.$wrap.onanimationend = () => t() : t() } } class xn { constructor(e, t, n) { g(this, "$el"), g(this, "wrap"), g(this, "onAfterHide"), this.wrap = e, this.$el = this.wrap .createItem(t, n) } setOnAfterHide(e) { this.onAfterHide = e } getEl() { return this.$el } show() { this.$el.style.display = "", this.wrap.show() } hide() { this.wrap.hide((() => { this.$el.style.display = "none", this.onAfterHide && this.onAfterHide() })) } destroy() { this.wrap.hide((() => { this.$el.remove(), this.onAfterHide && this.onAfterHide() })) } } class Cn { constructor(e) { g(this, "wrap"), g(this, "ctx"), this.ctx = e, this.wrap = new wn, document.body.appendChild( this.wrap.getWrap()), e.on("destroy", (() => { this.wrap.getWrap().remove() })), bn().init() } getEl() { return this.wrap.getWrap() } create(e, t) { return new xn(this.wrap, e, t) } } const Sn = "ArtalkUser"; class En { constructor(e) { g(this, "data"), this.opts = e; const t = JSON.parse(window.localStorage.getItem(Sn) || "{}"); this.data = { nick: t.nick || "", email: t.email || "", link: t.link || "", token: t.token || "", isAdmin: t.isAdmin || !1 } } getData() { return this.data } update(e = {}) { Object.entries(e).forEach((([e, t]) => { this.data[e] = t })), window.localStorage.setItem(Sn, JSON.stringify(this.data)), this.opts.onUserChanged && this.opts.onUserChanged(this.data) } logout() { this.update({ token: "", isAdmin: !1 }) } checkHasBasicUserInfo() { return !!this.data.nick && !!this.data.email } } const Tn = { i18n(e) { U(e.conf.locale), e.on("conf-loaded", (() => { U(e.conf.locale) })) }, user: e => new En({ onUserChanged: t => { e.trigger("user-changed", t) } }), layerManager: e => new Cn(e), checkerLauncher: e => new Ut({ getCtx: () => e, getApi: () => e.getApi(), getIframeURLBase: () => e.conf.server, onReload: () => e.reload() }), editor(e) { const t = new Wt(e); return e.$root.appendChild(t.$el), t }, list(e) { const t = new yn(e); return e.$root.appendChild(t.$el), t }, sidebarLayer: e => new jt(e), editorPlugs() {} }; function _n(e) { const t = y(`${e.errMsg},${D("listLoadFailMsg")}
    `); if (e.retryFn) { const n = y(`${D("listRetry")}`); n.onclick = () => e.retryFn && e.retryFn(), t.appendChild(n) } if (e.onOpenSidebar) { const n = y( ` | ${D("open")+D("ctrlCenter")}` ); t.appendChild(n), n.onclick = () => e.onOpenSidebar && e.onOpenSidebar() } Pt(e.$err, t) } function Ln(e) { e.getApi().system.conf().then((t => { let n = { apiVersion: t.version.version }; if (e.conf.useBackendConf) { if (!t.frontend_conf) throw new Error( "The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled" ); n = u(u({}, n), function(e) { const t = ["el", "pageKey", "pageTitle", "server", "site", "darkMode"]; return Object.keys(e).forEach((n => { t.includes(n) && delete e[n] })), e.emoticons && "string" == typeof e.emoticons && (e.emoticons = e.emoticons.trim(), e.emoticons.startsWith("[") || e.emoticons .startsWith("{") ? e.emoticons = JSON.parse(e.emoticons) : "false" === e.emoticons && (e.emoticons = !1)), e }(t.frontend_conf)) } e.conf.remoteConfModifier && e.conf.remoteConfModifier(n), e.updateConf(n) })).catch((t => { var n; e.updateConf({}); let i = ""; if (null == (n = t.data) ? void 0 : n.err_no_site) { const t = { create_name: e.conf.site, create_urls: `${window.location.protocol}//${window.location.host}` }; i = `sites|${JSON.stringify(t)}` } throw _n({ $err: e.get("list").$el, errMsg: t.msg || String(t), errData: t.data, retryFn: () => Ln(e), onOpenSidebar: e.get("user").getData().isAdmin ? () => e.showSidebar({ view: i }) : void 0 }), t })).then((() => { e.conf.remoteConfModifier || e.fetch({ offset: 0 }) })).catch((() => {})) } const An = "ArtalkContent"; class On { constructor(e) { this.kit = e } reqAdd() { return k(this, null, (function*() { return yield this.kit.useApi().comment.add(u({}, this.getSubmitAddParams())) })) } getSubmitAddParams() { const { nick: e, email: t, link: n } = this.kit.useUser().getData(), i = this.kit.useConf(); return { content: this.kit.useEditor().getContentFinal(), nick: e, email: t, link: n, rid: 0, page_key: i.pageKey, page_title: i.pageTitle, site_name: i.site } } postSubmitAdd(e) { this.kit.useGlobalCtx().getData().insertComment(e) } } class Pn extends qt { constructor(e) { super(e), g(this, "customs", []), g(this, "defaultPreset"), this.defaultPreset = new On(this .kit); const t = () => this.do(); this.kit.useMounted((() => { this.kit.useGlobalCtx().on("editor-submit", t) })), this.kit.useUnmounted((() => { this.kit.useGlobalCtx().off("editor-submit", t) })) } registerCustom(e) { this.customs.push(e) } do() { return k(this, null, (function*() { if ("" === this.kit.useEditor().getContentFinal().trim()) return void this.kit .useEditor().focus(); const e = this.customs.find((e => e.activeCond())); this.kit.useEditor().showLoading(); try { let t; (null == e ? void 0 : e.pre) && e.pre(), t = (null == e ? void 0 : e.req) ? yield e.req(): yield this.defaultPreset.reqAdd(), (null == e ? void 0 : e.post) ? e.post(t) : this.defaultPreset.postSubmitAdd(t) } catch (t) { return console.error(t), void this.kit.useEditor().showNotify( `${D("commentFail")},${t.msg||String(t)}`, "e") } finally { this.kit.useEditor().hideLoading() } this.kit.useEditor().reset(), this.kit.useGlobalCtx().trigger( "editor-submitted") })) } } class Rn extends qt { constructor(e) { super(e), g(this, "emoticons", []), g(this, "loadingTask", null), g(this, "$grpWrap"), g(this, "$grpSwitcher"), g(this, "isListLoaded", !1), g(this, "isImgLoaded", !1), this.kit .useMounted((() => { this.usePanel('
    '), this.useBtn(D( "emoticon")) })), this.kit.useUnmounted((() => {})), this.useContentTransformer((e => this .transEmoticonImageText(e))), this.usePanelShow((() => { (() => { k(this, null, (function*() { yield this.loadEmoticonsData(), this.isImgLoaded || ( this.initEmoticonsList(), this.isImgLoaded = !0 ), setTimeout((() => { this.changeListHeight() }), 30) })) })() })), this.usePanelHide((() => { this.$panel.parentElement.style.height = "" })), window.setTimeout((() => { this.loadEmoticonsData() }), 1e3) } loadEmoticonsData() { return k(this, null, (function*() { this.isListLoaded || (null === this.loadingTask ? (this.loadingTask = (() => k( this, null, (function*() { Tt(this.$panel), this.emoticons = yield this .handleData(this.kit.useConf().emoticons), _t(this.$panel), this.loadingTask = null, this.isListLoaded = !0 })))(), yield this.loadingTask) : yield this.loadingTask) })) } handleData(e) { return k(this, null, (function*() { if (!Array.isArray(e) && ["object", "string"].includes(typeof e) && (e = [e]), ! Array.isArray(e)) return Pt(this.$panel, "表情包数据必须为 Array/Object/String 类型"), _t(this.$panel), []; const t = t => { "object" == typeof t && (t.name && e.find((e => e.name === t.name)) || e .push(t)) }, n = e => k(this, null, (function*() { yield Promise.all(e.map(((e, i) => k(this, null, (function*() { if ("object" != typeof e || Array .isArray(e)) { if (Array.isArray(e)) yield n( e); else if ("string" == typeof e) { const i = yield this .remoteLoad(e); Array.isArray(i) ? yield n( i): "object" == typeof i && t(i) } } else t(e) }))))) })); return yield n(e), e.forEach((e => { if (this.isOwOFormat(e)) { this.convertOwO(e).forEach((e => { t(e) })) } else Array.isArray(e) && e.forEach((e => { t(e) })) })), e = e.filter((e => "object" == typeof e && !Array.isArray(e) && !! e && !!e.name)), this.solveNullKey(e), this.solveSameKey(e), e })) } remoteLoad(e) { return k(this, null, (function*() { if (!e) return []; try { const t = yield fetch(e); return yield t.json() } catch (t) { return _t(this.$panel), console.error("[Emoticons] Load Failed:", t), Pt( this.$panel, `${D("emoticon")}${D("loadFail")} ${String(t)}`), [] } })) } solveNullKey(e) { e.forEach((e => { e.items.forEach(((t, n) => { t.key || (t.key = `${e.name} ${n+1}`) })) })) } solveSameKey(e) { const t = {}; e.forEach((e => { e.items.forEach((e => { e.key && "" !== String(e.key).trim() && (t[e.key] ? t[e.key]++ : t[e.key] = 1, t[e.key] > 1 && (e.key = `${e.key} ${t[e.key]}`)) })) })) } isOwOFormat(e) { try { return "object" == typeof e && !!Object.values(e).length && Array.isArray(Object.keys(Object .values(e)[0].container)) && Object.keys(Object.values(e)[0].container[0]).includes( "icon") } catch (t) { return !1 } } convertOwO(e) { const t = []; return Object.entries(e).forEach((([e, n]) => { const i = { name: e, type: n.type, items: [] }; n.container.forEach(((t, n) => { const s = t.icon; if (/<(img|IMG)/.test(s)) { const e = /src=["'](.*?)["']/.exec(s); e && e.length > 1 && (t.icon = e[1]) } i.items.push({ key: t.text || `${e} ${n+1}`, val: t.icon }) })), t.push(i) })), t } initEmoticonsList() { this.$grpWrap = y('
    '), this.$panel.append(this.$grpWrap), this .emoticons.forEach(((e, t) => { const n = y(''); this.$grpWrap.append(n), n.setAttribute("data-index", String(t)), n .setAttribute("data-grp-name", e.name), n.setAttribute("data-type", e.type), e.items.forEach((t => { const i = y(''); if (n.append(i), t.key && !new RegExp( `^(${e.name})?\\s?[0-9]+$`).test(t.key) && i .setAttribute("title", t.key), "image" === e.type) { const e = document.createElement("img"); e.src = t.val, e.alt = t.key, i.append(e) } else i.innerText = t.val; i.onclick = () => { "image" === e.type ? this.kit.useEditor().insertContent( `:[${t.key}]`) : this.kit.useEditor() .insertContent(t.val || "") } })) })), this.emoticons.length > 1 && (this.$grpSwitcher = y( '
    '), this.$panel.append(this.$grpSwitcher), this .emoticons.forEach(((e, t) => { const n = y(""); n.innerText = e.name, n.setAttribute("data-index", String(t)), n.onclick = () => this.openGrp(t), this.$grpSwitcher.append(n) }))), this.emoticons.length > 0 && this.openGrp(0) } openGrp(e) { var t, n, i; Array.from(this.$grpWrap.children).forEach((t => { const n = t; n.getAttribute("data-index") !== String(e) ? n.style.display = "none" : n.style .display = "" })), null == (t = this.$grpSwitcher) || t.querySelectorAll("span.active").forEach((e => e .classList.remove("active"))), null == (i = null == (n = this.$grpSwitcher) ? void 0 : n .querySelector(`span[data-index="${e}"]`)) || i.classList.add("active"), this .changeListHeight() } changeListHeight() {} transEmoticonImageText(e) { return this.emoticons && Array.isArray(this.emoticons) ? (this.emoticons.forEach((t => { "image" === t.type && Object.entries(t.items).forEach((([t, n]) => { e = e.split(`:[${n.key}]`).join( ``) })) })), e) : e } } const Mn = ["png", "jpg", "jpeg", "gif", "bmp", "svg", "webp"]; class In extends qt { constructor(e) { super(e), g(this, "$imgUploadInput"), this.kit.useMounted((() => this.init())), this .initDragImg() } init() { this.$imgUploadInput = document.createElement("input"), this.$imgUploadInput.type = "file", this .$imgUploadInput.style.display = "none", this.$imgUploadInput.accept = Mn.map((e => `.${e}`)).join(","); const e = this.useBtn(`${D("image")}`); e.after(this.$imgUploadInput), e.onclick = () => { const e = this.$imgUploadInput; e.onchange = () => { (() => { k(this, null, (function*() { if (!e.files || 0 === e.files.length) return; const t = e.files[0]; this.uploadImg(t) })) })() }, e.click() }, this.kit.useConf().imgUpload || this.$btn.setAttribute("atk-only-admin-show", "") } initDragImg() { const e = e => { if (e) for (let t = 0; t < e.length; t++) { const n = e[t]; this.uploadImg(n) } }, t = e => { e.stopPropagation(), e.preventDefault() }, n = t => { var n; const i = null == (n = t.dataTransfer) ? void 0 : n.files; (null == i ? void 0 : i.length) && (t.preventDefault(), e(i)) }, i = t => { var n; const i = null == (n = t.clipboardData) ? void 0 : n.files; (null == i ? void 0 : i.length) && (t.preventDefault(), e(i)) }; this.kit.useMounted((() => { this.kit.useUI().$textarea.addEventListener("dragover", t), this.kit.useUI() .$textarea.addEventListener("drop", n), this.kit.useUI().$textarea .addEventListener("paste", i) })), this.kit.useUnmounted((() => { this.kit.useUI().$textarea.removeEventListener("dragover", t), this.kit.useUI() .$textarea.removeEventListener("drop", n), this.kit.useUI().$textarea .removeEventListener("paste", i) })) } uploadImg(e) { return k(this, null, (function*() { const t = /[^.]+$/.exec(e.name); if (!t || !Mn.includes(t[0])) return; if (!this.kit.useUser().checkHasBasicUserInfo()) return void this.kit .useEditor().showNotify(D("uploadLoginMsg"), "w"); let n = "\n"; "" === this.kit.useUI().$textarea.value.trim() && (n = ""); const i = `${n}![](Uploading ${e.name}...)`; let s; this.kit.useEditor().insertContent(i); try { const t = this.kit.useConf().imgUploader; s = t ? { img_url: yield t(e) } : yield this.kit.useApi().upload.imgUpload(e) } catch (r) { console.error(r), this.kit.useEditor().showNotify( `${D("uploadFail")},${r.msg}`, "e") } if (s && s.img_url) { let e = s.img_url; E(e) || (e = T({ base: this.kit.useConf().server, path: e })), this.kit.useEditor().setContent(this.kit.useUI().$textarea.value .replace(i, `${n}![](${e})`)) } else this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace( i, "")) })) } } class Un extends qt { constructor(e) { super(e), g(this, "isPlugPanelShow", !1), this.kit.useMounted((() => { this.usePanel('
    '); let e = D("preview"); kt() && (e += ' ' ), this.useBtn(e) })), this.kit.useUnmounted((() => {})), this.kit.useEvents().on("content-updated", (e => { this.isPlugPanelShow && this.updateContent() })), this.usePanelShow((() => { this.isPlugPanelShow = !0, this.updateContent() })), this.usePanelHide((() => { this.isPlugPanelShow = !1 })) } updateContent() { this.$panel.innerHTML = this.kit.useEditor().getContentMarked() } } const Dn = [class extends qt { constructor(e) { super(e); const t = () => { this.save() }; this.kit.useMounted((() => { const e = window.localStorage.getItem(An) || ""; "" !== e.trim() && (this.kit.useEditor().showNotify(D("restoredMsg"), "i"), this.kit.useEditor().setContent(e)), this.kit.useEvents() .on("content-updated", t) })), this.kit.useUnmounted((() => { this.kit.useEvents().off("content-updated", t) })) } save() { window.localStorage.setItem(An, this.kit.useEditor().getContentRaw().trim()) } }, class extends qt { get $inputs() { return this.kit.useEditor().getHeaderInputEls() } constructor(e) { super(e); const t = {}, n = {}, i = (e, t, n) => () => { this.kit.useEvents().trigger(e, { field: n, $input: t }) }; this.kit.useMounted((() => { Object.entries(this.$inputs).forEach((([e, s]) => { s.addEventListener("input", t[e] = i("header-input", s, e)), s.addEventListener("change", n[e] = i("header-change", s, e)) })) })), this.kit.useUnmounted((() => { Object.entries(this.$inputs).forEach((([e, i]) => { i.removeEventListener("input", t[e]), i.removeEventListener( "change", n[e]) })) })) } }, class extends qt { constructor(e) { super(e), g(this, "query", { timer: null, abortFn: null }); const t = ({ $input: e, field: t }) => { "edit" !== this.kit.useEditor().getState() && (this.kit.useUser().update({ [t]: e.value.trim() }), "nick" !== t && "email" !== t || this.fetchUserInfo()) }; this.kit.useMounted((() => { Object.entries(this.kit.useEditor().getHeaderInputEls()).forEach((([e, t]) => { t.placeholder = `${D(e)}`, t.value = this.kit.useUser() .getData()[e] || "" })), this.kit.useEvents().on("header-input", t) })), this.kit.useUnmounted((() => { this.kit.useEvents().off("header-input", t) })) } fetchUserInfo() { this.kit.useUser().logout(), this.query.timer && window.clearTimeout(this.query.timer), this.query.abortFn && this.query.abortFn(), this.query.timer = window.setTimeout(( () => { this.query.timer = null; const { req: e, abort: t } = this.kit.useApi().user.userGet(this.kit.useUser().getData().nick, this.kit.useUser().getData().email); this.query.abortFn = t, e.then((e => this.onUserInfoFetched(e))).catch(( e => {})).finally((() => { this.query.abortFn = null })) }), 400) } onUserInfoFetched(e) { var t; e.is_login || this.kit.useUser().logout(), this.kit.useGlobalCtx().getData() .updateUnreads(e.unread), this.kit.useUser().checkHasBasicUserInfo() && !e .is_login && (null == (t = e.user) ? void 0 : t.is_admin) && this.kit.useGlobalCtx() .checkAdmin({ onSuccess: () => {} }), e.user && e.user.link && (this.kit.useUI().$link.value = e.user.link, this.kit .useUser().update({ link: e.user.link })) } }, class extends qt { constructor(e) { super(e); const t = ({ field: e }) => { "link" === e && this.onLinkInputChange() }; this.kit.useMounted((() => { this.kit.useEvents().on("header-change", t) })), this.kit.useUnmounted((() => { this.kit.useEvents().off("header-change", t) })) } onLinkInputChange() { const e = this.kit.useUI().$link.value.trim(); e && !/^(http|https):\/\//.test(e) && (this.kit.useUI().$link.value = `https://${e}`, this.kit.useUser().update({ link: this.kit.useUI().$link.value })) } }, class extends qt { constructor(e) { super(e); const t = e => this.onKeydown(e), n = () => this.onInput(); this.kit.useMounted((() => { this.kit.useUI().$textarea.placeholder = this.kit.useConf() .placeholder || D("placeholder"), this.kit.useUI().$textarea .addEventListener("keydown", t), this.kit.useUI().$textarea .addEventListener("input", n) })), this.kit.useUnmounted((() => { this.kit.useUI().$textarea.removeEventListener("keydown", t), this.kit .useUI().$textarea.removeEventListener("input", n) })), this.kit.useEvents().on("content-updated", (() => { window.setTimeout((() => { this.adaptiveHeightByContent() }), 80) })) } onKeydown(e) { 9 === (e.keyCode || e.which) && (e.preventDefault(), this.kit.useEditor().insertContent( "\t")) } onInput() { this.kit.useEvents().trigger("content-updated", this.kit.useEditor().getContentRaw()) } adaptiveHeightByContent() { const e = this.kit.useUI().$textarea.offsetHeight - this.kit.useUI().$textarea .clientHeight; this.kit.useUI().$textarea.style.height = "0px", this.kit.useUI().$textarea.style .height = `${this.kit.useUI().$textarea.scrollHeight+e}px` } }, Pn, class extends qt { constructor(e) { super(e); const t = () => { this.kit.useEditor().submit() }; this.kit.useMounted((() => { this.kit.useUI().$submitBtn.innerText = this.kit.useConf().sendBtn || D( "send"), this.kit.useUI().$submitBtn.addEventListener("click", t) })), this.kit.useUnmounted((() => { this.kit.useUI().$submitBtn.removeEventListener("click", t) })) } }, Ft, class extends qt { constructor(e) { super(e), g(this, "comment"), this.useEditorStateEffect("reply", (e => (this.setReply( e), () => { this.cancelReply() }))), this.kit.useEvents().on("mounted", (() => { const e = this.kit.useDeps(Pn); if (!e) throw Error("SubmitPlug not initialized"); const t = new On(this.kit); e.registerCustom({ activeCond: () => !!this.comment, req: () => k(this, null, (function*() { if (!this.comment) throw new Error( "reply comment cannot be empty"); return yield this.kit.useApi().comment.add( p(u({}, t .getSubmitAddParams()), { rid: this.comment.id, page_key: this.comment .page_key, page_title: void 0, site_name: this.comment .site_name })) })), post: e => { const n = this.kit.useConf(); e.page_key !== n.pageKey && window.open( `${e.page_url}#atk-comment-${e.id}`), t .postSubmitAdd(e) } }) })) } setReply(e) { const t = this.kit.useUI(); t.$sendReply || (t.$sendReply = y( `
    ${D("reply")} ×
    ` ), t.$sendReply.querySelector(".atk-text").innerText = `@${e.nick}`, t .$sendReply.addEventListener("click", (() => { this.kit.useEditor().resetState() })), t.$textareaWrap.append(t.$sendReply)), this.comment = e, t.$textarea .focus() } cancelReply() { if (!this.comment) return; const e = this.kit.useUI(); e.$sendReply && (e.$sendReply.remove(), e.$sendReply = void 0), this.comment = void 0 } }, class extends qt { constructor(e) { super(e), g(this, "comment"), g(this, "originalSubmitBtnText", "Send"), this .useEditorStateEffect("edit", (e => (this.edit(e), () => { this.cancelEdit() }))), this.kit.useMounted((() => { const e = this.kit.useDeps(Pn); if (!e) throw Error("SubmitPlug not initialized"); e.registerCustom({ activeCond: () => !!this.comment, req: () => k(this, null, (function*() { const e = { content: this.kit.useEditor() .getContentFinal(), nick: this.kit.useUI().$nick.value, email: this.kit.useUI().$email .value, link: this.kit.useUI().$link.value }; return yield this.kit.useApi().comment .commentEdit(u(u({}, this.comment), e)) })), post: e => { this.kit.useGlobalCtx().getData().updateComment(e) } }) })) } edit(e) { const t = this.kit.useUI(); if (!t.$editCancelBtn) { const e = y( `
    ${D("editCancel")} ×
    ` ); e.onclick = () => { this.kit.useEditor().resetState() }, t.$textareaWrap.append(e), t.$editCancelBtn = e } this.comment = e, t.$header.style.display = "none", t.$nick.value = e.nick || "", t .$email.value = e.email || "", t.$link.value = e.link || "", this.kit.useEditor() .setContent(e.content), t.$textarea.focus(), this.updateSubmitBtnText(D("save")) } cancelEdit() { if (!this.comment) return; const e = this.kit.useUI(); e.$editCancelBtn && (e.$editCancelBtn.remove(), e.$editCancelBtn = void 0), this .comment = void 0; const { nick: t, email: n, link: i } = this.kit.useUser().getData(); e.$nick.value = t, e.$email.value = n, e.$link.value = i, this.kit.useEditor() .setContent(""), this.restoreSubmitBtnText(), e.$header.style.display = "" } updateSubmitBtnText(e) { this.originalSubmitBtnText = this.kit.useUI().$submitBtn.innerText, this.kit.useUI() .$submitBtn.innerText = e } restoreSubmitBtnText() { this.kit.useUI().$submitBtn.innerText = this.originalSubmitBtnText } }, class extends qt { constructor(e) { super(e); const t = () => this.open(), n = () => this.close(); this.kit.useMounted((() => { this.kit.useEvents().on("editor-open", t), this.kit.useEvents().on( "editor-close", n) })), this.kit.useUnmounted((() => { this.kit.useEvents().off("editor-open", t), this.kit.useEvents().off( "editor-close", n) })) } open() { var e; null == (e = this.kit.useUI().$textareaWrap.querySelector(".atk-comment-closed")) || e .remove(), this.kit.useUI().$textarea.style.display = "", this.kit.useUI().$bottom .style.display = "" } close() { this.kit.useUI().$textareaWrap.querySelector(".atk-comment-closed") || this.kit.useUI() .$textareaWrap.prepend(y( `
    ${D("onlyAdminCanReply")}
    `)), this.kit .useUser().getData().isAdmin ? (this.kit.useUI().$textarea.style.display = "", this .kit.useUI().$bottom.style.display = "") : (this.kit.useUI().$textarea.style .display = "none", this.kit.useEvents().trigger("panel-close"), this.kit.useUI() .$bottom.style.display = "none") } }, Rn, In, Un]; class Bn { constructor(e) { this.plugs = e } useEditor() { return this.plugs.editor } useGlobalCtx() { return this.plugs.editor.ctx } useConf() { return this.plugs.editor.ctx.conf } useApi() { return this.plugs.editor.ctx.getApi() } useUser() { return this.plugs.editor.ctx.get("user") } useUI() { return this.plugs.editor.getUI() } useEvents() { return this.plugs.getEvents() } useMounted(e) { this.useEvents().on("mounted", e) } useUnmounted(e) { this.useEvents().on("unmounted", e) } useDeps(e) { return this.plugs.get(e) } } class qn { constructor(e) { g(this, "plugs", []), g(this, "openedPlug", null), g(this, "events", new bt), this.editor = e; let t = !1; this.editor.ctx.on("conf-loaded", (() => { t && this.getEvents().trigger("unmounted"), this.clear(); const e = (n = this.editor.ctx.conf, [{ k: In, v: n.imgUpload }, { k: Rn, v: n.emoticons }, { k: Un, v: n.preview }, { k: Ft, v: n.editorTravel }].filter((e => !e.v)).flatMap((e => e.k))); var n; Dn.filter((t => !e.includes(t))).forEach((e => { const t = new Bn(this); this.plugs.push(new e(t)) })), this.getEvents().trigger("mounted"), t = !0, this.loadPluginUI() })), this.events.on("panel-close", (() => this.closePlugPanel())) } getPlugs() { return this.plugs } getEvents() { return this.events } clear() { this.plugs = [], this.events = new bt, this.openedPlug && this.closePlugPanel() } loadPluginUI() { this.editor.getUI().$plugPanelWrap.innerHTML = "", this.editor.getUI().$plugPanelWrap.style .display = "none", this.editor.getUI().$plugBtnWrap.innerHTML = "", this.plugs.forEach((e => this.loadPluginItem(e))) } loadPluginItem(e) { const t = e.$btn; if (!t) return; this.editor.getUI().$plugBtnWrap.appendChild(t), !t.onclick && (t.onclick = () => { this.editor.getUI().$plugBtnWrap.querySelectorAll(".active").forEach((e => e .classList.remove("active"))), e !== this.openedPlug ? (this.openPlugPanel( e), t.classList.add("active")) : this.closePlugPanel() }); const n = e.$panel; n && (n.style.display = "none", this.editor.getUI().$plugPanelWrap.appendChild(n)) } get(e) { return this.plugs.find((t => t instanceof e)) } openPlugPanel(e) { this.plugs.forEach((t => { const n = t.$panel; n && (t === e ? (n.style.display = "", this.events.trigger("panel-show", e)) : ( n.style.display = "none", this.events.trigger("panel-hide", e))) })), this.editor.getUI().$plugPanelWrap.style.display = "", this.openedPlug = e } closePlugPanel() { this.openedPlug && (this.editor.getUI().$plugPanelWrap.style.display = "none", this.events .trigger("panel-hide", this.openedPlug), this.openedPlug = null) } getTransformedContent(e) { let t = e; return this.plugs.forEach((e => { e.contentTransformer && (t = e.contentTransformer(t)) })), t } } const Fn = "2.7.3"; function zn(e) { return k(this, null, (function*() { e.countEl && document.querySelector(e.countEl) && Wn(e, { query: "page_comment", numEl: e.countEl }); const t = e.pvAdd ? { [e.pageKey]: yield e.getApi().page.pv() } : void 0; e.pvEl && document.querySelector(e.pvEl) && Wn(e, { query: "page_pv", numEl: e.pvEl, data: t }) })) } function Wn(e, t) { return k(this, null, (function*() { let n = t.data || {}, i = Array.from(document.querySelectorAll(t.numEl)).map((t => t.getAttribute( "data-page-key") || e.pageKey)).filter((e => "number" != typeof n[e])); if (i = [...new Set(i)], i.length > 0) { const s = yield e.getApi().page.stat(t.query, i); n = u(u({}, n), s) }! function(e, t, n) { document.querySelectorAll(e).forEach((e => { const i = e.getAttribute("data-page-key"), s = Number(i ? t[i] : n); e.innerHTML = `${s}` })) }(t.numEl, n, n[e.pageKey]) })) } let jn = !1; let Nn; function Hn(e, t) { const n = "atk-dark-mode"; e.forEach((e => { t ? e.classList.add(n) : e.classList.remove(n) })) } const Qn = [...[e => { e.on("inited", (() => { !1 !== e.conf.immediateFetch && e.trigger("conf-fetch") })), e.on("conf-fetch", (() => { Ln(e) })) }, e => { ! function() { try { if (!Ee.name) return } catch (e) { return } Ee.setOptions(u({ renderer: ht() }, ft)), gt = Ee }(), e.on("conf-loaded", (e => { var t; e.markedReplacers && (t = e.markedReplacers, mt = t) })) }, e => { const t = e.get("editor"), n = new qn(t); e.inject("editorPlugs", n) }, e => { const t = () => { var t; t = e.get("user").getData().isAdmin, function(e) { const t = []; e.$root.querySelectorAll("[atk-only-admin-show]").forEach((e => t.push(e))); const n = document.querySelector(".atk-sidebar"); return n && n.querySelectorAll("[atk-only-admin-show]").forEach((e => t .push(e))), t }({ $root: e.$root }).forEach((e => { t ? e.classList.remove("atk-hide") : e.classList.add("atk-hide") })) }; e.on("list-loaded", (() => { t() })), e.on("user-changed", (e => { t() })) }, ...[e => { e.on("list-fetch", (t => { if (e.getData().getLoading()) return; e.getData().setLoading(!0); const n = u({ offset: 0, limit: e.conf.pagination.pageSize, flatMode: e.conf.flatMode, paramsModifier: e.conf.listFetchParamsModifier }, t); e.getData().setListLastFetch({ params: n }), e.getApi().comment.get(n.offset, n.limit, n.flatMode, n .paramsModifier).then((t => { e.getData().setListLastFetch({ params: n, data: t }), e.getData().loadComments(t.comments), e .getData().updatePage(t.page), e.getData() .updateUnreads(t.unread || []), n.onSuccess && n .onSuccess(t), e.trigger("list-fetched", { params: n, data: t }) })).catch((t => { const i = { msg: t.msg || String(t), data: t.data }; throw n.onError && n.onError(i), e.trigger("list-error", i), e.trigger("list-fetched", { params: n, error: i }), t })).finally((() => { e.getData().setLoading(!1) })) })) }, e => { e.on("list-fetch", (t => { const n = e.get("list"); 0 === t.offset && Lt(!0, n.$el) })), e.on("list-fetched", (() => { Lt(!1, e.get("list").$el) })) }, e => { e.on("comment-rendered", (t => { if (!0 === e.conf.listUnreadHighlight) { const n = e.getData().getUnreads(), i = n.find((e => e.comment_id === t.getID())); i ? (t.getRender().setUnread(!0), t.getRender().setOpenAction(( () => { window.open(i.read_link), e.getData() .updateUnreads(n.filter((e => e .comment_id !== t.getID()))) }))) : t.getRender().setUnread(!1) } })), e.on("list-goto", (t => { const n = b("atk_notify_key"); n && e.getApi().user.markRead(t, n).then((() => { e.getData().updateUnreads(e.getData().getUnreads() .filter((e => e.comment_id !== t))) })) })) }, e => { let t; e.on("inited", (() => { const n = e.get("list"); t = n.$el.querySelector('[data-action="admin-close-comment"]'), t .addEventListener("click", (() => { const t = e.getData().getPage(); if (!t) throw new Error("Page data not found"); t.admin_only = !t.admin_only, function(e, t) { e.editorShowLoading(), e.getApi().page.pageEdit( t).then((t => { e.getData().updatePage(t) })).catch((t => { e.editorShowNotify( `${D("editFail")}: ${t.msg||String(t)}`, "e") })).finally((() => { e.editorHideLoading() })) }(e, t) })) })), e.on("page-loaded", (n => { var i, s; const r = e.get("editor"); !0 === (null == n ? void 0 : n.admin_only) ? (null == (i = r .getPlugs()) || i.getEvents().trigger("editor-close"), t && (t .innerText = D("openComment"))) : (null == (s = r .getPlugs()) || s.getEvents().trigger("editor-open"), t && (t .innerText = D("closeComment"))) })), e.on("list-loaded", (t => { e.editorResetState() })) }, e => { e.on("list-loaded", (() => { (() => { var t, n; const i = e.get("list").$el.querySelector( ".atk-comment-count .atk-text"); if (!i) return; const s = $(D("counter", { count: `${Number(null==(n=null==(t=e.getData().getListLastFetch())?void 0:t.data)?void 0:n.total)||0}` })); i.innerHTML = s.replace(/(\d+)/, '$1') })() })), e.on("comment-inserted", (() => { const t = e.getData().getListLastFetch(); (null == t ? void 0 : t.data) && (t.data.total += 1) })), e.on("comment-deleted", (() => { const t = e.getData().getListLastFetch(); (null == t ? void 0 : t.data) && (t.data.total -= 1) })) }, e => { let t = null; const n = () => { if (!t) return; const n = e.get("user").getData(); if (n.nick && n.email) { t.classList.remove("atk-hide"); const e = t.querySelector(".atk-text"); e && (e.innerText = n.isAdmin ? D("ctrlCenter") : D("msgCenter")) } else t.classList.add("atk-hide") }; e.on("conf-loaded", (() => { const i = e.get("list"); t = i.$el.querySelector('[data-action="open-sidebar"]'), t && (t .onclick = () => { e.showSidebar() }, n()) })), e.on("user-changed", (e => { n() })) }, e => { let t = null; e.on("conf-loaded", (() => { const n = e.get("list"); t = n.$el.querySelector(".atk-unread-badge") })), e.on("unreads-updated", (e => { var n; n = e.length || 0, t && (n > 0 ? (t.innerText = `${Number(n||0)}`, t .style.display = "block") : t.style.display = "none") })) }, e => { const t = t => { e.conf.listFetchParamsModifier = t, e.reload() }, n = e => { ! function(e) { const { $dropdownWrap: t, dropdownList: n } = e; if (t.querySelector(".atk-dropdown")) return; t.classList.add("atk-dropdown-wrap"), t.append(y( '')); let i = 0; const s = (e, t, n, s) => { s(), i = e, r.querySelectorAll(".active").forEach((e => { e.classList.remove("active") })), t.classList.add("active"), r.style.display = "none", setTimeout((() => { r.style.display = "" }), 80) }, r = y(''); n.forEach(((e, t) => { const n = e[0], o = e[1], a = y( '
  • '), l = a.querySelector("span"); l.innerText = n, l.onclick = () => { s(t, a, n, o) }, r.append(a), t === i && a.classList.add("active") })), t.append(r) }({ $dropdownWrap: e, dropdownList: [ [D("sortLatest"), () => { t((e => { e.sort_by = "date_desc" })) }], [D("sortBest"), () => { t((e => { e.sort_by = "vote" })) }], [D("sortOldest"), () => { t((e => { e.sort_by = "date_asc" })) }], [D("sortAuthor"), () => { t((e => { e.view_only_admin = !0 })) }] ] }) }; e.on("conf-loaded", (() => { const t = e.get("list").$el.querySelector(".atk-comment-count"); t && (e.conf.listSort ? n(t) : function(e) { var t, n; const { $dropdownWrap: i } = e; i.classList.remove("atk-dropdown-wrap"), null == (t = i .querySelector(".atk-arrow-down-icon")) || t .remove(), null == (n = i.querySelector( ".atk-dropdown")) || n.remove() }({ $dropdownWrap: t })) })) }, e => { let t = !0; const n = () => { const n = function() { let e = Number(b("atk_comment")); if (!e) { const t = window.location.hash.match(/#atk-comment-([0-9]+)/); if (!t || !t[1] || Number.isNaN(Number(t[1]))) return null; e = Number(t[1]) } return e || null }(); n && (e.trigger("list-goto", n), t = !0) }, i = () => { t = !1, n() }; e.on("inited", (() => { window.addEventListener("hashchange", i), e.on("list-loaded", n) })), e.on("destroy", (() => { window.removeEventListener("hashchange", i), e.off("list-loaded", n) })); let s = 0; e.on("list-goto", (n => { if (s === n) return; const i = e.get("list").getCommentNodes().find((e => e.getID() === n)); if (!i) return; s = n, i.getParents().forEach((e => { e.getRender().heightLimitRemoveForChildren() })); const r = () => { At(i.getEl(), !1), i.getEl().classList.remove("atk-flash-once"), window.setTimeout((() => { i.getEl().classList.add("atk-flash-once") }), 150) }; t ? window.setTimeout((() => r()), 350) : r() })) }, e => { e.on("list-loaded", (t => { const n = e.get("list"), i = t.length <= 0; let s = n.getCommentsWrapEl().querySelector(".atk-list-no-comment"); i ? s || (s = y('
    '), s .innerHTML = at(n.ctx.conf.noComment || n.ctx.$t("noComment")), n.getCommentsWrapEl().appendChild(s)) : null == s || s.remove() })) }, e => { e.on("conf-loaded", (() => { const t = e.get("list").$el.querySelector(".atk-copyright"); t && (t.innerHTML = `Powered By Artalk` ) })) }, e => { let t = null; e.on("inited", (() => { t = window.setInterval((() => { e.get("list").$el.querySelectorAll( "[data-atk-comment-date]").forEach((t => { const n = t.getAttribute( "data-atk-comment-date"); t.innerText = C(new Date(Number(n)), e .$t) })) }), 3e4) })), e.on("destroy", (() => { t && window.clearInterval(t) })) }, e => { e.on("list-fetch", (() => { Pt(e.get("list").$el, null) })), e.on("list-error", (t => { _n({ $err: e.get("list").$el, errMsg: t.msg, errData: t.data, retryFn: () => e.fetch({ offset: 0 }) }) })) }, e => { const t = document; let n = null; const i = () => { null == n || n.disconnect(), n = null }; e.on("list-loaded", (() => { i(); const s = e.get("list").getCommentsWrapEl().querySelector( ".atk-comment-wrap:nth-last-child(3)"); s && ("IntersectionObserver" in window ? (s => { n = new IntersectionObserver((([t]) => { t.isIntersecting && (i(), e.trigger( "list-reach-bottom")) }), { root: t }), n.observe(s) })(s) : console.warn("IntersectionObserver api not supported")) })), e.on("destroy", (() => { i() })) }, e => { const t = () => { const t = e.get("list"), n = e.conf.scrollRelativeTo && e.conf.scrollRelativeTo(); (n || window).scroll({ top: w(t.$el, n).top, left: 0 }) }; e.on("inited", (() => { e.on("list-goto-first", t) })), e.on("destroy", (() => { e.off("list-goto-first", t) })) }], e => { e.on("conf-loaded", (() => { zn({ getApi: () => e.getApi(), pageKey: e.conf.pageKey, countEl: e.conf.countEl, pvEl: e.conf.pvEl, pvAdd: !0 }) })) }, e => { e.on("conf-loaded", (() => { const t = e.get("list"); e.conf.apiVersion && e.conf.versionCheck && !jn && function(e, t, n) { const i = function(e, t) { const n = e.split("."), i = t.split("."); for (let s = 0; s < 3; s++) { const e = Number(n[s]), t = Number(i[s]); if (e > t) return 1; if (t > e) return -1; if (!Number.isNaN(e) && Number.isNaN(t)) return 1; if (Number.isNaN(e) && !Number.isNaN(t)) return -1 } return 0 }(t, n); if (0 === i) return; const s = y( `
    ${D("updateMsg",{name:D(i<0?"frontend":"backend")})}

    ${D("currentVersion")}: ${D("frontend")} ${t} / ${D("backend")} ${n}

    ` ), r = y(`${D("ignore")}`); r.onclick = () => { Pt(e.$el.parentElement, null), jn = !0, e.ctx.fetch({ offset: 0 }) }, s.append(r), Pt(e.$el.parentElement, s, 'Artalk Warn') }(t, Fn, e.conf.apiVersion) })) }, e => { let t; const n = n => { const i = [e.$root, e.get("layerManager").getEl()]; Nn || (Nn = window.matchMedia("(prefers-color-scheme: dark)")), "auto" === n ? (t || (t = e => Hn(i, e.matches), Nn.addEventListener("change", t)), Hn(i, Nn .matches)) : (t && (Nn.removeEventListener("change", t), t = void 0), Hn(i, n)) }; e.on("inited", (() => n(e.conf.darkMode))), e.on("conf-loaded", (e => n(e.darkMode))), e.on( "dark-mode-changed", (e => n(e))), e.on("destroy", (() => { t && (null == Nn || Nn.removeEventListener("change", t)), t = void 0 })) }]]; class Vn { constructor(e) { g(this, "ctx"), g(this, "plugins", [...Qn]); const t = xt(e, !0); this.ctx = new St(t), Object.entries(Tn).forEach((([e, t]) => { const n = t(this.ctx); n && this.ctx.inject(e, n) })), this.plugins.forEach((e => { "function" == typeof e && e(this.ctx) })), this.ctx.trigger("inited") } getConf() { return this.ctx.getConf() } getEl() { return this.ctx.$root } update(e) { return this.ctx.updateConf(e), this } reload() { this.ctx.reload() } destroy() { this.ctx.trigger("destroy"), this.ctx.$root.remove() } on(e, t) { this.ctx.on(e, t) } off(e, t) { this.ctx.off(e, t) } trigger(e, t) { this.ctx.trigger(e, t) } setDarkMode(e) { this.ctx.setDarkMode(e) } static init(e) { return new Vn(e) } static use(e) { Qn.includes(e) || Qn.push(e) } static loadCountWidget(e) { const t = xt(e, !0); zn({ getApi: () => new W(Ct(t)), pageKey: t.pageKey, countEl: t.countEl, pvEl: t.pvEl, pvAdd: !1 }) } get $root() { return this.ctx.$root } get conf() { return this.ctx.getConf() } } const Gn = Vn.init, Kn = Vn.use, Zn = Vn.loadCountWidget; e.default = Vn, e.init = Gn, e.loadCountWidget = Zn, e.use = Kn, Object.defineProperties(e, { __esModule: { value: !0 }, [Symbol.toStringTag]: { value: "Module" } }) })); //# sourceMappingURL=Artalk.js.map