UPToZ
d19c1191ef
detailed: 1.增加了侧栏中的小板报、最新评论、最近发布、爱发电、广告、文章目录、分类的图标颜色。 2.增加了对侧栏的广告图片鼠标移入图片轻微放大的效果。 3.增加了爱发电API请求失败时的默认显示。 4.修改了侧栏中的标题与图标之间的间距。 5.修改了侧栏中爱发电内容区域的边距。
6413 lines
194 KiB
JavaScript
6413 lines
194 KiB
JavaScript
! 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 && /^<a /i.test(t[0]) ? this.lexer.state.inLink = !0 :
|
||
this.lexer.state.inLink && /^<\/a>/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)) {
|
||
if (!/>$/.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(n) && (n = this.options.pedantic && !/>$/.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]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\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 = /<!--(?!-?>)[\s\S]*?(?:-->|$)/, 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",
|
||
"</?(?:tag)(?: +|\\n|/?>)|<(?: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", "</?(?:tag)(?: +|\\n|/?>)|<(?: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",
|
||
"</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", me._tag).getRegex(),
|
||
me.pedantic = p(u({}, me.normal), {
|
||
html: ne(
|
||
"^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\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: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\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:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\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]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
|
||
punctuation: /^((?![*_])[\spunctuation])/
|
||
};
|
||
|
||
function ke(e) {
|
||
return e.replace(/---/g, "—").replace(/--/g, "–").replace(/(^|[-\u2014/(\[{"\s])'/g, "$1‘").replace(
|
||
/'/g, "’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1“").replace(/"/g, "”").replace(/\.{3}/g,
|
||
"…")
|
||
}
|
||
|
||
function ye(e) {
|
||
let t = "";
|
||
for (let n = 0; n < e.length; n++) {
|
||
t += "&#" + (Math.random() > .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]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
|
||
}), fe.gfm.url = ne(fe.gfm.url, "i").replace("email", fe.gfm._extended_email).getRegex(), fe.breaks = p(
|
||
u({}, fe.gfm), {
|
||
br: ne(fe.br).replace("{2,}", "*").getRegex(),
|
||
text: ne(fe.gfm.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
|
||
});
|
||
class ve {
|
||
constructor(e) {
|
||
g(this, "tokens"), g(this, "options"), g(this, "state"), g(this, "tokenizer"), g(this,
|
||
"inlineQueue"), this.tokens = [], this.tokens.links = Object.create(null), this
|
||
.options = e || N, this.options.tokenizer = this.options.tokenizer || new ge, this
|
||
.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer
|
||
.lexer = this, this.inlineQueue = [], this.state = {
|
||
inLink: !1,
|
||
inRawBlock: !1,
|
||
top: !0
|
||
};
|
||
const t = {
|
||
block: me.normal,
|
||
inline: fe.normal
|
||
};
|
||
this.options.pedantic ? (t.block = me.pedantic, t.inline = fe.pedantic) : this.options.gfm && (t
|
||
.block = me.gfm, this.options.breaks ? t.inline = fe.breaks : t.inline = fe.gfm), this
|
||
.tokenizer.rules = t
|
||
}
|
||
static get rules() {
|
||
return {
|
||
block: me,
|
||
inline: fe
|
||
}
|
||
}
|
||
static lex(e, t) {
|
||
return new ve(t).lex(e)
|
||
}
|
||
static lexInline(e, t) {
|
||
return new ve(t).inlineTokens(e)
|
||
}
|
||
lex(e) {
|
||
let t;
|
||
for (e = e.replace(/\r\n|\r/g, "\n"), this.blockTokens(e, this.tokens); t = this.inlineQueue
|
||
.shift();) this.inlineTokens(t.src, t.tokens);
|
||
return this.tokens
|
||
}
|
||
blockTokens(e, t = []) {
|
||
let n, i, s, r;
|
||
for (e = this.options.pedantic ? e.replace(/\t/g, " ").replace(/^ +$/gm, "") : e.replace(
|
||
/^( *)(\t+)/gm, ((e, t, n) => 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 ? '<pre><code class="' + this.options.langPrefix + X(
|
||
s) + '">' + (n ? e : X(e, !0)) + "</code></pre>\n" : "<pre><code>" + (n ? e : X(e, !
|
||
0)) + "</code></pre>\n"
|
||
}
|
||
blockquote(e) {
|
||
return `<blockquote>\n${e}</blockquote>\n`
|
||
}
|
||
html(e, t) {
|
||
return e
|
||
}
|
||
heading(e, t, n, i) {
|
||
if (this.options.headerIds) {
|
||
return `<h${t} id="${this.options.headerPrefix+i.slug(n)}">${e}</h${t}>\n`
|
||
}
|
||
return `<h${t}>${e}</h${t}>\n`
|
||
}
|
||
hr() {
|
||
return this.options.xhtml ? "<hr/>\n" : "<hr>\n"
|
||
}
|
||
list(e, t, n) {
|
||
const i = t ? "ol" : "ul";
|
||
return "<" + i + (t && 1 !== n ? ' start="' + n + '"' : "") + ">\n" + e + "</" + i + ">\n"
|
||
}
|
||
listitem(e, t, n) {
|
||
return `<li>${e}</li>\n`
|
||
}
|
||
checkbox(e) {
|
||
return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox"' + (this.options
|
||
.xhtml ? " /" : "") + "> "
|
||
}
|
||
paragraph(e) {
|
||
return `<p>${e}</p>\n`
|
||
}
|
||
table(e, t) {
|
||
return t && (t = `<tbody>${t}</tbody>`), "<table>\n<thead>\n" + e + "</thead>\n" + t +
|
||
"</table>\n"
|
||
}
|
||
tablerow(e) {
|
||
return `<tr>\n${e}</tr>\n`
|
||
}
|
||
tablecell(e, t) {
|
||
const n = t.header ? "th" : "td";
|
||
return (t.align ? `<${n} align="${t.align}">` : `<${n}>`) + e + `</${n}>\n`
|
||
}
|
||
strong(e) {
|
||
return `<strong>${e}</strong>`
|
||
}
|
||
em(e) {
|
||
return `<em>${e}</em>`
|
||
}
|
||
codespan(e) {
|
||
return `<code>${e}</code>`
|
||
}
|
||
br() {
|
||
return this.options.xhtml ? "<br/>" : "<br>"
|
||
}
|
||
del(e) {
|
||
return `<del>${e}</del>`
|
||
}
|
||
link(e, t, n) {
|
||
const i = re(this.options.sanitize, this.options.baseUrl, e);
|
||
if (null === i) return n;
|
||
let s = '<a href="' + (e = i) + '"';
|
||
return t && (s += ' title="' + t + '"'), s += ">" + n + "</a>", s
|
||
}
|
||
image(e, t, n) {
|
||
const i = re(this.options.sanitize, this.options.baseUrl, e);
|
||
if (null === i) return n;
|
||
let s = `<img src="${e=i}" alt="${n}"`;
|
||
return t && (s += ` title="${t}"`), s += this.options.xhtml ? "/>" : ">", 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 = "<p>An error occurred:</p><pre>" + X(i.message + "", !0) + "</pre>";
|
||
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 = /^</,
|
||
Ke = /^<\s*\//;
|
||
var Ze = Ie,
|
||
Ye = De,
|
||
Xe = Fe,
|
||
Je = ze;
|
||
var et = Ue,
|
||
tt = function(e, t) {
|
||
for (var n, i = function() {
|
||
var e = [];
|
||
return e.lastItem = function() {
|
||
return e[e.length - 1]
|
||
}, e
|
||
}(), s = e; e;) r();
|
||
|
||
function r() {
|
||
n = !0,
|
||
function() {
|
||
"\x3c!--" === e.substr(0, 4) ? (i = e.indexOf("--\x3e")) >= 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(
|
||
"</"), s(t), 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 '<span style="color: slategray">' + e + "</span>"
|
||
}
|
||
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 + "|" + /</.source + ")|(" + t().source + ")", "gmi");
|
||
return e.replace(l, (function(e, t, n) {
|
||
if (n) return i(n);
|
||
if ("<" === t) return "<";
|
||
var s;
|
||
a[t] ? s = a[t] : (s = r[o], a[t] = s);
|
||
var l = '<span style="color: #' + s + '">' + t + "</span>";
|
||
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(/^<a /,
|
||
`<a target="_blank" ${r?"":'rel="noreferrer noopener nofollow"'} `)
|
||
},
|
||
pt = () => (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),
|
||
`<pre rel="${n}">\n<code class="hljs language-${n}">${i.replace(/&/g,"&")}</code>\n</pre>`
|
||
};
|
||
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) =>
|
||
`<pre><code>${dt(t)}</code></pre>`)).replace(/!\[(.*?)\]\((.*?)\)/g, ((e, t, n) =>
|
||
`<img src="${n}" alt="${t}" />`)).replace(/\[(.*?)\]\((.*?)\)/g, ((e, t, n) =>
|
||
`<a href="${n}" target="_blank">${t}</a>`)).replace(/\n/g, "<br>")
|
||
}(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(
|
||
'<div class="atk-layer-dialog-wrap">\n <div class="atk-layer-dialog">\n <div class="atk-layer-dialog-content"></div>\n <div class="atk-layer-dialog-actions"></div>\n </div>\n </div>'
|
||
), 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(`<button data-action="confirm">${D("confirm")}</button>`);
|
||
return t.onclick = this.onBtnClick(e), this.$actions.appendChild(t), this
|
||
}
|
||
setNo(e) {
|
||
const t = y(`<button data-action="cancel">${D("cancel")}</button>`);
|
||
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(
|
||
'<div class="atk-loading atk-fade-in" style="display: none;">\n <div class="atk-loading-spinner">\n <svg viewBox="25 25 50 50"><circle cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"></circle></svg>\n </div>\n </div>'),
|
||
(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 = '<span class="atk-error-title">Artalk Error</span>') {
|
||
let i = e.querySelector(".atk-error-layer");
|
||
if (null === t) return void(null !== i && i.remove());
|
||
i || (i = y(`<div class="atk-error-layer">${n}<span class="atk-error-text"></span></div>`), 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('<div class="atk-checker-iframe-wrap"></div>'),
|
||
n = y('<iframe class="atk-fade-in" referrerpolicy="strict-origin-when-cross-origin"></iframe>');
|
||
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('<div class="atk-close-btn"><i class="atk-icon atk-icon-close"></i></div>');
|
||
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(
|
||
`<span><img class="atk-captcha-img" src="${e.get("img_data")||""}">${D("captchaCheck")}</span>`
|
||
);
|
||
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(`<span>${D("adminCheck")}</span>`),
|
||
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(
|
||
`<input id="check" type="${e.inputType||"text"}" autocomplete="off" required placeholder="">`
|
||
);
|
||
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 = "<div></div>") {
|
||
return this.$btn = y(`<span class="atk-plug-btn">${e}</span>`), this.$btn
|
||
}
|
||
usePanel(e = "<div></div>") {
|
||
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('<div class="atk-editor-travel-placeholder"></div>'));
|
||
const n = y("<div></div>");
|
||
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(
|
||
'<div class="atk-main-editor">\n <div class="atk-header">\n <input name="nick" class="atk-nick" type="text" required="required">\n <input name="email" class="atk-email" type="email" required="required">\n <input name="link" class="atk-link" type="url">\n </div>\n <div class="atk-textarea-wrap">\n <textarea class="atk-textarea"></textarea>\n </div>\n <div class="atk-plug-panel-wrap" style="display: none;"></div>\n <div class="atk-bottom">\n <div class="atk-item atk-plug-btn-wrap"></div>\n <div class="atk-item">\n <button type="button" class="atk-send-btn"></button>\n </div>\n </div>\n <div class="atk-notify-wrap"></div>\n</div>\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(
|
||
`<div class="atk-notify atk-fade-in" style="background-color: ${{s:"#57d59f",e:"#ff6f6c",w:"#ffc721",i:"#2ebcfc"}[n]}"><span class="atk-notify-content"></span></div>`
|
||
);
|
||
i.querySelector(".atk-notify-content").innerHTML = $(t).replace("\n", "<br/>"), 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(
|
||
'<div class="atk-sidebar-layer">\n <div class="atk-sidebar-inner">\n <div class="atk-sidebar-header">\n <div class="atk-sidebar-close"><i class="atk-icon atk-icon-close"></i></div>\n </div>\n <div class="atk-sidebar-iframe-wrap"></div>\n </div>\n</div>\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('<iframe referrerpolicy="strict-origin-when-cross-origin"></iframe>'),
|
||
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(
|
||
`<div class="atk-height-limit-btn">${D("readMore")}</span>`);
|
||
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('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
|
||
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('<span class="atk-badge"></span>');
|
||
i.innerText = t.replace("管理员", e.ctx.$t("admin")), i.style.backgroundColor = n || "", e
|
||
.$headerBadgeWrap.append(i)
|
||
}
|
||
if (e.data.is_pinned) {
|
||
const t = y(`<span class="atk-pinned-badge">${e.ctx.$t("pin")}</span>`);
|
||
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('<span class="atk-ua-wrap"></span>'), e.$header.append(t)), t.innerHTML = "", e.data
|
||
.ip_region) {
|
||
const n = y('<span class="atk-region-badge"></span>');
|
||
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('<span class="atk-ua ua-browser"></span>');
|
||
e.innerText = n, t.append(e)
|
||
}
|
||
if (String(i).trim()) {
|
||
const e = y('<span class="atk-ua ua-os"></span>');
|
||
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('<span class="atk-common-action-btn"></span>'), 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(`<span>${e.ctx.$t("reply")}</span>`);
|
||
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("<img />"),
|
||
i = e.conf.avatarURLBuilder;
|
||
if (n.src = i ? i(e.data) : e.comment.getGravatarURL(), e.data.link) {
|
||
const i = y('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
|
||
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 <div class="atk-collapsed">\n <span class="atk-text">${e.ctx.$t("collapsedMsg")}</span>\n <span class="atk-show-btn">${e.ctx.$t("expand")}</span>\n </div>`
|
||
);
|
||
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(
|
||
'<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>'
|
||
), 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 <div class="atk-reply-to">\n <div class="atk-meta">${e.ctx.$t("reply")} <span class="atk-nick"></span>:</div>\n <div class="atk-content"></div>\n </div>`
|
||
);
|
||
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(`<div class="atk-pending">${e.ctx.$t("pendingMsg")}</div>`);
|
||
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(
|
||
'<div class="atk-comment-wrap">\n <div class="atk-comment">\n <div class="atk-avatar"></div>\n <div class="atk-main">\n <div class="atk-header">\n <span class="atk-item atk-nick"></span>\n <span class="atk-badge-wrap"></span>\n <span class="atk-item atk-date"></span>\n </div>\n <div class="atk-body">\n <div class="atk-content"></div>\n </div>\n <div class="atk-footer">\n <div class="atk-actions"></div>\n </div>\n </div>\n </div>\n</div>\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(
|
||
'<div class="atk-comment-children"></div>'), 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(
|
||
`<div class="atk-list-read-more" style="display: none;">\n <div class="atk-list-read-more-inner">\n <div class="atk-loading-icon" style="display: none;"></div>\n <span class="atk-text">${this.origText}</span>\n </div>\n </div>`
|
||
), 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(
|
||
'<div class="atk-pagination-wrap">\n <div class="atk-pagination">\n <div class="atk-btn atk-btn-prev">Prev</div>\n <input type="text" class="atk-input" aria-label="Enter the number of page" />\n <div class="atk-btn atk-btn-next">Next</div>\n </div>\n </div>'
|
||
), 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(
|
||
'<div class="atk-list">\n <div class="atk-list-header">\n <div class="atk-comment-count">\n <div class="atk-text"></div>\n </div>\n <div class="atk-right-action">\n <span data-action="admin-close-comment" class="atk-hide" atk-only-admin-show></span>\n <span data-action="open-sidebar" class="atk-hide atk-on">\n <span class="atk-unread-badge" style="display: none;"></span>\n <div class="atk-text"></div>\n </span>\n </div>\n </div>\n <div class="atk-list-body">\n <div class="atk-list-comments-wrap"></div>\n </div>\n <div class="atk-list-footer">\n <div class="atk-copyright"></div>\n </div>\n</div>\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(
|
||
'<div class="atk-layer-wrap" style="display: none;"><div class="atk-layer-mask"></div></div>'
|
||
), 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(`<span>${e.errMsg},${D("listLoadFailMsg")}<br/></span>`);
|
||
if (e.retryFn) {
|
||
const n = y(`<span style="cursor:pointer;">${D("listRetry")}</span>`);
|
||
n.onclick = () => e.retryFn && e.retryFn(), t.appendChild(n)
|
||
}
|
||
if (e.onOpenSidebar) {
|
||
const n = y(
|
||
`<span atk-only-admin-show> | <span style="cursor:pointer;">${D("open")+D("ctrlCenter")}</span></span>`
|
||
);
|
||
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('<div class="atk-editor-plug-emoticons"></div>'), 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('<div class="atk-grp-wrap"></div>'), this.$panel.append(this.$grpWrap), this
|
||
.emoticons.forEach(((e, t) => {
|
||
const n = y('<div class="atk-grp" style="display: none;"></div>');
|
||
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('<span class="atk-item"></span>');
|
||
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(
|
||
'<div class="atk-grp-switcher"></div>'), this.$panel.append(this.$grpSwitcher), this
|
||
.emoticons.forEach(((e, t) => {
|
||
const n = y("<span />");
|
||
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(
|
||
`<img src="${n.val}" atk-emoticon="${n.key}">`)
|
||
}))
|
||
})), 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('<div class="atk-editor-plug-preview"></div>');
|
||
let e = D("preview");
|
||
kt() && (e +=
|
||
' <i title="Markdown is supported"><svg class="markdown" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"></path></svg></i>'
|
||
), 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(
|
||
`<div class="atk-send-reply">${D("reply")} <span class="atk-text"></span><span class="atk-cancel">×</span></div>`
|
||
), 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(
|
||
`<div class="atk-send-reply">${D("editCancel")} <span class="atk-cancel">×</span></div>`
|
||
);
|
||
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(
|
||
`<div class="atk-comment-closed">${D("onlyAdminCanReply")}</div>`)), 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+)/,
|
||
'<span class="atk-comment-count-num">$1</span>')
|
||
})()
|
||
})), 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(
|
||
'<span class="atk-arrow-down-icon"></span>'));
|
||
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('<ul class="atk-dropdown atk-fade-in"></ul>');
|
||
n.forEach(((e, t) => {
|
||
const n = e[0],
|
||
o = e[1],
|
||
a = y(
|
||
'<li class="atk-dropdown-item"><span></span></li>'),
|
||
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('<div class="atk-list-no-comment"></div>'), 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 <a href="https://artalk.js.org" target="_blank" title="Artalk v${Fn}">Artalk</a>`
|
||
)
|
||
}))
|
||
}, 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(
|
||
`<div>${D("updateMsg",{name:D(i<0?"frontend":"backend")})}<br/><br/><span style="color: var(--at-color-meta);">${D("currentVersion")}: ${D("frontend")} ${t} / ${D("backend")} ${n}</span><br/><br/></div>`
|
||
),
|
||
r = y(`<span style="cursor:pointer">${D("ignore")}</span>`);
|
||
r.onclick = () => {
|
||
Pt(e.$el.parentElement, null), jn = !0, e.ctx.fetch({
|
||
offset: 0
|
||
})
|
||
}, s.append(r), Pt(e.$el.parentElement, s,
|
||
'<span class="atk-warn-title">Artalk Warn</span>')
|
||
}(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
|